diff --git a/android/build.gradle b/android/build.gradle index 754ed755a6..6baac3f81f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -21,8 +21,8 @@ android { applicationId "com.unciv.game" minSdkVersion 14 targetSdkVersion 26 - versionCode 83 - versionName "2.4.12" + versionCode 84 + versionName "2.5.0" } buildTypes { release { diff --git a/core/src/com/unciv/logic/battle/BattleDamage.kt b/core/src/com/unciv/logic/battle/BattleDamage.kt index 3ac2ebea92..a567093527 100644 --- a/core/src/com/unciv/logic/battle/BattleDamage.kt +++ b/core/src/com/unciv/logic/battle/BattleDamage.kt @@ -1,41 +1,68 @@ package com.unciv.logic.battle +import com.unciv.logic.map.MapUnit import com.unciv.models.gamebasics.unit.UnitType +class BattleDamageModifier(val vs:String,val modificationAmount:Float){ + fun getText(): String = "vs $vs" +} class BattleDamage{ + private fun getBattleDamageModifiersOfUnit(unit:MapUnit): MutableList { + val modifiers = mutableListOf() + for (ability in unit.getSpecialAbilities()) { + // This beut allows us to have generic unit uniques: "Bonus vs City 75%", "Penatly vs Mounted 25%" etc. + val regexResult = Regex("""(Bonus|Penalty) vs (.*) (\d*)%""").matchEntire(ability) + if (regexResult == null) continue + val vs = regexResult.groups[2]!!.value + val modificationAmount = regexResult.groups[3]!!.value.toFloat() / 100 // if it says 15%, that's 0.15f in modification + if (regexResult.groups[1]!!.value == "Bonus") + modifiers.add(BattleDamageModifier(vs, modificationAmount)) + else + modifiers.add(BattleDamageModifier(vs, -modificationAmount)) + } + return modifiers + } + + private fun getGeneralModifiers(combatant: ICombatant, enemy: ICombatant): HashMap { val modifiers = HashMap() if (combatant is MapUnitCombatant) { - val uniques = combatant.unit.getBaseUnit().uniques - if (uniques != null) { - // This beut allows us to have generic unit uniques: "Bonus vs City 75%", "Penatly vs Mounted 25%" etc. - for (unique in uniques) { - val regexResult = Regex("""(Bonus|Penalty) vs (\S*) (\d*)%""").matchEntire(unique) - if (regexResult == null) continue - val vsType = UnitType.valueOf(regexResult.groups[2]!!.value) - val modificationAmount = regexResult.groups[3]!!.value.toFloat() / 100 // if it says 15%, that's 0.15f in modification - if (enemy.getUnitType() == vsType) { - if (regexResult.groups[1]!!.value == "Bonus") - modifiers["Bonus vs $vsType"] = modificationAmount - else modifiers["Penalty vs $vsType"] = -modificationAmount - } - } + for (BDM in getBattleDamageModifiersOfUnit(combatant.unit)) { + if (BDM.vs == enemy.getUnitType().toString()) modifiers[BDM.getText()] = BDM.modificationAmount } - - if(enemy.getCivilization().isBarbarianCivilization()) - modifiers["vs Barbarians"] = 0.33f - - if(combatant.getCivilization().happiness<0) + if (combatant.getCivilization().happiness < 0) modifiers["Unhappiness"] = 0.02f * combatant.getCivilization().happiness //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php } + if (enemy.getCivilization().isBarbarianCivilization()) + modifiers["vs Barbarians"] = 0.33f + return modifiers } fun getAttackModifiers(attacker: ICombatant, defender: ICombatant): HashMap { val modifiers = getGeneralModifiers(attacker, defender) + + if(attacker is MapUnitCombatant) { + val defenderTile = defender.getTile() + val isDefenderInRoughTerrain = defenderTile.baseTerrain=="Hill" || defenderTile.terrainFeature == "Forest" || defenderTile.terrainFeature == "Jungle" + for (BDM in getBattleDamageModifiersOfUnit(attacker.unit)) { + val text = BDM.getText() + if (BDM.vs == "units in open terrain" && !isDefenderInRoughTerrain) { + if(modifiers.containsKey(text)) + modifiers[text] =modifiers[text]!! + BDM.modificationAmount + else modifiers[text] = BDM.modificationAmount + } + if (BDM.vs == "units in rough terrain" && isDefenderInRoughTerrain) { + if (modifiers.containsKey(text)) + modifiers[text] = modifiers[text]!! + BDM.modificationAmount + else modifiers[text] = BDM.modificationAmount + } + } + } + if (attacker.isMelee()) { val numberOfAttackersSurroundingDefender = defender.getTile().neighbors.count { it.militaryUnit != null @@ -55,8 +82,28 @@ class BattleDamage{ val tileDefenceBonus = defender.getTile().getDefensiveBonus() if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus } + + if(defender is MapUnitCombatant) { + val defenderTile = defender.getTile() + val isDefenderInRoughTerrain = defenderTile.baseTerrain=="Hill" || defenderTile.terrainFeature == "Forest" || defenderTile.terrainFeature == "Jungle" + for (BDM in getBattleDamageModifiersOfUnit(defender.unit)) { + val text = BDM.getText() + if (BDM.vs == "units in open terrain" && !isDefenderInRoughTerrain) { + if(modifiers.containsKey(text)) + modifiers[text] =modifiers[text]!! + BDM.modificationAmount + else modifiers[text] = BDM.modificationAmount + } + if (BDM.vs == "units in rough terrain" && isDefenderInRoughTerrain) { + if (modifiers.containsKey(text)) + modifiers[text] = modifiers[text]!! + BDM.modificationAmount + else modifiers[text] = BDM.modificationAmount + } + } + } + if(defender is MapUnitCombatant && defender.unit.isFortified()) modifiers["Fortification"]=0.2f*defender.unit.getFortificationTurns() + return modifiers } diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index 3fa576024f..b2bc42e688 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -118,15 +118,16 @@ class MapUnit { doPreTurnAction() } - fun getUniques(): MutableList { - val uniques = mutableListOf() + fun getSpecialAbilities(): MutableList { + val abilities = mutableListOf() val baseUnit = getBaseUnit() - if(baseUnit.uniques!=null) uniques.addAll(baseUnit.uniques!!) - return uniques + if(baseUnit.uniques!=null) abilities.addAll(baseUnit.uniques!!) + abilities.addAll(promotions.promotions.map { GameBasics.UnitPromotions[it]!!.effect }) + return abilities } fun hasUnique(unique:String): Boolean { - return getUniques().contains(unique) + return getSpecialAbilities().contains(unique) } fun movementAlgs() = UnitMovementAlgorithms(this) @@ -137,7 +138,7 @@ class MapUnit { fun getViewableTiles(): MutableList { var visibilityRange = 2 - visibilityRange += getUniques().count{it=="+1 Visibility Range"} + visibilityRange += getSpecialAbilities().count{it=="+1 Visibility Range"} if(hasUnique("Limited Visibility")) visibilityRange-=1 return getTile().getViewableTiles(visibilityRange) } diff --git a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt index 84a686dd1f..7b417a7772 100644 --- a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt +++ b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt @@ -71,8 +71,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() { val defenderModifiers = BattleDamage().getDefenceModifiers(attacker, defender).map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" } for(i in 0..max(attackerModifiers.size,defenderModifiers.size)){ - if (attackerModifiers.size > i) add(attackerModifiers[i]) else add() - if (defenderModifiers.size > i) add(defenderModifiers[i]) else add() + if (attackerModifiers.size > i) add(attackerModifiers[i]).actor.setFont(14) else add() + if (defenderModifiers.size > i) add(defenderModifiers[i]).actor.setFont(14) else add() row().pad(2f) }