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:
@@ -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;
|
||||
};
|
||||
|
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user