mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2026-01-02 02:19:02 +00:00
reverts are now string-based
This commit is contained in:
@@ -151,7 +151,7 @@ struct room {
|
||||
void replace_block_frev(int x, int y, eWall w) {
|
||||
auto orig = at(x, y);
|
||||
replace_block(x, y, w);
|
||||
add_revert(fountain_revert, [this, x, y, orig] { replace_block(x, y, orig); });
|
||||
add_revert(fountain_revert, {"BLOCK", roomname, its(x), its(y), its(orig)});
|
||||
}
|
||||
|
||||
void replace_block_frev(intxy xy, eWall w) { replace_block_frev(xy.x, xy.y, w); }
|
||||
@@ -688,9 +688,8 @@ struct item : public entity {
|
||||
kino();
|
||||
if(intersect(get_pixel_bbox(), m.get_pixel_bbox())) {
|
||||
addMessage(pickup_message);
|
||||
int q0 = powers[id].qty_filled;
|
||||
int q1 = powers[id].qty_owned;
|
||||
add_revert(death_revert, [this, q0, q1] { existing = true; powers[id].qty_filled = q0; powers[id].qty_owned = q1; });
|
||||
add_revert(death_revert, {"ITEM", powers[id].name, its(powers[id].qty_filled), its(powers[id].qty_owned)});
|
||||
add_revert(death_revert, {"EXIST", name});
|
||||
powers[id].picked_up(qty);
|
||||
existing = false;
|
||||
}
|
||||
|
||||
@@ -162,11 +162,15 @@ void render_the_map();
|
||||
void shuffle_all();
|
||||
void assign_potion_powers();
|
||||
|
||||
using revert_stack = vector<reaction_t>;
|
||||
using revert_type = vector<string>;
|
||||
|
||||
using revert_stack = vector<revert_type>;
|
||||
|
||||
revert_stack death_revert, fountain_revert;
|
||||
|
||||
void add_revert(revert_stack& s, const reaction_t& what);
|
||||
void add_revert(revert_stack& s, const revert_type& what);
|
||||
|
||||
void revert(const revert_type& r);
|
||||
|
||||
void revert_all(revert_stack& s);
|
||||
|
||||
@@ -177,4 +181,7 @@ struct power& find_power(string name);
|
||||
tuple<struct xy, ld, int> get_next_room(struct xy w, room *r, int which = -1);
|
||||
|
||||
extern shiftmatrix scrm;
|
||||
|
||||
struct hr_name_error : hr_exception { hr_name_error(const char *s) : hr_exception(s) {} };
|
||||
|
||||
}
|
||||
|
||||
@@ -116,12 +116,12 @@ void man::on_kill() {
|
||||
addMessage("You die... permanently. You will have to create a new character. Or just press [key:Extra Life] for a narrative cheat.");
|
||||
}
|
||||
|
||||
void add_revert(revert_stack& s, const reaction_t& what) {
|
||||
void add_revert(revert_stack& s, const revert_type& what) {
|
||||
s.push_back(what);
|
||||
}
|
||||
|
||||
void revert_all(revert_stack& s) {
|
||||
while(!s.empty()) { s.back()(); s.pop_back(); }
|
||||
while(!s.empty()) { revert(s.back()); s.pop_back(); }
|
||||
}
|
||||
|
||||
void man::launch_attack(power *p, int fac, boxfun f) {
|
||||
|
||||
@@ -215,9 +215,7 @@ int gold_id;
|
||||
power *dexmode;
|
||||
|
||||
void power_death_revert(power& p) {
|
||||
int q0 = p.qty_filled;
|
||||
int q1 = p.qty_owned;
|
||||
add_revert(death_revert, [&p, q0, q1] { p.qty_filled = q0; p.qty_owned = q1; });
|
||||
add_revert(death_revert, {"ITEM", p.name, its(p.qty_filled), its(p.qty_owned)});
|
||||
}
|
||||
|
||||
void gen_powers() {
|
||||
@@ -515,7 +513,7 @@ void gen_powers() {
|
||||
addMessage(si->pickup_message);
|
||||
power_death_revert(powers[si->id]);
|
||||
powers[si->id].qty_owned += si->qty; powers[si->id].qty_filled += si->qty1;
|
||||
add_revert(death_revert, [si] { si->existing = true; });
|
||||
add_revert(death_revert, {"EXIST", si->name});
|
||||
si->existing = false;
|
||||
}
|
||||
else if(it == 0 && on && si->existing && si->bought) {
|
||||
@@ -523,7 +521,7 @@ void gen_powers() {
|
||||
addMessage("You get some gold.");
|
||||
power_death_revert(powers[gold_id]);
|
||||
powers[gold_id].qty_owned += si->price; powers[gold_id].qty_filled += si->price;
|
||||
add_revert(death_revert, [si] { si->existing = true; });
|
||||
add_revert(death_revert, {"EXIST", si->name});
|
||||
si->existing = false;
|
||||
}
|
||||
else if((it ? !done_something : on) && !si->existing && !si->bought) {
|
||||
@@ -531,7 +529,7 @@ void gen_powers() {
|
||||
addMessage("You rethink your purchase.");
|
||||
power_death_revert(powers[si->id]);
|
||||
powers[si->id].qty_owned -= si->qty; powers[si->id].qty_filled -= si->qty1;
|
||||
add_revert(death_revert, [si] { si->existing = false; });
|
||||
add_revert(death_revert, {"UNEXIST", si->name});
|
||||
si->existing = true;
|
||||
}
|
||||
else if((it ? !done_something : on) && !si->existing && si->bought) {
|
||||
@@ -539,7 +537,7 @@ void gen_powers() {
|
||||
addMessage("You rethink your actions.");
|
||||
power_death_revert(powers[gold_id]);
|
||||
powers[gold_id].qty_owned -= si->price; powers[gold_id].qty_filled -= si->price;
|
||||
add_revert(death_revert, [si] { si->existing = false; });
|
||||
add_revert(death_revert, {"UNEXIST", si->name});
|
||||
si->existing = true;
|
||||
}
|
||||
else if(it == 0 && on_trader && !si->existing && d.p->qty_owned >= si->price) {
|
||||
@@ -548,7 +546,7 @@ void gen_powers() {
|
||||
power_death_revert(powers[gold_id]);
|
||||
powers[gold_id].qty_owned -= si->price; powers[gold_id].qty_filled -= si->price;
|
||||
si->existing = true; si->bought = true;
|
||||
add_revert(death_revert, [si] { si->existing = false; si->bought = false; });
|
||||
add_revert(death_revert, {"UNBOUGHT", si->name});
|
||||
}
|
||||
else if(it == 0 && on_trader && !si->existing && !si->bought) {
|
||||
done_something = true;
|
||||
@@ -627,7 +625,7 @@ void shuffle_all() {
|
||||
|
||||
power& find_power(string name) {
|
||||
for(auto& p: powers) if(p.name == name) return p;
|
||||
throw hr_exception("unknown power");
|
||||
throw hr_name_error("unknown power");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
49
rogueviz/ru/reverts.cpp
Normal file
49
rogueviz/ru/reverts.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
namespace rogue_unlike {
|
||||
|
||||
room fake_room;
|
||||
|
||||
room *find_room(string s) {
|
||||
for(auto& [c,r]: rooms) if(r.roomname == s) return &r;
|
||||
throw hr_name_error("find_room");
|
||||
}
|
||||
|
||||
entity* find_entity(string s) {
|
||||
auto e = entity_by_name[s];
|
||||
if(!e) throw hr_name_error("find_entity");
|
||||
return e;
|
||||
}
|
||||
|
||||
template<class T> T force_exist(const T& c) { if(!c) throw hr_name_error("check"); return c; }
|
||||
|
||||
void revert(const revert_type& r) {
|
||||
// auto rf = [] (string s) { return atof(s.c_str()); };
|
||||
auto ri = [] (string s) { return atoi(s.c_str()); };
|
||||
|
||||
try {
|
||||
|
||||
if(r[0] == "BLOCK") find_room(r[1])->replace_block(ri(r[2]), ri(r[3]), (eWall) ri(r[4]));
|
||||
else if(r[0] == "ITEM") {
|
||||
auto& p = find_power(r[1]);
|
||||
p.qty_filled = ri(r[2]);
|
||||
p.qty_owned = ri(r[3]);
|
||||
}
|
||||
else if(r[0] == "EXIST") {
|
||||
auto e = find_entity(r[1]);
|
||||
if(e) e->existing = true;
|
||||
}
|
||||
else if(r[0] == "UNEXIST") {
|
||||
auto e = find_entity(r[1]);
|
||||
if(e) e->existing = false;
|
||||
}
|
||||
else if(r[0] == "UNBOUGHT") {
|
||||
auto e = find_entity(r[1]);
|
||||
if(e) e->existing = false;
|
||||
force_exist(e->as_shopitem())->bought = false;
|
||||
}
|
||||
|
||||
} catch(hr_name_error& e) {
|
||||
println(hlog, "a name error occured while reverting: ", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,6 +35,7 @@ Have fun!
|
||||
#include "save.cpp"
|
||||
#include "stats.cpp"
|
||||
#include "randeff.cpp"
|
||||
#include "reverts.cpp"
|
||||
|
||||
namespace rogue_unlike {
|
||||
|
||||
|
||||
@@ -313,6 +313,8 @@ void load_room(fhstream& f, cell *c) {
|
||||
}
|
||||
}
|
||||
|
||||
map<string, entity*> entity_by_name;
|
||||
|
||||
void load_map(string fname) {
|
||||
fhstream f(fname, "r");
|
||||
load_room(f, currentmap->gamestart());
|
||||
@@ -326,6 +328,14 @@ void load_map(string fname) {
|
||||
}
|
||||
else err("load_map", s);
|
||||
}
|
||||
for(auto& [c,r]: rooms)
|
||||
for(auto& e: r.entities) if(e->name != "") {
|
||||
while(entity_by_name.count(e->name)) {
|
||||
println(hlog, "error: double entity name: ", e->name);
|
||||
e->name += "'";
|
||||
}
|
||||
entity_by_name[e->name] = &*e;
|
||||
}
|
||||
}
|
||||
|
||||
void load_cheat(string fname) {
|
||||
|
||||
Reference in New Issue
Block a user