From 858c2cb081c1e911adf2ef948bd104c7c5e69121 Mon Sep 17 00:00:00 2001 From: Misa Date: Sat, 6 Jan 2024 20:53:51 -0800 Subject: [PATCH] Indicate modes when loading in to gameplay If you load in to gameplay with invincibility mode, glitchrunner mode, Flip Mode, or slowdown enabled, then there will be text displayed on screen for a few seconds that says so. This is to serve as a useful reminder. A common pitfall with using invincibility is forgetting to turn it off when you don't want it anymore. What usually happens is that players forget that they have it on until they encounter a hazard. Now, they can realize it as soon as they load in. See #1091. --- desktop_version/src/Game.cpp | 3 + desktop_version/src/Game.h | 3 + desktop_version/src/Render.cpp | 94 ++++++++++++++++++++++++++++- desktop_version/src/RenderFixed.cpp | 6 ++ desktop_version/src/Script.cpp | 15 +++++ 5 files changed, 120 insertions(+), 1 deletion(-) diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index fa64f1e2..54582aa0 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -361,6 +361,9 @@ void Game::init(void) old_skip_message_timer = 0; skip_message_timer = 0; + old_mode_indicator_timer = 0; + mode_indicator_timer = 0; + setdefaultcontrollerbuttons(); } diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index 48752127..1248d1aa 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -589,6 +589,9 @@ public: int old_skip_message_timer; int skip_message_timer; + + int old_mode_indicator_timer; + int mode_indicator_timer; }; #ifndef GAME_DEFINITION diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 9592aafa..f0bf6a9c 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -2175,6 +2175,87 @@ static const char* interact_prompt( return buffer; } +static void mode_indicator_text(const int alpha) +{ + const int flags = PR_BRIGHTNESS(alpha) | PR_BOR | PR_RTL_XFLIP; + const int r = 220 - help.glow; + const int g = 220 - help.glow; + const int b = 255 - help.glow/2; + const int x = 5; + const int spacing = font::height(flags) + 2; + int y = 5; + if (game.advancetext) + { + /* Prevent clashing */ + y += 15; + } + + /* FIXME: Some strings have not yet been translated. In order to not have + * English text in other languages, they are substituted with existing + * ones. Remove all substitute text when they're fully translated. */ + + if (map.invincibility) + { + const char* english = "Invincibility mode enabled"; + const char* text = loc::gettext(english); + if (loc::lang != "en" && SDL_strcmp(english, text) == 0) + { + /* Substitute text */ + text = loc::gettext("Invincibility"); + } + font::print(flags, x, y, text, r, g, b); + y += spacing; + } + + enum GlitchrunnerMode mode = GlitchrunnerMode_get(); + if (mode != GlitchrunnerNone) + { + char buffer[SCREEN_WIDTH_CHARS + 1]; + const char* english = "Glitchrunner mode enabled ({version})"; + const char* text = loc::gettext(english); + if (loc::lang != "en" && SDL_strcmp(english, text) == 0) + { + /* Substitute text */ + SDL_strlcpy(buffer, loc::gettext("Glitchrunner Mode"), sizeof(buffer)); + } + else + { + const char* mode_string = loc::gettext(GlitchrunnerMode_enum_to_string(mode)); + vformat_buf(buffer, sizeof(buffer), text, "version:str", mode_string); + } + font::print(flags, x, y, buffer, r, g, b); + y += spacing; + } + + if (graphics.flipmode) + { + const char* english = "Flip Mode enabled"; + const char* text = loc::gettext(english); + if (loc::lang != "en" && SDL_strcmp(english, text) == 0) + { + /* Substitute text */ + text = loc::gettext("Flip Mode"); + } + font::print(flags, x, y, text, r, g, b); + y += spacing; + } + + switch (game.slowdown) + { + case 24: + font::print(flags, x, y, loc::gettext("Game speed is at 80%"), r, g, b); + y += spacing; + break; + case 18: + font::print(flags, x, y, loc::gettext("Game speed is at 60%"), r, g, b); + y += spacing; + break; + case 12: + font::print(flags, x, y, loc::gettext("Game speed is at 40%"), r, g, b); + y += spacing; + } +} + void gamerender(void) { graphics.set_render_target(graphics.gameplayTexture); @@ -2232,6 +2313,11 @@ void gamerender(void) draw_return_editor_text = return_editor_alpha > 100; } + int mode_indicator_alpha = graphics.lerp( + game.old_mode_indicator_timer, game.mode_indicator_timer + ); + bool draw_mode_indicator_text = mode_indicator_alpha > 100; + if (graphics.fademode == FADE_NONE && !game.intimetrial && !game.isingamecompletescreen() @@ -2239,7 +2325,8 @@ void gamerender(void) && game.showingametimer && !roomname_translator::enabled && (!game.swnmode || game.swngame != SWN_START_GRAVITRON_STEP_3) - && !draw_return_editor_text) + && !draw_return_editor_text + && !draw_mode_indicator_text) { const char* tempstring = loc::gettext("TIME:"); int label_len = font::len(0, tempstring); @@ -2302,6 +2389,11 @@ void gamerender(void) graphics.drawgui(); + if (draw_mode_indicator_text && !draw_return_editor_text) + { + mode_indicator_text(mode_indicator_alpha); + } + graphics.set_render_target(graphics.gameTexture); graphics.copy_texture(graphics.gameplayTexture, NULL, NULL); diff --git a/desktop_version/src/RenderFixed.cpp b/desktop_version/src/RenderFixed.cpp index b2ca3e6c..c68f484d 100644 --- a/desktop_version/src/RenderFixed.cpp +++ b/desktop_version/src/RenderFixed.cpp @@ -137,6 +137,12 @@ void gamerenderfixed(void) ed.return_message_timer -= 15; } + game.old_mode_indicator_timer = game.mode_indicator_timer; + if (game.mode_indicator_timer > 0) + { + game.mode_indicator_timer -= 15; + } + // Editor ghosts! if (game.ghostsenabled) { diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index 8207f7ac..6573a924 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -2694,6 +2694,21 @@ void scriptclass::startgamemode(const enum StartMode mode) font::set_level_font_interface(); } + /* Indicate invincibility, glitchrunner, etc. for all modes except these */ + switch (mode) + { + case Start_EDITOR: + case Start_CUTSCENETEST: + break; + case Start_QUIT: + VVV_unreachable(); + + default: + /* If there's editor return text, make this show up after it */ + game.mode_indicator_timer = ed.return_message_timer + 2000; + game.old_mode_indicator_timer = game.mode_indicator_timer; + } + game.jumpheld = true; switch (mode)