diff --git a/rogueviz/ru/classes.cpp b/rogueviz/ru/classes.cpp index 59894e8f..2c354cf8 100644 --- a/rogueviz/ru/classes.cpp +++ b/rogueviz/ru/classes.cpp @@ -228,6 +228,8 @@ struct entity { data get_dat(); + virtual bool hidden() { return false; } + struct bbox get_pixel_bbox_at(xy, ld scalex = 1, ld scaley = 1); struct bbox get_pixel_bbox() { return get_pixel_bbox_at(where); } @@ -295,6 +297,7 @@ struct entity { struct statdata { statarray stats; int jump_control, coyote_time, hallucinating; + ld detect_area; void reset(); vector> mods; }; @@ -326,6 +329,7 @@ struct man : public entity { virtual int max_hp() { return 10 * current.stats[stat::con]; } + bool can_see(entity& e); man() { facing = 1; attack_facing = 1; for(auto s: allstats) base_stats[s] = 10; @@ -465,6 +469,7 @@ struct vtrap : public entity { xy siz() override { return {6, 18}; } string glyph() override { return "^"; } color_t color() override { return 0xD00000FF; } + bool hidden() override { return true; } void act() override; string get_name() override { return "moving trap"; } string get_help() override { return "A deadly but invisible trap."; } diff --git a/rogueviz/ru/man.cpp b/rogueviz/ru/man.cpp index 298f85da..f178346f 100644 --- a/rogueviz/ru/man.cpp +++ b/rogueviz/ru/man.cpp @@ -41,6 +41,7 @@ void statdata::reset() { for(auto i: allstats) stats[i] = m.base_stats[i]; coyote_time = 0; jump_control = 0; + detect_area = 0; hallucinating = false; mods.clear(); } @@ -85,6 +86,11 @@ void man::act() { check_fountains(); } +bool man::can_see(entity& e) { + ld d = hdist(to_hyper(m.where), to_hyper(e.where)); + return d < inverse_wvolarea_auto(m.current.detect_area); + } + void man::on_kill() { entity::on_kill(); if(extra_life->flags & ACTIVE) diff --git a/rogueviz/ru/randeff.cpp b/rogueviz/ru/randeff.cpp index 75a813a7..15e09bf2 100644 --- a/rogueviz/ru/randeff.cpp +++ b/rogueviz/ru/randeff.cpp @@ -31,7 +31,20 @@ randeff jump_bubble("Bubble", "Lets you create bubbles to reach higher places.", randeff jump_light("Lightness", "Causes you to be less affected by gravity.", "You feel lighter!", [] (data &d) { }); // trap powers -randeff trap_detect("Detect traps", "Lets you see traps and secret passages in a circle around you.", "You see things you could not see before!", [] (data &d) { }); +randeff trap_detect("Detect traps", "Lets you see traps and secret passages in a circle around you.", "You see things you could not see before!", [] (data &d) { + bool grow = gframeid > m.last_action + 10; + auto& nd = m.next.detect_area; + nd = m.current.detect_area; + if(grow) { + nd += 0.01 / game_fps * m.current.stats[stat::wis]; + if(nd > 5) nd = 5; + } + else { + nd *= (1 - 5. / game_fps); + if(nd < 0) nd = 0; + } + }); + 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_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) { }); diff --git a/rogueviz/ru/render.cpp b/rogueviz/ru/render.cpp index cf23208f..69c9685a 100644 --- a/rogueviz/ru/render.cpp +++ b/rogueviz/ru/render.cpp @@ -263,14 +263,25 @@ void man::draw() { } } effects.resize(efs - effects.begin()); + + if(m.current.detect_area > 0) { + ld r = inverse_wvolarea_auto(m.current.detect_area); + for(int a=0; a<=360; a++) { + auto h = from_hyper(eupush(to_hyper(m.where)) * xspinpush0(a*1._deg, r)); + curvepoint(eupush(h.x, h.y) * C0); + } + queuecurve(scrm, 0x800080, 0, PPR::LINE); + } } void render_room_objects(room *r) { initquickqueue(); if(r == current_room && m.visible_inv() && m.existing) m.draw(); for(auto& e: r->entities) - if(e->existing && (cmode == mode::editmap || (e->visible(r) && e->visible_inv()))) + if(e->existing && (cmode == mode::editmap || (e->visible(r) && e->visible_inv()))) { + if(e->hidden() && !m.can_see(*e)) continue; e->draw(); + } quickqueue(); }