Added battle modifiers, specifically - terrain defence bonuses
This commit is contained in:
parent
4e36aa0d5a
commit
7ff9f17943
6 changed files with 84 additions and 19 deletions
|
@ -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"]
|
||||
}
|
||||
]
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -32,6 +32,7 @@ class Terrain : NamedStats(), ICivilopedia {
|
|||
|
||||
var movementCost = 1
|
||||
|
||||
var defenceBonus:Float = 0f
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue