Added battle modifiers, specifically - terrain defence bonuses

This commit is contained in:
Yair Morgenstern 2018-04-04 23:10:16 +03:00
parent 4e36aa0d5a
commit 7ff9f17943
6 changed files with 84 additions and 19 deletions

View file

@ -40,6 +40,7 @@
type:"BaseTerrain",
production:2,
movementCost:2,
defenceBonus: 0.25,
RGB: [74,81,40]
},
@ -52,6 +53,7 @@
movementCost:2,
overrideStats:true,
unbuildable:true,
defenceBonus: 0.25,
occursOn:["Tundra","Plains","Grassland"]
},
{
@ -61,6 +63,7 @@
movementCost:2,
overrideStats:true,
unbuildable:true,
defenceBonus: 0.25,
occursOn:["Plains","Grassland"]
},
{
@ -69,6 +72,7 @@
food:-1,
movementCost:3,
unbuildable:true,
defenceBonus: -0.1,
occursOn:["Grassland"]
},
{
@ -77,6 +81,7 @@
food:3,
movementCost:1,
unbuildable:true,
defenceBonus: -0.1,
occursOn:["Desert"]
},
{
@ -84,6 +89,7 @@
type:"TerrainFeature",
food:2,
movementCost:1,
defenceBonus: -0.1,
occursOn:["Desert"]
}
]

View file

@ -2,15 +2,51 @@ package com.unciv.logic.battle
import com.unciv.logic.GameInfo
import java.util.*
import kotlin.collections.HashMap
class Battle(val gameInfo:GameInfo) {
fun getAttackModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
return HashMap<String,Float>()
}
fun getDefenceModifiers(attacker: ICombatant, defender: ICombatant): HashMap<String, Float> {
val modifiers = HashMap<String,Float>()
val tileDefenceBonus = defender.getTile().getDefensiveBonus()
if(tileDefenceBonus > 0) modifiers.put("Terrain",tileDefenceBonus)
return modifiers
}
fun modifiersToMultiplicationBonus(modifiers:HashMap<String,Float> ):Float{
// modifiers are like 0.1 for a 10% bonus, -0.1 for a 10% loss
var modifier = 1f
for(m in modifiers.values) modifier *= (1+m)
return modifier
}
/**
* Includes attack modifiers
*/
fun getAttackingStrength(attacker: ICombatant, defender: ICombatant): Float {
val attackModifier = modifiersToMultiplicationBonus(getAttackModifiers(attacker,defender))
return attacker.getAttackingStrength(defender) * attackModifier
}
/**
* Includes defence modifiers
*/
fun getDefendingStrength(attacker: ICombatant, defender: ICombatant): Float {
val defenceModifier = modifiersToMultiplicationBonus(getDefenceModifiers(attacker,defender))
return defender.getDefendingStrength(attacker) * defenceModifier
}
fun calculateDamageToAttacker(attacker: ICombatant, defender: ICombatant): Int {
return defender.getDefendingStrength(attacker) * 50 / attacker.getAttackingStrength(defender)
return (getDefendingStrength(attacker,defender) * 50 / getAttackingStrength(attacker,defender)).toInt()
}
fun calculateDamageToDefender(attacker: ICombatant, defender: ICombatant): Int {
return attacker.getAttackingStrength(defender)*50/defender.getDefendingStrength(attacker)
return (getAttackingStrength(attacker, defender)*50/ getDefendingStrength(attacker,defender)).toInt()
}
fun attack(attacker: ICombatant, defender: ICombatant) {

View file

@ -173,4 +173,10 @@ class TileInfo {
return tileMap.getViewableTiles(this.position,distance)
}
fun getDefensiveBonus(): Float {
var bonus = getBaseTerrain().defenceBonus
if(terrainFeature!=null) bonus += getTerrainFeature()!!.defenceBonus
return bonus
}
}

View file

@ -32,6 +32,7 @@ class Terrain : NamedStats(), ICivilopedia {
var movementCost = 1
var defenceBonus:Float = 0f
}

View file

