1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-05-16 22:24:07 +00:00

ru:: snakes and kestrels

This commit is contained in:
Zeno Rogue 2025-05-04 10:03:09 +02:00
parent 60293264a6
commit e0f60cb447
5 changed files with 122 additions and 4 deletions

View File

@ -303,6 +303,27 @@ struct boar : public enemy {
string get_help() override { return "Beware their tusks."; }
};
struct snake : public enemy {
int dir;
xy siz() override { return {18, 8}; }
string glyph() override { return "S"; }
color_t color() override { return 0x20D020FF; }
void act() override;
void attacked(int s) override;
string get_name() override { return "snake"; }
string get_help() override { return "A nasty dungeon snake."; }
};
struct kestrel : public enemy {
xy siz() override { return {10, 10}; }
string glyph() override { return "K"; }
color_t color() override { return 0xD0A0A0FF; }
void act() override;
void attacked(int s) override;
string get_name() override { return "kestrel"; }
string get_help() override { return "A standard dungeon kestrel."; }
};
struct hint : public entity {
string hint_text;
int state;

View File

@ -288,6 +288,26 @@ void boar::attacked(int dmg) {
if(on_floor) vel.x = dat.d * dat.modv * s * 2, vel.y = -dat.d * dat.modv * 2.5;
}
void snake::act() {
kino();
if(abs(vel.x) < 1e-6) {
auto dat = get_dat();
vel.x = zero_vel.x + dat.d * dat.modv * dir;
dir = -dir;
}
if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) {
if(m.reduce_hp(25)) addMessage("The snake bites you!");
}
}
void snake::attacked(int dmg) {
current_target = this;
reduce_hp(dmg);
if(!existing) addMessage("You kill the snake."); else addMessage("You hit the snake.");
if(where.x < m.where.x) vel.x = -abs(vel.x);
if(where.x > m.where.x) vel.x = +abs(vel.x);
}
void hint::act() {
bool cur = intersect(get_pixel_bbox(), m.get_pixel_bbox());
if(cur && !state) {
@ -323,5 +343,60 @@ void moving_platform::act() {
where = location_at(gframeid);
}
void kestrel::act() {
int loopcount = 0;
again:
loopcount++;
auto obb = pixel_to_block(get_pixel_bbox());
auto nbb = pixel_to_block(get_pixel_bbox_at(where + vel));
auto jbb = join(obb, nbb);
flagtype blocking = (W_BLOCK | W_BLOCKBIRD);
if(loopcount >= 100) return;
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 & blocking) {
vel.y = -vel.y; goto again;
}
}
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);
if(walls[b].flags & blocking) {
vel.y = -vel.y; goto again;
}
}
for(int x = nbb.minx; x < nbb.maxx; x++) for(int y = jbb.miny; y < jbb.maxy; y++) {
eWall b = current_room->at(x, y);
if(walls[b].flags & blocking) {
vel.x = -vel.x; goto again;
}
}
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);
if(walls[b].flags & blocking) {
vel.x = -vel.x; goto again;
}
}
apply_vel();
if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) {
if(m.reduce_hp(15)) addMessage("The kestrel claws you!");
}
}
void kestrel::attacked(int dmg) {
current_target = this;
reduce_hp(dmg);
if(!existing) addMessage("You kill the kestrel."); else addMessage("You hit the kestrel.");
if(where.x < m.where.x) vel.x = -abs(vel.x);
if(where.x > m.where.x) vel.x = +abs(vel.x);
}
}

View File

@ -64,6 +64,7 @@ flagtype W_STAIRCASE = 8;
flagtype W_PAIN = 16;
flagtype W_BOUNCY = 32;
flagtype W_FROZEN = 64;
flagtype W_BLOCKBIRD = 128;
constexpr int qwall = int(wGUARD);
@ -71,8 +72,8 @@ ruwall walls[qwall] = {
{"air", ".", 0x40404080, W_TRANS, "Looks like an empty space, but actually necessary for survival."},
{"wall", "#", 0xFFFFFFFF, W_BLOCK, "These kinds of tough walls can never be destroyed."},
{"bouncy wall", "#", 0x80FF80FF, W_BLOCK | W_BOUNCY, "Like walls, but things bounce off them."},
{"spike", "^", 0xC08080FF, W_TRANS | W_PAIN, "Dangerous!"},
{"water", "~", 0x0000FFFF, W_BLOCK | W_TRANS, "Not used yet."},
{"spike", "^", 0xC08080FF, W_TRANS | W_PAIN | W_BLOCKBIRD, "Dangerous!"},
{"water", "~", 0x0000FFFF, W_BLOCK | W_TRANS | W_BLOCKBIRD, "Not used yet."},
{"frozen water", "#", 0xC0C0FFFF, W_BLOCK | W_FROZEN, "Water magically turned into a slippery wall."},
{"door", "+", 0xC06000FF, W_BLOCK, "Attack the doors with your weapon to open them."},
{"smashed door", "'", 0xC06000FF, W_TRANS, "This door has been already opened."},
@ -81,9 +82,9 @@ ruwall walls[qwall] = {
{"magic fountain (active)", "!", 0xA0A0FFFF, W_TRANS, "Wow! An active magic fountain!"},
{"blue portal", "=", 0x4040C0FF, W_TRANS, "Blue portal."},
{"orange portal", "=", 0xC08040FF, W_TRANS, "Orange portal."},
{"platform", "-", 0xFFFFFFFF, W_PLATFORM | W_TRANS, "You can fall down through such platforms."},
{"platform", "-", 0xFFFFFFFF, W_PLATFORM | W_TRANS | W_BLOCKBIRD, "You can fall down through such platforms."},
{"staircase", "-", 0xFFFF80FF, W_PLATFORM | W_TRANS | W_STAIRCASE, "You can climb staircases and ladders." },
{"column", "|", 0x40404080, W_TRANS, "A background decoration." },
{"column", "|", 0x40404080, W_TRANS | W_BLOCKBIRD, "A background decoration." },
{"forge", "&", 0xB0202080, W_TRANS | W_PAIN, "Used by runesmiths."},
};

View File

@ -425,6 +425,14 @@ What a shiny crystal ball!
ITEM 75 200 20
gold
You found 20 gold pieces
KESTREL 85 66 15 15
KESTREL 527 65 20 10
KESTREL 309 211 10 20
KESTREL 100 190 25 5
KESTREL 561 198 25 5
SNAKE 111 220 1
SNAKE 549 234 1
SNAKE 493 135 1
OK
MOVE 2 Dungeon Entrance

View File

@ -134,6 +134,19 @@ void load_room(fhstream& f, cell *c) {
b->respawn = b->where;
r.entities.emplace_back(std::move(b));
}
else if(cap == "KESTREL") {
auto b = std::make_unique<kestrel>();
sscanf(param.c_str(), "%lf%lf%lf%lf", &b->where.x, &b->where.y, &b->vel.x, &b->vel.y);
b->vel *= xy(block_x, block_y) / game_fps;
b->respawn = b->where;
r.entities.emplace_back(std::move(b));
}
else if(cap == "SNAKE") {
auto b = std::make_unique<snake>();
sscanf(param.c_str(), "%lf%lf%d", &b->where.x, &b->where.y, &b->dir);
b->respawn = b->where;
r.entities.emplace_back(std::move(b));
}
else if(cap == "FERRIS") {
ld cx, cy, radius; int qty;
sscanf(param.c_str(), "%lf%lf%lf%d", &cx, &cy, &radius, &qty);