mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-09 10:29:02 +07:00
Massive change - Unit in TileInfo now spit to CivilianUnit and MilitaryUnit!
This commit is contained in:
parent
c50a919e2a
commit
f6ca98b1d7
@ -12,6 +12,7 @@ class GameStarter(){
|
||||
val gameInfo = GameInfo()
|
||||
|
||||
gameInfo.tileMap = TileMap(mapRadius)
|
||||
gameInfo.tileMap.gameInfo = gameInfo // need to set this transient before placing units in the map
|
||||
gameInfo.civilizations.add(CivilizationInfo(civilization, Vector2.Zero, gameInfo)) // first one is player civ
|
||||
|
||||
val freeTiles = gameInfo.tileMap.values.toMutableList()
|
||||
|
@ -57,7 +57,7 @@ class GameInfo {
|
||||
var tile = tileToPlace
|
||||
if(tileToPlace==null) {
|
||||
val playerViewableTiles = getPlayerCivilization().getViewableTiles().toHashSet()
|
||||
val viableTiles = tileMap.values.filterNot { playerViewableTiles.contains(it) || it.unit != null }
|
||||
val viableTiles = tileMap.values.filterNot { playerViewableTiles.contains(it) || it.militaryUnit != null || it.civilianUnit!=null}
|
||||
tile=viableTiles.getRandom()
|
||||
}
|
||||
tileMap.placeUnitNearTile(tile!!.position,"Warrior",getBarbarianCivilization())
|
||||
@ -72,8 +72,12 @@ class GameInfo {
|
||||
civInfo.setTransients()
|
||||
}
|
||||
|
||||
for (tile in tileMap.values.filter { it.unit!=null })
|
||||
tile.unit!!.civInfo = civilizations.first { it.civName == tile.unit!!.owner }
|
||||
val civNameToCiv = civilizations.associateBy ({ it.civName},{it})
|
||||
|
||||
for (tile in tileMap.values) {
|
||||
if (tile.militaryUnit != null) tile.militaryUnit!!.civInfo = civNameToCiv[tile.militaryUnit!!.owner]!!
|
||||
if (tile.civilianUnit!= null) tile.civilianUnit!!.civInfo = civNameToCiv[tile.civilianUnit!!.owner]!!
|
||||
}
|
||||
|
||||
|
||||
for (civInfo in civilizations)
|
||||
|
@ -68,7 +68,7 @@ class Automation {
|
||||
private fun trainCombatUnit(city: CityInfo) {
|
||||
val combatUnits = city.cityConstructions.getConstructableUnits().filter { it.unitType != UnitType.Civilian }
|
||||
val chosenUnit:Unit
|
||||
if(city.civInfo.cities.any { it.getCenterTile().unit==null}
|
||||
if(city.civInfo.cities.any { it.getCenterTile().militaryUnit==null}
|
||||
&& combatUnits.any { it.unitType==UnitType.Archery }) // this is for city defence so get an archery unit if we can
|
||||
chosenUnit = combatUnits.filter { it.unitType==UnitType.Archery }.maxBy { it.cost }!!
|
||||
|
||||
|
@ -1,15 +1,11 @@
|
||||
package com.unciv.logic.automation
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.UnitType
|
||||
import com.unciv.ui.utils.getRandom
|
||||
import com.unciv.ui.worldscreen.unit.UnitActions
|
||||
|
||||
@ -22,14 +18,14 @@ class UnitAutomation{
|
||||
val unitTile = unit.getTile()
|
||||
|
||||
// Go to friendly tile if within distance - better healing!
|
||||
val friendlyTile = tilesInDistance.firstOrNull { it.getOwner()?.civName == unit.owner && it.unit == null }
|
||||
val friendlyTile = tilesInDistance.firstOrNull { it.getOwner()?.civName == unit.owner && unit.canMoveTo(it) }
|
||||
if (unitTile.getOwner()?.civName != unit.owner && friendlyTile != null) {
|
||||
unit.moveToTile(friendlyTile)
|
||||
return
|
||||
}
|
||||
|
||||
// Or at least get out of enemy territory yaknow
|
||||
val neutralTile = tilesInDistance.firstOrNull { it.getOwner() == null && it.unit == null }
|
||||
val neutralTile = tilesInDistance.firstOrNull { it.getOwner() == null && unit.canMoveTo(it)}
|
||||
if (unitTile.getOwner()?.civName != unit.owner && unitTile.getOwner() != null && neutralTile != null) {
|
||||
unit.moveToTile(neutralTile)
|
||||
return
|
||||
@ -37,8 +33,9 @@ class UnitAutomation{
|
||||
}
|
||||
|
||||
fun containsAttackableEnemy(tile: TileInfo, civInfo: CivilizationInfo): Boolean {
|
||||
return (tile.unit != null && tile.unit!!.owner != civInfo.civName)
|
||||
|| (tile.isCityCenter() && tile.getCity()!!.civInfo!=civInfo)
|
||||
val tileCombatant = Battle().getMapCombatantOfTile(tile)
|
||||
if(tileCombatant==null) return false
|
||||
return tileCombatant.getCivilization()!=civInfo
|
||||
}
|
||||
|
||||
fun getAttackableEnemies(unit: MapUnit): List<TileInfo> {
|
||||
@ -53,7 +50,7 @@ class UnitAutomation{
|
||||
return attackableTiles.filter {
|
||||
it.neighbors.any {
|
||||
unit.getTile()==it || // We're already right nearby
|
||||
it.unit == null
|
||||
unit.canMoveTo(it)
|
||||
&& distanceToTiles.containsKey(it)
|
||||
&& distanceToTiles[it]!! < unit.currentMovement // We can get there
|
||||
}
|
||||
@ -89,23 +86,7 @@ class UnitAutomation{
|
||||
val enemyTileToAttack = getAttackableEnemies(unit).firstOrNull()
|
||||
|
||||
if (enemyTileToAttack != null) {
|
||||
|
||||
val enemy:ICombatant
|
||||
if(enemyTileToAttack.isCityCenter()){
|
||||
enemy = CityCombatant(enemyTileToAttack.getCity()!!)
|
||||
}
|
||||
|
||||
else {
|
||||
val unitToAttack = enemyTileToAttack.unit!!
|
||||
if (unitToAttack.getBaseUnit().unitType == UnitType.Civilian) { // kill
|
||||
unitToAttack.civInfo.addNotification("Our " + unitToAttack.name + " was destroyed by an enemy " + unit.name + "!", enemyTileToAttack.position, Color.RED)
|
||||
enemyTileToAttack.unit = null
|
||||
unit.movementAlgs().headTowards(enemyTileToAttack)
|
||||
return
|
||||
}
|
||||
enemy=MapUnitCombatant(unitToAttack)
|
||||
}
|
||||
|
||||
val enemy = Battle().getMapCombatantOfTile(enemyTileToAttack)!!
|
||||
val damageToAttacker = Battle(unit.civInfo.gameInfo).calculateDamageToAttacker(MapUnitCombatant(unit), enemy)
|
||||
|
||||
if (damageToAttacker < unit.health) { // don't attack if we'll die from the attack
|
||||
@ -118,7 +99,8 @@ class UnitAutomation{
|
||||
|
||||
if(unit.getTile().isCityCenter()) return // It's always good to have a unit in the city center, so if you havn't found annyonw aroud to attack, forget it.
|
||||
|
||||
val reachableCitiesWithoutUnits = unit.civInfo.cities.filter { it.getCenterTile().unit==null
|
||||
val reachableCitiesWithoutUnits = unit.civInfo.cities.filter {
|
||||
unit.canMoveTo(it.getCenterTile())
|
||||
&& unit.movementAlgs().canReach(it.getCenterTile()) }
|
||||
if(reachableCitiesWithoutUnits.isNotEmpty()){
|
||||
val closestCityWithoutUnit = reachableCitiesWithoutUnits
|
||||
@ -153,7 +135,7 @@ class UnitAutomation{
|
||||
|
||||
// else, go to a random space
|
||||
val reachableTiles = unit.getDistanceToTiles()
|
||||
.filter { it.key.unit == null} // at edge of walking distance
|
||||
.filter { unit.canMoveTo(it.key)}
|
||||
val reachableTilesMaxWalkingDistance = reachableTiles.filter { it.value==unit.currentMovement}
|
||||
if(reachableTilesMaxWalkingDistance.any()) unit.moveToTile(reachableTilesMaxWalkingDistance.toList().getRandom().first)
|
||||
else if(reachableTiles.any()) unit.moveToTile(reachableTiles.toList().getRandom().first)
|
||||
@ -184,7 +166,7 @@ class UnitAutomation{
|
||||
if(possibleTiles.isEmpty()) // We got a badass over here, all tiles within 5 are taken? Screw it, random walk.
|
||||
{
|
||||
unit.moveToTile(unit.getDistanceToTiles()
|
||||
.filter { it.key.unit == null && it.value==unit.currentMovement } // at edge of walking distance
|
||||
.filter { unit.canMoveTo(it.key) && it.value==unit.currentMovement } // at edge of walking distance
|
||||
.toList().getRandom().first)
|
||||
return
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ class WorkerAutomation {
|
||||
|
||||
fun automateWorkerAction(unit: MapUnit) {
|
||||
val enemyUnitsInWalkingDistance = unit.getDistanceToTiles().keys
|
||||
.filter { it.unit!=null && it.unit!!.civInfo!=unit.civInfo }
|
||||
.filter { it.militaryUnit!=null && it.militaryUnit!!.civInfo!=unit.civInfo }
|
||||
|
||||
if(enemyUnitsInWalkingDistance.isNotEmpty()) return // Don't you dare move.
|
||||
|
||||
@ -33,7 +33,7 @@ class WorkerAutomation {
|
||||
val currentTile=worker.getTile()
|
||||
val workableTiles = currentTile.getTilesInDistance(4)
|
||||
.filter {
|
||||
(it.unit == null || it == currentTile)
|
||||
(it.civilianUnit== null || it == currentTile)
|
||||
&& it.improvement == null
|
||||
&& it.canBuildImprovement(chooseImprovement(it), worker.civInfo)
|
||||
&& {val city=it.getCity(); city==null || it.getCity()?.civInfo == worker.civInfo}() // don't work tiles belonging to another civ
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.unciv.logic.battle
|
||||
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.TileInfo
|
||||
@ -12,7 +13,7 @@ import kotlin.math.max
|
||||
/**
|
||||
* Damage calculations according to civ v wiki and https://steamcommunity.com/sharedfiles/filedetails/?id=170194443
|
||||
*/
|
||||
class Battle(val gameInfo:GameInfo) {
|
||||
class Battle(val gameInfo:GameInfo=UnCivGame.Current.gameInfo) {
|
||||
|
||||
private fun getGeneralModifiers(combatant: ICombatant, enemy: ICombatant): HashMap<String, Float> {
|
||||
val modifiers = HashMap<String, Float>()
|
||||
@ -47,9 +48,9 @@ class Battle(val gameInfo:GameInfo) {
|
||||
val modifiers = getGeneralModifiers(attacker, defender)
|
||||
if (attacker.isMelee()) {
|
||||
val numberOfAttackersSurroundingDefender = defender.getTile().neighbors.count {
|
||||
it.unit != null
|
||||
&& it.unit!!.owner == attacker.getCivilization().civName
|
||||
&& MapUnitCombatant(it.unit!!).isMelee()
|
||||
it.militaryUnit != null
|
||||
&& it.militaryUnit!!.owner == attacker.getCivilization().civName
|
||||
&& MapUnitCombatant(it.militaryUnit!!).isMelee()
|
||||
}
|
||||
if (numberOfAttackersSurroundingDefender > 1)
|
||||
modifiers["Flanking"] = 0.1f * (numberOfAttackersSurroundingDefender-1) //https://www.carlsguides.com/strategy/civilization5/war/combatbonuses.php
|
||||
@ -101,6 +102,7 @@ class Battle(val gameInfo:GameInfo) {
|
||||
|
||||
fun calculateDamageToAttacker(attacker: ICombatant, defender: ICombatant): Int {
|
||||
if(attacker.isRanged()) return 0
|
||||
if(defender.getUnitType()==UnitType.Civilian) return 0
|
||||
val ratio = getDefendingStrength(attacker,defender) / getAttackingStrength(attacker,defender)
|
||||
return (ratio * 30 * getHealthDependantDamageRatio(defender)).toInt()
|
||||
}
|
||||
@ -180,7 +182,11 @@ class Battle(val gameInfo:GameInfo) {
|
||||
attacker.getCivilization().cities.add(city)
|
||||
city.civInfo = attacker.getCivilization()
|
||||
city.health = city.getMaxHealth() / 2 // I think that cities recover to half health?
|
||||
city.getCenterTile().unit = null
|
||||
city.getCenterTile().apply {
|
||||
militaryUnit = null
|
||||
civilianUnit=null
|
||||
}
|
||||
|
||||
city.expansion.cultureStored = 0
|
||||
city.expansion.reset()
|
||||
|
||||
@ -201,4 +207,11 @@ class Battle(val gameInfo:GameInfo) {
|
||||
(attacker as MapUnitCombatant).unit.moveToTile(city.getCenterTile())
|
||||
city.civInfo.gameInfo.updateTilesToCities()
|
||||
}
|
||||
|
||||
fun getMapCombatantOfTile(tile:TileInfo): ICombatant? {
|
||||
if(tile.isCityCenter()) return CityCombatant(tile.getCity()!!)
|
||||
if(tile.militaryUnit!=null) return MapUnitCombatant(tile.militaryUnit!!)
|
||||
if(tile.civilianUnit!=null) return MapUnitCombatant(tile.civilianUnit!!)
|
||||
return null
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ class MapUnitCombatant(val unit: MapUnit) : ICombatant {
|
||||
|
||||
override fun takeDamage(damage: Int) {
|
||||
unit.health -= damage
|
||||
if(isDefeated()) unit.getTile().unit=null
|
||||
if(isDefeated()) unit.removeFromTile()
|
||||
}
|
||||
|
||||
override fun getAttackingStrength(defender: ICombatant): Int {
|
||||
|
@ -174,16 +174,15 @@ class CivilizationInfo {
|
||||
}
|
||||
|
||||
fun getCivUnits(): List<MapUnit> {
|
||||
return gameInfo.tileMap.values.filter { it.unit!=null && it.unit!!.owner==civName }.map { it.unit!! }
|
||||
return gameInfo.tileMap.values.flatMap { it.getUnits() }.filter { it.civInfo==this }
|
||||
}
|
||||
|
||||
fun getViewableTiles(): List<TileInfo> {
|
||||
var viewablePositions = emptyList<TileInfo>()
|
||||
viewablePositions += cities.flatMap { it.getTiles() }
|
||||
.flatMap { it.neighbors } // tiles adjacent to city tiles
|
||||
viewablePositions += gameInfo.tileMap.values
|
||||
.filter { it.unit != null && it.unit!!.owner == civName }
|
||||
.flatMap { it.getViewableTiles(it.unit!!.getVisibilityRange())} // Tiles within 2 tiles of units
|
||||
viewablePositions += getCivUnits()
|
||||
.flatMap { it.getViewableTiles()} // Tiles within 2 tiles of units
|
||||
viewablePositions.map { it.position }.filterNot { exploredTiles.contains(it) }.toCollection(exploredTiles)
|
||||
return viewablePositions
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ class MapUnit {
|
||||
fun getBaseUnit(): Unit = GameBasics.Units[name]!!
|
||||
fun getMovementString(): String = DecimalFormat("0.#").format(currentMovement.toDouble()) + "/" + maxMovement
|
||||
fun getTile(): TileInfo {
|
||||
return civInfo.gameInfo.tileMap.values.first{it.unit==this}
|
||||
return civInfo.gameInfo.tileMap.values.first{it.militaryUnit==this || it.civilianUnit==this}
|
||||
}
|
||||
|
||||
fun getDistanceToTiles(): HashMap<TileInfo, Float> {
|
||||
@ -34,7 +34,7 @@ class MapUnit {
|
||||
if (currentMovement == 0f) return // We've already done stuff this turn, and can't do any more stuff
|
||||
|
||||
val enemyUnitsInWalkingDistance = getDistanceToTiles().keys
|
||||
.filter { it.unit!=null && it.unit!!.civInfo!=civInfo }
|
||||
.filter { it.militaryUnit!=null && it.militaryUnit!!.civInfo!=civInfo }
|
||||
if(enemyUnitsInWalkingDistance.isNotEmpty()) return // Don't you dare move.
|
||||
|
||||
if (action != null && action!!.startsWith("moveTo")) {
|
||||
@ -88,23 +88,17 @@ class MapUnit {
|
||||
if(health>100) health=100
|
||||
}
|
||||
|
||||
fun canMove(tile: TileInfo): Boolean {
|
||||
if(tile.unit!=null) return false
|
||||
if(tile.isCityCenter() && tile.getOwner()!=civInfo) return false
|
||||
return true
|
||||
}
|
||||
|
||||
fun moveToTile(otherTile: TileInfo) {
|
||||
val distanceToTiles = getDistanceToTiles()
|
||||
if (!distanceToTiles.containsKey(otherTile))
|
||||
throw Exception("You can't get there from here!")
|
||||
if (otherTile.unit != null ) throw Exception("Tile already contains a unit!")
|
||||
if(!canMoveTo(otherTile)) throw Exception("Can't enter this tile!")
|
||||
if(otherTile.isCityCenter() && otherTile.getOwner()!=civInfo) throw Exception("This is an enemy city, you can't go here!")
|
||||
|
||||
currentMovement -= distanceToTiles[otherTile]!!
|
||||
if (currentMovement < 0.1) currentMovement = 0f // silly floats which are "almost zero"
|
||||
getTile().unit = null
|
||||
otherTile.unit = this
|
||||
removeFromTile()
|
||||
putInTile(otherTile)
|
||||
}
|
||||
|
||||
fun endTurn() {
|
||||
@ -130,10 +124,10 @@ class MapUnit {
|
||||
return "$name - $owner"
|
||||
}
|
||||
|
||||
fun getVisibilityRange(): Int {
|
||||
fun getViewableTiles(): MutableList<TileInfo> {
|
||||
var visibilityRange = 2
|
||||
if(hasUnique("Limited Visibility")) visibilityRange-=1
|
||||
return visibilityRange
|
||||
return getTile().getViewableTiles(visibilityRange)
|
||||
}
|
||||
|
||||
fun isFortified(): Boolean {
|
||||
@ -144,4 +138,33 @@ class MapUnit {
|
||||
if(!isFortified()) return 0
|
||||
return action!!.split(" ")[1].toInt()
|
||||
}
|
||||
|
||||
fun removeFromTile(){
|
||||
if (getBaseUnit().unitType==UnitType.Civilian) getTile().civilianUnit=null
|
||||
else getTile().militaryUnit=null
|
||||
}
|
||||
|
||||
fun putInTile(tile:TileInfo){
|
||||
if(!canMoveTo(tile)) throw Exception("I can't go there!")
|
||||
if(getBaseUnit().unitType==UnitType.Civilian)
|
||||
tile.civilianUnit=this
|
||||
else tile.militaryUnit=this
|
||||
}
|
||||
|
||||
/**
|
||||
* Designates whether we can walk to the tile - without attacking
|
||||
*/
|
||||
fun canMoveTo(tile: TileInfo): Boolean {
|
||||
if(tile.isCityCenter() && tile.getOwner()!!.civName!=owner) return false
|
||||
if (getBaseUnit().unitType==UnitType.Civilian)
|
||||
return tile.civilianUnit==null && (tile.militaryUnit==null || tile.militaryUnit!!.owner==owner)
|
||||
else return tile.militaryUnit==null
|
||||
}
|
||||
|
||||
fun isIdle(): Boolean {
|
||||
if (currentMovement == 0f) return false
|
||||
if (name == "Worker" && getTile().improvementInProgress != null) return false
|
||||
if (isFortified()) return false
|
||||
return true
|
||||
}
|
||||
}
|
@ -10,10 +10,14 @@ import com.unciv.models.gamebasics.TileImprovement
|
||||
import com.unciv.models.gamebasics.TileResource
|
||||
import com.unciv.models.stats.Stats
|
||||
|
||||
class TileInfo {
|
||||
open class TileInfo {
|
||||
@Transient lateinit var tileMap: TileMap
|
||||
|
||||
var unit: MapUnit? = null
|
||||
var unit:MapUnit?=null
|
||||
var militaryUnit:MapUnit?=null
|
||||
var civilianUnit:MapUnit?=null
|
||||
fun getUnits()= listOf(militaryUnit,civilianUnit).filterNotNull()
|
||||
|
||||
var position: Vector2 = Vector2.Zero
|
||||
var baseTerrain: String? = null
|
||||
var terrainFeature: String? = null
|
||||
@ -153,10 +157,12 @@ class TileInfo {
|
||||
if (roadStatus !== RoadStatus.None && !isCityCenter()) SB.appendln(roadStatus)
|
||||
if (improvement != null) SB.appendln(improvement!!)
|
||||
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 && unit!!.health<100) unitString += "(" + unit!!.health + ")"
|
||||
SB.appendln(unitString)
|
||||
val isViewableToPlayer = UnCivGame.Current.gameInfo.getPlayerCivilization().getViewableTiles().contains(this)
|
||||
if (civilianUnit != null && isViewableToPlayer) SB.appendln(civilianUnit!!.name)
|
||||
if(militaryUnit!=null && isViewableToPlayer){
|
||||
var milUnitString = militaryUnit!!.name
|
||||
if(militaryUnit!!.health<100) milUnitString += "(" + militaryUnit!!.health + ")"
|
||||
SB.appendln(milUnitString)
|
||||
}
|
||||
return SB.toString().trim()
|
||||
}
|
||||
@ -166,11 +172,7 @@ class TileInfo {
|
||||
}
|
||||
|
||||
fun hasIdleUnit(): Boolean {
|
||||
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
|
||||
return getUnits().any{it.isIdle()}
|
||||
}
|
||||
|
||||
fun getViewableTiles(distance:Int): MutableList<TileInfo> {
|
||||
@ -191,5 +193,4 @@ class TileInfo {
|
||||
val city = getCity()
|
||||
return city!=null && city.workedTiles.contains(position)
|
||||
}
|
||||
|
||||
}
|
@ -47,8 +47,8 @@ class TileMap {
|
||||
unit.owner = civInfo.civName
|
||||
unit.civInfo = civInfo
|
||||
val tilesInDistance = getTilesInDistance(position, 2)
|
||||
val unitToPlaceTile = tilesInDistance.firstOrNull { it.unit == null }
|
||||
if(unitToPlaceTile!=null) unitToPlaceTile.unit = unit // And if there's none, then kill me.
|
||||
val unitToPlaceTile = tilesInDistance.firstOrNull { unit.canMoveTo(it) }
|
||||
if(unitToPlaceTile!=null) unit.putInTile(unitToPlaceTile)
|
||||
return unit
|
||||
}
|
||||
|
||||
@ -65,7 +65,13 @@ class TileMap {
|
||||
}
|
||||
|
||||
fun setTransients() {
|
||||
for (tileInfo in values) tileInfo.tileMap = this
|
||||
for (tileInfo in values){
|
||||
tileInfo.tileMap = this
|
||||
if(tileInfo.unit!=null){
|
||||
tileInfo.unit!!.putInTile(tileInfo)
|
||||
tileInfo.unit=null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -37,7 +37,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
|
||||
var totalDistanceToTile:Float
|
||||
if ((neighbor.getOwner() != unit.civInfo && neighbor.isCityCenter())// Enemy city,
|
||||
|| neighbor.unit!=null && neighbor.unit!!.civInfo!=unit.civInfo) // Enemy unit
|
||||
|| neighbor.getUnits().isNotEmpty() && neighbor.getUnits().first().civInfo!=unit.civInfo) // Enemy unit
|
||||
totalDistanceToTile = unitMovement // can't move through it - we'll be "stuck" there
|
||||
|
||||
else {
|
||||
@ -80,7 +80,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
distanceToDestination[tileToCheck] = distanceToTilesThisTurn[reachableTile]!!
|
||||
else {
|
||||
if (movementTreeParents.containsKey(reachableTile)) continue // We cannot be faster than anything existing...
|
||||
if (!unit.canMove(reachableTile)) continue // This is a tile that we can''t actually enter - either an intermediary tile containing our unit, or an enemy unit/city
|
||||
if (!unit.canMoveTo(reachableTile)) continue // This is a tile that we can''t actually enter - either an intermediary tile containing our unit, or an enemy unit/city
|
||||
movementTreeParents[reachableTile] = tileToCheck
|
||||
newTilesToCheck.add(reachableTile)
|
||||
}
|
||||
@ -121,7 +121,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
|
||||
val destinationTileThisTurn: TileInfo
|
||||
if (distanceToTiles.containsKey(destination)) { // we can get there this turn
|
||||
if (unit.canMove(destination))
|
||||
if (unit.canMoveTo(destination))
|
||||
destinationTileThisTurn = destination
|
||||
else // Someone is blocking to the path to the final tile...
|
||||
{
|
||||
@ -130,7 +130,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
return currentTile
|
||||
|
||||
val reachableDestinationNeighbors = destinationNeighbors
|
||||
.filter { distanceToTiles.containsKey(it) && unit.canMove(it)}
|
||||
.filter { distanceToTiles.containsKey(it) && unit.canMoveTo(it)}
|
||||
if (reachableDestinationNeighbors.isEmpty()) // We can't get closer...
|
||||
return currentTile
|
||||
|
||||
|
@ -6,7 +6,6 @@ import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.ui.tilegroups.TileGroup
|
||||
import com.unciv.ui.utils.ImageGetter
|
||||
import com.unciv.ui.utils.center
|
||||
import com.unciv.ui.utils.centerX
|
||||
|
||||
class CityTileGroup(private val city: CityInfo, tileInfo: TileInfo) : TileGroup(tileInfo) {
|
||||
@ -25,12 +24,6 @@ class CityTileGroup(private val city: CityInfo, tileInfo: TileInfo) : TileGroup(
|
||||
fun update() {
|
||||
super.update(true)
|
||||
|
||||
updateUnitImage(true)
|
||||
if(unitImage!=null) {
|
||||
unitImage!!.center(this)
|
||||
unitImage!!.y += 20 // top
|
||||
}
|
||||
|
||||
updatePopulationImage()
|
||||
if (improvementImage != null) improvementImage!!.setColor(1f, 1f, 1f, 0.5f)
|
||||
if (resourceImage != null) resourceImage!!.setColor(1f, 1f, 1f, 0.5f)
|
||||
|
@ -29,7 +29,8 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
var populationImage: Image? = null
|
||||
private val roadImages = HashMap<String, Image>()
|
||||
private val borderImages = ArrayList<Image>()
|
||||
protected var unitImage: Group? = null
|
||||
protected var civilianUnitImage: Group? = null
|
||||
protected var militaryUnitImage: Group? = null
|
||||
private val circleImage = ImageGetter.getImage("OtherIcons/Circle.png") // for blue and red circles on the tile
|
||||
private val fogImage = ImageGetter.getImage("TerrainIcons/Fog.png")
|
||||
|
||||
@ -71,8 +72,8 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
populationImage!!.run {
|
||||
setSize(20f, 20f)
|
||||
center(this@TileGroup)
|
||||
y -= 20
|
||||
} // top left
|
||||
x += 20 // right
|
||||
}
|
||||
addActor(populationImage)
|
||||
}
|
||||
|
||||
@ -96,6 +97,9 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
updateResourceImage(isViewable)
|
||||
updateImprovementImage(isViewable)
|
||||
|
||||
civilianUnitImage = newUnitImage(tileInfo.civilianUnit,civilianUnitImage,isViewable,-20f)
|
||||
militaryUnitImage = newUnitImage(tileInfo.militaryUnit,militaryUnitImage,isViewable,20f)
|
||||
|
||||
updateRoadImages()
|
||||
updateBorderImages()
|
||||
|
||||
@ -202,7 +206,8 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
improvementImage!!.run {
|
||||
setSize(20f, 20f)
|
||||
center(this@TileGroup)
|
||||
this.x+=20 // right
|
||||
this.x -= 22 // left
|
||||
this.y -= 10 // bottom
|
||||
}
|
||||
improvementType = tileInfo.improvement
|
||||
}
|
||||
@ -218,7 +223,8 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
resourceImage = ImageGetter.getImage(fileName)
|
||||
resourceImage!!.setSize(20f, 20f)
|
||||
resourceImage!!.center(this)
|
||||
resourceImage!!.x -= 20 // left
|
||||
resourceImage!!.x -= 22 // left
|
||||
resourceImage!!.y += 10 // top
|
||||
addActor(resourceImage!!)
|
||||
}
|
||||
if(resourceImage!=null){
|
||||
@ -228,41 +234,35 @@ open class TileGroup(var tileInfo: TileInfo) : Group() {
|
||||
}
|
||||
|
||||
|
||||
protected fun updateUnitImage(isViewable: Boolean) {
|
||||
if (unitImage != null) { // The unit can change within one update - for instance, when attacking, the attacker replaces the defender!
|
||||
unitImage!!.remove()
|
||||
unitImage = null
|
||||
protected fun newUnitImage(unit:MapUnit?, currentImage:Group?, isViewable: Boolean, yFromCenter:Float): Group? {
|
||||
var newImage:Group? = null
|
||||
if (currentImage!= null) { // The unit can change within one update - for instance, when attacking, the attacker replaces the defender!
|
||||
currentImage.remove()
|
||||
}
|
||||
|
||||
if (tileInfo.unit != null && (isViewable || viewEntireMapForDebug)) { // Tile is visible
|
||||
val unit = tileInfo.unit!!
|
||||
unitImage = getUnitImage(unit, unit.civInfo.getCivilization().getColor())
|
||||
addActor(unitImage!!)
|
||||
unitImage!!.setSize(20f, 20f)
|
||||
}
|
||||
|
||||
|
||||
if (unitImage != null) {
|
||||
if (!tileInfo.hasIdleUnit())
|
||||
unitImage!!.color = Color(1f, 1f, 1f, 0.5f)
|
||||
else
|
||||
unitImage!!.color = Color.WHITE
|
||||
if (unit != null && (isViewable || viewEntireMapForDebug)) { // Tile is visible
|
||||
newImage = getUnitImage(unit, unit.civInfo.getCivilization().getColor(), 25f)
|
||||
addActor(newImage)
|
||||
newImage.center(this)
|
||||
newImage.y+=yFromCenter
|
||||
if(!unit.isIdle()) newImage.color = Color(1f, 1f, 1f, 0.5f)
|
||||
}
|
||||
return newImage
|
||||
}
|
||||
|
||||
|
||||
private fun getUnitImage(unit: MapUnit, color:Color): Group {
|
||||
private fun getUnitImage(unit: MapUnit, color: Color, size: Float): Group {
|
||||
val unitBaseImage = ImageGetter.getUnitIcon(unit.name)
|
||||
.apply { setSize(15f,15f) }
|
||||
.apply { setSize(20f,20f) }
|
||||
|
||||
val background = if(unit.isFortified()) ImageGetter.getImage("OtherIcons/Shield.png")
|
||||
else ImageGetter.getImage("OtherIcons/Circle.png")
|
||||
background.apply {
|
||||
this.color = color
|
||||
setSize(20f,20f)
|
||||
setSize(size,size)
|
||||
}
|
||||
val group = Group().apply {
|
||||
setSize(background.width,background.height)
|
||||
setSize(size,size)
|
||||
addActor(background)
|
||||
}
|
||||
unitBaseImage.center(group)
|
||||
|
@ -7,7 +7,9 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.UnCivGame
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.map.UnitType
|
||||
import com.unciv.ui.cityscreen.CityScreen
|
||||
import com.unciv.ui.cityscreen.addClickListener
|
||||
import com.unciv.ui.utils.CameraStageBaseScreen
|
||||
@ -19,33 +21,28 @@ import com.unciv.ui.utils.setFontColor
|
||||
class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) {
|
||||
var cityButton: Table? = null
|
||||
|
||||
fun addWhiteHaloAroundUnit(){
|
||||
val whiteHalo = if(tileInfo.unit!!.isFortified()) ImageGetter.getImage("OtherIcons/Shield.png")
|
||||
fun addWhiteHaloAroundUnit(unit: MapUnit) {
|
||||
val whiteHalo = if(unit.isFortified()) ImageGetter.getImage("OtherIcons/Shield.png")
|
||||
else ImageGetter.getImage("OtherIcons/Circle.png")
|
||||
whiteHalo.setSize(25f,25f)
|
||||
whiteHalo.center(unitImage!!)
|
||||
unitImage!!.addActor(whiteHalo)
|
||||
whiteHalo.setSize(30f,30f)
|
||||
val unitImage = if(unit.getBaseUnit().unitType==UnitType.Civilian) civilianUnitImage!!
|
||||
else militaryUnitImage!!
|
||||
whiteHalo.center(unitImage)
|
||||
unitImage.addActor(whiteHalo)
|
||||
whiteHalo.toBack()
|
||||
}
|
||||
|
||||
|
||||
override fun update(isViewable: Boolean) {
|
||||
super.update(isViewable)
|
||||
if (!tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)
|
||||
&& !viewEntireMapForDebug) return
|
||||
|
||||
if (populationImage != null) removePopulationIcon()
|
||||
|
||||
val city = tileInfo.getCity()
|
||||
if (tileInfo.isWorked() && city!!.civInfo.isPlayerCivilization() && populationImage == null)
|
||||
if (isViewable && tileInfo.isWorked() && city!!.civInfo.isPlayerCivilization() && populationImage == null)
|
||||
addPopulationIcon()
|
||||
|
||||
updateCityButton(city)
|
||||
updateUnitImage(isViewable)
|
||||
if(unitImage!=null) {
|
||||
unitImage!!.center(this)
|
||||
unitImage!!.y += 20 // top
|
||||
}
|
||||
if (tileInfo.tileMap.gameInfo.getPlayerCivilization().exploredTiles.contains(tileInfo.position)
|
||||
|| viewEntireMapForDebug) updateCityButton(city) // needs to be before the update so the units will be above the city button
|
||||
|
||||
super.update(isViewable)
|
||||
}
|
||||
|
||||
private fun updateCityButton(city: CityInfo?) {
|
||||
|
@ -5,7 +5,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||
import com.unciv.logic.automation.UnitAutomation
|
||||
import com.unciv.logic.battle.Battle
|
||||
import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.battle.ICombatant
|
||||
import com.unciv.logic.battle.MapUnitCombatant
|
||||
import com.unciv.logic.map.UnitType
|
||||
@ -42,15 +41,11 @@ class BattleTable(val worldScreen: WorldScreen): Table() {
|
||||
|
||||
if (worldScreen.tileMapHolder.selectedTile == null) return
|
||||
val selectedTile = worldScreen.tileMapHolder.selectedTile!!
|
||||
val defender: ICombatant
|
||||
if (attacker.getCivilization().exploredTiles.contains(selectedTile.position)
|
||||
&& selectedTile.isCityCenter() && selectedTile.getOwner() != worldScreen.civInfo)
|
||||
defender = CityCombatant(selectedTile.getCity()!!)
|
||||
else if (selectedTile.unit != null
|
||||
&& selectedTile.unit!!.owner != worldScreen.civInfo.civName // enemy unit on selected tile,
|
||||
&& worldScreen.civInfo.getViewableTiles().contains(selectedTile))
|
||||
defender = MapUnitCombatant(selectedTile.unit!!)
|
||||
else {
|
||||
|
||||
val defender: ICombatant? = Battle().getMapCombatantOfTile(selectedTile)
|
||||
|
||||
if(defender==null || defender.getCivilization()==worldScreen.civInfo
|
||||
|| !attacker.getCivilization().exploredTiles.contains(selectedTile.position)) {
|
||||
hide()
|
||||
return
|
||||
}
|
||||
|
@ -93,20 +93,26 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
|
||||
if(worldScreen.bottomBar.unitTable.selectedUnit!=null){
|
||||
val unit = worldScreen.bottomBar.unitTable.selectedUnit!!
|
||||
tileGroups[unit.getTile()]!!.addWhiteHaloAroundUnit()
|
||||
|
||||
tileGroups[unit.getTile()]!!.addWhiteHaloAroundUnit(unit)
|
||||
|
||||
for(tile: TileInfo in unit.getDistanceToTiles().keys)
|
||||
tileGroups[tile]!!.showCircle(colorFromRGB(0, 120, 215))
|
||||
|
||||
val attackableTiles: List<TileInfo> = when(unit.getBaseUnit().unitType){
|
||||
UnitType.Civilian -> listOf()
|
||||
UnitType.Civilian -> unit.getDistanceToTiles().keys.toList()
|
||||
UnitType.Melee, UnitType.Mounted -> unit.getDistanceToTiles().keys.toList()
|
||||
UnitType.Archery, UnitType.Siege -> unit.getTile().getTilesInDistance(2)
|
||||
UnitType.City -> throw Exception("A unit shouldn't have a City unittype!")
|
||||
}
|
||||
|
||||
for(tile: TileInfo in unit.getDistanceToTiles().keys)
|
||||
tileGroups[tile]!!.showCircle(colorFromRGB(0, 120, 215))
|
||||
|
||||
for (tile in attackableTiles.filter { it.unit!=null && it.unit!!.owner != unit.owner && civViewableTiles.contains(it)})
|
||||
tileGroups[tile]!!.showCircle(colorFromRGB(237, 41, 57))
|
||||
for (tile in attackableTiles.filter {
|
||||
it.getUnits().isNotEmpty()
|
||||
&& it.getUnits().first().owner != unit.owner
|
||||
&& civViewableTiles.contains(it)}) {
|
||||
if(unit.getBaseUnit().unitType==UnitType.Civilian) tileGroups[tile]!!.hideCircle()
|
||||
else tileGroups[tile]!!.showCircle(colorFromRGB(237, 41, 57))
|
||||
}
|
||||
}
|
||||
|
||||
if(selectedTile!=null)
|
||||
|
@ -13,7 +13,7 @@ class IdleUnitButton internal constructor(internal val unitTable: UnitTable,
|
||||
: TextButton(if(previous)"<" else ">", CameraStageBaseScreen.skin) {
|
||||
|
||||
fun getTilesWithIdleUnits() = tileMapHolder.tileMap.values
|
||||
.filter { it.hasIdleUnit() && it.unit!!.owner == unitTable.worldScreen.civInfo.civName }
|
||||
.filter { it.hasIdleUnit() && it.getUnits().first().owner == unitTable.worldScreen.civInfo.civName }
|
||||
init {
|
||||
addClickListener {
|
||||
val tilesWithIdleUnits = getTilesWithIdleUnits()
|
||||
|
@ -2,7 +2,6 @@ package com.unciv.ui.worldscreen.unit
|
||||
|
||||
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
|
||||
@ -15,10 +14,10 @@ class UnitAction(var name: String, var action:()->Unit, var canAct:Boolean)
|
||||
|
||||
class UnitActions {
|
||||
|
||||
private fun constructImprovementAndDestroyUnit(tileInfo: TileInfo, improvementName: String): () -> Unit {
|
||||
private fun constructImprovementAndDestroyUnit(unit:MapUnit, improvementName: String): () -> Unit {
|
||||
return {
|
||||
tileInfo.improvement = improvementName
|
||||
tileInfo.unit = null// destroy!
|
||||
unit.getTile().improvement = improvementName
|
||||
unit.removeFromTile()
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +55,7 @@ class UnitActions {
|
||||
{
|
||||
unit.civInfo.gold -= goldCostOfUpgrade
|
||||
val unitTile = unit.getTile()
|
||||
unitTile.unit = null
|
||||
unit.removeFromTile()
|
||||
val newunit = unit.civInfo.placeUnitNearTile(unitTile.position, upgradedUnit.name)
|
||||
newunit.health = unit.health
|
||||
newunit.currentMovement=0f
|
||||
@ -74,7 +73,7 @@ class UnitActions {
|
||||
unit.civInfo.addCity(tile.position)
|
||||
tile.improvement=null
|
||||
unitTable.currentlyExecutingAction = null // In case the settler was in the middle of doing something and we then founded a city with it
|
||||
tile.unit = null // Remove settler!
|
||||
unit.removeFromTile()
|
||||
},
|
||||
unit.currentMovement != 0f &&
|
||||
!tile.getTilesInDistance(2).any { it.isCityCenter() })
|
||||
@ -94,8 +93,8 @@ class UnitActions {
|
||||
else {
|
||||
actionList += UnitAction("Automate",
|
||||
{
|
||||
tile.unit!!.action = "automation"
|
||||
WorkerAutomation().automateWorkerAction(tile.unit!!)
|
||||
unit.action = "automation"
|
||||
WorkerAutomation().automateWorkerAction(unit)
|
||||
},unit.currentMovement != 0f
|
||||
)
|
||||
}
|
||||
@ -105,30 +104,30 @@ class UnitActions {
|
||||
actionList += UnitAction( "Discover Technology",
|
||||
{
|
||||
unit.civInfo.tech.freeTechs += 1
|
||||
tile.unit = null// destroy!
|
||||
unit.removeFromTile()
|
||||
worldScreen.game.screen = TechPickerScreen(true, unit.civInfo)
|
||||
|
||||
},unit.currentMovement != 0f)
|
||||
actionList += UnitAction("Construct Academy",
|
||||
constructImprovementAndDestroyUnit(tile, "Academy"),unit.currentMovement != 0f)
|
||||
constructImprovementAndDestroyUnit(unit, "Academy"),unit.currentMovement != 0f)
|
||||
}
|
||||
|
||||
if (unit.name == "Great Artist") {
|
||||
actionList += UnitAction( "Start Golden Age",
|
||||
{
|
||||
unit.civInfo.goldenAges.enterGoldenAge()
|
||||
tile.unit = null// destroy!
|
||||
unit.removeFromTile()
|
||||
},unit.currentMovement != 0f
|
||||
)
|
||||
actionList += UnitAction("Construct Landmark",
|
||||
constructImprovementAndDestroyUnit(tile, "Landmark"),unit.currentMovement != 0f)
|
||||
constructImprovementAndDestroyUnit(unit, "Landmark"),unit.currentMovement != 0f)
|
||||
}
|
||||
|
||||
if (unit.name == "Great Engineer") {
|
||||
actionList += UnitAction( "Hurry Wonder",
|
||||
{
|
||||
tile.getCity()!!.cityConstructions.addConstruction(300 + 30 * tile.getCity()!!.population.population) //http://civilization.wikia.com/wiki/Great_engineer_(Civ5)
|
||||
tile.unit = null // destroy!
|
||||
unit.removeFromTile()
|
||||
},
|
||||
unit.currentMovement != 0f &&
|
||||
tile.isCityCenter() &&
|
||||
@ -136,17 +135,17 @@ class UnitActions {
|
||||
(tile.getCity()!!.cityConstructions.getCurrentConstruction() as Building).isWonder)
|
||||
|
||||
actionList += UnitAction("Construct Manufactory",
|
||||
constructImprovementAndDestroyUnit(tile, "Manufactory"),unit.currentMovement != 0f)
|
||||
constructImprovementAndDestroyUnit(unit, "Manufactory"),unit.currentMovement != 0f)
|
||||
}
|
||||
|
||||
if (unit.name == "Great Merchant") {
|
||||
actionList += UnitAction("Conduct Trade Mission",
|
||||
{
|
||||
unit.civInfo.gold += 350 // + 50 * era_number - todo!
|
||||
tile.unit = null // destroy!
|
||||
unit.removeFromTile()
|
||||
},unit.currentMovement != 0f)
|
||||
actionList += UnitAction( "Construct Customs House",
|
||||
constructImprovementAndDestroyUnit(tile, "Customs house"),
|
||||
constructImprovementAndDestroyUnit(unit, "Customs house"),
|
||||
unit.currentMovement != 0f)
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,6 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
|
||||
fun tileSelected(selectedTile: TileInfo) {
|
||||
if(currentlyExecutingAction=="moveTo"){
|
||||
|
||||
if(selectedUnit!!.movementAlgs()
|
||||
.getShortestPath(selectedTile).isEmpty())
|
||||
return // can't reach there with the selected unit, watcha want me to do?
|
||||
@ -86,8 +85,13 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){
|
||||
currentlyExecutingAction = null
|
||||
}
|
||||
|
||||
if(selectedTile.unit!=null && selectedTile.unit!!.civInfo == worldScreen.civInfo)
|
||||
selectedUnit= selectedTile.unit
|
||||
if(selectedTile.militaryUnit!=null && selectedTile.militaryUnit!!.civInfo == worldScreen.civInfo
|
||||
&& selectedUnit!=selectedTile.militaryUnit)
|
||||
selectedUnit = selectedTile.militaryUnit
|
||||
|
||||
else if (selectedTile.civilianUnit!=null && selectedTile.civilianUnit!!.civInfo == worldScreen.civInfo
|
||||
&& selectedUnit!=selectedTile.civilianUnit)
|
||||
selectedUnit = selectedTile.civilianUnit
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user