Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Generals/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ class GlobalData : public SubsystemInterface
Int m_systemTimeFontSize;
Int m_gameTimeFontSize;

// TheSuperHackers @feature L3-M 21/08/2025 toggle the money per minute display, false shows only the original current money
Bool m_showMoneyPerMinute;

Real m_shakeSubtleIntensity; ///< Intensity for shaking a camera with SHAKE_SUBTLE
Real m_shakeNormalIntensity; ///< Intensity for shaking a camera with SHAKE_NORMAL
Real m_shakeStrongIntensity; ///< Intensity for shaking a camera with SHAKE_STRONG
Expand Down
14 changes: 11 additions & 3 deletions Generals/Code/GameEngine/Include/Common/Money.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,14 @@ class Money : public Snapshot

public:

inline Money() : m_money(0), m_playerIndex(0)
inline Money() : m_playerIndex(0)
{
init();
}

void init()
{
m_money = 0;
setStartingCash(0);
}

inline UnsignedInt countMoney() const
Expand All @@ -77,7 +78,11 @@ class Money : public Snapshot

/// returns the actual amount withdrawn, which may be less than you want. (sorry, can't go into debt...)
UnsignedInt withdraw(UnsignedInt amountToWithdraw, Bool playSound = TRUE);
void deposit(UnsignedInt amountToDeposit, Bool playSound = TRUE);
void deposit(UnsignedInt amountToDeposit, Bool playSound = TRUE, Bool trackIncome = TRUE);

void setStartingCash(UnsignedInt amount);
void updateIncomeBucket();
UnsignedInt getCashPerMinute() const;

void setPlayerIndex(Int ndx) { m_playerIndex = ndx; }

Expand All @@ -102,4 +107,7 @@ class Money : public Snapshot

UnsignedInt m_money; ///< amount of money
Int m_playerIndex; ///< what is my player index?
UnsignedInt m_incomeBuckets[60]; ///< circular buffer of 60 seconds for income tracking
UnsignedInt m_currentBucket;
UnsignedInt m_cashPerMinute;
};
1 change: 1 addition & 0 deletions Generals/Code/GameEngine/Include/Common/STLTypedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ enum DrawableID CPP_11(: Int);
#include <Utility/hash_map_adapter.h>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
Expand Down
2 changes: 2 additions & 0 deletions Generals/Code/GameEngine/Include/Common/UserPreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ class OptionPreferences : public UserPreferences
Int getGameTimeFontSize(void);

Real getResolutionFontAdjustment(void);

Bool getShowMoneyPerMinute(void) const;
};

//-----------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions Generals/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,8 @@ GlobalData::GlobalData()
m_systemTimeFontSize = 8;
m_gameTimeFontSize = 8;

m_showMoneyPerMinute = FALSE;

m_debugShowGraphicalFramerate = FALSE;

// By default, show all asserts.
Expand Down Expand Up @@ -1192,6 +1194,7 @@ void GlobalData::parseGameDataDefinition( INI* ini )
TheWritableGlobalData->m_renderFpsFontSize = optionPref.getRenderFpsFontSize();
TheWritableGlobalData->m_systemTimeFontSize = optionPref.getSystemTimeFontSize();
TheWritableGlobalData->m_gameTimeFontSize = optionPref.getGameTimeFontSize();
TheWritableGlobalData->m_showMoneyPerMinute = optionPref.getShowMoneyPerMinute();

Int val=optionPref.getGammaValue();
//generate a value between 0.6 and 2.0.
Expand Down
59 changes: 56 additions & 3 deletions Generals/Code/GameEngine/Source/Common/RTS/Money.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -78,7 +79,7 @@ UnsignedInt Money::withdraw(UnsignedInt amountToWithdraw, Bool playSound)
}

// ------------------------------------------------------------------------------------------------
void Money::deposit(UnsignedInt amountToDeposit, Bool playSound)
void Money::deposit(UnsignedInt amountToDeposit, Bool playSound, Bool trackIncome)
{
if (amountToDeposit == 0)
return;
Expand All @@ -88,9 +89,43 @@ void Money::deposit(UnsignedInt amountToDeposit, Bool playSound)
triggerAudioEvent(TheAudio->getMiscAudio()->m_moneyDepositSound);
}

if (trackIncome)
{
m_incomeBuckets[m_currentBucket] += amountToDeposit;
m_cashPerMinute += amountToDeposit;
}

m_money += amountToDeposit;
}

