save/load mode data, via CLI

This commit is contained in:
Zeno Rogue 2024-03-14 19:28:33 +01:00
parent 424186b10d
commit c85b4d2f2b
3 changed files with 98 additions and 1 deletions

View File

@ -335,6 +335,19 @@ int arg::readCommon() {
clearMessages();
}
else if(argis("-save-mode")) {
save_mode_to_file(shift_args());
}
else if(argis("-load-mode")) {
try {
load_mode_from_file(shift_args());
}
catch(hstream_exception& e) {
println(hlog, "exception!");
}
}
// informational
else if(argis("-version") || argis("-v")) {
printf("HyperRogue version " VER "\n");

View File

@ -1782,6 +1782,28 @@ EX void finishAll() {
callhooks(hooks_final_cleanup);
}
string modheader = "# HyperRogue saved game mode file";
EX void save_mode_to_file(const string& fname) {
shstream ss;
save_mode_data(ss);
string s = as_hexstring(ss.s);
fhstream f(fname, "w");
println(f, modheader);
println(f, s);
}
EX void load_mode_from_file(const string& fname) {
fhstream f(fname, "r");
string header = scanline(f);
if(header[0] != '#') throw hstream_exception();
string hex = scanline(f);
shstream ss;
ss.s = from_hexstring(hex + "00");
stop_game();
load_mode_data_with_zero(ss);
start_game();
}
auto cgm = addHook(hooks_clearmemory, 40, [] () {
pathq.clear();

View File

@ -959,7 +959,7 @@ EX map<modecode_t, string> meaning;
char xcheat;
void save_mode_data(hstream& f) {
EX void save_mode_data(hstream& f) {
mapstream::save_geometry(f);
if(yendor::on || tactic::on)
@ -1006,6 +1006,68 @@ void save_mode_data(hstream& f) {
}
}
EX void load_mode_data_with_zero(hstream& f) {
mapstream::load_geometry(f);
land_structure = (eLandStructure) f.get<char>();
shmup::on = f.get<char>();
inv::on = f.get<char>();
#if CAP_TOUR
tour::on = f.get<char>();
#else
f.get<char>();
#endif
peace::on = f.get<char>();
peace::otherpuzzles = f.get<char>();
peace::explore_other = f.get<char>();
multi::players = f.get<char>();
xcheat = f.get<char>();
casual = false;
bow::weapon = bow::wBlade;
while(true) {
char option = f.get<char>();
switch(option) {
case 0:
return;
case 1:
casual = true;
break;
case 2:
bow::weapon = (bow::eWeapon) f.get<char>();
bow::style = (bow::eCrossbowStyle) f.get<char>();
break;
case 3: {
use_custom_land_list = true;
int lt = f.get<int>();
if(lt > landtypes) throw hstream_exception();
for(int i=0; i<lt; i++) {
custom_land_list[i] = f.get<char>();
custom_land_treasure[i] = f.get<int>();
custom_land_difficulty[i] = f.get<int>();
custom_land_wandering[i] = f.get<int>();
}
break;
}
case 4:
horodisk_from = f.get<int>();
break;
case 5:
randomwalk_size = f.get<int>();
break;
default:
throw hstream_exception();
}
}
}
EX modecode_t modecode(int mode) {
modecode_t x = legacy_modecode();
if(x != UNKNOWN) return x;