Fix gold able to over- and underflow (#4065)

This commit is contained in:
SomeTroglodyte 2021-06-06 18:29:23 +02:00 committed by GitHub
parent 298dbcb3ee
commit cc3eeb3c7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 29 additions and 20 deletions

View File

@ -122,7 +122,7 @@ object Battle {
} }
civUnit.getCivInfo().policies.addCulture(cultureReward) civUnit.getCivInfo().policies.addCulture(cultureReward)
civUnit.getCivInfo().gold += goldReward civUnit.getCivInfo().addGold(goldReward)
} }
private fun takeDamage(attacker: ICombatant, defender: ICombatant) { private fun takeDamage(attacker: ICombatant, defender: ICombatant) {
@ -203,7 +203,7 @@ object Battle {
&& attacker.getCivInfo().hasUnique("67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment") && attacker.getCivInfo().hasUnique("67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment")
&& Random().nextDouble() < 0.67) { && Random().nextDouble() < 0.67) {
attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName()) attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName())
attacker.getCivInfo().gold += 25 attacker.getCivInfo().addGold(25)
attacker.getCivInfo().addNotification("A barbarian [${defender.getName()}] has joined us!", attackedTile.position, defender.getName()) attacker.getCivInfo().addNotification("A barbarian [${defender.getName()}] has joined us!", attackedTile.position, defender.getName())
} }
@ -213,7 +213,7 @@ object Battle {
&& attacker.getCivInfo().hasUnique("50% chance of capturing defeated Barbarian naval units and earning 25 Gold") && attacker.getCivInfo().hasUnique("50% chance of capturing defeated Barbarian naval units and earning 25 Gold")
&& Random().nextDouble() > 0.5) { && Random().nextDouble() > 0.5) {
attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName()) attacker.getCivInfo().placeUnitNearTile(attackedTile.position, defender.getName())
attacker.getCivInfo().gold += 25 attacker.getCivInfo().addGold(25)
} }
} }

View File

@ -397,7 +397,7 @@ class CityConstructions {
return false // nothing built - no pay return false // nothing built - no pay
if (!cityInfo.civInfo.gameInfo.gameParameters.godMode) if (!cityInfo.civInfo.gameInfo.gameParameters.godMode)
cityInfo.civInfo.gold -= getConstruction(constructionName).getGoldCost(cityInfo.civInfo) cityInfo.civInfo.addGold(-getConstruction(constructionName).getGoldCost(cityInfo.civInfo))
if (queuePosition in 0 until constructionQueue.size) if (queuePosition in 0 until constructionQueue.size)
removeFromQueue(queuePosition, automatic) removeFromQueue(queuePosition, automatic)

View File

@ -51,7 +51,7 @@ class CityExpansionManager {
class NotEnoughGoldToBuyTileException : Exception() class NotEnoughGoldToBuyTileException : Exception()
if (cityInfo.civInfo.gold < goldCost && !cityInfo.civInfo.gameInfo.gameParameters.godMode) if (cityInfo.civInfo.gold < goldCost && !cityInfo.civInfo.gameInfo.gameParameters.godMode)
throw NotEnoughGoldToBuyTileException() throw NotEnoughGoldToBuyTileException()
cityInfo.civInfo.gold -= goldCost cityInfo.civInfo.addGold(-goldCost)
takeOwnership(tileInfo) takeOwnership(tileInfo)
} }

View File