// ------------------------------------------------------------------------------------------------
void Money::setStartingCash(UnsignedInt amount)
{
m_money = amount;
std::fill(m_incomeBuckets, m_incomeBuckets + ARRAY_SIZE(m_incomeBuckets), 0u);
m_currentBucket = 0u;
m_cashPerMinute = 0u;
}

// ------------------------------------------------------------------------------------------------
void Money::updateIncomeBucket()
{
UnsignedInt frame = TheGameLogic->getFrame();
UnsignedInt nextBucket = (frame / LOGICFRAMES_PER_SECOND) % ARRAY_SIZE(m_incomeBuckets);
if (nextBucket != m_currentBucket)
{
m_cashPerMinute -= m_incomeBuckets[nextBucket];
m_currentBucket = nextBucket;
m_incomeBuckets[m_currentBucket] = 0u;
}
}

// ------------------------------------------------------------------------------------------------
UnsignedInt Money::getCashPerMinute() const
{
return m_cashPerMinute;
}

void Money::triggerAudioEvent(const AudioEventRTS& audioEvent)
{
Real volume = TheAudio->getAudioSettings()->m_preferredMoneyTransactionVolume;
Expand All @@ -116,19 +151,35 @@ void Money::crc( Xfer *xfer )
// ------------------------------------------------------------------------------------------------
/** Xfer method
* Version Info:
* 1: Initial version */
* 1: Initial version
* 2: Add saveload support for the cash per minute income tracking */
// ------------------------------------------------------------------------------------------------
void Money::xfer( Xfer *xfer )
{

// version
#if RETAIL_COMPATIBLE_XFER_SAVE
XferVersion currentVersion = 1;
#else
XferVersion currentVersion = 2;
#endif
XferVersion version = currentVersion;
xfer->xferVersion( &version, currentVersion );

// money value
xfer->xferUnsignedInt( &m_money );

if (version <= 1)
{
setStartingCash(m_money);
}
else
{
xfer->xferUser(m_incomeBuckets, sizeof(m_incomeBuckets));
xfer->xferUnsignedInt(&m_currentBucket);

m_cashPerMinute = std::accumulate(m_incomeBuckets, m_incomeBuckets + ARRAY_SIZE(m_incomeBuckets), 0u);
}
}

// ------------------------------------------------------------------------------------------------
Expand All @@ -147,5 +198,7 @@ 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 );
UnsignedInt moneyAmount;
INI::parseUnsignedInt( ini, instance, &moneyAmount, userData );
money->setStartingCash(moneyAmount);
}
6 changes: 3 additions & 3 deletions Generals/Code/GameEngine/Source/Common/RTS/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,11 +434,11 @@ void Player::init(const PlayerTemplate* pt)
// Note that copying the entire Money class instead would also copy the player index inside of it.
if ( TheGameInfo )
{
m_money.deposit( TheGameInfo->getStartingCash().countMoney(), FALSE );
m_money.deposit( TheGameInfo->getStartingCash().countMoney(), FALSE, FALSE );
}
else
{
m_money.deposit( TheGlobalData->m_defaultStartingCash.countMoney(), FALSE );
m_money.deposit( TheGlobalData->m_defaultStartingCash.countMoney(), FALSE, FALSE );
}
}

Expand Down Expand Up @@ -1771,7 +1771,7 @@ void Player::transferAssetsFromThat(Player *that)
// transfer all his money
UnsignedInt allMoney = that->getMoney()->countMoney();
that->getMoney()->withdraw(allMoney);
getMoney()->deposit(allMoney);
getMoney()->deposit(allMoney, TRUE, FALSE);
}

//=============================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ AsciiString PlayerTemplate::getStartingUnit( Int i ) const
// assign the money into the 'Money' (m_money) pointed to at 'store'
Money *theMoney = (Money *)store;
theMoney->init();
theMoney->deposit( money );
theMoney->setStartingCash(money);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ void BuildAssistant::update( void )
sellValue = REAL_TO_UNSIGNEDINT( obj->getTemplate()->calcCostToBuild( player ) *
TheGlobalData->m_sellPercentage );

player->getMoney()->deposit( sellValue );
player->getMoney()->deposit( sellValue, TRUE, FALSE );
// this money shouldn't be scored since it wasn't really "earned."
// player->getScoreKeeper()->addMoneyEarned( sellValue );

Expand Down
2 changes: 1 addition & 1 deletion Generals/Code/GameEngine/Source/Common/UserPreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ Money CustomMatchPreferences::getStartingCash(void) const
}

