1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-09-03 19:27:54 +00:00

ru:: trap disarm

This commit is contained in:
Zeno Rogue
2025-08-01 17:06:38 +02:00
parent c7a40edb66
commit b2c163ca6c
5 changed files with 48 additions and 3 deletions

View File

@@ -26,7 +26,7 @@ struct randeff {
randeff (string name, string desc, string effect, powerfun act) : name(name), desc(desc), effect(effect), act(act) {}
};
enum class mod { burning, freezing };
enum class mod { burning, freezing, disarming };
struct power {
int key;
@@ -214,6 +214,8 @@ struct entity {
virtual struct trader* as_trader() { return nullptr; }
virtual struct missile* as_missile() { return nullptr; }
virtual bool is_disarmer() override { return false; }
int hp;
int invinc_end;
@@ -310,7 +312,7 @@ struct entity {
struct statdata {
statarray<ld> stats;
int jump_control, coyote_time, hallucinating;
ld detect_area, detect_cross;
ld detect_area, detect_cross, rough_detect;
void reset();
vector<tuple<power*, mod, int>> mods;
};

View File

@@ -43,6 +43,7 @@ void statdata::reset() {
jump_control = 0;
detect_area = 0;
detect_cross = 0;
rough_detect = 0;
hallucinating = false;
mods.clear();
}
@@ -139,6 +140,10 @@ void man::launch_attack(power *p, int fac, boxfun f) {
for(auto& [m, qty]: p->mods) {
if(m == mod::burning) { e->invinc_end = sav; e->attacked(qty); }
if(m == mod::freezing) { e->invinc_end = sav; e->attacked(qty); }
if(m == mod::disarming && e->hidden()) {
e->existing = false;
addMessage("You have disarmed a "+e->get_name()+".");
}
}
}
for(int y=bb.miny; y<bb.maxy; y++)
@@ -157,6 +162,10 @@ void man::launch_attack(power *p, int fac, boxfun f) {
current_room->replace_block_frev(x, y, wFrozen);
addMessage("You freeze the water!");
}
if(m == mod::disarming && b == wRogueWallHidden) {
current_room->replace_block_frev(x, y, wRogueWall);
addMessage("You open a secret passage!");
}
}
}
}

View File

@@ -31,12 +31,14 @@ power& power::be_weapon() {
for(auto& [m, qty]: mods) {
if(m == mod::burning) s = "flaming " + s;
if(m == mod::freezing) s = "freezing " + s;
if(m == mod::disarming) s = "disarming " + s;
}
return s;
};
auto gc = get_color; get_color = [gc, this] {
auto col = gc();
for(auto& [m, qty]: mods) {
if(m == mod::disarming) col = 0x4040C0FF;
if(m == mod::burning) col = gradient(0xFFFF00FF, 0xFF0000FF, -1, sin(ticks/100), 1);
if(m == mod::freezing) col = 0x8080FFFF;
}

View File

@@ -50,7 +50,12 @@ randeff trap_detect_cross("Detect cross", "Lets you see traps and secret passage
});
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) { });
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;
if(d.mode == rev::active)
m.next.mods.emplace_back(d.re->which_weapon, mod::disarming, m.current.stats[stat::wis]);
});
// health powers
randeff health_heal("Healing", "Instantly heals you.", "You feel healthier!", [] (data &d) {

View File

@@ -287,6 +287,33 @@ void man::draw() {
});
}
if(m.current.rough_detect > 0) {
ld r = inverse_wvolarea_auto(m.current.rough_detect);
auto h0 = to_hyper(m.where);
bool found = false;
for(auto& e: current_room->entities) if(e->existing && e->hidden() && hdist(h0, to_hyper(e->where)) < r) found = true;
if(!found) current_room->bfs(xy_to_block(m.where), [&] (intxy xy) {
if(hdist(h0, block_to_hyper(xy)) > r) return false;
auto what = current_room->at(xy);
if(what == wRogueWallHidden) { found = true; return false; }
return true;
});
if(found) {
auto T = eupush(h0);
for(int a=0; a<=360; a++) {
auto h = from_hyper(T * xspinpush0(a*1._deg, r));
curvepoint(eupush(h.x, h.y) * C0);
}
vid.linewidth *= 3;
queuecurve(scrm, 0xFF000080, 0, PPR::LINE);
vid.linewidth /= 3;
}
}
if(m.current.detect_cross > 0) for(int d: {0, 1, 2, 3}) {
transmatrix T = eupush(to_hyper(m.where)) * spin(90._deg * d);
ld dist = 0;