@ -427,7 +427,7 @@ class CityInfo {
fun sellBuilding(buildingName: String) { fun sellBuilding(buildingName: String) {
cityConstructions.removeBuilding(buildingName) cityConstructions.removeBuilding(buildingName)
civInfo.gold += getGoldForSellingBuilding(buildingName) civInfo.addGold(getGoldForSellingBuilding(buildingName))
hasSoldBuildingThisTurn = true hasSoldBuildingThisTurn = true
population.unassignExtraPopulation() // If the building provided specialists, release them to other work population.unassignExtraPopulation() // If the building provided specialists, release them to other work

View File

@ -32,7 +32,7 @@ class CityInfoConquestFunctions(val city: CityInfo){
// Gain gold for plundering city // Gain gold for plundering city
val goldPlundered = getGoldForCapturingCity(conqueringCiv) val goldPlundered = getGoldForCapturingCity(conqueringCiv)
city.apply { city.apply {
conqueringCiv.gold += goldPlundered conqueringCiv.addGold(goldPlundered)
conqueringCiv.addNotification("Received [$goldPlundered] Gold for capturing [$name]", getCenterTile().position, NotificationIcon.Gold) conqueringCiv.addNotification("Received [$goldPlundered] Gold for capturing [$name]", getCenterTile().position, NotificationIcon.Gold)
val oldCiv = civInfo val oldCiv = civInfo

View File

@ -107,7 +107,7 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo) {
} }
if (goldGained > 0) { if (goldGained > 0) {
civInfo.gold += goldGained civInfo.addGold(goldGained)
civInfo.addNotification("We have received [" + goldGained + "] Gold for discovering [" + tile.naturalWonder + "]", NotificationIcon.Gold) civInfo.addNotification("We have received [" + goldGained + "] Gold for discovering [" + tile.naturalWonder + "]", NotificationIcon.Gold)
} }

View File

@ -523,7 +523,7 @@ class CivilizationInfo {
} }
} }
gold += nextTurnStats.gold.toInt() addGold( nextTurnStats.gold.toInt() )
if (cities.isNotEmpty() && gameInfo.ruleSet.technologies.isNotEmpty()) if (cities.isNotEmpty() && gameInfo.ruleSet.technologies.isNotEmpty())
tech.endTurn(nextTurnStats.science.toInt()) tech.endTurn(nextTurnStats.science.toInt())
@ -543,6 +543,14 @@ class CivilizationInfo {
updateHasActiveGreatWall() updateHasActiveGreatWall()
} }
fun addGold(delta: Int) {
gold = when {
delta > 0 && gold > Int.MAX_VALUE - delta -> Int.MAX_VALUE
delta < 0 && gold < Int.MIN_VALUE - delta -> Int.MIN_VALUE
else -> gold + delta
}
}
fun getGreatPersonPointsForNextTurn(): Stats { fun getGreatPersonPointsForNextTurn(): Stats {
val stats = Stats() val stats = Stats()
for (city in cities) stats.add(city.getGreatPersonPoints()) for (city in cities) stats.add(city.getGreatPersonPoints())
@ -619,7 +627,8 @@ class CivilizationInfo {
fun giveGoldGift(cityState: CivilizationInfo, giftAmount: Int) { fun giveGoldGift(cityState: CivilizationInfo, giftAmount: Int) {
if (!cityState.isCityState()) throw Exception("You can only gain influence with City-States!") if (!cityState.isCityState()) throw Exception("You can only gain influence with City-States!")
gold -= giftAmount addGold(-giftAmount)
cityState.addGold(giftAmount)
cityState.getDiplomacyManager(this).influence += influenceGainedByGift(cityState, giftAmount) cityState.getDiplomacyManager(this).influence += influenceGainedByGift(cityState, giftAmount)
cityState.updateAllyCivForCityState() cityState.updateAllyCivForCityState()
updateStatsForNextTurn() updateStatsForNextTurn()

View File

@ -631,7 +631,7 @@ class MapUnit {
if (civInfo.hasUnique("Receive triple Gold from Barbarian encampments and pillaging Cities")) if (civInfo.hasUnique("Receive triple Gold from Barbarian encampments and pillaging Cities"))
goldGained *= 3f goldGained *= 3f
civInfo.gold += goldGained.toInt() civInfo.addGold(goldGained.toInt())
civInfo.addNotification( civInfo.addNotification(
"We have captured a barbarian encampment and recovered [${goldGained.toInt()}] gold!", "We have captured a barbarian encampment and recovered [${goldGained.toInt()}] gold!",
tile.position, tile.position,
@ -660,7 +660,7 @@ class MapUnit {
destroy() destroy()
if (currentTile.getOwner() == civInfo) if (currentTile.getOwner() == civInfo)
civInfo.gold += baseUnit.getDisbandGold(civInfo) civInfo.addGold(baseUnit.getDisbandGold(civInfo))
if (civInfo.isDefeated()) civInfo.destroy() if (civInfo.isDefeated()) civInfo.destroy()
} }
@ -725,7 +725,7 @@ class MapUnit {
actions.add { actions.add {
val amount = listOf(25, 60, 100).random(tileBasedRandom) val amount = listOf(25, 60, 100).random(tileBasedRandom)
civInfo.gold += amount civInfo.addGold(amount)
civInfo.addNotification( civInfo.addNotification(
"We have found a stash of [$amount] gold in the ruins!", "We have found a stash of [$amount] gold in the ruins!",
tile.position, tile.position,

View File

@ -79,8 +79,8 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
fun transferTrade(to: CivilizationInfo, from: CivilizationInfo, trade: Trade) { fun transferTrade(to: CivilizationInfo, from: CivilizationInfo, trade: Trade) {
for (offer in trade.theirOffers) { for (offer in trade.theirOffers) {
if (offer.type == TradeType.Gold) { if (offer.type == TradeType.Gold) {
to.gold += offer.amount to.addGold(offer.amount)
from.gold -= offer.amount from.addGold(-offer.amount)
} }
if (offer.type == TradeType.Technology) { if (offer.type == TradeType.Technology) {
to.tech.addTechnology(offer.name) to.tech.addTechnology(offer.name)
@ -95,7 +95,7 @@ class TradeLogic(val ourCivilization:CivilizationInfo, val otherCivilization: Ci
if (offer.type == TradeType.Treaty) { if (offer.type == TradeType.Treaty) {
if (offer.name == Constants.peaceTreaty) to.getDiplomacyManager(from).makePeace() if (offer.name == Constants.peaceTreaty) to.getDiplomacyManager(from).makePeace()
if (offer.name == Constants.researchAgreement) { if (offer.name == Constants.researchAgreement) {
to.gold -= offer.amount to.addGold(-offer.amount)
to.getDiplomacyManager(from).setFlag(DiplomacyFlags.ResearchAgreement, offer.duration) to.getDiplomacyManager(from).setFlag(DiplomacyFlags.ResearchAgreement, offer.duration)
} }
} }

View File

@ -198,7 +198,7 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() {
val nextTurnStats = civInfo.statsForNextTurn val nextTurnStats = civInfo.statsForNextTurn
val goldPerTurn = "(" + (if (nextTurnStats.gold > 0) "+" else "") + nextTurnStats.gold.roundToInt() + ")" val goldPerTurn = "(" + (if (nextTurnStats.gold > 0) "+" else "") + nextTurnStats.gold.roundToInt() + ")"
goldLabel.setText(civInfo.gold.toFloat().roundToInt().toString() + goldPerTurn) goldLabel.setText(civInfo.gold.toString() + goldPerTurn)
scienceLabel.setText("+" + nextTurnStats.science.roundToInt()) scienceLabel.setText("+" + nextTurnStats.science.roundToInt())

View File

@ -235,7 +235,7 @@ object UnitActions {
title = "Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)", title = "Upgrade to [${upgradedUnit.name}] ([$goldCostOfUpgrade] gold)",
uncivSound = UncivSound.Upgrade, uncivSound = UncivSound.Upgrade,
action = { action = {
unit.civInfo.gold -= goldCostOfUpgrade unit.civInfo.addGold(-goldCostOfUpgrade)
val unitTile = unit.getTile() val unitTile = unit.getTile()
unit.destroy() unit.destroy()
val newunit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)!! val newunit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)!!
@ -334,7 +334,7 @@ object UnitActions {
var goldEarned = ((350 + 50 * unit.civInfo.getEraNumber()) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt() var goldEarned = ((350 + 50 * unit.civInfo.getEraNumber()) * unit.civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
if (unit.civInfo.hasUnique("Double gold from Great Merchant trade missions")) if (unit.civInfo.hasUnique("Double gold from Great Merchant trade missions"))
goldEarned *= 2 goldEarned *= 2
unit.civInfo.gold += goldEarned unit.civInfo.addGold(goldEarned)
tile.owningCity!!.civInfo.getDiplomacyManager(unit.civInfo).influence += influenceEarned tile.owningCity!!.civInfo.getDiplomacyManager(unit.civInfo).influence += influenceEarned
unit.civInfo.addNotification("Your trade mission to [${tile.owningCity!!.civInfo}] has earned you [${goldEarned}] gold and [$influenceEarned] influence!", unit.civInfo.addNotification("Your trade mission to [${tile.owningCity!!.civInfo}] has earned you [${goldEarned}] gold and [$influenceEarned] influence!",
tile.owningCity!!.civInfo.civName, NotificationIcon.Gold, NotificationIcon.Culture) tile.owningCity!!.civInfo.civName, NotificationIcon.Gold, NotificationIcon.Culture)
@ -428,7 +428,7 @@ object UnitActions {
val cityWithMausoleum = civInfo.cities.firstOrNull { it.containsBuildingUnique(uniqueText) } val cityWithMausoleum = civInfo.cities.firstOrNull { it.containsBuildingUnique(uniqueText) }
?: return ?: return
val goldEarned = (100 * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt() val goldEarned = (100 * civInfo.gameInfo.gameParameters.gameSpeed.modifier).toInt()
civInfo.gold += goldEarned civInfo.addGold(goldEarned)
val mausoleum = cityWithMausoleum.cityConstructions.getBuiltBuildings().first { it.uniques.contains(uniqueText) } val mausoleum = cityWithMausoleum.cityConstructions.getBuiltBuildings().first { it.uniques.contains(uniqueText) }
civInfo.addNotification("[${mausoleum.name}] has provided [$goldEarned] Gold!", cityWithMausoleum.location, NotificationIcon.Gold) civInfo.addNotification("[${mausoleum.name}] has provided [$goldEarned] Gold!", cityWithMausoleum.location, NotificationIcon.Gold)