-
Notifications
You must be signed in to change notification settings - Fork 94
feat(display): Implement player money per minute #1481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about we just call init() here if that sets everything to 0 already? |
||
{ | ||
m_incomeBuckets[i] = 0; | ||
} | ||
} | ||
|
||
void init() | ||
{ | ||
m_money = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like |
||
m_startingCash = 0; | ||
m_currentBucket = 0; | ||
m_lastBucketFrame = 0; | ||
for (UnsignedInt i = 0; i < 60; ++i) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can be simplified/optimized with std::fill |
||
{ | ||
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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this for? It appears to do nothing. |
||
UnsignedInt m_incomeBuckets[60]; | ||
UnsignedInt m_currentBucket; | ||
UnsignedInt m_lastBucketFrame; | ||
}; | ||
|
||
#endif // _MONEY_H_ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
m_incomeBuckets[i] = 0; | ||
} | ||
|
||
// ------------------------------------------------------------------------------------------------ | ||
void Money::updateIncomeBucket() | ||
{ | ||
UnsignedInt frame = TheGameLogic->getFrame(); | ||
UnsignedInt lastSec = m_lastBucketFrame / LOGICFRAMES_PER_SECOND; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this value not be derived from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But do we care for this frame number? We only care for bucket position, no? I would expect that this logic can be simplified. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UnsignedInt lastSec = curSec - ((curSec + ARRAY_SIZE(m_incomeBuckets) - m_currentBucket) % ARRAY_SIZE(m_incomeBuckets)); |
||
UnsignedInt curSec = frame / LOGICFRAMES_PER_SECOND; | ||
UnsignedInt diff = (curSec > lastSec) ? curSec - lastSec : 0; | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (diff > 0) | ||
{ | ||
if (diff > 60) | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
diff = 60; | ||
for (UnsignedInt i = 0; i < diff; ++i) | ||
{ | ||
m_currentBucket = (m_currentBucket + 1) % 60; | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
m_incomeBuckets[m_currentBucket] = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks wrong now. Could probably also use std::fill here. |
||
} | ||
} | ||
m_lastBucketFrame = frame; | ||
} | ||
|
||
// ------------------------------------------------------------------------------------------------ | ||
UnsignedInt Money::getCashPerMinute() const | ||
{ | ||
UnsignedInt sum = 0; | ||
for (UnsignedInt i = 0; i < 60; ++i) | ||
sum += m_incomeBuckets[i]; | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -462,6 +462,7 @@ void Player::init(const PlayerTemplate* pt) | |
{ | ||
m_money.deposit( TheGlobalData->m_defaultStartingCash.countMoney(), FALSE ); | ||
} | ||
m_money.setStartingCash(m_money.countMoney()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs another look. First depositing money and then setting starting cash is not good. It should be one call. Better design |
||
} | ||
|
||
m_playerDisplayName.clear(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code portion can become prettier by breaking out the money values formatting: UnicodeString moneyStr = formatMoneyValue(currentMoney);
UnicodeString incomeStr = formatIncomeValue(cashPerMin); |
||
{ | ||
moneyStr.format(L"%dK", currentMoney / 1000); | ||
} | ||
else | ||
{ | ||
moneyStr.format(L"%d", currentMoney); | ||
} | ||
if (cashPerMin >= 10000) | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
incomeStr.format(L"%dK", cashPerMin / 1000); | ||
xezon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
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())); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the Money symbol? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The limitation here would be the ControlBarPro money texture. It has much less space compared to the original game's ControlBar, hence I removed it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you show image for it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You tested Control Bar Pro correctly in 16:9. The Original Control Bar always needs to be tested in 4:3. That is because its elements are stretched wide in 16:9 and beyond. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
GadgetStaticTextSetText(moneyWin, buffer); | ||
lastMoney = currentMoney; | ||
lastIncome = cashPerMin; | ||
} | ||
} | ||
moneyWin->winHide(FALSE); | ||
powerWin->winHide(FALSE); | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.