From 80b9bcf0ddb1a41a1294360284afc294408d8394 Mon Sep 17 00:00:00 2001 From: Dav999-v Date: Sat, 26 Nov 2022 03:33:17 +0100 Subject: [PATCH] Add level exploring menu for translators I would, of course, recommend translators to translate the roomnames while playing the full game (optionally in invincibility) so they can immediately get all the context and maybe the most inspiration. And if you want to go back into a specific level, then there's always the time trials and intermission replays which will give you full coverage of all the room names. However, the time trials weren't really made for room name translation. They have some annoying features like the instant restart when you press ENTER at the wrong time, they remove context clues like teleporters and companions, but the worst problem is that the last room in a level is often completely untranslatable inside the time trials because you immediately get sent to the results screen... So, I added a new menu in the translator options, "explore game", which gives you access to all the time trials and the two intermissions, from the same menu. All these time trials (which they're still based off of, under the hood) are stripped of the annoying features that come with time trials. These are the changes I made to time trial behavior in translator exploring mode: - No 3-2-1-Go! countdown - No on-screen time/death/shiny/par - ENTER doesn't restart, and the map menu works. The entire map is also revealed. - Prize for the Reckless is in its normal form - The teleporters in Entanglement Generator, Wheeler's Wormhole and Level Complete are restored as context for room names (actually, we should probably restore them in time trials anyway? Their "press to teleport" prompt is already blocked out in time trials and they do nothing other than being a checkpoint. I guess the reason they were removed was to stop people from opening the teleporter menu when that was not specifically blocked out in time trials yet.) - The companions are there at the end of levels, and behave like in no death mode (become happy and follow you to the teleporter). Also for context. - At the end of each level, you're not suddenly sent to the menu, but you can use the teleporter at your leisure just like in the intermission replays. In the Final Level, you do get sent to the menu automatically, but after a longer delay. I made another mark on VVVVVV: don't be startled, I added gamestates. I wanted all teleporters at the end of levels to behave like the ones at the end of the intermission replays, and all handling for teleporting with specific companions is already done in gamestates, so rather than adding conditional blocks across 5 or so different gamestates, it made more sense to make a single gamestate for "teleporting in translator exploring mode" (3090). I also added an alternative to having to use gamestate 3500 or 82 for the end of the final level: 3091-3092. One other thing I want to add to the "explore game" menu: a per-level count of how many room names are left to translate. That shouldn't be too difficult, and I'm planning that for the next commit. --- desktop_version/lang/en/strings.xml | 10 +++- desktop_version/lang/eo/strings.xml | 10 +++- desktop_version/lang/es/strings.xml | 10 +++- desktop_version/lang/nl/strings.xml | 14 ++++-- desktop_version/src/Finalclass.cpp | 10 ++-- desktop_version/src/Game.cpp | 55 ++++++++++++++++++++- desktop_version/src/Game.h | 5 ++ desktop_version/src/Input.cpp | 71 ++++++++++++++++++++++++--- desktop_version/src/Labclass.cpp | 7 ++- desktop_version/src/Logic.cpp | 2 +- desktop_version/src/Render.cpp | 45 +++++++++++++++-- desktop_version/src/Script.cpp | 12 +++++ desktop_version/src/Spacestation2.cpp | 8 +-- desktop_version/src/WarpClass.cpp | 4 +- 14 files changed, 234 insertions(+), 29 deletions(-) diff --git a/desktop_version/lang/en/strings.xml b/desktop_version/lang/en/strings.xml index 53f26422..4b6ab504 100644 --- a/desktop_version/lang/en/strings.xml +++ b/desktop_version/lang/en/strings.xml @@ -160,10 +160,14 @@ - + + + + + @@ -349,6 +353,10 @@ + + + + diff --git a/desktop_version/lang/eo/strings.xml b/desktop_version/lang/eo/strings.xml index d3f15272..9f35d28c 100644 --- a/desktop_version/lang/eo/strings.xml +++ b/desktop_version/lang/eo/strings.xml @@ -160,10 +160,14 @@ - + + + + + @@ -349,6 +353,10 @@ + + + + diff --git a/desktop_version/lang/es/strings.xml b/desktop_version/lang/es/strings.xml index 9e78d699..039831d9 100644 --- a/desktop_version/lang/es/strings.xml +++ b/desktop_version/lang/es/strings.xml @@ -160,10 +160,14 @@ - + + + + + @@ -349,6 +353,10 @@ + + + + diff --git a/desktop_version/lang/nl/strings.xml b/desktop_version/lang/nl/strings.xml index f85a5ea3..cc9f0f78 100644 --- a/desktop_version/lang/nl/strings.xml +++ b/desktop_version/lang/nl/strings.xml @@ -158,12 +158,16 @@ - - - + + + + + + + @@ -349,6 +353,10 @@ + + + + diff --git a/desktop_version/src/Finalclass.cpp b/desktop_version/src/Finalclass.cpp index 5593293d..41b98756 100644 --- a/desktop_version/src/Finalclass.cpp +++ b/desktop_version/src/Finalclass.cpp @@ -611,7 +611,7 @@ const short* finalclass::loadlevel(int rx, int ry) if(!obj.flags[72]) { - if (game.intimetrial || game.nocutscenes) + if ((game.intimetrial || game.nocutscenes) && !game.translator_exploring) { obj.createblock(1, 152 - 4, 112, 20, 16, 85); } @@ -1369,7 +1369,11 @@ const short* finalclass::loadlevel(int rx, int ry) obj.createblock(0, 315, 0, 5, 240); - if(game.intimetrial) + if (game.translator_exploring) + { + obj.createblock(1, 0, 0, 320, 120, 3091); + } + else if(game.intimetrial) { obj.createblock(1, 0, 0, 320, 120, 82); } @@ -1641,7 +1645,7 @@ const short* finalclass::loadlevel(int rx, int ry) obj.createentity(16, 112, 10, 1, 50520); // (savepoint) roomname = "Seeing Red"; - if(!game.intimetrial) + if(!game.intimetrial || game.translator_exploring) { if(game.companion==0 && !obj.flags[8] && !game.crewstats[3]) //also need to check if he's rescued in a previous game { diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index 5fb0613b..b7b3d188 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -299,6 +299,9 @@ void Game::init(void) timetrialresulttrinkets = 0; timetrialresultpar = 0; timetrialresultdeaths = 0; + start_translator_exploring = false; + translator_exploring = false; + translator_exploring_allowtele = false; totalflips = 0; hardestroom = "Welcome Aboard"; @@ -1492,6 +1495,12 @@ void Game::updatestate(void) case 82: //Time Trial Complete! obj.removetrigger(82); + if (translator_exploring) + { + translator_exploring_allowtele = true; + state = 0; + break; + } hascontrol = false; if (timetrialcheater) @@ -2311,6 +2320,11 @@ void Game::updatestate(void) break; //Intermission 1 } + if (translator_exploring_allowtele) + { + state = 3090; + } + int i = obj.getplayer(); if (INBOUNDS_VEC(i, obj.entities)) { @@ -2708,6 +2722,26 @@ void Game::updatestate(void) setstate(0); break; + case 3090: + /* Teleporting in translator_exploring should be just like + * the intermission replays: simply return to the menu */ + companion = 0; + supercrewmate = false; + graphics.fademode = FADE_START_FADEOUT; + music.fadeout(); + state=3100; + break; + case 3091: + /* Different Final Level ending for translator_exploring */ + music.fadeout(); + state++; + statedelay = 60; + break; + case 3092: + graphics.fademode = FADE_START_FADEOUT; + state=3100; + break; + case 3100: if (graphics.fademode == FADE_FULLY_BLACK) { @@ -6412,6 +6446,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) case Menu::translator_options: option(loc::gettext("language statistics")); option(loc::gettext("translate room names")); + option(loc::gettext("explore game")); option(loc::gettext("menu test")); option(loc::gettext("limits check")); option(loc::gettext("return")); @@ -6426,6 +6461,18 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) option(loc::gettext("return")); menuyoff = 64; break; + case Menu::translator_options_exploregame: + option(loc::gettext("space station 1")); + option(loc::gettext("the laboratory")); + option(loc::gettext("the tower")); + option(loc::gettext("space station 2")); + option(loc::gettext("the warp zone")); + option(loc::gettext("intermission 1")); + option(loc::gettext("intermission 2")); + option(loc::gettext("the final level")); + option(loc::gettext("return")); + menuyoff = -20; + break; case Menu::translator_maintenance: option(loc::gettext("sync language files")); option(loc::gettext("global statistics"), false); @@ -6644,6 +6691,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) menuyoff = -35; break; case Menu::playint1: + start_translator_exploring = false; option(loc::gettext("Vitellary")); option(loc::gettext("Vermilion")); option(loc::gettext("Verdigris")); @@ -6652,6 +6700,7 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ ) menuyoff = 10; break; case Menu::playint2: + start_translator_exploring = false; option(loc::gettext("Vitellary")); option(loc::gettext("Vermilion")); option(loc::gettext("Verdigris")); @@ -6944,7 +6993,11 @@ void Game::quittomenu(void) //or "who do you want to play the level with?" //or "do you want cutscenes?" //or the confirm-load-quicksave menu - if (intimetrial) + if (translator_exploring) + { + returntomenu(Menu::translator_options_exploregame); + } + else if (intimetrial) { returntomenu(Menu::timetrials); } diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index 55adf16b..33c3cbfa 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -65,6 +65,7 @@ namespace Menu translator_options, translator_options_limitscheck, translator_options_stats, + translator_options_exploregame, translator_maintenance, translator_maintenance_sync, translator_error_setlangwritedir, @@ -357,6 +358,10 @@ public: int timetrialresultshinytarget, timetrialresulttrinkets, timetrialresultpar; int timetrialresultdeaths; + bool start_translator_exploring; + bool translator_exploring; + bool translator_exploring_allowtele; + int creditposition; int oldcreditposition; bool insecretlab; diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index 0c8eaffa..91b66a3c 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -1182,13 +1182,19 @@ static void menuactionpress(void) game.savestatsandsettings_menu(); break; case 2: + // enter game + music.playef(11); + game.createmenu(Menu::translator_options_exploregame); + map.nexttowercolour(); + break; + case 3: // menu test music.playef(18); game.menutestmode = true; game.createmenu((Menu::MenuName) 0); map.nexttowercolour(); break; - case 3: + case 4: // limits check music.playef(11); loc::local_limits_check(); @@ -1227,6 +1233,59 @@ static void menuactionpress(void) game.returnmenu(); map.nexttowercolour(); break; + case Menu::translator_options_exploregame: + music.playef(11); + switch (game.currentmenuoption) + { + case 0: + // SS1 + game.start_translator_exploring = true; + startmode(3); + break; + case 1: + // Lab + game.start_translator_exploring = true; + startmode(4); + break; + case 2: + // Tower + game.start_translator_exploring = true; + startmode(5); + break; + case 3: + // SS2 + game.start_translator_exploring = true; + startmode(6); + break; + case 4: + // WZ + game.start_translator_exploring = true; + startmode(7); + break; + case 5: + // Int 1 + game.createmenu(Menu::playint1); + game.start_translator_exploring = true; + map.nexttowercolour(); + break; + case 6: + // Int 2 + game.createmenu(Menu::playint2); + game.start_translator_exploring = true; + map.nexttowercolour(); + break; + case 7: + // Final + game.start_translator_exploring = true; + startmode(8); + break; + default: + // return + game.returnmenu(); + map.nexttowercolour(); + break; + } + break; case Menu::translator_maintenance: music.playef(11); switch (game.currentmenuoption) @@ -2352,7 +2411,7 @@ void gameinput(void) game.interactheld = false; } - if (game.intimetrial && graphics.fademode == FADE_FULLY_BLACK && game.quickrestartkludge) + if (game.intimetrial && graphics.fademode == FADE_FULLY_BLACK && game.quickrestartkludge && !game.translator_exploring) { //restart the time trial game.quickrestartkludge = false; @@ -2417,7 +2476,7 @@ void gameinput(void) if (interact_pressed && !script.running) { - if (game.activetele && game.readytotele > 20 && !game.intimetrial) + if (game.activetele && game.readytotele > 20 && (!game.intimetrial || game.translator_exploring_allowtele)) { enter_already_processed = true; if(int(SDL_fabsf(obj.entities[ie].vx))<=1 && int(obj.entities[ie].vy)==0) @@ -2448,7 +2507,7 @@ void gameinput(void) game.setstate(4000); game.setstatedelay(0); } - else if (game.companion == 0) + else if (game.companion == 0 && !game.translator_exploring_allowtele) { //Alright, normal teleporting game.mapmenuchange(TELEPORTERMODE, true); @@ -2645,7 +2704,7 @@ void gameinput(void) game.gamesavefailed = false; game.menupage = 20; // The Map Page } - else if (game.intimetrial && graphics.fademode == FADE_NONE) + else if (game.intimetrial && graphics.fademode == FADE_NONE && !game.translator_exploring) { //Quick restart of time trial graphics.fademode = FADE_START_FADEOUT; @@ -2653,7 +2712,7 @@ void gameinput(void) music.fadeout(); game.quickrestartkludge = true; } - else if (game.intimetrial) + else if (game.intimetrial && !game.translator_exploring) { //Do nothing if we're in a Time Trial but a fade animation is playing } diff --git a/desktop_version/src/Labclass.cpp b/desktop_version/src/Labclass.cpp index 221e3e40..280e85a1 100644 --- a/desktop_version/src/Labclass.cpp +++ b/desktop_version/src/Labclass.cpp @@ -1038,7 +1038,10 @@ const short* labclass::loadlevel(int rx, int ry) //obj.createentity(224, 192, 10, 0, 249550); // (savepoint) - if(!game.intimetrial) obj.createentity((12 * 8)-4, (6 * 8) + 4, 14); //Teleporter! + if(!game.intimetrial || game.translator_exploring) + { + obj.createentity((12 * 8)-4, (6 * 8) + 4, 14); //Teleporter! + } rcol = 5; roomname = "Entanglement Generator"; @@ -2022,7 +2025,7 @@ const short* labclass::loadlevel(int rx, int ry) }; rcol=0; - if(!game.intimetrial) + if(!game.intimetrial || game.translator_exploring) { if(game.companion==0 && !obj.flags[9] && !game.crewstats[5]) //also need to check if he's rescued in a previous game { diff --git a/desktop_version/src/Logic.cpp b/desktop_version/src/Logic.cpp index 8fd9e60c..b001e992 100644 --- a/desktop_version/src/Logic.cpp +++ b/desktop_version/src/Logic.cpp @@ -1432,7 +1432,7 @@ void gamelogic(void) } game.oldreadytotele = game.readytotele; - if (game.activetele && game.hascontrol && !script.running && !game.intimetrial) + if (game.activetele && game.hascontrol && !script.running && (!game.intimetrial || game.translator_exploring_allowtele)) { int i = obj.getplayer(); SDL_Rect temprect = SDL_Rect(); diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 4a3bfc66..ff2ab8c7 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -648,7 +648,7 @@ static void menurender(void) case 1: { graphics.bigprint( -1, 30, loc::gettext("Translate rooms"), tr, tg, tb, true); - int next_y = graphics.PrintWrap( -1, 65, loc::gettext("Enable room name translation mode, so you can translate room names in context."), tr, tg, tb, true); + int next_y = graphics.PrintWrap( -1, 65, loc::gettext("Enable room name translation mode, so you can translate room names in context. Press I for invincibility."), tr, tg, tb, true); if (roomname_translator::enabled) { @@ -661,10 +661,14 @@ static void menurender(void) break; } case 2: + graphics.bigprint( -1, 30, loc::gettext("Explore game"), tr, tg, tb, true); + graphics.PrintWrap( -1, 65, loc::gettext("Explore the rooms of any level in the game, to find all room names to translate."), tr, tg, tb, true); + break; + case 3: graphics.bigprint( -1, 30, loc::gettext("Menu test"), tr, tg, tb, true); graphics.PrintWrap( -1, 65, loc::gettext("Cycle through most menus in the game. The menus will not actually work, all options take you to the next menu instead. Press Escape to stop."), tr, tg, tb, true); break; - case 3: + case 4: graphics.bigprint( -1, 30, loc::gettext("Limits check"), tr, tg, tb, true); graphics.PrintWrap( -1, 65, loc::gettext("Find translations that don't fit within their defined bounds."), tr, tg, tb, true); break; @@ -750,6 +754,39 @@ static void menurender(void) break; } + case Menu::translator_options_exploregame: + switch (game.currentmenuoption) + { + case 0: + graphics.bigprint( -1, 30, loc::gettext("Space Station 1"), tr, tg, tb, true); + break; + case 1: + graphics.bigprint( -1, 30, loc::gettext("The Laboratory"), tr, tg, tb, true); + break; + case 2: + graphics.bigprint( -1, 30, loc::gettext("The Tower"), tr, tg, tb, true); + break; + case 3: + graphics.bigprint( -1, 30, loc::gettext("Space Station 2"), tr, tg, tb, true); + break; + case 4: + graphics.bigprint( -1, 30, loc::gettext("The Warp Zone"), tr, tg, tb, true); + break; + case 5: + graphics.bigprint( -1, 30, loc::gettext("Intermission 1"), tr, tg, tb, true); + break; + case 6: + graphics.bigprint( -1, 30, loc::gettext("Intermission 2"), tr, tg, tb, true); + break; + case 7: + graphics.bigprint( -1, 30, loc::gettext("The Final Level"), tr, tg, tb, true); + break; + } + if (!roomname_translator::enabled) + { + graphics.PrintWrap( -1, 65, loc::gettext("You have not enabled room name translation mode!"), tr, tg, tb, true); + } + break; case Menu::translator_maintenance: switch (game.currentmenuoption) { @@ -2066,7 +2103,7 @@ void gamerender(void) graphics.bigbprint( -1, 100, "3", 220 - (help.glow), 220 - (help.glow), 255 - (help.glow / 2), true, 4); } } - else if (!roomname_translator::is_pausing()) + else if (!roomname_translator::is_pausing() && !game.translator_exploring) { char buffer[SCREEN_WIDTH_CHARS + 1]; game.timestringcenti(buffer, sizeof(buffer)); @@ -2610,7 +2647,7 @@ void maprender(void) } case 3: { - if (game.inintermission) + if (game.inintermission || game.translator_exploring) { graphics.PrintWrap(0, 115, loc::gettext("Cannot Save in Level Replay"), 146, 146, 180, true); break; diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index c2c06903..d0498b17 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -2643,6 +2643,14 @@ void scriptclass::startgamemode(const enum StartMode mode) } game.starttrial(game.timetriallevel); + + if (game.translator_exploring) + { + game.timetrialcountdown = 0; + game.timetrialparlost = true; + SDL_memset(map.explored, true, sizeof(map.explored)); + } + graphics.fademode = FADE_START_FADEIN; break; @@ -3045,6 +3053,10 @@ void scriptclass::hardreset(void) game.timetrialpar = 0; game.timetrialcheater = false; + game.translator_exploring = game.start_translator_exploring; + game.start_translator_exploring = false; + game.translator_exploring_allowtele = false; + game.totalflips = 0; game.hardestroom = loc::gettext_roomname(false, 13, 5, "Welcome Aboard", false); game.hardestroomdeaths = 0; diff --git a/desktop_version/src/Spacestation2.cpp b/desktop_version/src/Spacestation2.cpp index b3e30ea0..f69a34f1 100644 --- a/desktop_version/src/Spacestation2.cpp +++ b/desktop_version/src/Spacestation2.cpp @@ -1094,7 +1094,7 @@ const short* spacestation2class::loadlevel(int rx, int ry) obj.createentity(7 * 8, (36 * 8)-216, 1, 12, 1); // Enemy //FACTORY emitter starts here (manually placed) - if(!game.intimetrial) + if(!game.intimetrial || game.translator_exploring) { obj.createentity(18 * 8, (5 * 8) + 4, 14); //Teleporter! } @@ -2540,7 +2540,7 @@ const short* spacestation2class::loadlevel(int rx, int ry) }; //Remove spikes in modes where the player shouldn't kill themselves - int spikevalue = (game.nodeathmode || game.intimetrial) ? 0 : 9; + int spikevalue = (game.nodeathmode || (game.intimetrial && !game.translator_exploring)) ? 0 : 9; for (int i = 23; i < 23+14; i++) { contents[i + 8*40] = spikevalue; @@ -2559,7 +2559,7 @@ const short* spacestation2class::loadlevel(int rx, int ry) roomname = "I Can't Believe You Got This Far"; roomname_special = true; } - else if (game.intimetrial) + else if (game.intimetrial && !game.translator_exploring) { roomname = "Imagine Spikes There, if You Like"; roomname_special = true; @@ -2751,7 +2751,7 @@ const short* spacestation2class::loadlevel(int rx, int ry) obj.createentity(192, 88, 10, 0, 441490); // (savepoint) - if(!game.intimetrial) + if(!game.intimetrial || game.translator_exploring) { if(game.companion==0 && !obj.flags[10] && !game.crewstats[2]) //also need to check if he's rescued in a previous game { diff --git a/desktop_version/src/WarpClass.cpp b/desktop_version/src/WarpClass.cpp index c56801af..951ecd83 100644 --- a/desktop_version/src/WarpClass.cpp +++ b/desktop_version/src/WarpClass.cpp @@ -427,7 +427,7 @@ const short* warpclass::loadlevel(int rx, int ry) 86,86,208,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206,86,86, 86,86,208,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,206,86,86, }; - if(!game.intimetrial) + if(!game.intimetrial || game.translator_exploring) { obj.createentity((7 * 8) + 4, (6 * 8), 14); //Teleporter! } @@ -1112,7 +1112,7 @@ const short* warpclass::loadlevel(int rx, int ry) rcol = 0; warpy = true; - if(!game.intimetrial) + if(!game.intimetrial || game.translator_exploring) { if(game.companion==0 && !obj.flags[11] && !game.crewstats[4]) //also need to check if he's rescued in a previous game {