diff --git a/android/assets/UnitIcons/Shield.png b/android/assets/UnitIcons/Shield.png new file mode 100644 index 0000000000..97d840f252 Binary files /dev/null and b/android/assets/UnitIcons/Shield.png differ diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index f146ee1332..1dc28f948f 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -31,9 +31,14 @@ class Battle(val gameInfo:GameInfo) { } } } + + if(enemy.getCivilization() == enemy.getCivilization().gameInfo.getBarbarianCivilization()) + modifiers["vs Barbarians"] = 0.33f + + if(combatant.getCivilization().happiness<0) + modifiers["Unhappiness"] = 0.02f * combatant.getCivilization().happiness //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php } - if(enemy.getCivilization() == enemy.getCivilization().gameInfo.getBarbarianCivilization()) - modifiers["vs Barbarians"] = 0.33f + return modifiers } @@ -45,7 +50,8 @@ class Battle(val gameInfo:GameInfo) { && it.unit!!.owner == attacker.getCivilization().civName && MapUnitCombatant(it.unit!!).isMelee() } - if (numberOfAttackersSurroundingDefender > 1) modifiers["Flanking"] = 0.15f + if (numberOfAttackersSurroundingDefender > 1) + modifiers["Flanking"] = 0.1f * (numberOfAttackersSurroundingDefender-1) //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php } return modifiers @@ -57,6 +63,8 @@ class Battle(val gameInfo:GameInfo) { val tileDefenceBonus = defender.getTile().getDefensiveBonus() if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus } + if(defender is MapUnitCombatant && defender.unit.isFortified()) + modifiers["Fortification"]=0.2f*defender.unit.getFortificationTurns() return modifiers } @@ -160,6 +168,7 @@ class Battle(val gameInfo:GameInfo) { if (attacker.unit.hasUnique("Can move after attacking")) attacker.unit.currentMovement = max(0f, attacker.unit.currentMovement - 1) else attacker.unit.currentMovement = 0f + attacker.unit.action=null // for instance, if it was fortified } } diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index 2de21c2e37..ca00eeb693 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -53,6 +53,11 @@ class MapUnit { private fun doPostTurnAction() { if (name == "Worker" && getTile().improvementInProgress != null) workOnImprovement() + if(currentMovement==maxMovement.toFloat() + && isFortified()){ + val currentTurnsFortified = getFortificationTurns() + if(currentTurnsFortified<2) action = "Fortify ${currentTurnsFortified+1}" + } } private fun workOnImprovement() { @@ -122,7 +127,7 @@ class MapUnit { fun movementAlgs() = UnitMovementAlgorithms(this) override fun toString(): String { - return name +" - "+owner + return "$name - $owner" } fun getVisibilityRange(): Int { @@ -130,4 +135,13 @@ class MapUnit { if(hasUnique("Limited Visibility")) visibilityRange-=1 return visibilityRange } + + fun isFortified(): Boolean { + return action!=null && action!!.startsWith("Fortify") + } + + fun getFortificationTurns(): Int { + if(!isFortified()) return 0 + return action!!.split(" ")[1].toInt() + } } \ No newline at end of file diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index 08f6381be1..4396c66c4c 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -155,7 +155,7 @@ class TileInfo { if (improvementInProgress != null) SB.appendln("$improvementInProgress in ${this.turnsToImprovement} turns") if (unit != null && UnCivGame.Current.gameInfo.getPlayerCivilization().getViewableTiles().contains(this)){ var unitString = unit!!.name - if(unit!!.getBaseUnit().unitType!=UnitType.Civilian) unitString += "(" + unit!!.health + ")" + if(unit!!.getBaseUnit().unitType!=UnitType.Civilian && unit!!.health<100) unitString += "(" + unit!!.health + ")" SB.appendln(unitString) } return SB.toString().trim() @@ -169,6 +169,7 @@ class TileInfo { if (unit == null) return false if (unit!!.currentMovement == 0f) return false if (unit!!.name == "Worker" && improvementInProgress != null) return false + if (unit!!.isFortified()) return false return true } diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index e43c351e34..707cf3cccb 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.Group import com.badlogic.gdx.scenes.scene2d.ui.Image import com.badlogic.gdx.utils.Align +import com.unciv.logic.map.MapUnit import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.TileInfo import com.unciv.ui.utils.HexMath @@ -235,7 +236,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() { if (tileInfo.unit != null && (isViewable || viewEntireMapForDebug)) { // Tile is visible val unit = tileInfo.unit!! - unitImage = getUnitImage(unit.name, unit.civInfo.getCivilization().getColor()) + unitImage = getUnitImage(unit, unit.civInfo.getCivilization().getColor()) addActor(unitImage!!) unitImage!!.setSize(20f, 20f) } @@ -250,10 +251,13 @@ open class TileGroup(var tileInfo: TileInfo) : Group() { } - private fun getUnitImage(unitType:String, color:Color): Group { - val unitBaseImage = ImageGetter.getImage("UnitIcons/$unitType.png") + private fun getUnitImage(unit: MapUnit, color:Color): Group { + val unitBaseImage = ImageGetter.getImage("UnitIcons/${unit.name}.png") .apply { setSize(15f,15f) } - val background = ImageGetter.getImage("UnitIcons/Circle.png").apply { + + val background = if(unit.isFortified()) ImageGetter.getImage("UnitIcons/Shield.png") + else ImageGetter.getImage("UnitIcons/Circle.png") + background.apply { this.color = color setSize(20f,20f) } diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index a289e3b12a..1561c7e899 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -5,6 +5,7 @@ import com.unciv.UnCivGame import com.unciv.logic.automation.WorkerAutomation import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo +import com.unciv.logic.map.UnitType import com.unciv.models.gamebasics.Building import com.unciv.models.gamebasics.GameBasics import com.unciv.ui.cityscreen.addClickListener @@ -50,6 +51,11 @@ class UnitActions { },true) } + if(unit.getBaseUnit().unitType!=UnitType.Civilian && !unit.hasUnique("No defensive terrain bonus")){ + if(!unit.isFortified()) + actionList += UnitAction("Fortify",{unit.action="Fortify 0"}, unit.currentMovement != 0f) + } + if (unit.name == "Settler") { actionList += UnitAction("Found city", { diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt index 9c11dd94ca..0c5805eecc 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt @@ -45,15 +45,19 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ if(selectedUnit!=null) { val unit = selectedUnit!! - unitNameLabel.setText(unit.name) + var nameLabelText = unit.name + if(unit.health<100) nameLabelText+=" ("+unit.health+")" + unitNameLabel.setText(nameLabelText) var unitLabelText = "Movement: " + unit.getMovementString() if (unit.getBaseUnit().unitType != UnitType.Civilian) { - unitLabelText += "\r\nHealth: " + unit.health + - "\r\nStrength: " + unit.getBaseUnit().strength + unitLabelText += "\nStrength: " + unit.getBaseUnit().strength } if (unit.getBaseUnit().rangedStrength!=0) - unitLabelText += "\r\nRanged strength: "+unit.getBaseUnit().rangedStrength + unitLabelText += "\nRanged strength: "+unit.getBaseUnit().rangedStrength + + if(unit.isFortified() && unit.getFortificationTurns()>0) + unitLabelText+="\n+"+unit.getFortificationTurns()*20+"% fortification" unitDescriptionLabel.setText(unitLabelText) @@ -80,6 +84,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ val reachedTile = selectedUnit!!.movementAlgs().headTowards(selectedTile) + selectedUnit!!.action=null // Disable any prior action (automation, fortification...) if(reachedTile!=selectedTile) // Didn't get all the way there selectedUnit!!.action = "moveTo " + selectedTile.position.x.toInt() + "," + selectedTile.position.y.toInt() currentlyExecutingAction = null