@ -60,9 +60,9 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
unitImage = null
}
if (tileInfo.unit != null) {
if (tileInfo.unit != null && color.a==1f) { // Tile is visible
val unit = tileInfo.unit!!
unitImage = getUnitImage(unit.name!!, unit.civInfo.getCivilization().getColor())
unitImage = getUnitImage(unit.name, unit.civInfo.getCivilization().getColor())
addActor(unitImage!!)
unitImage!!.setSize(20f, 20f)
unitImage!!.setPosition(width/2 - unitImage!!.width/2,

View file

@ -8,10 +8,14 @@ import com.unciv.logic.map.UnitType
import com.unciv.ui.cityscreen.addClickListener
import com.unciv.ui.utils.CameraStageBaseScreen
import com.unciv.ui.utils.disable
import kotlin.math.max
class BattleTable(val worldScreen: WorldScreen): Table() {
private val battle = Battle(worldScreen.civInfo.gameInfo)
init{
skin = CameraStageBaseScreen.skin
}
fun update(){
if(worldScreen.unitTable.selectedUnit==null
@ -38,17 +42,34 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
fun simulateBattle(attacker: MapUnitCombatant, defender: ICombatant){
clear()
val attackerLabel = Label(attacker.getName(), CameraStageBaseScreen.skin)
row().pad(5f)
val attackerLabel = Label(attacker.getName(), skin)
attackerLabel.style= Label.LabelStyle(attackerLabel.style)
attackerLabel.style.fontColor=attacker.getCivilization().getCivilization().getColor()
add(attackerLabel)
val defenderLabel = Label(attacker.getName(), CameraStageBaseScreen.skin)
val defenderLabel = Label(attacker.getName(), skin)
defenderLabel.style= Label.LabelStyle(defenderLabel.style)
defenderLabel.style.fontColor=defender.getCivilization().getCivilization().getColor()
add(defenderLabel)
row()
row().pad(5f)
add("Strength: "+attacker.getAttackingStrength(defender)/100f)
add("Strength: "+defender.getDefendingStrength(attacker)/100f)
row().pad(5f)
val attackerModifiers = battle.getAttackModifiers(attacker,defender) .map { it.key+": "+(if(it.value>0)"+" else "")+(it.value*100).toInt()+"%" }
val defenderModifiers = battle.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()
row().pad(5f)
}
add((battle.getAttackingStrength(attacker,defender)/100f).toString())
add((battle.getDefendingStrength(attacker,defender)/100f).toString())
row().pad(5f)
var damageToDefender = battle.calculateDamageToDefender(attacker,defender)
var damageToAttacker = battle.calculateDamageToAttacker(attacker,defender)
@ -73,20 +94,16 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
else if (damageToDefender>defender.getHealth()) damageToDefender=defender.getHealth()
val attackLabel = Label(attacker.getHealth().toString() + " -> "
+ (attacker.getHealth()- damageToAttacker), CameraStageBaseScreen.skin)
add(attackLabel)
add("Health: "+attacker.getHealth().toString() + " -> "
+ (attacker.getHealth()- damageToAttacker))
val defendLabel = Label(defender.getHealth().toString() + " -> "
+ (defender.getHealth()- damageToDefender),
CameraStageBaseScreen.skin)
add(defendLabel)
add("Health: "+defender.getHealth().toString() + " -> "
+ (defender.getHealth()- damageToDefender))
row()
val attackButton = TextButton("Attack",CameraStageBaseScreen.skin)
row().pad(5f)
val attackButton = TextButton("Attack", skin)
attackButton.addClickListener {
//todo this should be in battletabl and not n the logic! It's to make things easier for the player!
if(attacker.getCombatantType() == CombatantType.Melee)
attacker.unit.headTowards(defender.getTile().position)
battle.attack(attacker,defender)
@ -98,8 +115,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
add(attackButton).colspan(2)
pack()
setPosition(worldScreen.stage.width/2-width/2,
5f)
setPosition(worldScreen.stage.width/2-width/2, 5f)
}
}