diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index 31589ea7..a4c19b22 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -395,6 +395,18 @@ struct kestrel : public enemy { int max_hp() { return 30; } }; +struct gridbug : public enemy { + int next_move; + xy siz() override { return {10, 10}; } + string glyph() override { return "x"; } + color_t color() override { return 0xD000D0FF; } + void act() override; + string get_name() override { return "grid bug"; } + string get_help() override { return "You are not sure whether this is some kind of insect or some glitch in the fabric of the reality."; } + int base_xp() { return 10; } + int max_hp() { return 10; } + }; + struct bat : public enemy { int next_change; xy siz() override { return {6, 6}; } diff --git a/rogueviz/ru/entity.cpp b/rogueviz/ru/entity.cpp index 12fa5a23..e8c59126 100644 --- a/rogueviz/ru/entity.cpp +++ b/rogueviz/ru/entity.cpp @@ -422,6 +422,68 @@ void kestrel::act() { } } +void gridbug::act() { + + if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) { + if(m.reduce_hp(15)) addMessage("The grid bug zaps you!"); + } + + if(gframeid < next_move || !visible(current_room) || gframeid < invinc_end) return; + auto gridbox = pixel_to_block(get_pixel_bbox()); + + array, room_y> times; + for(int y=0; yentities) if(&*e != this) { + auto obox = pixel_to_block(e->get_pixel_bbox()); + for(int x=obox.minx; x>> q; + + auto visit = [&] (int x, int y, ld t) { + q.push({-t, {x, y}}); + }; + + auto manbox = pixel_to_block(m.get_pixel_bbox()); + for(int x=manbox.minx; x memt) continue; + memt = t; + + auto move_to = [&] (int x1, int y1) { + if(x1 < 0 || y1 < 0 || x1 >= room_x || y1 >= room_y) return; + auto b = current_room->at(x1, y1); + flagtype blocking = (W_BLOCK | W_BLOCKBIRD); + if(walls[b].flags & blocking) return; + ld d = hdist(to_hyper(block_x*(x+.5), block_y*(y+.5)), to_hyper(block_x*(x1+.5), block_y*(y+1.5))) * 10; + if(x1 == origx && y1 == origy && rest > t+d) { rest = t+d; resx = x; resy = y; res_move_t = d; } + visit(x1, y1, t+d); + }; + + move_to(x+1, y); + move_to(x-1, y); + move_to(x, y+1); + move_to(x, y-1); + } + + next_move = gframeid + game_fps * res_move_t; + where = xy(block_x * (resx + .5), block_y * (resy + .5)); + } + void bat::act() { if(gframeid >= next_change && gframeid > invinc_end + 300) { next_change = gframeid + 300 + rand() % 300; diff --git a/rogueviz/ru/save.cpp b/rogueviz/ru/save.cpp index b4ab85dc..c1b78290 100644 --- a/rogueviz/ru/save.cpp +++ b/rogueviz/ru/save.cpp @@ -141,6 +141,12 @@ void load_room(fhstream& f, cell *c) { b->respawn = b->where; b->postfix(); r.entities.emplace_back(std::move(b)); } + else if(cap == "GRIDBUG") { + auto b = std::make_unique(); + sscanf(param.c_str(), "%lf%lf", &b->where.x, &b->where.y); + b->respawn = b->where; b->postfix(); + r.entities.emplace_back(std::move(b)); + } else if(cap == "KESTREL") { auto b = std::make_unique(); sscanf(param.c_str(), "%lf%lf%lf%lf", &b->where.x, &b->where.y, &b->vel.x, &b->vel.y);