From aa4a81423af8e9315e5b3ca6d22435d66f80a579 Mon Sep 17 00:00:00 2001 From: L3-M <100478094+L3-M@users.noreply.github.com> Date: Thu, 21 Aug 2025 22:15:52 +0300 Subject: [PATCH 1/3] feat(display): Implement player money per minute --- .../GameEngine/Include/Common/GlobalData.h | 3 + .../Code/GameEngine/Include/Common/Money.h | 21 ++++++- .../Include/Common/UserPreferences.h | 1 + .../GameEngine/Source/Common/GlobalData.cpp | 3 + .../GameEngine/Source/Common/RTS/Money.cpp | 43 ++++++++++++++ .../GameEngine/Source/Common/RTS/Player.cpp | 1 + .../Source/Common/RTS/PlayerTemplate.cpp | 1 + .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 22 +++++++ .../GameEngine/Source/GameClient/InGameUI.cpp | 58 ++++++++++++++++--- 9 files changed, 145 insertions(+), 8 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index ed3bbcc1d1..2cce7fa6c3 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -405,6 +405,9 @@ class GlobalData : public SubsystemInterface Bool m_saveCameraInReplay; Bool m_useCameraInReplay; + // TheSuperHackers @feature L3-M 21/08/2025 toggle the money per minute display; 'no' shows only the original current money + Bool m_moneyPerMinute; + // TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game time font size to be set, a size of zero disables them Int m_systemTimeFontSize; Int m_gameTimeFontSize; diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Money.h b/GeneralsMD/Code/GameEngine/Include/Common/Money.h index 9b17177669..9bda19c5ec 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Money.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Money.h @@ -64,13 +64,24 @@ class Money : public Snapshot public: - inline Money() : m_money(0), m_playerIndex(0) + inline Money() : m_money(0), m_playerIndex(0), m_startingCash(0), m_currentBucket(0), m_lastBucketFrame(0) { + for (UnsignedInt i = 0; i < 60; ++i) + { + m_incomeBuckets[i] = 0; + } } void init() { m_money = 0; + m_startingCash = 0; + m_currentBucket = 0; + m_lastBucketFrame = 0; + for (UnsignedInt i = 0; i < 60; ++i) + { + m_incomeBuckets[i] = 0; + } } inline UnsignedInt countMoney() const @@ -82,6 +93,10 @@ class Money : public Snapshot UnsignedInt withdraw(UnsignedInt amountToWithdraw, Bool playSound = TRUE); void deposit(UnsignedInt amountToDeposit, Bool playSound = TRUE); + void setStartingCash(UnsignedInt amount); + void updateIncomeBucket(); + UnsignedInt getCashPerMinute() const; + void setPlayerIndex(Int ndx) { m_playerIndex = ndx; } static void parseMoneyAmount( INI *ini, void *instance, void *store, const void* userData ); @@ -105,6 +120,10 @@ class Money : public Snapshot UnsignedInt m_money; ///< amount of money Int m_playerIndex; ///< what is my player index? + UnsignedInt m_startingCash; + UnsignedInt m_incomeBuckets[60]; + UnsignedInt m_currentBucket; + UnsignedInt m_lastBucketFrame; }; #endif // _MONEY_H_ diff --git a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h index 9e4d83a4bf..5e533c5d7f 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h @@ -128,6 +128,7 @@ class OptionPreferences : public UserPreferences Bool getFPSLimitEnabled(void); Bool getNoDynamicLODEnabled(void); Bool getBuildingOcclusionEnabled(void); + Bool getMoneyPerMinute(void); Int getParticleCap(void); Int getCampaignDifficulty(void); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index be4b8962e2..1e0b93069a 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -934,6 +934,8 @@ GlobalData::GlobalData() m_saveCameraInReplay = FALSE; m_useCameraInReplay = FALSE; + m_moneyPerMinute = TRUE; + m_systemTimeFontSize = 8; m_gameTimeFontSize = 8; @@ -1203,6 +1205,7 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize(); TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize(); + TheWritableGlobalData->m_moneyPerMinute = optionPref.getMoneyPerMinute(); Int val=optionPref.getGammaValue(); //generate a value between 0.6 and 2.0. diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp index 8a45812ecc..1ca6fc93b3 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp @@ -51,6 +51,7 @@ #include "Common/Player.h" #include "Common/PlayerList.h" #include "Common/Xfer.h" +#include "GameLogic/GameLogic.h" // ------------------------------------------------------------------------------------------------ UnsignedInt Money::withdraw(UnsignedInt amountToWithdraw, Bool playSound) @@ -89,6 +90,7 @@ void Money::deposit(UnsignedInt amountToDeposit, Bool playSound) } m_money += amountToDeposit; + m_incomeBuckets[m_currentBucket] += amountToDeposit; if( amountToDeposit > 0 ) { @@ -100,6 +102,46 @@ void Money::deposit(UnsignedInt amountToDeposit, Bool playSound) } } +// ------------------------------------------------------------------------------------------------ +void Money::setStartingCash(UnsignedInt amount) +{ + m_startingCash = amount; + m_money = amount; + m_currentBucket = 0; + m_lastBucketFrame = 0; + for (UnsignedInt i = 0; i < 60; ++i) + m_incomeBuckets[i] = 0; +} + +// ------------------------------------------------------------------------------------------------ +void Money::updateIncomeBucket() +{ + UnsignedInt frame = TheGameLogic->getFrame(); + UnsignedInt lastSec = m_lastBucketFrame / LOGICFRAMES_PER_SECOND; + UnsignedInt curSec = frame / LOGICFRAMES_PER_SECOND; + UnsignedInt diff = (curSec > lastSec) ? curSec - lastSec : 0; + if (diff > 0) + { + if (diff > 60) + diff = 60; + for (UnsignedInt i = 0; i < diff; ++i) + { + m_currentBucket = (m_currentBucket + 1) % 60; + m_incomeBuckets[m_currentBucket] = 0; + } + } + m_lastBucketFrame = frame; +} + +// ------------------------------------------------------------------------------------------------ +UnsignedInt Money::getCashPerMinute() const +{ + UnsignedInt sum = 0; + for (UnsignedInt i = 0; i < 60; ++i) + sum += m_incomeBuckets[i]; + return sum; +} + void Money::triggerAudioEvent(const AudioEventRTS& audioEvent) { Real volume = TheAudio->getAudioSettings()->m_preferredMoneyTransactionVolume; @@ -157,4 +199,5 @@ void Money::parseMoneyAmount( INI *ini, void *instance, void *store, const void* // Someday, maybe, have mulitple fields like Gold:10000 Wood:1000 Tiberian:10 Money * money = (Money *)store; INI::parseUnsignedInt( ini, instance, &money->m_money, userData ); + money->setStartingCash(money->m_money); } diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp index 891adf3050..263ece90b2 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp @@ -462,6 +462,7 @@ void Player::init(const PlayerTemplate* pt) { m_money.deposit( TheGlobalData->m_defaultStartingCash.countMoney(), FALSE ); } + m_money.setStartingCash(m_money.countMoney()); } m_playerDisplayName.clear(); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerTemplate.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerTemplate.cpp index 3fe64a9088..493af04175 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerTemplate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/PlayerTemplate.cpp @@ -182,6 +182,7 @@ AsciiString PlayerTemplate::getStartingUnit( Int i ) const Money *theMoney = (Money *)store; theMoney->init(); theMoney->deposit( money ); + theMoney->setStartingCash(money); } // end parseStartMoney diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 2f4a306071..423f4ed125 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -828,6 +828,19 @@ Int OptionPreferences::getGameTimeFontSize(void) return fontSize; } +Bool OptionPreferences::getMoneyPerMinute(void) +{ + OptionPreferences::const_iterator it = find("MoneyPerMinute"); + if (it == end()) + return TheGlobalData->m_moneyPerMinute; + + if (stricmp(it->second.str(), "yes") == 0) + { + return TRUE; + } + return FALSE; +} + static OptionPreferences *pref = NULL; static void setDefaults( void ) @@ -1354,6 +1367,15 @@ static void saveOptions( void ) TheInGameUI->refreshGameTimeResources(); } + //------------------------------------------------------------------------------------------------- + // Set Money Per Minute + { + Bool showIncome = pref->getMoneyPerMinute(); + AsciiString prefString; + prefString = showIncome ? "yes" : "no"; + (*pref)["MoneyPerMinute"] = prefString; + } + //------------------------------------------------------------------------------------------------- // Resolution // diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index 2573860144..be3d721c0f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -1837,6 +1837,7 @@ void InGameUI::update( void ) // update the player money window if the money amount has changed // this seems like as good a place as any to do the power hide/show static Int lastMoney = -1; + static Int lastIncome = -1; static NameKeyType moneyWindowKey = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:MoneyDisplay" ); static NameKeyType powerWindowKey = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:PowerWindow" ); @@ -1852,16 +1853,59 @@ void InGameUI::update( void ) Player* moneyPlayer = TheControlBar->getCurrentlyViewedPlayer(); if( moneyPlayer) { - Int currentMoney = moneyPlayer->getMoney()->countMoney(); - if( lastMoney != currentMoney ) + Money *money = moneyPlayer->getMoney(); + Bool showIncome = TheGlobalData->m_moneyPerMinute; + if (!showIncome) { - UnicodeString buffer; + Int currentMoney = money->countMoney(); + if( lastMoney != currentMoney ) + { + UnicodeString buffer; - buffer.format( TheGameText->fetch( "GUI:ControlBarMoneyDisplay" ), currentMoney ); - GadgetStaticTextSetText( moneyWin, buffer ); - lastMoney = currentMoney; + buffer.format(TheGameText->fetch( "GUI:ControlBarMoneyDisplay" ), currentMoney ); + GadgetStaticTextSetText( moneyWin, buffer ); + lastMoney = currentMoney; - } // end if + } // end if + } + else + { + // TheSuperHackers @feature L3-M 21/08/2025 player money per minute + money->updateIncomeBucket(); + UnsignedInt currentMoney = money->countMoney(); + UnsignedInt cashPerMin = money->getCashPerMinute(); + if (lastMoney != (Int)currentMoney || lastIncome != (Int)cashPerMin) + { + UnicodeString buffer; + UnicodeString moneyStr; + UnicodeString incomeStr; + if (currentMoney >= 100000) + { + moneyStr.format(L"%dK", currentMoney / 1000); + } + else + { + moneyStr.format(L"%d", currentMoney); + } + if (cashPerMin >= 10000) + { + incomeStr.format(L"%dK", cashPerMin / 1000); + } + else if (cashPerMin >= 1000) + { + UnsignedInt k = cashPerMin / 100; + incomeStr.format(L"%d.%dK", k / 10, k % 10); + } + else + { + incomeStr.format(L"%d", cashPerMin); + } + buffer.format(TheGameText->FETCH_OR_SUBSTITUTE_FORMAT("GUI:ControlBarMoneyDisplayIncome", L"%ls (%ls)", moneyStr.str(), incomeStr.str())); + GadgetStaticTextSetText(moneyWin, buffer); + lastMoney = currentMoney; + lastIncome = cashPerMin; + } + } moneyWin->winHide(FALSE); powerWin->winHide(FALSE); } From 4c9114bdc5e96fe1fa872287f5d113b21652b91f Mon Sep 17 00:00:00 2001 From: L3-M <100478094+L3-M@users.noreply.github.com> Date: Sat, 23 Aug 2025 01:24:25 +0300 Subject: [PATCH 2/3] Implement suggestions --- .../Code/GameEngine/Include/Common/GlobalData.h | 2 +- .../Code/GameEngine/Include/Common/UserPreferences.h | 2 +- .../Code/GameEngine/Source/Common/GlobalData.cpp | 4 ++-- .../Code/GameEngine/Source/Common/RTS/Money.cpp | 12 ++++-------- .../GUI/GUICallbacks/Menus/OptionsMenu.cpp | 10 +++++----- .../Code/GameEngine/Source/GameClient/InGameUI.cpp | 10 ++++++---- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h index 2cce7fa6c3..4682573a7f 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h @@ -406,7 +406,7 @@ class GlobalData : public SubsystemInterface Bool m_useCameraInReplay; // TheSuperHackers @feature L3-M 21/08/2025 toggle the money per minute display; 'no' shows only the original current money - Bool m_moneyPerMinute; + Bool m_showMoneyPerMinute; // TheSuperHackers @feature Mauller 21/06/2025 allow the system time and game time font size to be set, a size of zero disables them Int m_systemTimeFontSize; diff --git a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h index 5e533c5d7f..207a9a2445 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h @@ -128,7 +128,7 @@ class OptionPreferences : public UserPreferences Bool getFPSLimitEnabled(void); Bool getNoDynamicLODEnabled(void); Bool getBuildingOcclusionEnabled(void); - Bool getMoneyPerMinute(void); + Bool getShowMoneyPerMinute(void); Int getParticleCap(void); Int getCampaignDifficulty(void); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index 1e0b93069a..3dc057e473 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -934,7 +934,7 @@ GlobalData::GlobalData() m_saveCameraInReplay = FALSE; m_useCameraInReplay = FALSE; - m_moneyPerMinute = TRUE; + m_showMoneyPerMinute = FALSE; m_systemTimeFontSize = 8; m_gameTimeFontSize = 8; @@ -1205,7 +1205,7 @@ void GlobalData::parseGameDataDefinition( INI* ini ) TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize(); TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize(); - TheWritableGlobalData->m_moneyPerMinute = optionPref.getMoneyPerMinute(); + TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute(); Int val=optionPref.getGammaValue(); //generate a value between 0.6 and 2.0. diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp index 1ca6fc93b3..08a6f20c09 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp @@ -44,6 +44,7 @@ #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine #include "Common/Money.h" +#include #include "Common/AudioSettings.h" #include "Common/GameAudio.h" @@ -109,7 +110,7 @@ void Money::setStartingCash(UnsignedInt amount) m_money = amount; m_currentBucket = 0; m_lastBucketFrame = 0; - for (UnsignedInt i = 0; i < 60; ++i) + for (UnsignedInt i = 0; i < ARRAY_SIZE(m_incomeBuckets); ++i) m_incomeBuckets[i] = 0; } @@ -124,11 +125,9 @@ void Money::updateIncomeBucket() { if (diff > 60) diff = 60; + m_currentBucket = (m_currentBucket + diff) % ARRAY_SIZE(m_incomeBuckets); for (UnsignedInt i = 0; i < diff; ++i) - { - m_currentBucket = (m_currentBucket + 1) % 60; m_incomeBuckets[m_currentBucket] = 0; - } } m_lastBucketFrame = frame; } @@ -136,10 +135,7 @@ void Money::updateIncomeBucket() // ------------------------------------------------------------------------------------------------ UnsignedInt Money::getCashPerMinute() const { - UnsignedInt sum = 0; - for (UnsignedInt i = 0; i < 60; ++i) - sum += m_incomeBuckets[i]; - return sum; + return std::accumulate(m_incomeBuckets, m_incomeBuckets + ARRAY_SIZE(m_incomeBuckets), 0u); } void Money::triggerAudioEvent(const AudioEventRTS& audioEvent) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp index 423f4ed125..636a2fce1e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp @@ -828,11 +828,11 @@ Int OptionPreferences::getGameTimeFontSize(void) return fontSize; } -Bool OptionPreferences::getMoneyPerMinute(void) +Bool OptionPreferences::getShowMoneyPerMinute(void) { - OptionPreferences::const_iterator it = find("MoneyPerMinute"); + OptionPreferences::const_iterator it = find("ShowMoneyPerMinute"); if (it == end()) - return TheGlobalData->m_moneyPerMinute; + return TheGlobalData->m_showMoneyPerMinute; if (stricmp(it->second.str(), "yes") == 0) { @@ -1370,10 +1370,10 @@ static void saveOptions( void ) //------------------------------------------------------------------------------------------------- // Set Money Per Minute { - Bool showIncome = pref->getMoneyPerMinute(); + Bool showIncome = pref->getShowMoneyPerMinute(); AsciiString prefString; prefString = showIncome ? "yes" : "no"; - (*pref)["MoneyPerMinute"] = prefString; + (*pref)["ShowMoneyPerMinute"] = prefString; } //------------------------------------------------------------------------------------------------- diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index be3d721c0f..c77505831b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -1854,7 +1854,7 @@ void InGameUI::update( void ) if( moneyPlayer) { Money *money = moneyPlayer->getMoney(); - Bool showIncome = TheGlobalData->m_moneyPerMinute; + Bool showIncome = TheGlobalData->m_showMoneyPerMinute; if (!showIncome) { Int currentMoney = money->countMoney(); @@ -1879,22 +1879,24 @@ void InGameUI::update( void ) UnicodeString buffer; UnicodeString moneyStr; UnicodeString incomeStr; + if (currentMoney >= 100000) { - moneyStr.format(L"%dK", currentMoney / 1000); + moneyStr.format(L"%dk", currentMoney / 1000); } else { moneyStr.format(L"%d", currentMoney); } + if (cashPerMin >= 10000) { - incomeStr.format(L"%dK", cashPerMin / 1000); + incomeStr.format(L"%dk", cashPerMin / 1000); } else if (cashPerMin >= 1000) { UnsignedInt k = cashPerMin / 100; - incomeStr.format(L"%d.%dK", k / 10, k % 10); + incomeStr.format(L"%d.%dk", k / 10, k % 10); } else { From 8a098535b1266d96ee8d884bdef2f8f82b075a63 Mon Sep 17 00:00:00 2001 From: L3-M <100478094+L3-M@users.noreply.github.com> Date: Mon, 25 Aug 2025 14:39:35 +0300 Subject: [PATCH 3/3] Implement suggestions 2 --- .../Code/GameEngine/Include/Common/Money.h | 17 +----- .../GameEngine/Source/Common/RTS/Money.cpp | 21 ++++--- .../GameEngine/Source/Common/RTS/Player.cpp | 1 - .../GameEngine/Source/GameClient/InGameUI.cpp | 60 +++++++++++-------- 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Money.h b/GeneralsMD/Code/GameEngine/Include/Common/Money.h index 9bda19c5ec..51e11620a1 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/Money.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/Money.h @@ -64,24 +64,14 @@ class Money : public Snapshot public: - inline Money() : m_money(0), m_playerIndex(0), m_startingCash(0), m_currentBucket(0), m_lastBucketFrame(0) + inline Money() : m_playerIndex(0) { - for (UnsignedInt i = 0; i < 60; ++i) - { - m_incomeBuckets[i] = 0; - } + init(); } void init() { - m_money = 0; - m_startingCash = 0; - m_currentBucket = 0; - m_lastBucketFrame = 0; - for (UnsignedInt i = 0; i < 60; ++i) - { - m_incomeBuckets[i] = 0; - } + setStartingCash(0); } inline UnsignedInt countMoney() const @@ -120,7 +110,6 @@ class Money : public Snapshot UnsignedInt m_money; ///< amount of money Int m_playerIndex; ///< what is my player index? - UnsignedInt m_startingCash; UnsignedInt m_incomeBuckets[60]; UnsignedInt m_currentBucket; UnsignedInt m_lastBucketFrame; diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp index 08a6f20c09..a4897235b1 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Money.cpp @@ -45,6 +45,7 @@ #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine #include "Common/Money.h" #include +#include #include "Common/AudioSettings.h" #include "Common/GameAudio.h" @@ -88,10 +89,10 @@ void Money::deposit(UnsignedInt amountToDeposit, Bool playSound) if (playSound) { triggerAudioEvent(TheAudio->getMiscAudio()->m_moneyDepositSound); + m_incomeBuckets[m_currentBucket] += amountToDeposit; } m_money += amountToDeposit; - m_incomeBuckets[m_currentBucket] += amountToDeposit; if( amountToDeposit > 0 ) { @@ -106,12 +107,10 @@ void Money::deposit(UnsignedInt amountToDeposit, Bool playSound) // ------------------------------------------------------------------------------------------------ void Money::setStartingCash(UnsignedInt amount) { - m_startingCash = amount; m_money = amount; m_currentBucket = 0; m_lastBucketFrame = 0; - for (UnsignedInt i = 0; i < ARRAY_SIZE(m_incomeBuckets); ++i) - m_incomeBuckets[i] = 0; + std::fill(m_incomeBuckets, m_incomeBuckets + ARRAY_SIZE(m_incomeBuckets), 0u); } // ------------------------------------------------------------------------------------------------ @@ -123,11 +122,17 @@ void Money::updateIncomeBucket() UnsignedInt diff = (curSec > lastSec) ? curSec - lastSec : 0; if (diff > 0) { - if (diff > 60) - diff = 60; + if (diff > ARRAY_SIZE(m_incomeBuckets)) + diff = ARRAY_SIZE(m_incomeBuckets); + + UnsignedInt next = (m_currentBucket + 1) % ARRAY_SIZE(m_incomeBuckets); + UnsignedInt first = std::min(diff, ARRAY_SIZE(m_incomeBuckets) - next); + std::fill(m_incomeBuckets + next, m_incomeBuckets + next + first, 0u); + + if (diff > first) + std::fill(m_incomeBuckets, m_incomeBuckets + (diff - first), 0u); + m_currentBucket = (m_currentBucket + diff) % ARRAY_SIZE(m_incomeBuckets); - for (UnsignedInt i = 0; i < diff; ++i) - m_incomeBuckets[m_currentBucket] = 0; } m_lastBucketFrame = frame; } diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp index 263ece90b2..891adf3050 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp @@ -462,7 +462,6 @@ void Player::init(const PlayerTemplate* pt) { m_money.deposit( TheGlobalData->m_defaultStartingCash.countMoney(), FALSE ); } - m_money.setStartingCash(m_money.countMoney()); } m_playerDisplayName.clear(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index c77505831b..62409c4939 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -96,6 +96,40 @@ static const Real placementOpacity = 0.45f; static const RGBColor illegalBuildColor = { 1.0, 0.0, 0.0 }; +// ------------------------------------------------------------------------------------------------ +static UnicodeString formatMoneyValue(UnsignedInt amount) +{ + UnicodeString result; + if (amount >= 100000) + { + result.format(L"%dk", amount / 1000); + } + else + { + result.format(L"%d", amount); + } + return result; +} + +static UnicodeString formatIncomeValue(UnsignedInt cashPerMin) +{ + UnicodeString result; + if (cashPerMin >= 10000) + { + result.format(L"%dk", cashPerMin / 1000); + } + else if (cashPerMin >= 1000) + { + UnsignedInt k = cashPerMin / 100; + result.format(L"%d.%dk", k / 10, k % 10); + } + else + { + result.format(L"%d", cashPerMin); + } + return result; +} + //------------------------------------------------------------------------------------------------- /// The InGameUI singleton instance. InGameUI *TheInGameUI = NULL; @@ -1877,31 +1911,9 @@ void InGameUI::update( void ) if (lastMoney != (Int)currentMoney || lastIncome != (Int)cashPerMin) { UnicodeString buffer; - UnicodeString moneyStr; - UnicodeString incomeStr; - - if (currentMoney >= 100000) - { - moneyStr.format(L"%dk", currentMoney / 1000); - } - else - { - moneyStr.format(L"%d", currentMoney); - } + UnicodeString moneyStr = formatMoneyValue(currentMoney); + UnicodeString incomeStr = formatIncomeValue(cashPerMin); - if (cashPerMin >= 10000) - { - incomeStr.format(L"%dk", cashPerMin / 1000); - } - else if (cashPerMin >= 1000) - { - UnsignedInt k = cashPerMin / 100; - incomeStr.format(L"%d.%dk", k / 10, k % 10); - } - else - { - incomeStr.format(L"%d", cashPerMin); - } buffer.format(TheGameText->FETCH_OR_SUBSTITUTE_FORMAT("GUI:ControlBarMoneyDisplayIncome", L"%ls (%ls)", moneyStr.str(), incomeStr.str())); GadgetStaticTextSetText(moneyWin, buffer); lastMoney = currentMoney;