Added damage modification from basic promotions

This commit is contained in:
Yair Morgenstern 2018-06-16 23:35:54 +03:00
parent c6caf0cecd
commit 80963e7eac
4 changed files with 77 additions and 29 deletions

View File

@ -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 {

View File

@ -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<BattleDamageModifier> {
val modifiers = mutableListOf<BattleDamageModifier>()
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<String, Float> {
val modifiers = HashMap<String, Float>()
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<String, Float> {
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
}

View File

@ -118,15 +118,16 @@ class MapUnit {
doPreTurnAction()
}
fun getUniques(): MutableList<String> {
val uniques = mutableListOf<String>()
fun getSpecialAbilities(): MutableList<String> {
val abilities = mutableListOf<String>()
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<TileInfo> {
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)
}

View File

@ -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)
}