mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	racing:: track selection; can be now set as a special game mode
This commit is contained in:
		
							
								
								
									
										3
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -676,6 +676,7 @@ namespace rg { | ||||
|   static const char princess = 'p'; | ||||
|   static const char daily = 'd'; | ||||
|   static const char daily_off = 'D'; | ||||
|   static const char racing = 'R'; | ||||
|    | ||||
|   // wrongmode only -- marks 'global' achievements not related to the current mode | ||||
|   static const char global = 'x';  | ||||
| @@ -4680,7 +4681,7 @@ ld sintick(int period, ld phase = 0); | ||||
| namespace racing { | ||||
|   extern bool on, player_relative, track_ready; | ||||
|   void generate_track(); | ||||
|   void show(); | ||||
|   void configure_race(); | ||||
|   void prepare_subscreens(); | ||||
|   extern vector<cell*> track; | ||||
|   extern int current_player; | ||||
|   | ||||
| @@ -494,6 +494,9 @@ void showChangeMode() { | ||||
|   dialog::addBoolItem(XLAT("Yendor Challenge"), (yendor::on), 'y'); | ||||
|   dialog::addBoolItem(XLAT("%1 Challenge", moPrincess), (princess::challenge), 'P'); | ||||
|   dialog::addBoolItem(XLAT("random pattern mode"), (randomPatternsMode), 'r'); | ||||
| #if CAP_RACING | ||||
|   dialog::addBoolItem(XLAT("racing mode"), racing::on, 'R'); | ||||
| #endif | ||||
| #if CAP_DAILY | ||||
|   dialog::addBoolItem(XLAT("Strange Challenge"), daily::on, 'z'); | ||||
| #endif | ||||
| @@ -539,6 +542,10 @@ void showChangeMode() { | ||||
|       } | ||||
|     else if(xuni == 'p') | ||||
|       pushScreen(peace::showMenu); | ||||
|     #if CAP_RACING | ||||
|     else if(xuni == 'R') | ||||
|       racing::configure_race(); | ||||
|     #endif | ||||
|     else if(xuni == 'i') dialog::do_if_confirmed([] { | ||||
|       restart_game(rg::inv); | ||||
|       }); | ||||
|   | ||||
							
								
								
									
										11
									
								
								quit.cpp
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								quit.cpp
									
									
									
									
									
								
							| @@ -299,6 +299,7 @@ void showMission() { | ||||
|     tour::on ? (canmove ? XLAT("Tutorial") : XLAT("GAME OVER")) : | ||||
| #endif | ||||
|     (cheater && !autocheat)? XLAT("It is a shame to cheat!") :  | ||||
|     racing::on ? "racing mode" : | ||||
|     showoff ? XLAT("Showoff mode") : | ||||
|     (canmove && princess::challenge) ? XLAT("%1 Challenge", moPrincess) : | ||||
|     canmove ? XLAT("Quest status") :  | ||||
| @@ -307,9 +308,9 @@ void showMission() { | ||||
|     ); | ||||
|   keyhandler = handleKeyQuit; | ||||
|  | ||||
|   if(!peace::on) | ||||
|   if(!peace::on && !racing::on) | ||||
|     dialog::addInfo(XLAT("Your score: %1", its(gold()))); | ||||
|   if(!peace::on) | ||||
|   if(!peace::on && !racing::on) | ||||
|     dialog::addInfo(XLAT("Enemies killed: %1", its(tkills()))); | ||||
|  | ||||
| #if CAP_TOUR | ||||
| @@ -326,6 +327,7 @@ void showMission() { | ||||
|     else if(tour::on) | ||||
|       ; | ||||
| #endif | ||||
|     else if(racing::on) ; | ||||
|     else if(princess::challenge)  | ||||
|       dialog::addInfo(XLAT("Follow the Mouse and escape with %the1!", moPrincess)); | ||||
|     else if(gold() < R30) | ||||
| @@ -354,6 +356,7 @@ void showMission() { | ||||
|   else if(tour::on) ; | ||||
| #endif | ||||
|   else if(peace::on) ; | ||||
|   else if(racing::on) ; | ||||
|   else if(tkills() < R100) | ||||
|     dialog::addInfo(XLAT("Defeat %1 enemies to access the Graveyard", its(R100))); | ||||
|   else if(kills[moVizier] == 0 && (items[itFernFlower] < U5 || items[itGold] < U5)) | ||||
| @@ -375,7 +378,7 @@ void showMission() { | ||||
|   if(cheater && !autocheat) { | ||||
|     dialog::addInfo(XLAT("you have cheated %1 times", its(cheater)), 0xFF2020); | ||||
|     } | ||||
|   else { | ||||
|   else if(!racing::on) { | ||||
|     dialog::addInfo(timeline(), dialog::dialogcolor); | ||||
|     } | ||||
|    | ||||
| @@ -439,6 +442,8 @@ void showMission() { | ||||
|     dialog::addItem(XLAT("restart"), SDLK_F5); | ||||
|     if(inv::on && items[itInventory]) | ||||
|       dialog::addItem(XLAT("inventory"), 'i'); | ||||
|     if(racing::on) | ||||
|       dialog::addItem(XLAT("racing menu"), 'o'); | ||||
|     #if ISMOBILE==0 | ||||
|     dialog::addItem(XLAT(quitsaves() ? "save" : "quit"), SDLK_F10); | ||||
|     #endif | ||||
|   | ||||
							
								
								
									
										87
									
								
								racing.cpp
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								racing.cpp
									
									
									
									
									
								
							| @@ -13,10 +13,13 @@ bool on; | ||||
| bool player_relative = false; | ||||
| bool track_ready; | ||||
|  | ||||
| static const int LENGTH = 50; | ||||
| static const int LENGTH = 250; | ||||
| static const int TWIDTH = 6; | ||||
| static const int DROP = 1; | ||||
|  | ||||
| int ghosts_to_show = 5; | ||||
| int ghosts_to_save = 10; | ||||
|  | ||||
| struct race_cellinfo { | ||||
|   cell *c; | ||||
|   int from_track; | ||||
| @@ -95,8 +98,9 @@ void hwrite(hstream& hs, const ghost& gh) { | ||||
|   } | ||||
|  | ||||
| bool read_ghosts(string seed, int mcode) { | ||||
|   fhstream f; | ||||
|   f.f = fopen(ghost_filename(seed, mcode).c_str(), "rb"); | ||||
|   string fname = ghost_filename(seed, mcode); | ||||
|   println(hlog, "trying to read ghosts from: ", fname); | ||||
|   fhstream f(fname, "rb"); | ||||
|   if(!f.f) return false; | ||||
|   f.get<int> (); | ||||
|   hread(f, race_ghosts[{seed, mcode}]); | ||||
| @@ -446,9 +450,7 @@ int readArgs() { | ||||
|   else if(argis("-racing")) { | ||||
|     PHASEFROM(2); | ||||
|     stop_game(); | ||||
|     shmup::on = true; | ||||
|     racing::on = true; | ||||
|     timerghost = false; | ||||
|     switch_game_mode(rg::racing); | ||||
|     } | ||||
|   else return 1; | ||||
|   return 0; | ||||
| @@ -580,10 +582,7 @@ void track_chooser(string new_track) { | ||||
|     dialog::addSelItem(XLAT1(linf[l].name), s, let++); | ||||
|     dialog::add_action([l, new_track] () { | ||||
|       stop_game(); | ||||
|       specialland = l; | ||||
|       racing::on = true; | ||||
|       shmup::on = true; | ||||
|       track_code = new_track; | ||||
|       if(!racing::on) switch_game_mode(rg::racing); | ||||
|       start_game(); | ||||
|       popScreenAll(); | ||||
|       }); | ||||
| @@ -626,6 +625,27 @@ struct race_configurer { | ||||
|    | ||||
|     dialog::init(XLAT("Racing")); | ||||
|    | ||||
|     dialog::addSelItem("track name", editing_track ? dialog::view_edited_string() : new_track, '/'); | ||||
|     dialog::add_action([this] () {  | ||||
|       editing_track = !editing_track; | ||||
|       if(editing_track) dialog::start_editing(new_track); | ||||
|       }); | ||||
|     dialog::addItem("play the official track", 'o'); | ||||
|     dialog::add_action([this] () { new_track = "OFFICIAL"; }); | ||||
|     dialog::addItem("play a random track", 'r'); | ||||
|     dialog::add_action([this] () { new_track = random_track_name(); }); | ||||
|    | ||||
|     dialog::addItem(XLAT("select the track and start!"), 's'); | ||||
|     dialog::add_action([this] () {  | ||||
|       if(race_ghosts[{new_track, modecode()}].empty()) | ||||
|         read_ghosts(new_track, modecode()); | ||||
|       else | ||||
|         println(hlog, "known ghosts: ", isize(race_ghosts[{new_track, modecode()}])); | ||||
|       pushScreen([this] () { track_chooser(new_track); });  | ||||
|       }); | ||||
|      | ||||
|     dialog::addBreak(100); | ||||
|  | ||||
|     dialog::addBoolItem(XLAT("player relative"), player_relative, 'p'); | ||||
|     dialog::add_action([] () {  | ||||
|       player_relative = !player_relative;  | ||||
| @@ -674,22 +694,23 @@ struct race_configurer { | ||||
|       } | ||||
|     else dialog::addBreak(100); | ||||
|      | ||||
|     dialog::addSelItem("track name", editing_track ? dialog::view_edited_string() : new_track, '/'); | ||||
|     dialog::add_action([this] () {  | ||||
|       editing_track = !editing_track; | ||||
|       if(editing_track) dialog::start_editing(new_track); | ||||
|       }); | ||||
|     dialog::addItem("play the official track", 'o'); | ||||
|     dialog::add_action([this] () { new_track = "OFFICIAL"; }); | ||||
|     dialog::addItem("play a random track", 'r'); | ||||
|     dialog::add_action([this] () { new_track = random_track_name(); }); | ||||
|     dialog::addBreak(100); | ||||
|      | ||||
|     dialog::addItem(XLAT("select the track and start!"), 's'); | ||||
|     dialog::add_action([this] () {  | ||||
|       if(race_ghosts[{new_track, modecode()}].empty()) | ||||
|         read_ghosts(new_track, modecode()); | ||||
|       pushScreen([this] () { track_chooser(new_track); });  | ||||
|     dialog::addSelItem(XLAT("best scores to show as ghosts"), its(ghosts_to_show), 'g'); | ||||
|     dialog::add_action([]() { dialog::editNumber(ghosts_to_show, 0, 100, 1, 5, "best scores to show as ghosts", ""); }); | ||||
|  | ||||
|     dialog::addSelItem(XLAT("best scores to save"), its(ghosts_to_save), 'b'); | ||||
|     dialog::add_action([]() { dialog::editNumber(ghosts_to_save, 0, 100, 1, 10, "best scores to save", ""); }); | ||||
|      | ||||
|      | ||||
|     if(racing::on) { | ||||
|       dialog::addItem(XLAT("disable the racing mode"), 'x'); | ||||
|       dialog::add_action([] () {  | ||||
|         stop_game(); | ||||
|         switch_game_mode(rg::racing); | ||||
|         start_game(); | ||||
|         }); | ||||
|       } | ||||
|  | ||||
|     dialog::addBack(); | ||||
|     dialog::display(); | ||||
| @@ -706,9 +727,13 @@ struct race_configurer { | ||||
|     } | ||||
|   }; | ||||
|  | ||||
| void configure_race() {  | ||||
|   pushScreen(race_configurer()); | ||||
|   } | ||||
|  | ||||
| auto hooks1 =  | ||||
|   addHook(hooks_o_key, 90, [] {  | ||||
|     if(racing::on) return named_dialog("race mode", race_configurer()); | ||||
|     if(racing::on) return named_dialog(XLAT("racing menu"), race_configurer()); | ||||
|     else return named_functionality(); | ||||
|     }); | ||||
|  | ||||
| @@ -745,12 +770,19 @@ void race_won() { | ||||
|       part(*x, 0) >>= 2; | ||||
|       } | ||||
|        | ||||
|     race_ghosts[{track_code, modecode()}] [specialland].emplace_back(ghost{gcs, ticks - race_start_tick, time(NULL), current_history[current_player]}); | ||||
|     auto &subtrack = race_ghosts[{track_code, modecode()}] [specialland]; | ||||
|  | ||||
|     subtrack.emplace_back(ghost{gcs, ticks - race_start_tick, time(NULL), current_history[current_player]}); | ||||
|     sort(subtrack.begin(), subtrack.end(), [] (const ghost &g1, const ghost &g2) { return g1.result > g2.result; }); | ||||
|     if(isize(subtrack) > ghosts_to_save && ghosts_to_save > 0)  | ||||
|       subtrack.resize(ghosts_to_save); | ||||
|     if(ghosts_to_save > 0) | ||||
|       write_ghosts(track_code, modecode()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| void markers() { | ||||
|   if(!racing::on) return; | ||||
|   if(racing::player_relative) { | ||||
|     using namespace racing; | ||||
|     cell *goal = NULL; | ||||
| @@ -760,7 +792,10 @@ void markers() { | ||||
|     queuestr(H, vid.fsize, its(celldistance(cwt.at, track.back())), 0x10101 * int(128 - 100 * sintick(150))); | ||||
|     addauraspecial(H, 0x10100, 0); | ||||
|     } | ||||
|   int ghosts_left = ghosts_to_show; | ||||
|   for(auto& ghost: race_ghosts[{track_code, modecode()}][specialland]) { | ||||
|     if(!ghosts_left) break; | ||||
|     ghosts_left--; | ||||
|     auto p = std::find_if(ghost.history.begin(), ghost.history.end(), [] (const ghostmoment gm) { return gm.step > ticks - race_start_tick;} ); | ||||
|     if(p == ghost.history.end()) p--; | ||||
|     cell *w = rti[p->where_id].c; | ||||
|   | ||||
							
								
								
									
										18
									
								
								system.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								system.cpp
									
									
									
									
									
								
							| @@ -1192,6 +1192,7 @@ void switch_game_mode(char switchWhat) { | ||||
|       peace::on = !peace::on; | ||||
|       tactic::on = yendor::on = princess::challenge =  | ||||
|       randomPatternsMode = inv::on = false; | ||||
|       racing::on = false; | ||||
|       break; | ||||
|      | ||||
|     case rg::inv: | ||||
| @@ -1199,6 +1200,7 @@ void switch_game_mode(char switchWhat) { | ||||
|       if(tactic::on) firstland = laIce; | ||||
|       tactic::on = yendor::on = princess::challenge =  | ||||
|       randomPatternsMode = peace::on = false; | ||||
|       racing::on = false; | ||||
|       break; | ||||
|  | ||||
|     case rg::chaos: | ||||
| @@ -1207,6 +1209,7 @@ void switch_game_mode(char switchWhat) { | ||||
|       need_reset_geometry = true; | ||||
|       chaosmode = !chaosmode; | ||||
|       if(bounded) set_geometry(gNormal); | ||||
|       racing::on = false; | ||||
|       break; | ||||
|  | ||||
| #if CAP_TOUR | ||||
| @@ -1219,6 +1222,7 @@ void switch_game_mode(char switchWhat) { | ||||
|       shmup::on = false; | ||||
|       need_reset_geometry = true;     | ||||
|       tour::on = !tour::on; | ||||
|       racing::on = false; | ||||
|       break; | ||||
| #endif | ||||
|  | ||||
| @@ -1230,9 +1234,20 @@ void switch_game_mode(char switchWhat) { | ||||
|       princess::challenge = false; | ||||
|       randomPatternsMode = false; | ||||
|       chaosmode = false; | ||||
|       racing::on = false; | ||||
|       if(!yendor::on) firstland = laIce; | ||||
|       break; | ||||
|      | ||||
|     case rg::racing: | ||||
|       racing::on = !racing::on; | ||||
|       shmup::on = racing::on; | ||||
|       peace::on = false; | ||||
|       tour::on = false; | ||||
|       inv::on = false; | ||||
|       chaosmode = false; | ||||
|       princess::challenge = false; | ||||
|       break; | ||||
|  | ||||
|     case rg::tactic: | ||||
|       tactic::on = !tactic::on; | ||||
|       yendor::on = false; | ||||
| @@ -1240,6 +1255,7 @@ void switch_game_mode(char switchWhat) { | ||||
|       inv::on = false; | ||||
|       randomPatternsMode = false; | ||||
|       princess::challenge = false; | ||||
|       racing::on = false; | ||||
|       chaosmode = false; | ||||
|       if(!tactic::on) firstland = laIce; | ||||
|       break; | ||||
| @@ -1247,6 +1263,7 @@ void switch_game_mode(char switchWhat) { | ||||
|     case rg::shmup: | ||||
|       shmup::on = !shmup::on; | ||||
|       princess::challenge = false; | ||||
|       if(!shmup::on) racing::on = false; | ||||
|       break; | ||||
|      | ||||
|     case rg::randpattern: | ||||
| @@ -1266,6 +1283,7 @@ void switch_game_mode(char switchWhat) { | ||||
|       yendor::on = false; | ||||
|       chaosmode = false; | ||||
|       inv::on = false; | ||||
|       racing::on = false; | ||||
|       break; | ||||
|      | ||||
| #if CAP_DAILY | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue