diff --git a/commandline.cpp b/commandline.cpp index 4fe464cd..9c514625 100644 --- a/commandline.cpp +++ b/commandline.cpp @@ -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"); diff --git a/system.cpp b/system.cpp index 70250164..fe1f0661 100644 --- a/system.cpp +++ b/system.cpp @@ -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(); diff --git a/yendor.cpp b/yendor.cpp index 2b5fb294..a225352a 100644 --- a/yendor.cpp +++ b/yendor.cpp @@ -959,7 +959,7 @@ EX map 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(); + shmup::on = f.get(); + inv::on = f.get(); + #if CAP_TOUR + tour::on = f.get(); + #else + f.get(); + #endif + peace::on = f.get(); + peace::otherpuzzles = f.get(); + peace::explore_other = f.get(); + multi::players = f.get(); + xcheat = f.get(); + casual = false; + bow::weapon = bow::wBlade; + + while(true) { + char option = f.get(); + switch(option) { + + case 0: + return; + + case 1: + casual = true; + break; + + case 2: + bow::weapon = (bow::eWeapon) f.get(); + bow::style = (bow::eCrossbowStyle) f.get(); + break; + + case 3: { + use_custom_land_list = true; + int lt = f.get(); + if(lt > landtypes) throw hstream_exception(); + for(int i=0; i(); + custom_land_treasure[i] = f.get(); + custom_land_difficulty[i] = f.get(); + custom_land_wandering[i] = f.get(); + } + break; + } + + case 4: + horodisk_from = f.get(); + break; + + case 5: + randomwalk_size = f.get(); + break; + + default: + throw hstream_exception(); + } + } + } + EX modecode_t modecode(int mode) { modecode_t x = legacy_modecode(); if(x != UNKNOWN) return x;