mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
casual mode
This commit is contained in:
parent
7fc91b1eaf
commit
b65e5f603f
@ -104,6 +104,7 @@ EX vector<string> achievementsReceived;
|
||||
*/
|
||||
EX bool wrongMode(char flags) {
|
||||
if(cheater) return true;
|
||||
if(casual) return true;
|
||||
if(flags == rg::global) return false;
|
||||
|
||||
if(flags != rg::special_geometry) {
|
||||
@ -214,6 +215,7 @@ EX void achievement_collection(eItem it) {
|
||||
|
||||
EX void achievement_collection2(eItem it, int q) {
|
||||
if(cheater && !test_achievements) return;
|
||||
if(casual && !test_achievements) return;
|
||||
if(randomPatternsMode) return;
|
||||
LATE( achievement_collection2(it, q); )
|
||||
|
||||
@ -544,6 +546,7 @@ EX void achievement_collection2(eItem it, int q) {
|
||||
|
||||
EX void achievement_count(const string& s, int current, int prev) {
|
||||
if(cheater && !test_achievements) return;
|
||||
if(casual && !test_achievements) return;
|
||||
if(shmup::on) return;
|
||||
if(randomPatternsMode) return;
|
||||
LATE( achievement_count(s, current, prev); )
|
||||
@ -610,6 +613,7 @@ EX void achievement_score(int cat, int number) {
|
||||
if(offlineMode) return;
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
if(cheater) return;
|
||||
if(casual) return;
|
||||
LATE( achievement_score(cat, number); )
|
||||
if(cat == LB_HALLOWEEN) {
|
||||
if(geometry != gSphere && geometry != gElliptic)
|
||||
@ -713,6 +717,7 @@ EX void achievement_final(bool really_final) {
|
||||
next_stat_tick = ticks + 600000;
|
||||
}
|
||||
if(cheater) return;
|
||||
if(casual) return;
|
||||
|
||||
#if CAP_TOUR
|
||||
if(tour::on) return;
|
||||
@ -831,6 +836,7 @@ EX void achievement_victory(bool hyper) {
|
||||
if(offlineMode) return;
|
||||
#ifdef HAVE_ACHIEVEMENTS
|
||||
if(cheater) return;
|
||||
if(casual) return;
|
||||
if(geometry) return;
|
||||
if(CHANGED_VARIATION) return;
|
||||
if(randomPatternsMode) return;
|
||||
@ -921,6 +927,7 @@ EX string get_rich_presence_text() {
|
||||
if(randomPatternsMode) res += "random ";
|
||||
if(inv::on) res += "OSM ";
|
||||
if(multi::players > 1) res += "multi ";
|
||||
if(casual) res += "casual ";
|
||||
|
||||
if(cheater || among(cwt.at->land, laCanvas, laCA))
|
||||
return res + "(?)";
|
||||
|
@ -17,6 +17,8 @@ namespace hr {
|
||||
EX bool hardcore = false;
|
||||
/** when did we switch to the hardcore mode */
|
||||
EX int hardcoreAt;
|
||||
/** are we in the casual mode */
|
||||
EX bool casual = false;
|
||||
|
||||
EX bool pureHardcore() { return hardcore && hardcoreAt < PUREHARDCORE_LEVEL; }
|
||||
|
||||
|
@ -164,6 +164,7 @@ EX namespace dialog {
|
||||
if(k == SDLK_ESCAPE) return "Esc";
|
||||
if(k == SDLK_F5) return "F5";
|
||||
if(k == SDLK_F10) return "F10";
|
||||
if(k == SDLK_F9) return "F9";
|
||||
if(k == SDLK_F1) return "F1";
|
||||
if(k == SDLK_HOME) return "Home";
|
||||
if(k == SDLK_BACKSPACE) return "Backspace";
|
||||
|
5
game.cpp
5
game.cpp
@ -259,6 +259,11 @@ EX void teleportToLand(eLand l, bool make_it_safe) {
|
||||
|
||||
EX void activateSafety(eLand l) {
|
||||
teleportToLand(l, true);
|
||||
if(casual) {
|
||||
saveStats();
|
||||
savecount++;
|
||||
save_turns = turncount;
|
||||
}
|
||||
}
|
||||
|
||||
EX void placeGolem(cell *on, cell *moveto, eMonster m) {
|
||||
|
21
menus.cpp
21
menus.cpp
@ -404,6 +404,23 @@ EX void switchHardcore() {
|
||||
if(pureHardcore()) popScreenAll();
|
||||
}
|
||||
|
||||
EX void switch_casual() {
|
||||
if(savecount > 0) {
|
||||
dialog::push_confirm_dialog([] {
|
||||
restart_game();
|
||||
casual = !casual;
|
||||
}, XLAT("Switching casual allowed only before saving the game. Do you want to restart?"));
|
||||
return;
|
||||
}
|
||||
else
|
||||
casual = !casual;
|
||||
if(casual) {
|
||||
addMessage(XLAT("You are in the Casual mode! Achievements are disabled."));
|
||||
addMessage(XLAT("Collect an Orb of Safety to save a checkpoint."));
|
||||
}
|
||||
popScreenAll();
|
||||
}
|
||||
|
||||
EX void showCreative() {
|
||||
cmode = sm::SIDE | sm::MAYDARK;
|
||||
gamescreen(3);
|
||||
@ -531,6 +548,7 @@ EX void show_chaos() {
|
||||
else
|
||||
dialog::addInfo("not eligible for achievements");
|
||||
if(cheater) dialog::addInfo("(but the cheat mode is on)");
|
||||
if(casual) dialog::addInfo("(but the casual mode is on)");
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addBack();
|
||||
@ -724,6 +742,9 @@ EX void showChangeMode() {
|
||||
dialog::addBoolItem(XLAT("multiplayer"), multi::players > 1, 'm');
|
||||
dialog::add_action_push(multi::showConfigureMultiplayer);
|
||||
|
||||
dialog::addSelItem(XLAT("casual mode"), ONOFF(casual), 'C');
|
||||
dialog::add_action(switch_casual);
|
||||
|
||||
if(!shmup::on) {
|
||||
dialog::addSelItem(XLAT("hardcore mode"),
|
||||
hardcore && !pureHardcore() ? XLAT("PARTIAL") : ONOFF(hardcore), 'h');
|
||||
|
15
quit.cpp
15
quit.cpp
@ -8,14 +8,18 @@
|
||||
#include "hyper.h"
|
||||
namespace hr {
|
||||
|
||||
EX bool quitsaves() { return (items[itOrbSafety] && CAP_SAVE && !arcm::in()); }
|
||||
EX bool quitsaves() {
|
||||
if(casual) return false;
|
||||
return (items[itOrbSafety] && CAP_SAVE && !arcm::in());
|
||||
}
|
||||
|
||||
EX bool needConfirmationEvenIfSaved() {
|
||||
return canmove && (gold() >= 30 || tkills() >= 50) && !cheater;
|
||||
}
|
||||
|
||||
EX bool needConfirmation() {
|
||||
return needConfirmationEvenIfSaved() && !quitsaves();
|
||||
if(casual) return needConfirmationEvenIfSaved() && turncount > save_turns + 10;
|
||||
else return needConfirmationEvenIfSaved() && quitsaves();
|
||||
}
|
||||
|
||||
EX int getgametime() {
|
||||
@ -498,6 +502,8 @@ EX void showMission() {
|
||||
#if !ISMOBILE
|
||||
dialog::addItem(quitsaves() ? XLAT("save") : XLAT("quit"), SDLK_F10);
|
||||
#endif
|
||||
if(casual && savecount)
|
||||
dialog::addItem(XLAT("load (%1 turns passed)", its(turncount - save_turns)), SDLK_F9);
|
||||
#if CAP_ANDROIDSHARE
|
||||
dialog::addItem(XLAT("SHARE"), 's'-96);
|
||||
#endif
|
||||
@ -534,6 +540,11 @@ EX void handleKeyQuit(int sym, int uni) {
|
||||
else if(uni == 'v') popScreenAll(), pushScreen(showMainMenu);
|
||||
else if(uni == 'l') popScreenAll(), pushScreen(showMessageLog), messagelogpos = isize(gamelog);
|
||||
else if(uni == 'z') hints[hinttoshow].action();
|
||||
else if(sym == SDLK_F9 && casual && savecount) {
|
||||
stop_game();
|
||||
load_last_save();
|
||||
start_game();
|
||||
}
|
||||
else if(sym == SDLK_F3 || (sym == ' ' || sym == SDLK_HOME))
|
||||
fullcenter();
|
||||
else if(uni == 'o') get_o_key().second();
|
||||
|
83
system.cpp
83
system.cpp
@ -53,6 +53,7 @@ EX int asteroids_generated, asteroid_orbs_generated;
|
||||
EX time_t timerstart, savetime;
|
||||
EX bool timerstopped;
|
||||
EX int savecount;
|
||||
EX int save_turns;
|
||||
EX bool doCross = false;
|
||||
|
||||
EX bool gamegen_failure;
|
||||
@ -419,7 +420,7 @@ EX namespace scores {
|
||||
/** \brief the amount of boxes reserved for each hr::score item */
|
||||
#define MAXBOX 500
|
||||
/** \brief currently used boxes in hr::score */
|
||||
#define POSSCORE 389
|
||||
#define POSSCORE 391
|
||||
/** \brief a struct to keep local score from an earlier game */
|
||||
struct score {
|
||||
/** \brief version used */
|
||||
@ -893,6 +894,9 @@ EX void applyBoxes() {
|
||||
|
||||
applyBoxNum(saved_modecode, "modecode");
|
||||
applyBoxBool(ineligible_starting_land, "ineligible_starting_land");
|
||||
|
||||
applyBoxNum(yasc_code, "YASC code");
|
||||
applyBoxBool(casual, "casual mode");
|
||||
|
||||
if(POSSCORE != boxid) printf("ERROR: %d boxes\n", boxid);
|
||||
if(isize(invorb)) { println(hlog, "ERROR: Orbs not taken into account"); exit(1); }
|
||||
@ -981,6 +985,8 @@ EX void remove_emergency_save() {
|
||||
#endif
|
||||
}
|
||||
|
||||
scores::score scorebox;
|
||||
|
||||
EX void saveStats(bool emergency IS(false)) {
|
||||
DEBBI(DF_INIT, ("saveStats [", scorefile, "]"));
|
||||
|
||||
@ -1064,6 +1070,7 @@ EX void saveStats(bool emergency IS(false)) {
|
||||
scores::saveBox();
|
||||
|
||||
for(int i=0; i<scores::boxid; i++) fprintf(f, " %d", scores::save.box[i]);
|
||||
scorebox = scores::save;
|
||||
anticheat::save(f);
|
||||
|
||||
fprintf(f, "\n");
|
||||
@ -1106,6 +1113,8 @@ EX void saveStats(bool emergency IS(false)) {
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
bool tamper = false;
|
||||
|
||||
// load the save
|
||||
EX void loadsave() {
|
||||
if(autocheat) return;
|
||||
@ -1117,10 +1126,9 @@ EX void loadsave() {
|
||||
FILE *f = fopen(scorefile, "rt");
|
||||
havesave = f;
|
||||
if(!f) return;
|
||||
scores::score sc;
|
||||
bool ok = false;
|
||||
bool tamper = false;
|
||||
int coh = counthints();
|
||||
auto& sc = scorebox;
|
||||
while(!feof(f)) {
|
||||
char buf[12000];
|
||||
if(fgets(buf, 12000, f) == NULL) break;
|
||||
@ -1215,40 +1223,45 @@ EX void loadsave() {
|
||||
|
||||
}
|
||||
fclose(f);
|
||||
if(ok && sc.box[65 + 4 + itOrbSafety - itOrbLightning]) {
|
||||
anticheat::tampered = tamper;
|
||||
if(ok && sc.box[65 + 4 + itOrbSafety - itOrbLightning])
|
||||
load_last_save();
|
||||
}
|
||||
|
||||
EX void load_last_save() {
|
||||
auto& sc = scorebox;
|
||||
anticheat::tampered = tamper;
|
||||
// printf("box = %d (%d)\n", sc.box[65 + 4 + itOrbSafety - itOrbLightning], boxid);
|
||||
// printf("boxid = %d\n", boxid);
|
||||
using namespace scores;
|
||||
for(int i=0; i<boxid; i++) save.box[i] = sc.box[i];
|
||||
for(int i=boxid; i<MAXBOX; i++) save.box[i] = 0;
|
||||
using namespace scores;
|
||||
for(int i=0; i<boxid; i++) save.box[i] = sc.box[i];
|
||||
for(int i=boxid; i<MAXBOX; i++) save.box[i] = 0;
|
||||
// for(int i=160; i<200; i++) printf("%d: %d ", i, save.box[i]);
|
||||
|
||||
if(meaning.count(sc.box[MODECODE_BOX])) {
|
||||
shstream ss;
|
||||
ss.s = meaning[sc.box[MODECODE_BOX]];
|
||||
ss.read(ss.vernum);
|
||||
mapstream::load_geometry(ss);
|
||||
}
|
||||
|
||||
loadBox();
|
||||
// printf("boxid = %d\n", boxid);
|
||||
if(items[itHolyGrail]) {
|
||||
items[itHolyGrail]--;
|
||||
camelot::knighted = newRoundTableRadius();
|
||||
items[itHolyGrail]++;
|
||||
}
|
||||
else camelot::knighted = 0;
|
||||
safety = true;
|
||||
if(items[itSavedPrincess] < 0) items[itSavedPrincess] = 0;
|
||||
addMessage(XLAT("Game loaded."));
|
||||
showstartmenu = false;
|
||||
// reset unsavable special modes just in case
|
||||
peace::on = false;
|
||||
randomPatternsMode = false;
|
||||
yendor::on = false;
|
||||
tour::on = false;
|
||||
if(meaning.count(sc.box[MODECODE_BOX])) {
|
||||
shstream ss;
|
||||
ss.s = meaning[sc.box[MODECODE_BOX]];
|
||||
ss.read(ss.vernum);
|
||||
mapstream::load_geometry(ss);
|
||||
}
|
||||
|
||||
loadBox();
|
||||
// printf("boxid = %d\n", boxid);
|
||||
if(items[itHolyGrail]) {
|
||||
items[itHolyGrail]--;
|
||||
camelot::knighted = newRoundTableRadius();
|
||||
items[itHolyGrail]++;
|
||||
}
|
||||
else camelot::knighted = 0;
|
||||
safety = true;
|
||||
if(items[itSavedPrincess] < 0) items[itSavedPrincess] = 0;
|
||||
addMessage(XLAT("Game loaded."));
|
||||
showstartmenu = false;
|
||||
// reset unsavable special modes just in case
|
||||
peace::on = false;
|
||||
randomPatternsMode = false;
|
||||
yendor::on = false;
|
||||
tour::on = false;
|
||||
save_turns = turncount;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1258,7 +1271,8 @@ EX void stop_game() {
|
||||
DEBBI(DF_INIT, ("stop_game"));
|
||||
achievement_final(true);
|
||||
#if CAP_SAVE
|
||||
saveStats();
|
||||
if(!casual)
|
||||
saveStats();
|
||||
#endif
|
||||
for(int i=0; i<ittypes; i++) items[i] = 0;
|
||||
lastkills = 0; for(int i=0; i<motypes; i++) kills[i] = 0;
|
||||
@ -1604,7 +1618,8 @@ EX void finishAll() {
|
||||
achievement_final(!items[itOrbSafety]);
|
||||
|
||||
#if CAP_SAVE
|
||||
saveStats();
|
||||
if(!casual)
|
||||
saveStats();
|
||||
#endif
|
||||
clearMemory();
|
||||
#if !ISMOBILE
|
||||
|
@ -1085,6 +1085,9 @@ void save_mode_data(hstream& f) {
|
||||
f.write<char>(peace::explore_other);
|
||||
f.write<char>(multi::players);
|
||||
f.write<char>(xcheat);
|
||||
if(casual) {
|
||||
f.write<char>(1);
|
||||
}
|
||||
}
|
||||
|
||||
EX modecode_t modecode(int mode) {
|
||||
|
Loading…
Reference in New Issue
Block a user