diff --git a/CREDITS.md b/CREDITS.md index 9a9120bdd0..3e6cb5b718 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -390,6 +390,7 @@ This page lists all the individual contributions to the project by their author. - Fix Ares' InitialPayload for teams spawned by trigger actions - Allow Reveal Crate to take effect when picking up by another player controlled house in campaign - Misc code refactor & maintenance, CN doc fixes, bugfixes + - Show game time - **FlyStar**: - Campaign load screen PCX support - New condition for automatic self-destruction logic when TechnoTypes exist/don't exist @@ -741,6 +742,7 @@ This page lists all the individual contributions to the project by their author. - Allow `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades - Dynamic team delays - Customize whether or not passenger can fire out when the transport is moving + - Show game time - **NaotoYuuki** - Vertical & meteor trajectory projectile prototypes - **handama**: - AI script action to `16005 Jump Back To Previous Script` diff --git a/docs/User-Interface.md b/docs/User-Interface.md index 26fc2b8418..d14a4b461d 100644 --- a/docs/User-Interface.md +++ b/docs/User-Interface.md @@ -399,6 +399,19 @@ In `RA2MD.INI`: ShowDesignatorRange=false ; boolean ``` +### Show game time +- A timer can be displayed to show how many time has passed since game starts. + - The timer will be shown in the format of `TXT_GAMETIME hh:mm:ss`. For localization add `TXT_GAMETIME` into your `.csf` file. + - `ShowGameTime.BoardOpacity` can be used to set the opacitiy of background for game time display. + - Observer can't see this timer since they've already gotten one on the top of sidebar. + +In `RA2MD.INI`: +```ini +[Phobos] +ShowGameTime=false ; boolean +ShowGameTime.BoardOpacity=40 ; integer +``` + ### SuperWeapon ShowTimer sorting - You can now sort the timers of superweapons in ascending order from top to bottom according to a given priority value. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index e0bc8c2488..ba4120db76 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -624,6 +624,7 @@ HideShakeEffects=false ; boolean - [Customize crash spin multiplier](Fixed-or-Improved-Logics.md#customize-crash-spin-multiplier) (by NetsuNegi) - Add a defining for the auto death effect on whether it can trigger when in Limbo state (by Noble_Fish) - Customize whether `Passengers.SyncOwner.RevertOnExit` triggers `AutoDeath.OnOwnerChange` (by Noble_Fish) +- [Show game time](User-Interface.md#show-game-time) (by Trsdy & Ollerus) #### Vanilla fixes: - Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya) diff --git a/src/Phobos.INI.cpp b/src/Phobos.INI.cpp index ac9f7649b2..245a097931 100644 --- a/src/Phobos.INI.cpp +++ b/src/Phobos.INI.cpp @@ -80,6 +80,8 @@ bool Phobos::Config::HideShakeEffects = true; bool Phobos::Config::ShowFlashOnSelecting = false; bool Phobos::Config::UnitPowerDrain = false; int Phobos::Config::SuperWeaponSidebar_RequiredSignificance = 0; +bool Phobos::Config::ShowGameTime = false; +int Phobos::Config::ShowGameTime_BoardOpacity = 40; bool Phobos::Misc::CustomGS = false; int Phobos::Misc::CustomGS_ChangeInterval[7] = { -1, -1, -1, -1, -1, -1, -1 }; @@ -115,6 +117,8 @@ DEFINE_HOOK(0x5FACDF, OptionsClass_LoadSettings_LoadPhobosSettings, 0x5) Phobos::Config::HideShakeEffects = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "HideShakeEffects", false); Phobos::Config::ShowFlashOnSelecting = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowFlashOnSelecting", false); Phobos::Config::SuperWeaponSidebar_RequiredSignificance = CCINIClass::INI_RA2MD.ReadInteger(phobosSection, "SuperWeaponSidebar.RequiredSignificance", 0); + Phobos::Config::ShowGameTime = CCINIClass::INI_RA2MD.ReadBool(phobosSection, "ShowGameTime", false); + Phobos::Config::ShowGameTime_BoardOpacity = CCINIClass::INI_RA2MD.ReadInteger(phobosSection, "ShowGameTime.BoardOpacity", 40); // Custom game speeds, 6 - i so that GS6 is index 0, just like in the engine Phobos::Config::CampaignDefaultGameSpeed = 6 - CCINIClass::INI_RA2MD.ReadInteger(phobosSection, "CampaignDefaultGameSpeed", 4); diff --git a/src/Phobos.cpp b/src/Phobos.cpp index e5943a2c88..5ce137def6 100644 --- a/src/Phobos.cpp +++ b/src/Phobos.cpp @@ -1,6 +1,7 @@ #include "Phobos.h" #include +#include #include #include @@ -12,6 +13,7 @@ #include #include #include "Utilities/AresHelper.h" +#include "Utilities/GeneralUtils.h" #include "Utilities/Parser.h" #ifndef IS_RELEASE_VER @@ -301,30 +303,75 @@ DEFINE_HOOK(0x683E7F, ScenarioClass_Start_Optimizations, 0x7) return 0; } -#ifndef IS_RELEASE_VER DEFINE_HOOK(0x4F4583, GScreenClass_DrawText, 0x6) { + const int marginX = Phobos::Config::MessageDisplayInCenter ? 28 : 10; + int coordY = 0; + +#ifndef IS_RELEASE_VER #ifndef STR_GIT_COMMIT if (!HideWarning) #endif // !STR_GIT_COMMIT { - auto wanted = Drawing::GetTextDimensions(Phobos::VersionDescription, { 0,0 }, 0, 2, 0); + auto wanted = Drawing::GetTextDimensions(Phobos::VersionDescription, { 0, 0 }, 0, 2, 0); RectangleStruct rect = { - DSurface::Composite->GetWidth() - wanted.Width - 10, + DSurface::Composite->GetWidth() - wanted.Width - marginX, 0, wanted.Width + 10, wanted.Height + 10 }; - Point2D location { rect.X + 5,5 }; - + Point2D location { rect.X + 5, 5 }; DSurface::Composite->FillRect(&rect, COLOR_BLACK); DSurface::Composite->DrawText(Phobos::VersionDescription, &location, COLOR_RED); + + // add margin for next text + coordY = rect.Height; + } +#endif // !IS_RELEASE_VER + + if (!Phobos::Config::ShowGameTime || HouseClass::CurrentPlayer->IsObserver()) // already has a timer + return 0; + + wchar_t buffer[0x20] {}; + const auto& timer = ScenarioClass::Instance->ElapsedTimer; + int currentTime = timer.TimeLeft; + + if (timer.StartTime != -1) + currentTime += SystemTimer::GetTime() - timer.StartTime; + + currentTime /= 60; + const int hours = currentTime / 3600; + const int minutes = (currentTime / 60) % 60; + const int seconds = currentTime % 60; + const auto text = GeneralUtils::LoadStringUnlessMissing("TXT_GAMETIME", L"Time:"); + + if (hours > 0) + { + swprintf(buffer, std::size(buffer), L"%ls %d:%02d:%02d", text, hours, minutes, seconds); + } + else + { + swprintf(buffer, std::size(buffer), L"%ls %02d:%02d", text, minutes, seconds); } + + auto wantedB = Drawing::GetTextDimensions(buffer, { 0, 0 }, 0, 2, 0); + + RectangleStruct rectB = { + DSurface::Composite->GetWidth() - wantedB.Width - marginX, + coordY, + wantedB.Width + 10, + wantedB.Height + 10 + }; + + Point2D locationB { rectB.X + 5, rectB.Y + 5 }; + ColorStruct color { 0x0, 0x0 ,0x0 }; + DSurface::Composite->FillRectTrans(&rectB, &color, Phobos::Config::ShowGameTime_BoardOpacity); + DSurface::Composite->DrawText(buffer, &locationB, COLOR_WHITE); + return 0; } -#endif // Mainly used to disable hooks for optimization. // Called after loading saved game and at end of scenario start after all INI data etc has been initialized. diff --git a/src/Phobos.h b/src/Phobos.h index 6bdb4073ec..1aa1ec1185 100644 --- a/src/Phobos.h +++ b/src/Phobos.h @@ -116,6 +116,8 @@ class Phobos static bool ShowFlashOnSelecting; static bool UnitPowerDrain; static int SuperWeaponSidebar_RequiredSignificance; + static bool ShowGameTime; + static int ShowGameTime_BoardOpacity; }; class Misc