mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-30 22:58:50 +07:00
Fixed a bug where all global unit discounts would always apply, despite only being for certain units (#5879)
This commit is contained in:
@ -28,27 +28,21 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
|
||||
var unitsToPayFor = civInfo.getCivUnits()
|
||||
if (civInfo.hasUnique("Units in cities cost no Maintenance"))
|
||||
// Only land military units can truly "garrison"
|
||||
unitsToPayFor = unitsToPayFor.filterNot {
|
||||
it.getTile().isCityCenter() && it.canGarrison()
|
||||
}
|
||||
// Handle unit maintenance discounts
|
||||
// Have to capture global and per-unit
|
||||
// Free Garrison already removed above from sequence
|
||||
// Initialize base maintenance cost empire-wide, default 1 aka 100%
|
||||
// Then calculate per-unit discounrts
|
||||
// To try and avoid concurrent modifications leading to crashes,
|
||||
// we calculate the costs of one unit at a time.
|
||||
// Each unit starts with 1f aka 100% of cost, and then the discout is addded.
|
||||
// Note all discounts are in the form of -X%, such as -25 for 25% reduction
|
||||
|
||||
var civWideMaintenance = 1f
|
||||
// Calculate global discounts
|
||||
for (unique in civInfo.getMatchingUniques(UniqueType.UnitMaintenanceDiscountGlobal, StateForConditionals(civInfo))) {
|
||||
civWideMaintenance *= unique.params[0].toPercent()
|
||||
}
|
||||
|
||||
val costsToPay = ArrayList<Float>()
|
||||
for (unit in unitsToPayFor) {
|
||||
var unitMaintenance = civWideMaintenance
|
||||
for (unique in unit.getMatchingUniques(UniqueType.UnitMaintenanceDiscount)){
|
||||
val stateForConditionals = StateForConditionals(civInfo=civInfo, unit=unit)
|
||||
var unitMaintenance = 1f
|
||||
for (unique in unit.getMatchingUniques(UniqueType.UnitMaintenanceDiscount, stateForConditionals, true)){
|
||||
unitMaintenance *= unique.params[0].toPercent()
|
||||
}
|
||||
costsToPay.add(unitMaintenance)
|
||||
@ -59,16 +53,16 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
costsToPay.sortDescending()
|
||||
val numberOfUnitsToPayFor = max(0.0, costsToPay.asSequence().drop(freeUnits).sumOf { it.toDouble() } ).toFloat()
|
||||
|
||||
val turnLimit =
|
||||
BASE_GAME_DURATION_TURNS * civInfo.gameInfo.gameParameters.gameSpeed.modifier
|
||||
val gameProgress =
|
||||
min(civInfo.gameInfo.turns / turnLimit, 1f) // as game progresses Maintenance cost rises
|
||||
// as game progresses Maintenance cost rises
|
||||
val turnLimit = BASE_GAME_DURATION_TURNS * civInfo.gameInfo.gameParameters.gameSpeed.modifier
|
||||
val gameProgress = min(civInfo.gameInfo.turns / turnLimit, 1f)
|
||||
|
||||
var cost = baseUnitCost * numberOfUnitsToPayFor * (1 + gameProgress)
|
||||
cost = cost.pow(1 + gameProgress / 3) // Why 3? To spread 1 to 1.33
|
||||
|
||||
if (!civInfo.isPlayerCivilization())
|
||||
cost *= civInfo.gameInfo.getDifficulty().aiUnitMaintenanceModifier
|
||||
|
||||
|
||||
return cost.toInt()
|
||||
}
|
||||
|
||||
|
@ -553,6 +553,7 @@ class MapUnit {
|
||||
return getMatchingUniques("All adjacent units heal [] HP when healing").sumOf { it.params[0].toInt() }
|
||||
}
|
||||
|
||||
// Only military land units can truly "garrison"
|
||||
fun canGarrison() = baseUnit.isMilitary() && baseUnit.isLandUnit()
|
||||
|
||||
fun isGreatPerson() = baseUnit.isGreatPerson()
|
||||
|
@ -130,7 +130,6 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
||||
/////// Other global uniques
|
||||
|
||||
FreeUnits("[amount] units cost no maintenance", UniqueTarget.Global),
|
||||
UnitMaintenanceDiscountGlobal("[amount]% maintenance costs for [mapUnitFilter] units", UniqueTarget.Global),
|
||||
|
||||
ConsumesResources("Consumes [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Building, UniqueTarget.Unit),
|
||||
ProvidesResources("Provides [amount] [resource]", UniqueTarget.Improvement, UniqueTarget.Building),
|
||||
@ -568,6 +567,9 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget, val flags:
|
||||
BonuxXPGain("[amount]% Bonus XP gain", UniqueTarget.Unit),
|
||||
@Deprecated("As of 3.18.12", ReplaceWith("[amount]% XP gained from combat <for [mapUnitFilter] units>"))
|
||||
BonusXPGainForUnits("[mapUnitFilter] units gain [amount]% more Experience from combat", UniqueTarget.Global),
|
||||
|
||||
@Deprecated("As of 3.18.14", ReplaceWith("[amount]% maintenance costs <for [mapUnitFilter] units>"))
|
||||
UnitMaintenanceDiscountGlobal("[amount]% maintenance costs for [mapUnitFilter] units", UniqueTarget.Global),
|
||||
|
||||
// endregion
|
||||
|
||||
|
Reference in New Issue
Block a user