Can now conquer cities! =D
This commit is contained in:
parent
7e2015572c
commit
17307f16f9
14 changed files with 220 additions and 127 deletions
|
@ -58,9 +58,11 @@ class UnCivGame : Game() {
|
|||
gameInfo.civilizations.add(CivilizationInfo("Greece", Vector2(3f,5f), gameInfo)) // all the rest whatever
|
||||
|
||||
barbarianCivilization.civName = "Barbarians"
|
||||
|
||||
gameInfo.setTransients() // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set
|
||||
|
||||
(1..5).forEach { gameInfo.placeBarbarianUnit() }
|
||||
|
||||
gameInfo.setTransients()
|
||||
|
||||
worldScreen = WorldScreen()
|
||||
setWorldScreen()
|
||||
|
|
|
@ -137,6 +137,7 @@ class GameInfo {
|
|||
}
|
||||
|
||||
val damageToAttacker = Battle(this).calculateDamageToAttacker(MapUnitCombatant(unit), MapUnitCombatant(unitToAttack))
|
||||
|
||||
if(damageToAttacker < unit.health) { // don't attack if we'll die from the attack
|
||||
unit.headTowards(unitTileToAttack.position)
|
||||
Battle(this).attack(MapUnitCombatant(unit), MapUnitCombatant(unitToAttack))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.unciv.logic.battle
|
||||
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.UnitType
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
|
@ -67,13 +69,15 @@ class Battle(val gameInfo:GameInfo) {
|
|||
var damageToDefender = calculateDamageToDefender(attacker,defender)
|
||||
var damageToAttacker = calculateDamageToAttacker(attacker,defender)
|
||||
|
||||
if (attacker.getCombatantType() == CombatantType.Ranged) {
|
||||
if(defender.getCombatantType() == CombatantType.Civilian){
|
||||
defender.takeDamage(100) // kill
|
||||
}
|
||||
else if (attacker.getCombatantType() == CombatantType.Ranged) {
|
||||
defender.takeDamage(damageToDefender) // straight up
|
||||
} else {
|
||||
//melee attack is complicated, because either side may defeat the other midway
|
||||
//so...for each round, we randomize who gets the attack in. Seems to be a good way to work for now.
|
||||
|
||||
|
||||
while (damageToDefender + damageToAttacker > 0) {
|
||||
if (Random().nextInt(damageToDefender + damageToAttacker) < damageToDefender) {
|
||||
damageToDefender--
|
||||
|
@ -87,7 +91,11 @@ class Battle(val gameInfo:GameInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
// After dust as settled
|
||||
postBattleAction(attacker,defender,attackedTile)
|
||||
|
||||
}
|
||||
|
||||
fun postBattleAction(attacker: ICombatant, defender: ICombatant, attackedTile:TileInfo){
|
||||
|
||||
if (defender.getCivilization().isPlayerCivilization()) {
|
||||
val whatHappenedString =
|
||||
|
@ -100,10 +108,38 @@ class Battle(val gameInfo:GameInfo) {
|
|||
gameInfo.getPlayerCivilization().addNotification(notificationString, attackedTile.position)
|
||||
}
|
||||
|
||||
if(defender.isDefeated()
|
||||
&& defender.getCombatantType() == CombatantType.City
|
||||
&& attacker.getCombatantType() == CombatantType.Melee){
|
||||
conquerCity((defender as CityCombatant).city, attacker)
|
||||
}
|
||||
|
||||
if (defender.isDefeated() && attacker.getCombatantType() == CombatantType.Melee)
|
||||
(attacker as MapUnitCombatant).unit.moveToTile(attackedTile)
|
||||
|
||||
if(attacker is MapUnitCombatant) attacker.unit.currentMovement = 0f
|
||||
}
|
||||
|
||||
private fun conquerCity(city: CityInfo, attacker: ICombatant) {
|
||||
val enemyCiv = city.civInfo
|
||||
attacker.getCivilization().addNotification("We have conquered the city of ${city.name}!",city.cityLocation)
|
||||
enemyCiv.cities.remove(city)
|
||||
attacker.getCivilization().cities.add(city)
|
||||
city.civInfo = attacker.getCivilization()
|
||||
city.health = city.getMaxHealth() / 2 // I think that cities recover to half health?
|
||||
city.getTile().unit = null
|
||||
city.expansion.cultureStored = 0;
|
||||
city.expansion.reset()
|
||||
if(city.cityConstructions.isBuilt("Palace")){
|
||||
city.cityConstructions.builtBuildings.remove("Palace")
|
||||
if(enemyCiv.cities.isEmpty()) {
|
||||
gameInfo.getPlayerCivilization()
|
||||
.addNotification("The ${enemyCiv.civName} civilization has been destroyed!", null)
|
||||
}
|
||||
else{
|
||||
enemyCiv.cities.first().cityConstructions.builtBuildings.add("Palace") // relocate palace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,6 @@ import com.unciv.logic.city.CityInfo
|
|||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import kotlin.math.max
|
||||
|
||||
class CityCombatant(val city: CityInfo) : ICombatant {
|
||||
override fun getHealth(): Int = city.health
|
||||
|
@ -14,7 +13,8 @@ class CityCombatant(val city: CityInfo) : ICombatant {
|
|||
override fun isDefeated(): Boolean = city.health==1
|
||||
|
||||
override fun takeDamage(damage: Int) {
|
||||
city.health = max(1, city.health - damage) // min health is 1
|
||||
city.health -= damage
|
||||
if(city.health<1) city.health=1 // min health is 1
|
||||
}
|
||||
|
||||
override fun getCombatantType(): CombatantType = CombatantType.City
|
||||
|
@ -37,7 +37,9 @@ class CityCombatant(val city: CityInfo) : ICombatant {
|
|||
// 10% bonus foreach pop
|
||||
val strengthWithPop = (baseStrength + strengthFromTechs) * (1 + 0.1*city.population.population)
|
||||
|
||||
return strengthWithPop.toInt()
|
||||
|
||||
|
||||
return strengthWithPop.toInt() * 100 // *100 because a city is always at 100% strength
|
||||
}
|
||||
|
||||
}
|
|
@ -3,5 +3,6 @@ package com.unciv.logic.battle
|
|||
enum class CombatantType{
|
||||
Melee,
|
||||
Ranged,
|
||||
Civilian,
|
||||
City
|
||||
}
|
|
@ -25,13 +25,16 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
|||
return attackerStrength*unit.health
|
||||
}
|
||||
|
||||
override fun getDefendingStrength(attacker: ICombatant): Int =
|
||||
unit.getBaseUnit().strength*unit.health
|
||||
override fun getDefendingStrength(attacker: ICombatant): Int {
|
||||
// too: if ranged units get ranged attacked, they use their ranged str to defend!
|
||||
return unit.getBaseUnit().strength*unit.health
|
||||
}
|
||||
|
||||
override fun getCombatantType(): CombatantType {
|
||||
when(unit.getBaseUnit().unitType){
|
||||
UnitType.Melee -> return CombatantType.Melee
|
||||
UnitType.Ranged -> return CombatantType.Ranged
|
||||
UnitType.Civilian -> return CombatantType.Civilian
|
||||
else -> throw Exception("Should never get here!")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
package com.unciv.logic.city
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
|
||||
class CityExpansionManager {
|
||||
|
||||
@Transient
|
||||
lateinit var cityInfo: CityInfo
|
||||
var cityTiles = ArrayList<Vector2>()
|
||||
var cultureStored: Int = 0
|
||||
private var tilesClaimed: Int = 0
|
||||
|
||||
fun reset(){
|
||||
cityTiles = ArrayList(cityInfo.civInfo.gameInfo.tileMap
|
||||
.getTilesInDistance(cityInfo.cityLocation, 1).map { it.position })
|
||||
}
|
||||
|
||||
// This one has conflicting sources -
|
||||
// http://civilization.wikia.com/wiki/Mathematics_of_Civilization_V says it's 20+(10(t-1))^1.1
|
||||
|
@ -13,31 +20,30 @@ class CityExpansionManager {
|
|||
// (per game XML files) at 6*(t+0.4813)^1.3
|
||||
// The second seems to be more based, so I'll go with that
|
||||
//Speciality of Angkor Wat
|
||||
val cultureToNextTile: Int
|
||||
get() {
|
||||
var cultureToNextTile = 6 * Math.pow(tilesClaimed + 1.4813, 1.3)
|
||||
if (cityInfo.civInfo.buildingUniques.contains("NewTileCostReduction")) cultureToNextTile *= 0.75
|
||||
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
|
||||
return Math.round(cultureToNextTile).toInt()
|
||||
}
|
||||
fun getCultureToNextTile(): Int {
|
||||
val numTilesClaimed = cityTiles.size - 7
|
||||
var cultureToNextTile = 6 * Math.pow(numTilesClaimed + 1.4813, 1.3)
|
||||
if (cityInfo.civInfo.buildingUniques.contains("NewTileCostReduction")) cultureToNextTile *= 0.75
|
||||
if (cityInfo.civInfo.policies.isAdopted("Tradition")) cultureToNextTile *= 0.75
|
||||
return Math.round(cultureToNextTile).toInt()
|
||||
}
|
||||
|
||||
private fun addNewTileWithCulture() {
|
||||
cultureStored -= cultureToNextTile
|
||||
cultureStored -= getCultureToNextTile()
|
||||
|
||||
for (i in 2..3) {
|
||||
val tiles = cityInfo.civInfo.gameInfo.tileMap.getTilesInDistance(cityInfo.cityLocation, i).filter { it.owner == null }
|
||||
if (tiles.isEmpty()) continue
|
||||
val chosenTile = tiles.maxBy { cityInfo.rankTile(it) }
|
||||
chosenTile!!.owner = cityInfo.civInfo.civName
|
||||
tilesClaimed++
|
||||
cityTiles.add(chosenTile!!.position)
|
||||
chosenTile.owner = cityInfo.civInfo.civName
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fun nextTurn(culture: Float) {
|
||||
|
||||
cultureStored += culture.toInt()
|
||||
if (cultureStored >= cultureToNextTile) {
|
||||
if (cultureStored >= getCultureToNextTile()) {
|
||||
addNewTileWithCulture()
|
||||
cityInfo.civInfo.addNotification(cityInfo.name + " has expanded its borders!", cityInfo.cityLocation)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ class CityInfo {
|
|||
var expansion = CityExpansionManager()
|
||||
var cityStats = CityStats()
|
||||
|
||||
|
||||
|
||||
internal val tileMap: TileMap
|
||||
get() = civInfo.gameInfo.tileMap
|
||||
|
||||
|
@ -51,23 +53,22 @@ class CityInfo {
|
|||
val buildingUniques: List<String?>
|
||||
get() = cityConstructions.getBuiltBuildings().filter { it.unique!=null }.map { it.unique }
|
||||
|
||||
val greatPersonPoints: Stats
|
||||
get() {
|
||||
var greatPersonPoints = population.getSpecialists().times(3f)
|
||||
fun getGreatPersonPoints(): Stats {
|
||||
var greatPersonPoints = population.getSpecialists().times(3f)
|
||||
|
||||
for (building in cityConstructions.getBuiltBuildings())
|
||||
if (building.greatPersonPoints != null)
|
||||
greatPersonPoints.add(building.greatPersonPoints!!)
|
||||
for (building in cityConstructions.getBuiltBuildings())
|
||||
if (building.greatPersonPoints != null)
|
||||
greatPersonPoints.add(building.greatPersonPoints!!)
|
||||
|
||||
if (civInfo.buildingUniques.contains("GreatPersonGenerationIncrease"))
|
||||
greatPersonPoints = greatPersonPoints.times(1.33f)
|
||||
if (civInfo.policies.isAdopted("Entrepreneurship"))
|
||||
greatPersonPoints.gold *= 1.25f
|
||||
if (civInfo.policies.isAdopted("Freedom"))
|
||||
greatPersonPoints = greatPersonPoints.times(1.25f)
|
||||
if (civInfo.buildingUniques.contains("GreatPersonGenerationIncrease"))
|
||||
greatPersonPoints = greatPersonPoints.times(1.33f)
|
||||
if (civInfo.policies.isAdopted("Entrepreneurship"))
|
||||
greatPersonPoints.gold *= 1.25f
|
||||
if (civInfo.policies.isAdopted("Freedom"))
|
||||
greatPersonPoints = greatPersonPoints.times(1.25f)
|
||||
|
||||
return greatPersonPoints
|
||||
}
|
||||
return greatPersonPoints
|
||||
}
|
||||
|
||||
constructor() // for json parsing, we need to have a default constructor
|
||||
|
||||
|
@ -88,9 +89,8 @@ class CityInfo {
|
|||
cityConstructions.currentConstruction = "Worker" // Default for first city only!
|
||||
}
|
||||
|
||||
for (tileInfo in civInfo.gameInfo.tileMap.getTilesInDistance(cityLocation, 1)) {
|
||||
tileInfo.owner = civInfo.civName
|
||||
}
|
||||
expansion.reset()
|
||||
|
||||
|
||||
val tile = getTile()
|
||||
tile.workingCity = this.name
|
||||
|
|
|
@ -141,7 +141,7 @@ class CivilizationInfo {
|
|||
|
||||
for (city in cities) {
|
||||
city.nextTurn()
|
||||
greatPeople.addGreatPersonPoints(city.greatPersonPoints)
|
||||
greatPeople.addGreatPersonPoints(city.getGreatPersonPoints())
|
||||
}
|
||||
|
||||
val greatPerson = greatPeople.getNewGreatPerson()
|
||||
|
|
|
@ -21,6 +21,11 @@ class TileInfo {
|
|||
var improvement: String? = null
|
||||
var improvementInProgress: String? = null
|
||||
var owner: String? = null // owning civ name
|
||||
get() {
|
||||
val containingCity = tileMap.gameInfo.civilizations.flatMap { it.cities }.firstOrNull{it.expansion.cityTiles.contains(position)}
|
||||
if(containingCity==null) return null
|
||||
return containingCity.civInfo.civName
|
||||
}
|
||||
var workingCity: String? = null // Working City name
|
||||
var roadStatus = RoadStatus.None
|
||||
var explored = false
|
||||
|
|
|
@ -17,7 +17,8 @@ class UnitMovementAlgorithms(val tileMap: TileMap){
|
|||
for (tileToCheck in tilesToCheck)
|
||||
for (maybeUpdatedTile in tileToCheck.neighbors) {
|
||||
if(maybeUpdatedTile.owner != null && maybeUpdatedTile.owner != civInfo.civName && maybeUpdatedTile.isCityCenter)
|
||||
continue
|
||||
continue // Enemy city, can't move through it!
|
||||
// if(maybeUpdatedTile.unit!=null && maybeUpdatedTile.unit!!.civInfo != civInfo) continue // Enemy unit!
|
||||
|
||||
var distanceBetweenTiles = maybeUpdatedTile.lastTerrain.movementCost.toFloat() // no road
|
||||
if (tileToCheck.roadStatus !== RoadStatus.None && maybeUpdatedTile.roadStatus !== RoadStatus.None) //Road
|
||||
|
@ -39,6 +40,11 @@ class UnitMovementAlgorithms(val tileMap: TileMap){
|
|||
|
||||
tilesToCheck = updatedTiles
|
||||
}
|
||||
|
||||
// now that we've used the tiles that have friendly units to "pass through" them,
|
||||
// we have to remove them from the final result since we can't actually get there.
|
||||
// distanceToTiles.filterKeys { it.unit!=null }.forEach { distanceToTiles.remove(it.key) }
|
||||
|
||||
return distanceToTiles
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class CityStatsTable(val cityScreen: CityScreen) : Table(){
|
|||
cityStatsValues["Gold"] = Math.round(stats.gold).toString() + ""
|
||||
cityStatsValues["Science"] = Math.round(stats.science).toString() + ""
|
||||
cityStatsValues["Culture"] = (Math.round(stats.culture).toString()
|
||||
+ " (" + city.expansion.cultureStored + "/" + city.expansion.cultureToNextTile + ")")
|
||||
+ " (" + city.expansion.cultureStored + "/" + city.expansion.getCultureToNextTile() + ")")
|
||||
cityStatsValues["Population"] = city.population.getFreePopulation().toString() + "/" + city.population.population
|
||||
|
||||
for (key in cityStatsValues.keys) {
|
||||
|
|
|
@ -57,50 +57,10 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||
return
|
||||
}
|
||||
|
||||
if(terrainFeatureImage==null && tileInfo.terrainFeature!=null){
|
||||
terrainFeatureImage = ImageGetter.getImage("TerrainIcons/${tileInfo.terrainFeature}.png")
|
||||
addActor(terrainFeatureImage)
|
||||
terrainFeatureImage!!.run {
|
||||
setSize(30f,30f)
|
||||
setColor(1f,1f,1f,0.5f)
|
||||
setPosition(this@TileGroup.width /2-width/2,
|
||||
this@TileGroup.height/2-height/2)
|
||||
}
|
||||
}
|
||||
|
||||
if(terrainFeatureImage!=null && tileInfo.terrainFeature==null){
|
||||
terrainFeatureImage!!.remove()
|
||||
terrainFeatureImage=null
|
||||
}
|
||||
|
||||
|
||||
val RGB= tileInfo.getBaseTerrain().RGB!!
|
||||
hexagon.color = Color(RGB[0]/255f,RGB[1]/255f,RGB[2]/255f,1f)
|
||||
if(!isViewable) hexagon.color = hexagon.color.lerp(Color.BLACK,0.6f)
|
||||
|
||||
|
||||
if (tileInfo.hasViewableResource(tileInfo.tileMap.gameInfo.getPlayerCivilization()) && resourceImage == null) { // Need to add the resource image!
|
||||
val fileName = "ResourceIcons/" + tileInfo.resource + "_(Civ5).png"
|
||||
resourceImage = ImageGetter.getImage(fileName)
|
||||
resourceImage!!.setSize(20f, 20f)
|
||||
resourceImage!!.setPosition(width/2 - resourceImage!!.width/2-20f,
|
||||
height/2 - resourceImage!!.height/2) // left
|
||||
addActor(resourceImage!!)
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (tileInfo.improvement != null && tileInfo.improvement != improvementType) {
|
||||
improvementImage = ImageGetter.getImage("ImprovementIcons/" + tileInfo.improvement!!.replace(' ', '_') + "_(Civ5).png")
|
||||
addActor(improvementImage)
|
||||
improvementImage!!.run {
|
||||
setSize(20f, 20f)
|
||||
|
||||
setPosition(this@TileGroup.width/2 - width/2+20f,
|
||||
this@TileGroup.height/2 - height/2) // right
|
||||
}
|
||||
improvementType = tileInfo.improvement
|
||||
}
|
||||
updateTerrainFeatureImage()
|
||||
updateTileColor(isViewable)
|
||||
updateResourceImage()
|
||||
updateImprovementImage()
|
||||
|
||||
if (populationImage != null) {
|
||||
if (tileInfo.workingCity != null)
|
||||
|
@ -109,6 +69,43 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||
populationImage!!.color = Color.GRAY
|
||||
}
|
||||
|
||||
updateRoadImages()
|
||||
updateBorderImages()
|
||||
}
|
||||
|
||||
private fun updateBorderImages() {
|
||||
for (border in borderImages) border.remove() //clear
|
||||
borderImages = arrayListOf()
|
||||
|
||||
if (tileInfo.owner != null) {
|
||||
for (neighbor in tileInfo.neighbors.filter { it.owner != tileInfo.owner }) {
|
||||
val image = ImageGetter.getImage(ImageGetter.WhiteDot)
|
||||
|
||||
val relativeHexPosition = tileInfo.position.cpy().sub(neighbor.position)
|
||||
val relativeWorldPosition = HexMath.Hex2WorldCoords(relativeHexPosition)
|
||||
|
||||
// This is some crazy voodoo magic so I'll explain.
|
||||
|
||||
image.setSize(35f, 2f)
|
||||
image.moveBy(width / 2 - image.width / 2, // center
|
||||
height / 2 - image.height / 2)
|
||||
// in addTiles, we set the position of groups by relative world position *0.8*groupSize, filter groupSize = 50
|
||||
// Here, we want to have the borders start HALFWAY THERE and extend towards the tiles, so we give them a position of 0.8*25.
|
||||
// BUT, we don't actually want it all the way out there, because we want to display the borders of 2 different civs!
|
||||
// So we set it to 0.75
|
||||
image.moveBy(-relativeWorldPosition.x * 0.75f * 25f, -relativeWorldPosition.y * 0.75f * 25f)
|
||||
|
||||
image.color = tileInfo.getOwner()!!.getCivilization().getColor()
|
||||
image.setOrigin(image.width / 2, image.height / 2) // This is so that the rotation is calculated from the middle of the road and not the edge
|
||||
image.rotation = (90 + 180 / Math.PI * Math.atan2(relativeWorldPosition.y.toDouble(), relativeWorldPosition.x.toDouble())).toFloat()
|
||||
addActor(image)
|
||||
borderImages.add(image)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateRoadImages() {
|
||||
if (tileInfo.roadStatus !== RoadStatus.None) {
|
||||
for (neighbor in tileInfo.neighbors) {
|
||||
if (neighbor.roadStatus === RoadStatus.None) continue
|
||||
|
@ -137,37 +134,54 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
|||
roadImages[neighbor.position.toString()]!!.color = Color.BROWN // road
|
||||
}
|
||||
}
|
||||
|
||||
// Borders
|
||||
if(tileInfo.owner!=null){
|
||||
for (border in borderImages) border.remove()
|
||||
for (neighbor in tileInfo.neighbors.filter { it.owner!=tileInfo.owner }){
|
||||
val image = ImageGetter.getImage(ImageGetter.WhiteDot)
|
||||
|
||||
val relativeHexPosition = tileInfo.position.cpy().sub(neighbor.position)
|
||||
val relativeWorldPosition = HexMath.Hex2WorldCoords(relativeHexPosition)
|
||||
|
||||
// This is some crazy voodoo magic so I'll explain.
|
||||
|
||||
image.setSize(35f, 2f)
|
||||
image.moveBy(width/2-image.width/2, // center
|
||||
height/2-image.height/2)
|
||||
// in addTiles, we set the position of groups by relative world position *0.8*groupSize, filter groupSize = 50
|
||||
// Here, we want to have the borders start HALFWAY THERE and extend towards the tiles, so we give them a position of 0.8*25.
|
||||
// BUT, we don't actually want it all the way out there, because we want to display the borders of 2 different civs!
|
||||
// So we set it to 0.75
|
||||
image.moveBy(-relativeWorldPosition.x * 0.75f * 25f, -relativeWorldPosition.y * 0.75f * 25f)
|
||||
|
||||
image.color = tileInfo.getOwner()!!.getCivilization().getColor()
|
||||
image.setOrigin(image.width/2, image.height/2) // This is so that the rotation is calculated from the middle of the road and not the edge
|
||||
image.rotation = (90 + 180 / Math.PI * Math.atan2(relativeWorldPosition.y.toDouble(), relativeWorldPosition.x.toDouble())).toFloat()
|
||||
addActor(image)
|
||||
borderImages.add(image)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
private fun updateTileColor(isViewable: Boolean) {
|
||||
val RGB = tileInfo.getBaseTerrain().RGB!!
|
||||
hexagon.color = Color(RGB[0] / 255f, RGB[1] / 255f, RGB[2] / 255f, 1f)
|
||||
if (!isViewable) hexagon.color = hexagon.color.lerp(Color.BLACK, 0.6f)
|
||||
}
|
||||
|
||||
private fun updateTerrainFeatureImage() {
|
||||
if (terrainFeatureImage == null && tileInfo.terrainFeature != null) {
|
||||
terrainFeatureImage = ImageGetter.getImage("TerrainIcons/${tileInfo.terrainFeature}.png")
|
||||
addActor(terrainFeatureImage)
|
||||
terrainFeatureImage!!.run {
|
||||
setSize(30f, 30f)
|
||||
setColor(1f, 1f, 1f, 0.5f)
|
||||
setPosition(this@TileGroup.width / 2 - width / 2,
|
||||
this@TileGroup.height / 2 - height / 2)
|
||||
}
|
||||
}
|
||||
|
||||
if (terrainFeatureImage != null && tileInfo.terrainFeature == null) {
|
||||
terrainFeatureImage!!.remove()
|
||||
terrainFeatureImage = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateImprovementImage() {
|
||||
if (tileInfo.improvement != null && tileInfo.improvement != improvementType) {
|
||||
improvementImage = ImageGetter.getImage("ImprovementIcons/" + tileInfo.improvement!!.replace(' ', '_') + "_(Civ5).png")
|
||||
addActor(improvementImage)
|
||||
improvementImage!!.run {
|
||||
setSize(20f, 20f)
|
||||
|
||||
setPosition(this@TileGroup.width / 2 - width / 2 + 20f,
|
||||
this@TileGroup.height / 2 - height / 2) // right
|
||||
}
|
||||
improvementType = tileInfo.improvement
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateResourceImage() {
|
||||
if (tileInfo.hasViewableResource(tileInfo.tileMap.gameInfo.getPlayerCivilization()) && resourceImage == null) { // Need to add the resource image!
|
||||
val fileName = "ResourceIcons/" + tileInfo.resource + "_(Civ5).png"
|
||||
resourceImage = ImageGetter.getImage(fileName)
|
||||
resourceImage!!.setSize(20f, 20f)
|
||||
resourceImage!!.setPosition(width / 2 - resourceImage!!.width / 2 - 20f,
|
||||
height / 2 - resourceImage!!.height / 2) // left
|
||||
addActor(resourceImage!!)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -108,21 +108,38 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
|||
row().pad(5f)
|
||||
val attackButton = TextButton("Attack", skin)
|
||||
|
||||
attackButton.addClickListener {
|
||||
if(attacker.getCombatantType() == CombatantType.Melee)
|
||||
attacker.unit.headTowards(defender.getTile().position)
|
||||
battle.attack(attacker,defender)
|
||||
worldScreen.update()
|
||||
val attackerDistanceToTiles = attacker.unit.getDistanceToTiles()
|
||||
|
||||
if(attacker.getCombatantType() == CombatantType.Melee){
|
||||
val tilesCanAttackFrom = attackerDistanceToTiles.filter {
|
||||
attacker.unit.currentMovement - it.value > 0 // once we reach it we'll still have energy to attack
|
||||
&& it.key.unit==null
|
||||
&& it.key.neighbors.contains(defender.getTile()) }
|
||||
|
||||
if(tilesCanAttackFrom.isEmpty()) attackButton.disable()
|
||||
else {
|
||||
val tileToMoveTo = tilesCanAttackFrom.minBy { it.value }!!.key // travel least distance
|
||||
attackButton.addClickListener {
|
||||
attacker.unit.moveToTile(tileToMoveTo)
|
||||
battle.attack(attacker,defender)
|
||||
worldScreen.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val attackerCanReachDefender:Boolean
|
||||
if (attacker.getCombatantType() == CombatantType.Ranged) {
|
||||
else { // ranged
|
||||
val tilesInRange = UnCivGame.Current.gameInfo.tileMap.getTilesInDistance(attacker.getTile().position, 2)
|
||||
attackerCanReachDefender = tilesInRange.contains(defender.getTile())
|
||||
val attackerCanReachDefender = tilesInRange.contains(defender.getTile())
|
||||
if(!attackerCanReachDefender) attackButton.disable()
|
||||
else {
|
||||
attackButton.addClickListener {
|
||||
battle.attack(attacker, defender)
|
||||
worldScreen.update()
|
||||
}
|
||||
}
|
||||
}
|
||||
else attackerCanReachDefender = attacker.unit.getDistanceToTiles().containsKey(defender.getTile())
|
||||
|
||||
if(attacker.unit.currentMovement==0f || !attackerCanReachDefender) attackButton.disable()
|
||||
if(attacker.unit.currentMovement==0f) attackButton.disable()
|
||||
add(attackButton).colspan(2)
|
||||
|
||||
pack()
|
||||
|
|
Loading…
Reference in a new issue