Money money;
money.deposit( strtoul( it->second.str(), NULL, 10 ), FALSE );
money.deposit( strtoul( it->second.str(), NULL, 10 ), FALSE, FALSE );

return money;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ Money LANPreferences::getStartingCash(void) const
}

Money money;
money.deposit( strtoul( it->second.str(), NULL, 10 ), FALSE );
money.deposit( strtoul( it->second.str(), NULL, 10 ), FALSE, FALSE );

return money;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,19 @@ Real OptionPreferences::getResolutionFontAdjustment(void)
return fontScale;
}

Bool OptionPreferences::getShowMoneyPerMinute(void) const
{
OptionPreferences::const_iterator it = find("ShowMoneyPerMinute");
if (it == end())
return TheGlobalData->m_showMoneyPerMinute;

if (stricmp(it->second.str(), "yes") == 0)
{
return TRUE;
}
return FALSE;
}

static OptionPreferences *pref = NULL;

static void setDefaults( void )
Expand Down Expand Up @@ -1496,6 +1509,16 @@ static void saveOptions( void )
TheGlobalLanguageData->m_userResolutionFontSizeAdjustment = (Real)val / 100.0f;
}

//-------------------------------------------------------------------------------------------------
// Set Money Per Minute
{
Bool show = pref->getShowMoneyPerMinute();
AsciiString prefString;
prefString = show ? "yes" : "no";
(*pref)["ShowMoneyPerMinute"] = prefString;
TheWritableGlobalData->m_showMoneyPerMinute = show;
}

//-------------------------------------------------------------------------------------------------
// Resolution
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ Money SkirmishPreferences::getStartingCash(void) const
}

Money money;
money.deposit( strtoul( it->second.str(), NULL, 10 ), FALSE );
money.deposit( strtoul( it->second.str(), NULL, 10 ), FALSE, FALSE );

return money;
}
Expand Down
71 changes: 64 additions & 7 deletions Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,39 @@
// ------------------------------------------------------------------------------------------------
static const RGBColor IllegalBuildColor = { 1.0, 0.0, 0.0 };

// ------------------------------------------------------------------------------------------------
static UnicodeString formatMoneyValue(UnsignedInt amount)
{
UnicodeString result;
if (amount >= 100000)
{
result.format(L"%uk", amount / 1000);
}
else
{
result.format(L"%u", amount);
}
return result;
}

static UnicodeString formatIncomeValue(UnsignedInt cashPerMin)
{
UnicodeString result;
if (cashPerMin >= 10000)
{
result.format(L"%uk", cashPerMin / 1000);
}
else if (cashPerMin >= 1000)
{
result.format(L"%u", (cashPerMin / 100) * 100);
}
else
{
result.format(L"%u", (cashPerMin / 10) * 10);
}
return result;
}

//-------------------------------------------------------------------------------------------------
/// The InGameUI singleton instance.
InGameUI *TheInGameUI = NULL;
Expand Down Expand Up @@ -1830,7 +1863,8 @@ 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 UnsignedInt lastMoney = ~0u;
static UnsignedInt lastIncome = ~0u;
static NameKeyType moneyWindowKey = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:MoneyDisplay" );
static NameKeyType powerWindowKey = TheNameKeyGenerator->nameToKey( "ControlBar.wnd:PowerWindow" );

Expand All @@ -1846,15 +1880,38 @@ 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_showMoneyPerMinute;
if (!showIncome)
{
UnicodeString buffer;
UnsignedInt 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;

}
}
else
{
// TheSuperHackers @feature L3-M 21/08/2025 player money per minute
money->updateIncomeBucket();
UnsignedInt currentMoney = money->countMoney();
UnsignedInt cashPerMin = money->getCashPerMinute();
if ( lastMoney != currentMoney || lastIncome != cashPerMin )
{
UnicodeString buffer;
UnicodeString moneyStr = formatMoneyValue(currentMoney);
UnicodeString incomeStr = formatIncomeValue(cashPerMin);

buffer.format(TheGameText->FETCH_OR_SUBSTITUTE_FORMAT("GUI:ControlBarMoneyDisplayIncome", L"$ %ls +%ls/min", moneyStr.str(), incomeStr.str()));
GadgetStaticTextSetText(moneyWin, buffer);
lastMoney = currentMoney;
lastIncome = cashPerMin;
}
}
moneyWin->winHide(FALSE);
powerWin->winHide(FALSE);
Expand Down
Loading
Loading