diff --git a/rogueviz/seuphorica.cpp b/rogueviz/seuphorica.cpp index 29995b24..029b175b 100644 --- a/rogueviz/seuphorica.cpp +++ b/rogueviz/seuphorica.cpp @@ -8,6 +8,11 @@ namespace hr { namespace seuphorica { + +void save_old_game_if_needed(); +void save(); +void load(); + void read_dictionary(struct language& l); void read_naughty_dictionary(language& l); void activate_scry(); @@ -825,8 +830,43 @@ void centermap() { View = iddspin(centerover,tile_orientation[centerover].spin,0); } -void seuphorica_screen() { +string get_setname() { + string res = ""; + if(bidirectional) res += "/bi"; + if(game_restricted) res += "/x"; + if(is_seeded) res += "/seeded"; + if(!enabled_spells) res += "/nospells"; + if(!enabled_stay) res += "/nostay"; + if(!enabled_power) res += "/nopower"; + if(!enabled_id) res += "/noid"; + return res; + } +void pre_achievements() { + #if RVCOL + for(auto p: just_placed) { + auto t = board.at(p); + if(has_power(t, sp::bending)) { + int qty = 0; + forCellEx(c1, p) if(just_placed.count(c1)) qty++; + if(qty >= 4) rogueviz::rv_achievement("SEUMIRROR"); + } + } + if(ev.total_score >= 2000) rogueviz::rv_achievement("SEU20000"); + #endif + } + +void post_achievements() { + #if RVCOL + if(word_use_count.count(current->gamename)) rogueviz::rv_achievement("SEUNAME"); + #endif + } + +string rv_data(); + +string get_geom_name(); + +void seuphorica_screen() { if(snapshots.empty()) start_tick = 0; @@ -984,7 +1024,20 @@ void seuphorica_screen() { if(ev.valid_move) { displayButton(lerp(ui.x0, ui.x2, 1/8.), vid.yres - vid.fsize, just_placed.empty() ? str_skip_turn : str_play, SDLK_RETURN, 8); - dialog::add_key_action(SDLK_RETURN, play); + dialog::add_key_action(SDLK_RETURN, [] { + pre_achievements(); + accept_move(); + post_achievements(); + if(roundindex == 21) { + save(); + if(is_daily && cheats == 0) rogueviz::rv_leaderboard(get_geom_name() + " daily " + its(daily), total_gain, 1, rvlc::num, rv_data()); + if(cheats == 0) rogueviz::rv_leaderboard(get_geom_name() + get_setname() + " (20 turns)", total_gain, 1, rvlc::num, rv_data()); + } + if(roundindex == 51) { + save(); + if(cheats == 0) rogueviz::rv_leaderboard(get_geom_name() + get_setname() + " (50 turns)", total_gain, 1, rvlc::num, rv_data()); + } + }); } displayButton(lerp(ui.x0, ui.x2, 3/8.), vid.yres - vid.fsize, "center", ' ', 8); @@ -1133,15 +1186,19 @@ vector special_setting; int pick_qty = 8; +ss get_default_special_setting(int i) { + return + (i < 2) ? ss::technical : + (sp(i) == sp::naughty) ? ss::disabled : + (i > int(sp::naughty)) ? ss::disabled : + ss::random; + } + void init_special_setting() { int qty = int(sp::first_artifact); special_setting.resize(qty); for(int i=0; i int(sp::naughty)) ? ss::disabled : - ss::random; + special_setting[i] = get_default_special_setting(i); } bool want_spells = true, want_stay = true, want_power = true, want_id = true; @@ -1158,6 +1215,7 @@ void reset_rv() { auto v = currentmap->allcells(); for(int i=0; i special_allowed; + int flags; + int best_turn_score; + pair best_word; + int score, turns, seed; + }; + +string rv_data() { + return lalign(0, best_word.first, " ", best_word.second, " ", best_turn_score); + } + +gamedata cur; +vector allsaves; + +void fill_gamedata() { + cur.geom_name = get_geom_name(); + time_t timer; + timer = time(NULL); + char buf[128]; + strftime(buf, 128, "%c", localtime(&timerstart)); cur.timerstart = buf; + strftime(buf, 128, "%c", localtime(&timer)); cur.timerend = buf; + cur.myname = "unnamed"; + cur.special_allowed = special_allowed; + cur.flags = 0; + if(enabled_spells) cur.flags |= 1; + if(enabled_stay) cur.flags |= 2; + if(enabled_power) cur.flags |= 4; + if(enabled_id) cur.flags |= 8; + if(is_daily) cur.flags |= 16; + if(is_seeded) cur.flags |= 32; + if(bidirectional) cur.flags |= 64; + cur.best_word = best_word; + cur.best_turn_score = best_turn_score; + } + +void save(const gamedata& sd) { + #if CAP_SAVE + fhstream f("seuphorica.save", "at"); + println(f, "Seuphorica ", SEUPHORICA_VERSION); + println(f, sd.geom_name); + println(f, sd.myname); + println(f, sd.timerstart); + println(f, sd.timerend); + for(auto v: sd.special_allowed) print(f, v ? "1" : "0"); + println(f, " ", sd.flags); + println(f, sd.score, " ", sd.turns, " ", sd.seed); + println(f, cur.best_word.second, " ", cur.best_word.first, " ", cur.best_turn_score); + println(f); + #endif + } + +void save() { + if(cheats) return; + fill_gamedata(); + save(cur); + allsaves.push_back(cur); + } + +string get_geom_name() { + if(current_seuphgeom == -1) return "unknown: " + full_geometry_name(); + return seuphgeoms[current_seuphgeom].name; + } + +void save_old_game_if_needed() { + // no point to save on the 1st turn, and also on 21st and 51st turn, it has just been saved + if(!among(roundindex, 0, 1, 21, 51)) save(); + if(cheats == 0) rogueviz::rv_leaderboard(get_geom_name() + get_setname() + " (endless)", total_gain, 1, rvlc::num); + } + +void load() { + allsaves.clear(); + fhstream f("seuphorica.save", "rt"); + if(!f.f) return; + string s; + while(!feof(f.f)) { + s = scanline_noblank(f); + if(s == "Seuphorica 20") { + gamedata gd; + gd.geom_name = scanline_noblank(f); + gd.myname = scanline_noblank(f); + gd.timerstart = scanline_noblank(f); + gd.timerend = scanline_noblank(f); + auto s = scanline_noblank(f); + int id = 0; + for(auto& v: gd.special_allowed) v = s[id++] == '1'; + sscanf(s.c_str()+id, "%d",&gd.flags); + sscanf(scanline_noblank(f).c_str(), "%d%d%d", &gd.score, &gd.turns, &gd.seed); + char buf[80]; + sscanf(scanline_noblank(f).c_str(), "%80s%d%d", buf, &gd.best_word.first, &gd.best_turn_score); gd.best_word.second = buf; + allsaves.push_back(gd); + } + } + } + } }