mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-08-28 00:12: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 missile* as_missile() { return nullptr; }
|
||||
|
||||
virtual bool is_disarmer() override { return false; }
|
||||
virtual bool is_disarmer() { return false; }
|
||||
|
||||
int hp;
|
||||
int invinc_end;
|
||||
@ -260,6 +260,7 @@ struct entity {
|
||||
void apply_grav();
|
||||
void apply_portal_grav();
|
||||
bool stay_on_screen(); /* returns true if flipped */
|
||||
void kill_off_screen(); /* returns true if flipped */
|
||||
virtual void act() { kino(); }
|
||||
/* for things which can act while not existing */
|
||||
virtual void unact() { }
|
||||
@ -582,6 +583,17 @@ struct snake : public enemy {
|
||||
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 {
|
||||
xy respawn_vel;
|
||||
xy siz() override { return {10, 10}; }
|
||||
|
@ -105,9 +105,18 @@ void entity::apply_walls() {
|
||||
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++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
if(walls[b].flags & W_DOWNWARD) continue;
|
||||
allside(x, y, b);
|
||||
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; }
|
||||
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++) {
|
||||
eWall b = current_room->at(x, y);
|
||||
allside(x, y, b);
|
||||
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; }
|
||||
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++) {
|
||||
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_BLOCK) {
|
||||
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++) {
|
||||
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_BLOCK) {
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
on_floor = false;
|
||||
on_ice = false;
|
||||
@ -451,7 +470,7 @@ void snake::act() {
|
||||
vel.x = zero_vel.x + dat.d * dat.modv * 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!");
|
||||
}
|
||||
}
|
||||
@ -690,4 +709,15 @@ cat::cat() {
|
||||
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];
|
||||
});
|
||||
|
||||
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) {
|
||||
m.next.rough_detect = 0.1;
|
||||
@ -158,7 +170,7 @@ void assign_potion_powers() {
|
||||
trap_disarm.which_weapon = wpn[1];
|
||||
using relist = vector<randeff*>;
|
||||
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("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] };
|
||||
|
Loading…
x
Reference in New Issue
Block a user