diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index f608a2c3..e388eff1 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -507,6 +507,32 @@ struct rope_platform : public moving_platform { void draw() override; }; +struct saw: public entity { + unique_ptr base; + string glyph() override { return "*"; } + color_t color() override { return walls[wWall].color; } + xy siz() override { return {18, 18}; } + string get_name() override { return "circular saw"; } + void act() override; + }; + +struct weaksaw : public saw { + color_t color() override { return walls[wWeakWall].color; } + string get_name() override { return "weak saw"; } + void attacked(int s, power *p) override; + }; + +struct woodsaw : public saw { + color_t color() override { return walls[wWoodWall].color; } + string get_name() override { return "wooden saw"; } + void attacked(int s, power *p) override; + }; + +struct fakesaw : public saw { + void attacked(int s, power *p) override; + void act() override; + }; + /* entities with a defined 'respawn' location */ struct located_entity : public entity { xy respawn; diff --git a/rogueviz/ru/entity.cpp b/rogueviz/ru/entity.cpp index dfd6f57e..5fba4830 100644 --- a/rogueviz/ru/entity.cpp +++ b/rogueviz/ru/entity.cpp @@ -669,6 +669,52 @@ void moving_platform::act() { where = location_at(gframeid); } +void saw::act() { + auto b = base->as_platform(); + if(!b) { addMessage("You have a vision of an otherworldly saw!"); existing = false; return; } + where = b->location_at(gframeid); + auto bb = get_pixel_bbox(); + if(intersect(bb, m.get_pixel_bbox())) { + if(m.reduce_hp(40)) addMessage("The " + get_name() + " shreds you!"); + } + } + +void weaksaw::attacked(int s, power *p) { + if(p->flags & WEAPON_AXE) { + addMessage("You smash the " + get_name() + "!"); + existing = false; + } + } + +void woodsaw::attacked(int s, power *p) { + if(p == fire_power) { + addMessage("You incinerate the " + get_name() + "!"); + existing = false; + } + } + +void fakesaw::act() { + auto b = base->as_platform(); + if(!b) { addMessage("You have a vision of an otherworldly saw!"); existing = false; return; } + where = b->location_at(gframeid); + auto bb = get_pixel_bbox(); + if(intersect(bb, m.get_pixel_bbox())) { + addMessage("This " + get_name() + " turned out to be an illusion!"); + existing = false; + } + if(m.can_see(self)) { + addMessage("You realize that the " + get_name() + " is an illusion!"); + existing = false; + } + } + +void fakesaw::attacked(int s, power *p) { + if(p == thief_power) { + addMessage("Your attack goes right through the " + get_name() + "!"); + existing = false; + } + } + void entity::apply_walls_reflect() { int loopcount = 0; again: diff --git a/rogueviz/ru/load-world.cpp b/rogueviz/ru/load-world.cpp index 9ddca00d..9efa5af8 100644 --- a/rogueviz/ru/load-world.cpp +++ b/rogueviz/ru/load-world.cpp @@ -326,6 +326,26 @@ void load_room(fhstream& f, cell *c) { b->a = get_xy(); b->b = get_xy(); b->period = get_ld(); b->shift = get_ld(); b->ratio = get_ld(); r.entities.emplace_back(std::move(b)); } + else if(cap == "SAW") { + auto b = std::make_unique(); nam(*b); + b->base = std::move(r.entities.back()); + r.entities.back() = std::move(b); + } + else if(cap == "WOODSAW") { + auto b = std::make_unique(); nam(*b); + b->base = std::move(r.entities.back()); + r.entities.back() = std::move(b); + } + else if(cap == "WEAKSAW") { + auto b = std::make_unique(); nam(*b); + b->base = std::move(r.entities.back()); + r.entities.back() = std::move(b); + } + else if(cap == "FAKESAW") { + auto b = std::make_unique(); nam(*b); + b->base = std::move(r.entities.back()); + r.entities.back() = std::move(b); + } else if(cap == "HINT") { auto b = std::make_unique(); b->respawn = get_xy(); b->size = get_xy();