A mishmash of different fixes: Unit uniques and promotions, happiness calculation, etc.
This commit is contained in:
parent
21c8336563
commit
6ff712b625
9 changed files with 27 additions and 31 deletions
|
@ -786,7 +786,7 @@
|
|||
"culture": 1,
|
||||
"isWonder": true,
|
||||
"greatPersonPoints": {"production": 2},
|
||||
"uniques": ["+1 Production from specialists"],
|
||||
"uniques": ["[+1 Production] from every specialist"],
|
||||
"requiredTech": "Replaceable Parts",
|
||||
"quote": "'Give me your tired, your poor, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore. Send these, the homeless, tempest-tossed to me, I lift my lamp beside the golden door!' - Emma Lazarus"
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{
|
||||
"name": "Aristocracy",
|
||||
"effect": "+15% production when constructing wonders, +1 happiness for every 10 citizens in a city",
|
||||
"uniques": ["+[15]% Production when constructing [Wonders]", "+1 happiness for every 10 citizens in a city"],
|
||||
"uniques": ["+[15]% Production when constructing [Wonders]", "[+1 Happiness] per [10] population in all cities"],
|
||||
"row": 1,
|
||||
"column": 1
|
||||
},
|
||||
|
|
|
@ -451,6 +451,6 @@
|
|||
},
|
||||
{
|
||||
"name": "Slinger Withdraw", // only for Slinger and subsequent upgrades
|
||||
"effect": "May withdraw before melee (133%)"
|
||||
"effect": "May withdraw before melee ([133]%)"
|
||||
}
|
||||
]
|
|
@ -656,7 +656,7 @@
|
|||
"requiredTech": "Astronomy",
|
||||
"upgradesTo": "Ironclad",
|
||||
"obsoleteTech": "Combustion",
|
||||
"uniques": ["+1 Visibility Range","May withdraw before melee"],
|
||||
"uniques": ["+1 Visibility Range","May withdraw before melee ([50]%)"],
|
||||
"hurryCostModifier": 20
|
||||
},
|
||||
{
|
||||
|
@ -1071,7 +1071,7 @@
|
|||
"interceptRange": 2,
|
||||
"cost": 375,
|
||||
"requiredTech": "Combustion",
|
||||
"uniques": ["Can attack submarines", "[40]% chance to intercept air attacks", "May withdraw before melee"], // todo: add bonus vs submarines
|
||||
"uniques": ["Can attack submarines", "[40]% chance to intercept air attacks", "May withdraw before melee ([50]%)"], // todo: add bonus vs submarines
|
||||
"hurryCostModifier": 20
|
||||
},
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ Get =
|
|||
|
||||
Hydro Plant =
|
||||
+1 population in each city =
|
||||
+1 happiness in each city =
|
||||
|
||||
# Diplomacy,Trade,Nations
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.unciv.logic.civilization.diplomacy.DiplomaticModifiers
|
|||
import com.unciv.logic.map.RoadStatus
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.AttackableTile
|
||||
import com.unciv.models.ruleset.Unique
|
||||
import com.unciv.models.ruleset.unit.UnitType
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
@ -49,8 +50,8 @@ object Battle {
|
|||
|
||||
// Withdraw from melee ability
|
||||
if (attacker is MapUnitCombatant && attacker.isMelee() && defender is MapUnitCombatant ) {
|
||||
val withdraw = defender.unit.getUniques().firstOrNull { it.text.startsWith("May withdraw before melee")}
|
||||
if (withdraw != null && doWithdrawFromMeleeAbility(attacker, defender, withdraw.text)) return
|
||||
val withdraw = defender.unit.getMatchingUniques("May withdraw before melee ([]%)").firstOrNull()
|
||||
if (withdraw != null && doWithdrawFromMeleeAbility(attacker, defender, withdraw)) return
|
||||
}
|
||||
|
||||
val isAlreadyDefeatedCity = defender is CityCombatant && defender.isDefeated()
|
||||
|
@ -411,7 +412,7 @@ object Battle {
|
|||
}
|
||||
}
|
||||
|
||||
private fun doWithdrawFromMeleeAbility(attacker: ICombatant, defender: ICombatant, withdraw: String): Boolean {
|
||||
private fun doWithdrawFromMeleeAbility(attacker: ICombatant, defender: ICombatant, withdrawUnique: Unique): Boolean {
|
||||
// Some notes...
|
||||
// unit.getUniques() is a union of baseunit uniques and promotion effects.
|
||||
// according to some strategy guide the slinger's withdraw ability is inherited on upgrade,
|
||||
|
@ -427,9 +428,8 @@ object Battle {
|
|||
// Promotions have no effect as per what I could find in available documentation
|
||||
val attackBaseUnit = attacker.unit.baseUnit
|
||||
val defendBaseUnit = defender.unit.baseUnit
|
||||
val withdrawMatch = Regex("""\((\d+)%\)""").find(withdraw)
|
||||
val percentChance = (
|
||||
(if(withdrawMatch!=null) withdrawMatch.groups[1]!!.value.toFloat() else 50f)
|
||||
val baseChance = withdrawUnique.params[0].toFloat()
|
||||
val percentChance = (baseChance
|
||||
* defendBaseUnit.strength / attackBaseUnit.strength
|
||||
* defendBaseUnit.movement / attackBaseUnit.movement).toInt()
|
||||
// Roll the dice - note the effect of the surroundings, namely how much room there is to evade to,
|
||||
|
|
|
@ -181,7 +181,7 @@ object BattleDamage {
|
|||
modifiers["Tile"] = tileDefenceBonus
|
||||
}
|
||||
|
||||
if(attacker.isRanged()) {
|
||||
if (attacker.isRanged()) {
|
||||
val defenceVsRanged = 0.25f * defender.unit.getUniques().count { it.text == "+25% Defence against ranged attacks" }
|
||||
if (defenceVsRanged > 0) modifiers["defence vs ranged"] = defenceVsRanged
|
||||
}
|
||||
|
@ -189,6 +189,11 @@ object BattleDamage {
|
|||
val carrierDefenceBonus = 0.25f * defender.unit.getUniques().count { it.text == "+25% Combat Bonus when defending" }
|
||||
if (carrierDefenceBonus > 0) modifiers["Armor Plating"] = carrierDefenceBonus
|
||||
|
||||
for(unique in defender.unit.getMatchingUniques("+[]% defence in [] tiles")) {
|
||||
if (tile.baseTerrain == unique.params[1] || tile.terrainFeature == unique.params[1])
|
||||
modifiers["[${unique.params[1]}] defence"] = unique.params[0].toFloat() / 100
|
||||
}
|
||||
|
||||
|
||||
if (defender.unit.isFortified())
|
||||
modifiers["Fortification"] = 0.2f * defender.unit.getFortificationTurns()
|
||||
|
|
|
@ -200,14 +200,10 @@ class CityStats {
|
|||
newHappinessList["Population"] = -unhappinessFromCitizens * unhappinessModifier
|
||||
|
||||
var happinessFromPolicies = 0f
|
||||
if (civInfo.hasUnique("+1 happiness for every 10 citizens in a city"))
|
||||
happinessFromPolicies += (cityInfo.population.population / 10).toFloat()
|
||||
if (civInfo.hasUnique("+1 gold and -1 unhappiness for every 2 citizens in capital")
|
||||
&& cityInfo.isCapital())
|
||||
happinessFromPolicies += (cityInfo.population.population / 2).toFloat()
|
||||
if (civInfo.hasUnique("+1 happiness for every city connected to capital")
|
||||
&& cityInfo.isConnectedToCapital())
|
||||
happinessFromPolicies += 1f
|
||||
happinessFromPolicies += getStatsFromUniques(civInfo.policies.policyUniques.getAllUniques()).happiness
|
||||
|
||||
if (cityInfo.getCenterTile().militaryUnit != null)
|
||||
for (unique in civInfo.getMatchingUniques("[] in all cities with a garrison"))
|
||||
|
@ -220,8 +216,7 @@ class CityStats {
|
|||
val happinessFromBuildings = cityInfo.cityConstructions.getStats().happiness.toInt().toFloat()
|
||||
newHappinessList["Buildings"] = happinessFromBuildings
|
||||
|
||||
if (civInfo.hasUnique("+1 happiness in each city"))
|
||||
newHappinessList["Wonders"] = 1f
|
||||
newHappinessList["Wonders"] = getStatsFromUniques(civInfo.getBuildingUniques()).happiness
|
||||
|
||||
newHappinessList["Tile yields"] = getStatsFromTiles().happiness
|
||||
|
||||
|
@ -243,8 +238,7 @@ class CityStats {
|
|||
|
||||
for(unique in cityInfo.civInfo.getMatchingUniques("[] from every specialist"))
|
||||
stats.add(Stats.parse(unique.params[0]))
|
||||
if (cityInfo.civInfo.hasUnique("+1 Production from specialists"))
|
||||
stats.production += 1
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
|
@ -267,8 +261,10 @@ class CityStats {
|
|||
val amountOfEffects = (cityInfo.population.population / unique.params[1].toInt()).toFloat()
|
||||
stats.add(Stats.parse(unique.params[0]).times(amountOfEffects))
|
||||
}
|
||||
if (unique.text == "+1 gold and -1 unhappiness for every 2 citizens in capital" && cityInfo.isCapital())
|
||||
if (unique.text == "+1 gold and -1 unhappiness for every 2 citizens in capital" && cityInfo.isCapital()) {
|
||||
stats.gold += (cityInfo.population.population / 2).toFloat()
|
||||
stats.happiness += (cityInfo.population.population / 2).toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
return stats
|
||||
|
|
|
@ -214,10 +214,10 @@ class MapUnit {
|
|||
}
|
||||
|
||||
fun getRange(): Int {
|
||||
if(type.isMelee()) return 1
|
||||
if (type.isMelee()) return 1
|
||||
var range = baseUnit().range
|
||||
if(hasUnique("+1 Range")) range++
|
||||
if(hasUnique("+2 Range")) range+=2
|
||||
if (hasUnique("+1 Range")) range++
|
||||
if (hasUnique("+2 Range")) range += 2
|
||||
return range
|
||||
}
|
||||
|
||||
|
@ -634,11 +634,7 @@ class MapUnit {
|
|||
}
|
||||
|
||||
fun interceptChance():Int{
|
||||
val interceptUnique = getUniques()
|
||||
.firstOrNull { it.text.endsWith(CHANCE_TO_INTERCEPT_AIR_ATTACKS) }
|
||||
if(interceptUnique==null) return 0
|
||||
val percent = Regex("\\d+").find(interceptUnique.text)!!.value.toInt()
|
||||
return percent
|
||||
return getMatchingUniques("[100]% chance to intercept air attacks").sumBy { it.params[0].toInt() }
|
||||
}
|
||||
|
||||
fun isTransportTypeOf(mapUnit: MapUnit): Boolean {
|
||||
|
|
Loading…
Reference in a new issue