mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-08-28 16:32:18 +00:00
ru:: hairsnakes implemented
This commit is contained in:
parent
b2c163ca6c
commit
c72b369aa5
@ -214,7 +214,7 @@ struct entity {
|
|||||||
virtual struct trader* as_trader() { return nullptr; }
|
virtual struct trader* as_trader() { return nullptr; }
|
||||||
virtual struct missile* as_missile() { return nullptr; }
|
virtual struct missile* as_missile() { return nullptr; }
|
||||||
|
|
||||||
virtual bool is_disarmer() override { return false; }
|
virtual bool is_disarmer() { return false; }
|
||||||
|
|
||||||
int hp;
|
int hp;
|
||||||
int invinc_end;
|
int invinc_end;
|
||||||
@ -260,6 +260,7 @@ struct entity {
|
|||||||
void apply_grav();
|
void apply_grav();
|
||||||
void apply_portal_grav();
|
void apply_portal_grav();
|
||||||
bool stay_on_screen(); /* returns true if flipped */
|
bool stay_on_screen(); /* returns true if flipped */
|
||||||
|
void kill_off_screen(); /* returns true if flipped */
|
||||||
virtual void act() { kino(); }
|
virtual void act() { kino(); }
|
||||||
/* for things which can act while not existing */
|
/* for things which can act while not existing */
|
||||||
virtual void unact() { }
|
virtual void unact() { }
|
||||||
@ -582,6 +583,17 @@ struct snake : public enemy {
|
|||||||
int max_hp() { return 30; }
|
int max_hp() { return 30; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct disnake : public snake {
|
||||||
|
color_t color() override { return 0x2020F0FF; }
|
||||||
|
void act() override;
|
||||||
|
bool is_disarmer() override { return true; }
|
||||||
|
string get_name() override { return "hairsnake"; }
|
||||||
|
string get_help() override { return "A magically animated hair."; }
|
||||||
|
int base_xp() { return 0; }
|
||||||
|
int max_hp() { return 1; }
|
||||||
|
virtual void unact() { destroyed = true; }
|
||||||
|
};
|
||||||
|
|
||||||
struct kestrel : public enemy {
|
struct kestrel : public enemy {
|
||||||
xy respawn_vel;
|
xy respawn_vel;
|
||||||
xy siz() override { return {10, 10}; }
|
xy siz() override { return {10, 10}; }
|
||||||
|
@ -105,9 +105,18 @@ void entity::apply_walls() {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto allside = [this] (int x, int y, eWall b) {
|
||||||
|
if(b == wRogueWallHidden && is_disarmer()) {
|
||||||
|
current_room->replace_block_frev(x, y, wRogueWall);
|
||||||
|
if(current_room->fov[y][x])
|
||||||
|
addMessage("Your hairsnake exposes a fake wall!");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for(int x = obb.minx; x < obb.maxx; x++) for(int y = obb.maxy; y < jbb.maxy; y++) {
|
for(int x = obb.minx; x < obb.maxx; x++) for(int y = obb.maxy; y < jbb.maxy; y++) {
|
||||||
eWall b = current_room->at(x, y);
|
eWall b = current_room->at(x, y);
|
||||||
if(walls[b].flags & W_DOWNWARD) continue;
|
if(walls[b].flags & W_DOWNWARD) continue;
|
||||||
|
allside(x, y, b);
|
||||||
if(walls[b].flags & blocking) {
|
if(walls[b].flags & blocking) {
|
||||||
if(walls[b].flags & W_BOUNCY) { vel.y = -vel.y; apply_grav(); apply_grav(); if(vel.y > 0) vel.y = 0; on_bounce = true; goto again; }
|
if(walls[b].flags & W_BOUNCY) { vel.y = -vel.y; apply_grav(); apply_grav(); if(vel.y > 0) vel.y = 0; on_bounce = true; goto again; }
|
||||||
on_floor = true;
|
on_floor = true;
|
||||||
@ -135,6 +144,7 @@ void entity::apply_walls() {
|
|||||||
|
|
||||||
for(int x = obb.minx; x < obb.maxx; x++) for(int y = jbb.miny; y < obb.miny; y++) {
|
for(int x = obb.minx; x < obb.maxx; x++) for(int y = jbb.miny; y < obb.miny; y++) {
|
||||||
eWall b = current_room->at(x, y);
|
eWall b = current_room->at(x, y);
|
||||||
|
allside(x, y, b);
|
||||||
if(walls[b].flags & W_BLOCK) {
|
if(walls[b].flags & W_BLOCK) {
|
||||||
if(walls[b].flags & W_BOUNCY) { vel.y = -vel.y; apply_grav(); apply_grav(); on_bounce = true; goto again; }
|
if(walls[b].flags & W_BOUNCY) { vel.y = -vel.y; apply_grav(); apply_grav(); on_bounce = true; goto again; }
|
||||||
vel.y /= 2;
|
vel.y /= 2;
|
||||||
@ -158,6 +168,7 @@ void entity::apply_walls() {
|
|||||||
|
|
||||||
for(int x = obb.maxx; x < jbb.maxx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
|
for(int x = obb.maxx; x < jbb.maxx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
|
||||||
eWall b = current_room->at(x, y);
|
eWall b = current_room->at(x, y);
|
||||||
|
allside(x, y, b);
|
||||||
if((walls[b].flags & W_DOWNWARD) && b == current_room->at(x-1, y)) continue;
|
if((walls[b].flags & W_DOWNWARD) && b == current_room->at(x-1, y)) continue;
|
||||||
if(walls[b].flags & W_BLOCK) {
|
if(walls[b].flags & W_BLOCK) {
|
||||||
if(walls[b].flags & W_BOUNCY) { vel.x = -vel.x; on_bounce = true; goto again; }
|
if(walls[b].flags & W_BOUNCY) { vel.x = -vel.x; on_bounce = true; goto again; }
|
||||||
@ -175,6 +186,7 @@ void entity::apply_walls() {
|
|||||||
|
|
||||||
for(int x = jbb.minx; x < obb.minx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
|
for(int x = jbb.minx; x < obb.minx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
|
||||||
eWall b = current_room->at(x, y);
|
eWall b = current_room->at(x, y);
|
||||||
|
allside(x, y, b);
|
||||||
if((walls[b].flags & W_DOWNWARD) && b == current_room->at(x+1, y)) continue;
|
if((walls[b].flags & W_DOWNWARD) && b == current_room->at(x+1, y)) continue;
|
||||||
if(walls[b].flags & W_BLOCK) {
|
if(walls[b].flags & W_BLOCK) {
|
||||||
if(walls[b].flags & W_BOUNCY) { vel.x = -vel.x; on_bounce = true; goto again; }
|
if(walls[b].flags & W_BOUNCY) { vel.x = -vel.x; on_bounce = true; goto again; }
|
||||||
@ -250,6 +262,13 @@ bool entity::stay_on_screen() {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void entity::kill_off_screen() {
|
||||||
|
if(where.x < l_margin_at && vel.x < 0) existing = false;
|
||||||
|
if(where.x > r_margin_at && vel.x > 0) existing = false;
|
||||||
|
if(where.y < t_margin_at && vel.y < 0) existing = false;
|
||||||
|
if(where.y > b_margin_at && vel.y > 0) existing = false;
|
||||||
|
}
|
||||||
|
|
||||||
void entity::kino() {
|
void entity::kino() {
|
||||||
on_floor = false;
|
on_floor = false;
|
||||||
on_ice = false;
|
on_ice = false;
|
||||||
@ -451,7 +470,7 @@ void snake::act() {
|
|||||||
vel.x = zero_vel.x + dat.d * dat.modv * dir;
|
vel.x = zero_vel.x + dat.d * dat.modv * dir;
|
||||||
dir = -dir;
|
dir = -dir;
|
||||||
}
|
}
|
||||||
if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) {
|
if(intersect(get_pixel_bbox(), m.get_pixel_bbox()) && gframeid > invinc_end) {
|
||||||
if(m.reduce_hp(25)) addMessage("The snake bites you!");
|
if(m.reduce_hp(25)) addMessage("The snake bites you!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,4 +709,15 @@ cat::cat() {
|
|||||||
col = hrand_elt(cat_colors);
|
col = hrand_elt(cat_colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disnake::act() {
|
||||||
|
snake::act();
|
||||||
|
kill_off_screen();
|
||||||
|
for(auto& e: current_room->entities)
|
||||||
|
if(e->hidden() && e->existing && intersect(e->get_pixel_bbox(), get_pixel_bbox())) {
|
||||||
|
addMessage("Your hear a sound of a " + e->get_name() + " colliding with a hairsnake.");
|
||||||
|
e->existing = false;
|
||||||
|
destroyed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,19 @@ randeff trap_detect_cross("Detect cross", "Lets you see traps and secret passage
|
|||||||
m.next.detect_cross = m.current.detect_cross + 0.01 / game_fps * m.current.stats[stat::wis];
|
m.next.detect_cross = m.current.detect_cross + 0.01 / game_fps * m.current.stats[stat::wis];
|
||||||
});
|
});
|
||||||
|
|
||||||
randeff trap_snake("Snake Hair", "Lets you create snakes that can be used to disarm traps and secret passages.", "You grow snakes on your head!", [] (data &d) { });
|
randeff trap_snake("Snake Hair", "Lets you create snakes that can be used to disarm traps and secret passages.", "You grow snakes on your head!", [] (data &d) {
|
||||||
|
if(d.mode == rev::start || (d.mode == rev::active && d.keystate == 1)) {
|
||||||
|
auto d = m.get_dat();
|
||||||
|
auto mi = std::make_unique<disnake>();
|
||||||
|
mi->where = m.where + xy(m.facing * m.get_scale() * m.siz().y * 0.45, 0);
|
||||||
|
mi->vel = m.vel + xy(m.facing * d.modv * 2, -d.modv * 3.5);
|
||||||
|
mi->clearg();
|
||||||
|
mi->invinc_end = gframeid + 50;
|
||||||
|
mi->postfix();
|
||||||
|
mi->dir = m.facing * 2;
|
||||||
|
current_room->entities.emplace_back(std::move(mi));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
randeff trap_disarm("Disarm traps", "Lets you see all traps on the level for a short time, and to attack them with your [weapon] to destroy them.", "You suddenly feel able to disarm traps with your [weapon]!", [] (data &d) {
|
randeff trap_disarm("Disarm traps", "Lets you see all traps on the level for a short time, and to attack them with your [weapon] to destroy them.", "You suddenly feel able to disarm traps with your [weapon]!", [] (data &d) {
|
||||||
m.next.rough_detect = 0.1;
|
m.next.rough_detect = 0.1;
|
||||||
@ -158,7 +170,7 @@ void assign_potion_powers() {
|
|||||||
trap_disarm.which_weapon = wpn[1];
|
trap_disarm.which_weapon = wpn[1];
|
||||||
using relist = vector<randeff*>;
|
using relist = vector<randeff*>;
|
||||||
find_power("health").randeffs = relist{ pick(&health_heal, &health_regen, &health_protect), random_powers[0] };
|
find_power("health").randeffs = relist{ pick(&health_heal, &health_regen, &health_protect), random_powers[0] };
|
||||||
find_power("the thief").randeffs = relist{ pick(&trap_detect, &trap_snake, &trap_disarm), random_powers[1] };
|
find_power("the thief").randeffs = relist{ pick(&trap_detect, &trap_snake, &trap_disarm, &trap_detect_cross), random_powers[1] };
|
||||||
find_power("polymorph").randeffs = relist{ pick(&morph_cat, &morph_capy), random_powers[2] };
|
find_power("polymorph").randeffs = relist{ pick(&morph_cat, &morph_capy), random_powers[2] };
|
||||||
find_power("reach").randeffs = relist{ pick(&jump_double, &jump_high, &jump_bubble, &jump_light), random_powers[3] };
|
find_power("reach").randeffs = relist{ pick(&jump_double, &jump_high, &jump_bubble, &jump_light), random_powers[3] };
|
||||||
find_power("fire").randeffs = relist{ pick(&fire_spit, &fire_weapon), random_powers[4] };
|
find_power("fire").randeffs = relist{ pick(&fire_spit, &fire_weapon), random_powers[4] };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user