1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-06-26 15:12:48 +00:00

ru:: mods, used to let fiery weapon work

This commit is contained in:
Zeno Rogue 2025-05-24 17:15:01 +02:00
parent 25f095d225
commit 299a3b64c6
4 changed files with 47 additions and 6 deletions

View File

@ -26,6 +26,8 @@ struct randeff {
randeff (string name, string desc, string effect, powerfun act) : name(name), desc(desc), effect(effect), act(act) {} randeff (string name, string desc, string effect, powerfun act) : name(name), desc(desc), effect(effect), act(act) {}
}; };
enum class mod { burning, freezing };
struct power { struct power {
int key; int key;
string name; string name;
@ -40,6 +42,7 @@ struct power {
int random_flavor; int random_flavor;
vector<struct randeff*> randeffs; vector<struct randeff*> randeffs;
void init(); void init();
vector<pair<mod, int>> mods;
hr::function<void(data&)> act, paused_act, dead_act; hr::function<void(data&)> act, paused_act, dead_act;
hr::function<string()> get_name; hr::function<string()> get_name;
hr::function<string()> get_desc; hr::function<string()> get_desc;
@ -291,6 +294,7 @@ struct statdata {
statarray<ld> stats; statarray<ld> stats;
int jump_control, coyote_time, hallucinating; int jump_control, coyote_time, hallucinating;
void reset(); void reset();
vector<tuple<power*, mod, int>> mods;
}; };
struct man : public entity { struct man : public entity {

View File

@ -42,6 +42,7 @@ void statdata::reset() {
coyote_time = 0; coyote_time = 0;
jump_control = 0; jump_control = 0;
hallucinating = false; hallucinating = false;
mods.clear();
} }
void man::act() { void man::act() {
@ -55,6 +56,8 @@ void man::act() {
auto h = max_hp(); auto h = max_hp();
current = next; current = next;
next.reset(); next.reset();
for(auto& po: powers) po.mods.clear();
for(auto& [po, type, val]: current.mods) po->mods.emplace_back(type, val);
if(h != max_hp()) if(h != max_hp())
hp = randround(1. * hp * max_hp() / h); hp = randround(1. * hp * max_hp() / h);
auto dat = get_dat(); auto dat = get_dat();

View File

@ -26,7 +26,22 @@ string addqof(string base, power *p) {
power& power::be_weapon() { power& power::be_weapon() {
flags |= WEAPON; flags |= WEAPON;
picked_up = [this] (int x) { qty_owned += x; qty_filled = max(qty_filled, x); }; picked_up = [this] (int x) { qty_owned += x; qty_filled = max(qty_filled, x); };
auto gn = get_name; get_name = [gn, this] { return addqof(gn(), this); }; auto gn = get_name; get_name = [gn, this] {
string s = addqof(gn(), this);
for(auto& [m, qty]: mods) {
if(m == mod::burning) s = "flaming " + s;
if(m == mod::freezing) s = "freezing " + s;
}
return s;
};
auto gc = get_color; get_color = [gc, this] {
auto col = gc();
for(auto& [m, qty]: mods) {
if(m == mod::burning) col = gradient(0xFFFF00FF, 0xFF0000FF, -1, sin(ticks/100), 1);
if(m == mod::freezing) col = 0x8080FFFF;
}
return col;
};
return self; return self;
} }
@ -305,15 +320,31 @@ void gen_powers() {
m.attack_facing = m.facing; m.attack_when = gframeid; m.attack_facing = m.facing; m.attack_when = gframeid;
auto pb = m.get_pixel_bbox_at(xy{m.where.x + m.attack_facing * m.dsiz().x, m.where.y}); auto pb = m.get_pixel_bbox_at(xy{m.where.x + m.attack_facing * m.dsiz().x, m.where.y});
auto bb = pixel_to_block(pb); auto bb = pixel_to_block(pb);
for(auto& e: current_room->entities) if(e->existing && intersect(e->get_pixel_bbox(), pb)) e->attacked((m.current.stats[stat::str] + 1) * 3 / 2); for(auto& e: current_room->entities)
if(e->existing && intersect(e->get_pixel_bbox(), pb)) {
int sav = e->invinc_end;
e->attacked((m.current.stats[stat::str] + 1) * 3 / 2);
for(auto& [m, qty]: d.p->mods) {
if(m == mod::burning) { e->invinc_end = sav; e->attacked(qty); }
if(m == mod::freezing) { e->invinc_end = sav; e->attacked(qty); }
}
}
for(int y=bb.miny; y<bb.maxy; y++) for(int y=bb.miny; y<bb.maxy; y++)
for(int x=bb.minx; x<bb.maxx; x++) { for(int x=bb.minx; x<bb.maxx; x++) {
int b = current_room->at(x, y); int b = current_room->at(x, y);
if(b == wDoor) { if(b == wDoor) {
current_room->replace_block(x, y, wSmashedDoor); current_room->replace_block_frev(x, y, wSmashedDoor);
addMessage("You smash the door!"); addMessage("You smash the door!");
auto cr = current_room; }
add_revert(fountain_revert, [cr, x, y] { cr->replace_block(x, y, wDoor); }); for(auto& [m, qty]: d.p->mods) {
if(m == mod::burning && b == wWoodWall) {
current_room->replace_block_frev(x, y, wAir);
addMessage("You burn the wall!");
}
if(m == mod::freezing && b == wWater) {
current_room->replace_block_frev(x, y, wFrozen);
addMessage("You freeze the water!");
}
} }
} }
}).be_weapon(), }).be_weapon(),

View File

@ -82,7 +82,10 @@ randeff fire_spit("Fiery Spit", "Lets you spit fire.", "You feel fire in your mo
current_room->entities.emplace_back(std::move(mi)); current_room->entities.emplace_back(std::move(mi));
} }
}); });
randeff fire_weapon("Fiery Weapon", "Attacks with your [weapon] set things on fire.", "Your hands glow, and your [weapon] burst into flame!", [] (data &d) { }); randeff fire_weapon("Fiery Weapon", "Attacks with your [weapon] set things on fire.", "Your hands glow, and your [weapon] burst into flame!", [] (data &d) {
if(d.mode == rev::active)
m.next.mods.emplace_back(d.re->which_weapon, mod::burning, 2 * m.current.stats[stat::wis] + 1e-6);
});
// morph powers // morph powers
randeff morph_cat("Cat", "Turns you into a cat.", "You turn into a cat!", [] (data &d) { }); randeff morph_cat("Cat", "Turns you into a cat.", "You turn into a cat!", [] (data &d) { });