Resolved #3408 - Unit maintenance cost reduction generalized, now works for Ottomans

This commit is contained in:
Yair Morgenstern
2020-12-11 14:24:09 +02:00
parent 3ab57f1ada
commit d0774db030
7 changed files with 36 additions and 30 deletions

View File

@ -337,7 +337,7 @@
"outerColor": [150,150,150],
"innerColor": [60,60,60],
"uniqueName": "Furor Teutonicus",
"uniques": ["67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment", "-25% land units maintenance"],
"uniques": ["67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment", "-[25]% [Land] unit maintenance costs"],
"cities": ["Berlin","Hamburg","Munich","Cologne","Frankfurt","Essen","Dortmund","Stuttgart","Dusseldorf","Bremen",
"Hannover","Duisburg","Leipzig","Dresden","Bonn","Bochum","Bielefeld","Karlsruhe","Gelsenkirchen","Wiesbaden",
"Munster","Rostok","Chemnitz","Braunschweig","Halle","Mצnchengladbach","Kiel","Wuppertal","Freiburg","Hagen",
@ -366,7 +366,7 @@
"outerColor": [245,248,185],
"innerColor": [18,84,30],
"uniqueName": "Barbary Corsairs",
"uniques": ["Pay only one third the usual cost for naval unit maintenance", "50% chance of capturing defeated Barbarian naval units and earning 25 Gold"],
"uniques": ["-[66]% [Water] unit maintenance costs", "50% chance of capturing defeated Barbarian naval units and earning 25 Gold"],
"cities": ["Istanbul","Edirne","Ankara","Bursa","Konya","Samsun","Gaziantep","Diyabakir","Izmir","Kayseri","Malatya",
"Marsin","Antalya","Zonguldak","Denizli","Ordu","Mugia","Eskishehir","Inebolu","Sinop","Adana","Artuin",
"Bodrum","Eregli","Silifke","Sivas","Amasya","Marmaris","Trabzon","Erzurum","Urfa","Izmit","Afyonkarhisar",

View File

@ -14,7 +14,7 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
override fun isDefeated(): Boolean = unit.health <= 0
override fun isInvisible(): Boolean = unit.isInvisible()
override fun canAttack(): Boolean = unit.canAttack()
override fun matchesCategory(category:String) = unit.matchesCategory(category)
override fun matchesCategory(category:String) = unit.matchesFilter(category)
override fun takeDamage(damage: Int) {
unit.health -= damage

View File

@ -1,6 +1,5 @@
package com.unciv.logic.civilization
import com.unciv.Constants
import com.unciv.logic.civilization.diplomacy.RelationshipLevel
import com.unciv.logic.map.RoadStatus
import com.unciv.models.metadata.BASE_GAME_DURATION_TURNS
@ -15,29 +14,37 @@ import kotlin.math.pow
/** CivInfo class was getting too crowded */
class CivInfoStats(val civInfo: CivilizationInfo){
private fun getUnitUpkeep(): Int {
private fun getUnitMaintenance(): Int {
val baseUnitCost = 0.5f
val freeUnits = 3
var unitsToPayFor = civInfo.getCivUnits()
if(civInfo.hasUnique("Units in cities cost no Maintenance"))
// Only land military units can truly "garrison"
if (civInfo.hasUnique("Units in cities cost no Maintenance"))
// Only land military units can truly "garrison"
unitsToPayFor = unitsToPayFor.filterNot {
it.getTile().isCityCenter() && it.canGarrison()
}
var numberOfUnitsToPayFor = max(0f, unitsToPayFor.count().toFloat() - freeUnits)
if(civInfo.hasUnique("-25% land units maintenance")){
// Deprecated and generalized as of 3.11.20 - here for mod transition period
if (civInfo.hasUnique("-25% land units maintenance")) {
val numberOfUnitsWithDiscount = min(numberOfUnitsToPayFor, unitsToPayFor.count { it.type.isLandUnit() }.toFloat())
numberOfUnitsToPayFor -= 0.25f * numberOfUnitsWithDiscount
}
for (unique in civInfo.getMatchingUniques("-[]% [] unit maintenance costs")) {
val numberOfUnitsWithDiscount = min(numberOfUnitsToPayFor, unitsToPayFor.count { it.matchesFilter(unique.params[1]) }.toFloat())
numberOfUnitsToPayFor -= numberOfUnitsWithDiscount * (1 - unique.params[0].toFloat() / 100)
}
val turnLimit = BASE_GAME_DURATION_TURNS * civInfo.gameInfo.gameParameters.gameSpeed.modifier
val gameProgress = civInfo.gameInfo.turns / turnLimit // as game progresses Maintenance cost rises
var cost = baseUnitCost*numberOfUnitsToPayFor*(1+gameProgress)
cost = cost.pow(1+gameProgress/3) // Why 3? To spread 1 to 1.33
if(!civInfo.isPlayerCivilization())
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
if(civInfo.hasUnique("-33% unit upkeep costs")) cost *= 0.66f
if (civInfo.hasUnique("-33% unit upkeep costs")) cost *= 0.66f
return cost.toInt()
}
@ -100,7 +107,7 @@ class CivInfoStats(val civInfo: CivilizationInfo){
}
statMap["Transportation upkeep"] = Stats().apply { gold=- getTransportationUpkeep().toFloat()}
statMap["Unit upkeep"] = Stats().apply { gold=- getUnitUpkeep().toFloat()}
statMap["Unit upkeep"] = Stats().apply { gold=- getUnitMaintenance().toFloat()}
if (civInfo.hasUnique("50% of excess happiness added to culture towards policies")) {
val happiness = civInfo.getHappiness()

View File

@ -109,7 +109,7 @@ class MapUnit {
movement += 2
for (unique in civInfo.getMatchingUniques("+[] Movement for all [] units"))
if (matchesCategory(unique.params[1]))
if (matchesFilter(unique.params[1]))
movement += unique.params[0].toInt()
if (civInfo.goldenAges.isGoldenAge() &&
@ -719,17 +719,17 @@ class MapUnit {
}
}
fun matchesCategory(category: String): Boolean {
if (category == type.name) return true
if (category == name) return true
if ((category == "Wounded" || category == "wounded units") && health < 100) return true
if ((category == "Land" || category == "land units") && type.isLandUnit()) return true
if ((category == "Water" || category == "water units") && type.isWaterUnit()) return true
if ((category == "Air" || category == "air units") && type.isAirUnit()) return true
if (category == "non-air" && !type.isAirUnit()) return true
if ((category == "military" || category == "military units") && type.isMilitary()) return true
if (hasUnique(category)) return true
if ((category == "Barbarians" || category == "Barbarian") && civInfo.isBarbarian()) return true
fun matchesFilter(filter: String): Boolean {
if (filter == type.name) return true
if (filter == name) return true
if ((filter == "Wounded" || filter == "wounded units") && health < 100) return true
if ((filter == "Land" || filter == "land units") && type.isLandUnit()) return true
if ((filter == "Water" || filter == "water units") && type.isWaterUnit()) return true
if ((filter == "Air" || filter == "air units") && type.isAirUnit()) return true
if (filter == "non-air" && !type.isAirUnit()) return true
if ((filter == "military" || filter == "military units") && type.isMilitary()) return true
if (hasUnique(filter)) return true
if ((filter == "Barbarians" || filter == "Barbarian") && civInfo.isBarbarian()) return true
return false
}

View File

@ -169,7 +169,7 @@ class TileMap {
unit.promotions.addPromotion(promotion, true)
for (unique in civInfo.getMatchingUniques("[] units gain the [] promotion")) {
if (unit.matchesCategory(unique.params[0])) {
if (unit.matchesFilter(unique.params[0])) {
unit.promotions.addPromotion(unique.params[1], true)
}
}

View File

@ -83,7 +83,7 @@ object UniqueTriggerActivation {
val filter = unique.params[0]
val promotion = unique.params[1]
for (unit in civInfo.getCivUnits())
if (unit.matchesCategory(filter)
if (unit.matchesFilter(filter)
|| (civInfo.gameInfo.ruleSet.unitPromotions.values.any { it.name == promotion
&& unit.type.name in it.unitTypes }))
unit.promotions.addPromotion(promotion, isFree = true)}

View File

@ -5,7 +5,6 @@ import com.unciv.logic.city.CityConstructions
import com.unciv.logic.city.IConstruction
import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.Unique
import com.unciv.models.translations.Translations
@ -179,7 +178,7 @@ class BaseUnit : INamed, IConstruction {
for (unique in construction.cityInfo.cityConstructions.builtBuildingUniqueMap.getUniques("New [] units start with [] Experience in this city")
+ civInfo.getMatchingUniques("New [] units start with [] Experience")) {
if (unit.matchesCategory(unique.params[0]))
if (unit.matchesFilter(unique.params[0]))
XP += unique.params[1].toInt()
}
unit.promotions.XP = XP
@ -188,7 +187,7 @@ class BaseUnit : INamed, IConstruction {
val filter = unique.params[0]
val promotion = unique.params[1]
if (unit.matchesCategory(filter) || (filter == "relevant" && civInfo.gameInfo.ruleSet.unitPromotions.values.any { unit.type.toString() in it.unitTypes && it.name == promotion }))
if (unit.matchesFilter(filter) || (filter == "relevant" && civInfo.gameInfo.ruleSet.unitPromotions.values.any { unit.type.toString() in it.unitTypes && it.name == promotion }))
unit.promotions.addPromotion(promotion, isFree = true)
}