From a855bc0e7bf20453b9cd858e8ea235b33b74de88 Mon Sep 17 00:00:00 2001 From: Yair Morgenstern Date: Thu, 11 Oct 2018 23:05:49 +0300 Subject: [PATCH] Organized unit image credits Sea civilian units are now universally recognized as civilian units --- Credits.md | 89 +++++++++++-------- core/src/com/unciv/GameStarter.kt | 14 +-- core/src/com/unciv/logic/HexMath.kt | 54 +++++------ .../com/unciv/logic/automation/Automation.kt | 6 +- .../unciv/logic/automation/UnitAutomation.kt | 66 ++++++++++---- core/src/com/unciv/logic/battle/Battle.kt | 6 +- .../com/unciv/logic/battle/BattleDamage.kt | 4 +- .../unciv/logic/city/CityExpansionManager.kt | 1 + core/src/com/unciv/logic/city/CityStats.kt | 2 +- .../logic/civilization/CivilizationInfo.kt | 2 +- core/src/com/unciv/logic/map/MapUnit.kt | 8 +- .../com/unciv/logic/map/RandomMapGenerator.kt | 18 ++-- core/src/com/unciv/logic/map/TileMap.kt | 14 +-- .../unciv/models/gamebasics/unit/BaseUnit.kt | 12 ++- .../unciv/models/gamebasics/unit/UnitType.kt | 6 ++ .../src/com/unciv/ui/cityscreen/CityScreen.kt | 2 +- core/src/com/unciv/ui/tilegroups/TileGroup.kt | 6 +- .../com/unciv/ui/tilegroups/WorldTileGroup.kt | 3 +- core/src/com/unciv/ui/worldscreen/Minimap.kt | 8 +- .../com/unciv/ui/worldscreen/TileMapHolder.kt | 6 +- .../ui/worldscreen/bottombar/BattleTable.kt | 4 +- .../unciv/ui/worldscreen/unit/UnitActions.kt | 4 +- .../unciv/ui/worldscreen/unit/UnitTable.kt | 5 +- 23 files changed, 200 insertions(+), 140 deletions(-) diff --git a/Credits.md b/Credits.md index 9e928cf92c..bb8e000214 100644 --- a/Credits.md +++ b/Credits.md @@ -9,60 +9,79 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc ## Units -* [Sword](https://thenounproject.com/search/?q=Sword&i=1215443) By Guilherme Furtado -* [Sword](https://thenounproject.com/search/?q=Sword&i=1432662) By uzeir syarief -* [Flag](https://thenounproject.com/search/?q=Flag&i=50114) By Melvin Poppelaars -* [Eagle](https://thenounproject.com/search/?q=Eagle&i=1619932) By anggun -* [Bow And Arrow](https://thenounproject.com/search/?q=Bow%20and%20Arrow&i=338261) By Viktor Ostrovsky -* [Chariot](https://thenounproject.com/search/?q=Chariot&i=1189930) By Andrew Doane -* [Pallet](https://thenounproject.com/search/?q=Pallet&i=6862) By James Keuning -* [Gear](https://thenounproject.com/search/?q=Gear&i=17369) By Melvin Salas -* [Beaker](https://thenounproject.com/search/?q=Beaker&i=621510) By Delwar Hossain -* [Horse](https://thenounproject.com/search/?q=Horse&i=1373793) By AFY Studio -* [Axe](https://thenounproject.com/search/?q=Axe&i=1688143) By ehab.abdullah -* [Hammer](https://thenounproject.com/search/?q=Hammer&i=667666) By Hea Poh Lin -* [Spear](https://thenounproject.com/search/?q=Spear&i=11432) By Stephen Copinger -* [Spear](https://thenounproject.com/search/?q=Spear&i=1233840) By Alvaro Cabrera +### Ancient Era + +* [Hammer](https://thenounproject.com/search/?q=Hammer&i=667666) By Hea Poh Lin for Worker +* [Flag](https://thenounproject.com/search/?q=Flag&i=50114) By Melvin Poppelaars for Settler +* [Eagle](https://thenounproject.com/search/?q=Eagle&i=1619932) By anggun for Scout +* [Axe](https://thenounproject.com/search/?q=Axe&i=1688143) By ehab.abdullah for Warrior +* [Bow And Arrow](https://thenounproject.com/search/?q=Bow%20and%20Arrow&i=338261) By Viktor Ostrovsky for Archer +* [Bow](https://thenounproject.com/search/?q=bow&i=101736) By Arthur Shlain for Bowman +* Work Boats +* [Chariot](https://thenounproject.com/search/?q=Chariot&i=1189930) By Andrew Doane for Chariot Archer +* [Spear](https://thenounproject.com/search/?q=Spear&i=11432) By Stephen Copinger for Spearman + +### Classical Era + * [Catapult](https://thenounproject.com/search/?q=Spear&i=1233840) By Jakub Ukrop -* [Crossbow](https://thenounproject.com/term/crossbow/965389/) By Creaticca Creative Agency +* [Unloaded Crossbow](https://thenounproject.com/term/unloaded-crossbow/815992/) By Hamish as Ballista +* [Sword](https://thenounproject.com/search/?q=Sword&i=1215443) By Guilherme Furtado for Swordsman +* [Horse](https://thenounproject.com/search/?q=Horse&i=1373793) By AFY Studio for Horseman +* [Horse Head](https://thenounproject.com/search/?q=Cavalry&i=374037) By Juan Pablo Bravo for Companion Cavalry + +### Medieval Era + +* [Crossbow](https://thenounproject.com/term/crossbow/965389/) By Creaticca Creative Agency for Crossbowman +* [Longbow](https://thenounproject.com/search/?q=longbow&i=815991) By Hamish for Longbowman * [Trebuchet](https://thenounproject.com/search/?q=Trebuchet&i=827987) By Ben Davis +* [Sword](https://thenounproject.com/search/?q=Sword&i=1432662) By uzeir syarief for Longswordsman +* [Spear](https://thenounproject.com/search/?q=Spear&i=1233840) By Alvaro Cabrera for Pikeman * [Knight](https://thenounproject.com/search/?q=Knight&i=30912) By Tyler Glaude -* [Lance](https://thenounproject.com/search/?q=Lance&i=440122) By parkjisun -* [Musket](https://thenounproject.com/search/?q=Musket&i=298302) By Cezary Lopacinski + +### Renaissance Era + * [Cannon](https://thenounproject.com/search/?q=Cannon&i=1618747) By Orin Zuu -* [Bow](https://thenounproject.com/search/?q=bow&i=101736) By Arthur Shlain -* [Longbow](https://thenounproject.com/search/?q=longbow&i=815991) By Hamish -* [Horse Head](https://thenounproject.com/search/?q=Cavalry&i=374037) By Juan Pablo Bravo -* [Rifle](https://thenounproject.com/search/?q=Rifle&i=604291) By Chameleon Design -* [Horse](https://thenounproject.com/search/?q=Horse&i=1023745) By Bakunetso Kaito +* [Musket](https://thenounproject.com/search/?q=Musket&i=298302) By Cezary Lopacinski for Musketman +* [Rapier](https://thenounproject.com/search/?q=musketeer&i=819822) By Hamish for Musketeer +* [Lance](https://thenounproject.com/search/?q=Lance&i=440122) By parkjisun for Lancer + +### Industrial + +* [Rifle](https://thenounproject.com/search/?q=Rifle&i=604291) By Chameleon Design for Rifleman +* [Horse](https://thenounproject.com/search/?q=Horse&i=1023745) By Bakunetso Kaito for Cavalry * [Artillery](https://thenounproject.com/search/?q=Artillery&i=1165261) By Creative Mania -* [Rapier](https://thenounproject.com/search/?q=musketeer&i=819822) By Hamish -* [Unloaded Crossbow](https://thenounproject.com/term/unloaded-crossbow/815992/) By Hamish + +### Great People + +* [Pallet](https://thenounproject.com/search/?q=Pallet&i=6862) By James Keuning for Great Artist +* [Gear](https://thenounproject.com/search/?q=Gear&i=17369) By Melvin Salas for Great Engineer +* [Beaker](https://thenounproject.com/search/?q=Beaker&i=621510) By Delwar Hossain for Great Scientist + ## Resources -* [Saffron](https://thenounproject.com/term/saffron/1576606/) By parkjisun -* [Can](https://thenounproject.com/term/can/708971/) By Nick Bluth +* [Saffron](https://thenounproject.com/term/saffron/1576606/) By parkjisun for Dye +* [Can](https://thenounproject.com/term/can/708971/) By Nick Bluth for Aluminum * [Coal](https://thenounproject.com/term/coal/213892/) By Michael Wohlwend -* [Anvil](https://thenounproject.com/term/anvil/166414/) By Jason Dilworth +* [Anvil](https://thenounproject.com/term/anvil/166414/) By Jason Dilworth for Iron * [Deer](https://thenounproject.com/term/deer/338013/) By Richard Nixon * [Banana](https://thenounproject.com/term/banana/1262865/) By Adrian Coquet * [Oil](https://thenounproject.com/term/oil/88649/) By Tiago Maricate -* [Statue](https://thenounproject.com/term/statue/5221/) By Joris Hoogendoorn -* [Ribbon](https://thenounproject.com/term/ribbon/418996) By Anton +* [Statue](https://thenounproject.com/term/statue/5221/) By Joris Hoogendoorn for Marble +* [Ribbon](https://thenounproject.com/term/ribbon/418996) By Anton for Silk * [Stone](https://thenounproject.com/term/stone/1373902/) By AFY Studio -* [Goblet](https://thenounproject.com/term/goblet/1005208/) By Pedro Santos +* [Goblet](https://thenounproject.com/term/goblet/1005208/) By Pedro Santos for Silver * [Sugar](https://thenounproject.com/term/sugar/1689203/) By ahmad * [Spice](https://thenounproject.com/term/spice/1689206/) By ahmad -* [Radiation symbol](https://thenounproject.com/term/radiation-symbol/211059/) By icon 54 +* [Radiation symbol](https://thenounproject.com/term/radiation-symbol/211059/) By icon 54 for Uranium * [Wine](https://thenounproject.com/term/wine/1290951/) By Adrien Coquet * [Wheat](https://thenounproject.com/term/wheat/1048428/) By Juraj Sedlak * [Sheep](https://thenounproject.com/term/sheep/8389/) By Unrecognized -* [Elephant](https://thenounproject.com/term/elephant/1853192/) By Kelsey Armstrong +* [Elephant](https://thenounproject.com/term/elephant/1853192/) By Kelsey Armstrong for Ivory * [Cattle](https://thenounproject.com/term/cattle/781342/) By Daniela Baptista -* [Leather](https://thenounproject.com/term/leather/16499/) By Alen Krummenacher +* [Leather](https://thenounproject.com/term/leather/16499/) By Alen Krummenacher for Furs * [Gem](https://thenounproject.com/term/gem/948920/) By Lluisa Iborra -* [Joss Stick](https://thenounproject.com/search/?q=incense&i=583033) By Hea Poh Lin +* [Joss Stick](https://thenounproject.com/search/?q=incense&i=583033) By Hea Poh Lin for Incense ## Improvements @@ -74,7 +93,7 @@ All the following are from [the Noun Project](https://thenounproject.com) licenc * [Academy](https://thenounproject.com/term/academy/1689703/) By CJS * [Factory](https://thenounproject.com/term/factory/1049531/) By RULI * [Mine](https://thenounproject.com/term/mine/543/) By Edward Boatman -* [Corral](https://thenounproject.com/term/corral/1340751/) By Luis Prado +* [Corral](https://thenounproject.com/term/corral/1340751/) By Luis Prado for Pasture * [Plants](https://thenounproject.com/term/plants/1760916/) By hendra sudibyo * [Pickaxe](https://thenounproject.com/term/pickaxe/175792/) By Creative Stall * [Food stall](https://thenounproject.com/term/food-stall/1618358/) By I Putu Kharismayadi diff --git a/core/src/com/unciv/GameStarter.kt b/core/src/com/unciv/GameStarter.kt index 094ad5e2c7..355f4b0c10 100644 --- a/core/src/com/unciv/GameStarter.kt +++ b/core/src/com/unciv/GameStarter.kt @@ -5,6 +5,7 @@ import com.unciv.logic.GameInfo import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.map.TileMap import com.unciv.models.gamebasics.GameBasics +import com.unciv.models.gamebasics.tile.TerrainType import com.unciv.ui.NewGameScreen import com.unciv.ui.utils.getRandom @@ -24,7 +25,9 @@ class GameStarter(){ } val distanceAroundStartingPointNoOneElseWillStartIn = 5 - val freeTiles = gameInfo.tileMap.values.toMutableList().filter { vectorIsWithinNTilesOfEdge(it.position,3)}.toMutableList() + val freeTiles = gameInfo.tileMap.values + .filter { it.getBaseTerrain().type==TerrainType.Land && vectorIsWithinNTilesOfEdge(it.position,3)} + .toMutableList() val playerPosition = freeTiles.getRandom().position val playerCiv = CivilizationInfo(newGameParameters.nation, gameInfo) playerCiv.difficulty=newGameParameters.difficulty @@ -63,15 +66,6 @@ class GameStarter(){ freeTiles.removeAll(gameInfo.tileMap.getTilesInDistance(startingLocation, distanceAroundStartingPointNoOneElseWillStartIn )) } - (1..5).forEach { - val freeTilesList = freeTiles.toList() - if(freeTilesList.isNotEmpty()){ - val placedTile = freeTilesList.getRandom() - gameInfo.placeBarbarianUnit(placedTile) - freeTiles.remove(placedTile) - } - } - return gameInfo } } \ No newline at end of file diff --git a/core/src/com/unciv/logic/HexMath.kt b/core/src/com/unciv/logic/HexMath.kt index 4649ff3ba2..681d6f5b74 100644 --- a/core/src/com/unciv/logic/HexMath.kt +++ b/core/src/com/unciv/logic/HexMath.kt @@ -7,12 +7,12 @@ import kotlin.math.max class HexMath { - fun GetVectorForAngle(angle: Float): Vector2 { + private fun getVectorForAngle(angle: Float): Vector2 { return Vector2(Math.sin(angle.toDouble()).toFloat(), Math.cos(angle.toDouble()).toFloat()) } - fun GetVectorByClockHour(hour: Int): Vector2 { - return GetVectorForAngle((2 * Math.PI * (hour / 12f)).toFloat()) + private fun getVectorByClockHour(hour: Int): Vector2 { + return getVectorForAngle((2 * Math.PI * (hour / 12f)).toFloat()) } // HexCoordinates are a (x,y) vector, where x is the vector getting us to the top-left hex (e.g. 10 o'clock) @@ -22,54 +22,54 @@ class HexMath { // For example, to get to the cell above me, I'll use a (1,1) vector. // To get to the cell below the cell to my bottom-right, I'll use a (-1,-2) vector. - fun Hex2WorldCoords(hexCoord: Vector2): Vector2 { + fun hex2WorldCoords(hexCoord: Vector2): Vector2 { // Distance between cells = 2* normal of triangle = 2* (sqrt(3)/2) = sqrt(3) - val xVector = GetVectorByClockHour(10).scl(Math.sqrt(3.0).toFloat()) - val yVector = GetVectorByClockHour(2).scl(Math.sqrt(3.0).toFloat()) + val xVector = getVectorByClockHour(10).scl(Math.sqrt(3.0).toFloat()) + val yVector = getVectorByClockHour(2).scl(Math.sqrt(3.0).toFloat()) return xVector.scl(hexCoord.x).add(yVector.scl(hexCoord.y)) } - fun GetAdjacentVectors(origin: Vector2): ArrayList { + fun getAdjacentVectors(origin: Vector2): ArrayList { val vectors = ArrayList() - vectors.add(Vector2(1f, 0f)) - vectors.add(Vector2(1f, 1f)) - vectors.add(Vector2(0f, 1f)) - vectors.add(Vector2(-1f, 0f)) - vectors.add(Vector2(-1f, -1f)) - vectors.add(Vector2(0f, -1f)) + vectors += Vector2(1f, 0f) + vectors += Vector2(1f, 1f) + vectors += Vector2(0f, 1f) + vectors += Vector2(-1f, 0f) + vectors += Vector2(-1f, -1f) + vectors += Vector2(0f, -1f) for (vector in vectors) vector.add(origin) return vectors } - fun GetVectorsAtDistance(origin: Vector2, distance: Int): List { + fun getVectorsAtDistance(origin: Vector2, distance: Int): List { val vectors = mutableListOf() if (distance == 0) { - vectors.add(origin.cpy()) + vectors += origin.cpy() return vectors } - val Current = origin.cpy().sub(distance.toFloat(), distance.toFloat()) // start at 6 o clock + val current = origin.cpy().sub(distance.toFloat(), distance.toFloat()) // start at 6 o clock for (i in 0 until distance) { // From 6 to 8 - vectors.add(Current.cpy()) - vectors.add(origin.cpy().scl(2f).sub(Current)) // Get vector on other side of cloick - Current.add(1f, 0f) + vectors += current.cpy() + vectors += origin.cpy().scl(2f).sub(current) // Get vector on other side of cloick + current.add(1f, 0f) } for (i in 0 until distance) { // 8 to 10 - vectors.add(Current.cpy()) - vectors.add(origin.cpy().scl(2f).sub(Current)) // Get vector on other side of clock - Current.add(1f, 1f) + vectors += current.cpy() + vectors += origin.cpy().scl(2f).sub(current) // Get vector on other side of clock + current.add(1f, 1f) } for (i in 0 until distance) { // 10 to 12 - vectors.add(Current.cpy()) - vectors.add(origin.cpy().scl(2f).sub(Current)) // Get vector on other side of clock - Current.add(0f, 1f) + vectors += current.cpy() + vectors += origin.cpy().scl(2f).sub(current) // Get vector on other side of clock + current.add(0f, 1f) } return vectors } - fun GetVectorsInDistance(origin: Vector2, distance: Int): List { + fun getVectorsInDistance(origin: Vector2, distance: Int): List { val hexesToReturn = mutableListOf() for (i in 0 .. distance) { - hexesToReturn.addAll(GetVectorsAtDistance(origin, i)) + hexesToReturn += getVectorsAtDistance(origin, i) } return hexesToReturn } diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index bc9e96a28c..2c8ea0db74 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -77,7 +77,7 @@ class Automation { // Declare war? if(civInfo.cities.isNotEmpty() && civInfo.diplomacy.isNotEmpty() && !civInfo.isAtWar() - && civInfo.getCivUnits().filter { it.baseUnit.unitType != UnitType.Civilian }.size > civInfo.cities.size*2) { + && civInfo.getCivUnits().filter { !it.baseUnit.unitType.isCivilian() }.size > civInfo.cities.size*2) { val enemyCivsByDistanceToOurs = civInfo.diplomacy.values.map { it.otherCiv() } .filterNot { it == civInfo || it.cities.isEmpty() || !civInfo.diplomacy[it.civName]!!.canDeclareWar() } @@ -142,7 +142,7 @@ class Automation { } private fun trainCombatUnit(city: CityInfo) { - val combatUnits = city.cityConstructions.getConstructableUnits().filter { it.unitType != UnitType.Civilian } + val combatUnits = city.cityConstructions.getConstructableUnits().filter { !it.unitType.isCivilian() } val chosenUnit: BaseUnit if(!city.civInfo.isAtWar() && city.civInfo.cities.any { it.getCenterTile().militaryUnit==null} && combatUnits.any { it.unitType== UnitType.Ranged }) // this is for city defence so get an archery unit if we can @@ -166,7 +166,7 @@ class Automation { val buildableWonders = getBuildableBuildings().filter { it.isWonder } val civUnits = cityInfo.civInfo.getCivUnits() - val militaryUnits = civUnits.filter { it.baseUnit().unitType != UnitType.Civilian }.size + val militaryUnits = civUnits.filter { !it.baseUnit().unitType.isCivilian()}.size val workers = civUnits.filter { it.name == CityConstructions.Worker }.size val cities = cityInfo.civInfo.cities.size diff --git a/core/src/com/unciv/logic/automation/UnitAutomation.kt b/core/src/com/unciv/logic/automation/UnitAutomation.kt index 33ed06c51f..3893cc3430 100644 --- a/core/src/com/unciv/logic/automation/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/UnitAutomation.kt @@ -11,6 +11,7 @@ import com.unciv.logic.civilization.DiplomaticStatus import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo import com.unciv.models.gamebasics.GameBasics +import com.unciv.models.gamebasics.tile.TerrainType import com.unciv.ui.utils.getRandom import com.unciv.ui.worldscreen.unit.UnitAction import com.unciv.ui.worldscreen.unit.UnitActions @@ -29,6 +30,11 @@ class UnitAutomation{ return } + if(unit.name=="Work Boats"){ + automateWorkBoats(unit) + return + } + if(unit.name.startsWith("Great")) return // I don't know what to do with you yet. val unitActions = UnitActions().getUnitActions(unit,UnCivGame.Current.worldScreen) @@ -75,6 +81,26 @@ class UnitAutomation{ // if both failed, then... there aren't any reachable tiles. Which is possible. } + private fun hasWorkableSeaResource(tileInfo: TileInfo): Boolean { + return tileInfo.resource!=null && tileInfo.getBaseTerrain().type==TerrainType.Water && tileInfo.improvement==null + } + + private fun automateWorkBoats(unit: MapUnit) { + val seaResourcesInCities = unit.civInfo.cities.flatMap { it.getTilesInRange() } + .filter { hasWorkableSeaResource(it) && (unit.canMoveTo(it) || unit.currentTile==it) } + if (seaResourcesInCities.any()) { + val reachableResource = seaResourcesInCities.asSequence().sortedBy { it.arialDistanceTo(unit.currentTile) } + .firstOrNull { unit.movementAlgs().canReach(it) } + if (reachableResource != null) { + unit.movementAlgs().headTowards(reachableResource) + if(unit.currentMovement>0 && hasWorkableSeaResource(unit.currentTile)) + UnitActions().getUnitActions(unit,UnCivGame.Current.worldScreen) + .first { it.name=="Create Fishing Boats" }.action() + } + } + explore(unit, unit.getDistanceToTiles()) + } + fun rankTileForHealing(tileInfo: TileInfo, unit: MapUnit): Int { val tileOwner = tileInfo.getOwner() when{ @@ -127,8 +153,8 @@ class UnitAutomation{ for(reachableTile in tilesToAttackFrom){ // tiles we'll still have energy after we reach there val tilesInAttackRange = if (unit.hasUnique("Indirect fire")) reachableTile.getTilesInDistance(rangeOfAttack) else reachableTile.getViewableTiles(rangeOfAttack) - attackableTiles += tilesInAttackRange.filter { it in tilesWithEnemies } - .map { AttackableTile(reachableTile,it) } + attackableTiles += tilesInAttackRange.asSequence().filter { it in tilesWithEnemies } + .map { AttackableTile(reachableTile,it) }.toList() } return attackableTiles } @@ -150,14 +176,13 @@ class UnitAutomation{ } private fun tryAccompanySettler(unit: MapUnit, unitDistanceToTiles: HashMap): Boolean { - val closeTileWithSettler = unitDistanceToTiles.keys.firstOrNull { - it.civilianUnit != null && it.civilianUnit!!.name == "Settler" - } - if (closeTileWithSettler != null && unit.canMoveTo(closeTileWithSettler)) { - unit.movementAlgs().headTowards(closeTileWithSettler) - return true - } - return false + val settlerToAccompany = unit.civInfo.getCivUnits() + .firstOrNull { val tile = it.currentTile; + it.name=="Settler" && tile.militaryUnit==null + && unit.canMoveTo(tile) && unit.movementAlgs().canReach(tile) } + if(settlerToAccompany==null) return false + unit.movementAlgs().headTowards(settlerToAccompany.currentTile) + return true } private fun tryUpgradeUnit(unit: MapUnit, unitActions: List): Boolean { @@ -303,11 +328,15 @@ class UnitAutomation{ fun rankTileAsCityCenter(tileInfo: TileInfo, nearbyTileRankings: Map): Float { val bestTilesFromOuterLayer = tileInfo.getTilesAtDistance(2) + .asSequence() .sortedByDescending { nearbyTileRankings[it] }.take(2) + .toList() val top5Tiles = tileInfo.neighbors.union(bestTilesFromOuterLayer) + .asSequence() .sortedByDescending { nearbyTileRankings[it] } .take(5) - var rank = top5Tiles.map { nearbyTileRankings[it]!! }.sum() + .toList() + var rank = top5Tiles.asSequence().map { nearbyTileRankings[it]!! }.sum() if(tileInfo.neighbors.any{it.baseTerrain == "Coast"}) rank += 5 return rank } @@ -315,18 +344,18 @@ class UnitAutomation{ private fun automateSettlerActions(unit: MapUnit) { if(unit.getTile().militaryUnit==null) return // Don't move until you're accompanied by a military unit - // find best city location within 5 tiles val tilesNearCities = unit.civInfo.gameInfo.civilizations.flatMap { it.cities } - .flatMap { it.getCenterTile().getTilesInDistance(3) } + .flatMap { it.getCenterTile().getTilesInDistance(3) }.toHashSet() // This is to improve performance - instead of ranking each tile in the area up to 19 times, do it once. val nearbyTileRankings = unit.getTile().getTilesInDistance(7) .associateBy ( {it},{ Automation().rankTile(it,unit.civInfo) }) - val possibleTiles = unit.getTile().getTilesInDistance(5) - .minus(tilesNearCities) + val possibleCityLocations = unit.getTile().getTilesInDistance(5) + .filter { (unit.canMoveTo(it) || unit.currentTile==it) && it !in tilesNearCities } - val bestCityLocation: TileInfo? = possibleTiles + val bestCityLocation: TileInfo? = possibleCityLocations + .asSequence() .sortedByDescending { rankTileAsCityCenter(it, nearbyTileRankings) } .firstOrNull { unit.movementAlgs().canReach(it) } @@ -336,7 +365,10 @@ class UnitAutomation{ return } - if (unit.getTile() == bestCityLocation) // already there! + if(bestCityLocation.getTilesInDistance(3).any { it.isCityCenter() }) + throw Exception("City within distance") + + if (unit.getTile() == bestCityLocation) UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen).first { it.name == "Found city" }.action() else { unit.movementAlgs().headTowards(bestCityLocation) diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index 9871c0f9e6..310facb614 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -18,7 +18,7 @@ class Battle(val gameInfo:GameInfo) { var damageToDefender = BattleDamage().calculateDamageToDefender(attacker,defender) var damageToAttacker = BattleDamage().calculateDamageToAttacker(attacker,defender) - if(defender.getUnitType() == UnitType.Civilian && attacker.isMelee()){ + if(defender.getUnitType().isCivilian() && attacker.isMelee()){ captureCivilianUnit(attacker,defender) } else if (attacker.isRanged()) { @@ -98,7 +98,7 @@ class Battle(val gameInfo:GameInfo) { } if(attacker.isMelee()){ - if(defender.getUnitType()!=UnitType.Civilian) // unit was not captured but actually attacked + if(!defender.getUnitType().isCivilian()) // unit was not captured but actually attacked { addXp(attacker,5,defender) addXp(defender,4,attacker) @@ -109,7 +109,7 @@ class Battle(val gameInfo:GameInfo) { addXp(defender,2,attacker) } - if(defender.isDefeated() && defender is MapUnitCombatant && defender.getUnitType()!=UnitType.Civilian + if(defender.isDefeated() && defender is MapUnitCombatant && !defender.getUnitType().isCivilian() && attacker.getCivilization().policies.isAdopted("Honor Complete")) attacker.getCivilization().gold += defender.unit.baseUnit.getGoldCost(hashSetOf()) / 10 diff --git a/core/src/com/unciv/logic/battle/BattleDamage.kt b/core/src/com/unciv/logic/battle/BattleDamage.kt index 0126b67d25..3a28f927b5 100644 --- a/core/src/com/unciv/logic/battle/BattleDamage.kt +++ b/core/src/com/unciv/logic/battle/BattleDamage.kt @@ -43,7 +43,7 @@ class BattleDamage{ if(combatant.getCivilization().policies.isAdopted("Dicipline") && combatant.isMelee() && combatant.getTile().neighbors.flatMap { it.getUnits() } - .any { it.civInfo==combatant.getCivilization() && it.baseUnit.unitType!=UnitType.Civilian}) + .any { it.civInfo==combatant.getCivilization() && !it.baseUnit.unitType.isCivilian()}) modifiers["Dicipline"] = 0.15f } @@ -154,7 +154,7 @@ class BattleDamage{ fun calculateDamageToAttacker(attacker: ICombatant, defender: ICombatant): Int { if(attacker.isRanged()) return 0 - if(defender.getUnitType()== UnitType.Civilian) return 0 + if(defender.getUnitType().isCivilian()) return 0 val ratio = getDefendingStrength(attacker,defender) / getAttackingStrength(attacker,defender) return (ratio * 30 * getHealthDependantDamageRatio(defender)).toInt() } diff --git a/core/src/com/unciv/logic/city/CityExpansionManager.kt b/core/src/com/unciv/logic/city/CityExpansionManager.kt index 72a7c404e6..a0e1facdd0 100644 --- a/core/src/com/unciv/logic/city/CityExpansionManager.kt +++ b/core/src/com/unciv/logic/city/CityExpansionManager.kt @@ -85,6 +85,7 @@ class CityExpansionManager { } private fun takeOwnership(tileInfo: TileInfo){ + if(tileInfo.isCityCenter()) throw Exception("What?") if(tileInfo.getCity()!=null) tileInfo.getCity()!!.expansion.relinquishOwnership(tileInfo) cityInfo.tiles.add(tileInfo.position) diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index c3a85e8058..c6d0065f52 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -212,7 +212,7 @@ class CityStats { stats.gold += 25f if (policies.contains("Sovereignty") && cityInfo.civInfo.happiness >= 0) stats.science += 15f - if (policies.contains("Total War") && currentConstruction is BaseUnit && currentConstruction.unitType!=UnitType.Civilian ) + if (policies.contains("Total War") && currentConstruction is BaseUnit && !currentConstruction.unitType.isCivilian() ) stats.production += 15f if (policies.contains("Aristocracy") && currentConstruction is Building diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index ce78664cd8..cf12d029ba 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -265,7 +265,7 @@ class CivilizationInfo { // disband units until there are none left OR the gold values are normal if(!isBarbarianCivilization() && gold < -100 && nextTurnStats.gold.toInt() < 0) { for (i in 1 until (gold / -100)) { - var civMilitaryUnits = getCivUnits().filter { it.baseUnit().unitType != UnitType.Civilian } + var civMilitaryUnits = getCivUnits().filter { !it.baseUnit().unitType.isCivilian() } if (civMilitaryUnits.isNotEmpty()) { val unitToDisband = civMilitaryUnits.first() unitToDisband.destroy() diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index adf5d72840..c58f58dc5b 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -110,7 +110,7 @@ class MapUnit { if(tileOwner!=null && tileOwner.civName!=owner && (tile.isCityCenter() || !civInfo.canEnterTiles(tileOwner))) return false - if (baseUnit().unitType== UnitType.Civilian) + if (baseUnit().unitType.isCivilian()) return tile.civilianUnit==null && (tile.militaryUnit==null || tile.militaryUnit!!.owner==owner) else return tile.militaryUnit==null && (tile.civilianUnit==null || tile.civilianUnit!!.owner==owner) } @@ -264,13 +264,13 @@ class MapUnit { } fun removeFromTile(){ - if (baseUnit().unitType== UnitType.Civilian) getTile().civilianUnit=null + if (baseUnit().unitType.isCivilian()) getTile().civilianUnit=null else getTile().militaryUnit=null } fun putInTile(tile:TileInfo){ if(!canMoveTo(tile)) throw Exception("I can't go there!") - if(baseUnit().unitType== UnitType.Civilian) + if(baseUnit().unitType.isCivilian()) tile.civilianUnit=this else tile.militaryUnit=this currentTile = tile @@ -302,7 +302,7 @@ class MapUnit { civInfo.addNotification("A [$chosenUnit] has joined us!",null, Color.BLUE) } - if(baseUnit.unitType!=UnitType.Civilian) + if(!baseUnit.unitType.isCivilian()) actions.add { promotions.XP+=10 civInfo.addNotification("An ancient tribe trains our [$name] in their ways of combat!",null, Color.RED) diff --git a/core/src/com/unciv/logic/map/RandomMapGenerator.kt b/core/src/com/unciv/logic/map/RandomMapGenerator.kt index ad31712b5a..2267b675a6 100644 --- a/core/src/com/unciv/logic/map/RandomMapGenerator.kt +++ b/core/src/com/unciv/logic/map/RandomMapGenerator.kt @@ -15,7 +15,7 @@ class PerlinNoiseRandomMapGenerator:SeedRandomMapGenerator(){ override fun generateMap(distance: Int): HashMap { val map = HashMap() val mapRandomSeed = Random().nextDouble() // without this, all the "random" maps would look the same - for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance)) + for (vector in HexMath().getVectorsInDistance(Vector2.Zero, distance)) map[vector] = generateTile(vector,mapRandomSeed) divideIntoAreas(6, 0f, map) @@ -50,7 +50,7 @@ class AlexanderRandomMapGenerator:RandomMapGenerator(){ fun generateMap(distance: Int, landExpansionChance:Float): HashMap { val map = HashMap() - for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance)) + for (vector in HexMath().getVectorsInDistance(Vector2.Zero, distance)) map[vector] = null val sparkList = ArrayList() @@ -64,7 +64,7 @@ class AlexanderRandomMapGenerator:RandomMapGenerator(){ while(sparkList.any()){ val currentSpark = sparkList.getRandom() - val emptyTilesAroundSpark = HexMath().GetAdjacentVectors(currentSpark) + val emptyTilesAroundSpark = HexMath().getAdjacentVectors(currentSpark) .filter { map.containsKey(it) && map[it]==null } if(map[currentSpark]!!.baseTerrain==grassland){ for(tile in emptyTilesAroundSpark){ @@ -84,7 +84,7 @@ class AlexanderRandomMapGenerator:RandomMapGenerator(){ for(entry in map){ entry.value!!.position = entry.key if(entry.value!!.baseTerrain==ocean - && HexMath().GetAdjacentVectors(entry.key).all { !map.containsKey(it) || map[it]!!.baseTerrain==grassland }) + && HexMath().getAdjacentVectors(entry.key).all { !map.containsKey(it) || map[it]!!.baseTerrain==grassland }) entry.value!!.baseTerrain=grassland newmap[entry.key.toString()] = entry.value!! @@ -117,7 +117,7 @@ open class SeedRandomMapGenerator : RandomMapGenerator() { val map = HashMap() - for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance)) + for (vector in HexMath().getVectorsInDistance(Vector2.Zero, distance)) map[vector] = TileInfo().apply { position=vector; baseTerrain="" } @@ -182,14 +182,14 @@ open class SeedRandomMapGenerator : RandomMapGenerator() { continue } val availableExpansionVectors = areaToExpand.locations - .flatMap { HexMath().GetAdjacentVectors(it) }.asSequence().distinct() + .flatMap { HexMath().getAdjacentVectors(it) }.asSequence().distinct() .filter { map.containsKey(it) && map[it]!!.baseTerrain=="" }.toList() if (availableExpansionVectors.isEmpty()) expandableAreas -= areaToExpand else { val expansionVector = availableExpansionVectors.getRandom() areaToExpand.addTile(map[expansionVector]!!) - val neighbors = HexMath().GetAdjacentVectors(expansionVector) + val neighbors = HexMath().getAdjacentVectors(expansionVector) val areasToJoin = areas.filter { it.terrain == areaToExpand.terrain && it != areaToExpand @@ -261,7 +261,7 @@ open class RandomMapGenerator { open fun generateMap(distance: Int): HashMap { val map = HashMap() - for (vector in HexMath().GetVectorsInDistance(Vector2.Zero, distance)) + for (vector in HexMath().getVectorsInDistance(Vector2.Zero, distance)) map[vector.toString()] = addRandomTile(vector) return map } @@ -278,7 +278,7 @@ open class RandomMapGenerator { fun setWaterTiles(map: HashMap) { for (tile in map.values.filter { it.baseTerrain == "Ocean" }) { - if (HexMath().GetVectorsInDistance(tile.position,2).any { hasWaterTile(map,it) }) + if (HexMath().getVectorsInDistance(tile.position,2).any { hasWaterTile(map,it) }) tile.baseTerrain = "Coast" } } diff --git a/core/src/com/unciv/logic/map/TileMap.kt b/core/src/com/unciv/logic/map/TileMap.kt index e832897e0b..91028e6879 100644 --- a/core/src/com/unciv/logic/map/TileMap.kt +++ b/core/src/com/unciv/logic/map/TileMap.kt @@ -51,11 +51,13 @@ class TileMap { } fun getTilesInDistance(origin: Vector2, distance: Int): List { - return HexMath().GetVectorsInDistance(origin, distance).filter {contains(it)}.map { get(it) } + return HexMath().getVectorsInDistance(origin, distance).asSequence() + .filter {contains(it)}.map { get(it) }.toList() } fun getTilesAtDistance(origin: Vector2, distance: Int): List { - return HexMath().GetVectorsAtDistance(origin, distance).filter {contains(it)}.map { get(it) } + return HexMath().getVectorsAtDistance(origin, distance).asSequence() + .filter {contains(it)}.map { get(it) }.toList() } @@ -88,10 +90,10 @@ class TileMap { if(tiles.any()) // tileList.addAll(tiles.values) - val topY=tileList.map { it.position.y.toInt() }.max()!! - bottomY= tileList.map { it.position.y.toInt() }.min()!! - val rightX=tileList.map { it.position.x.toInt() }.max()!! - leftX = tileList.map { it.position.x.toInt() }.min()!! + val topY= tileList.asSequence().map { it.position.y.toInt() }.max()!! + bottomY= tileList.asSequence().map { it.position.y.toInt() }.min()!! + val rightX= tileList.asSequence().map { it.position.x.toInt() }.max()!! + leftX = tileList.asSequence().map { it.position.x.toInt() }.min()!! for(x in leftX..rightX){ val row = ArrayList() diff --git a/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt b/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt index 81d4447de5..6153e532c5 100644 --- a/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt @@ -89,18 +89,24 @@ class BaseUnit : INamed, IConstruction, ICivilopedia { return (cost / 10).toInt() * 10 // rounded down o nearest ten } - override fun isBuildable(construction: CityConstructions): Boolean { - val civInfo = construction.cityInfo.civInfo + fun isBuildable(civInfo:CivilizationInfo): Boolean { if (unbuildable) return false if (requiredTech!=null && !civInfo.tech.isResearched(requiredTech!!)) return false if (obsoleteTech!=null && civInfo.tech.isResearched(obsoleteTech!!)) return false if (uniqueTo!=null && uniqueTo!=civInfo.civName) return false if (GameBasics.Units.values.any { it.uniqueTo==civInfo.civName && it.replaces==name }) return false if (requiredResource!=null && !civInfo.getCivResources().keys.any { it.name == requiredResource }) return false - if(unitType.isWaterUnit() && construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain=="Coast" }) return true } + override fun isBuildable(construction: CityConstructions): Boolean { + if(!isBuildable(construction.cityInfo.civInfo)) return false + if(unitType.isWaterUnit() && construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain=="Coast" }) + return false + return true + + } + override fun postBuildEvent(construction: CityConstructions) { val unit = construction.cityInfo.civInfo.placeUnitNearTile(construction.cityInfo.location, name) unit.promotions.XP += construction.getBuiltBuildings().sumBy { it.xpForNewUnits } diff --git a/core/src/com/unciv/models/gamebasics/unit/UnitType.kt b/core/src/com/unciv/models/gamebasics/unit/UnitType.kt index cd7130bedb..09d9292ff5 100644 --- a/core/src/com/unciv/models/gamebasics/unit/UnitType.kt +++ b/core/src/com/unciv/models/gamebasics/unit/UnitType.kt @@ -28,6 +28,12 @@ enum class UnitType{ || this == Ranged || this == Siege } + + fun isCivilian(): Boolean { + return this == Civilian + || this == WaterCivilian + } + fun isWaterUnit(): Boolean { return this == WaterCivilian } diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index 0982fa2095..fea0d6055d 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -218,7 +218,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() { } - val positionalVector = HexMath().Hex2WorldCoords(tileInfo.position.cpy().sub(cityInfo.location)) + val positionalVector = HexMath().hex2WorldCoords(tileInfo.position.cpy().sub(cityInfo.location)) val groupSize = 50 tileGroup.setPosition(stage.width / 2 + positionalVector.x * 0.8f * groupSize.toFloat(), stage.height / 2 + positionalVector.y * 0.8f * groupSize.toFloat()) diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index e7c65fdad0..6ade79a050 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -179,7 +179,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() { if (neigborOwner != tileOwner && !borderImages.containsKey(neighbor)) { // there should be a border here but there isn't val relativeHexPosition = tileInfo.position.cpy().sub(neighbor.position) - val relativeWorldPosition = HexMath().Hex2WorldCoords(relativeHexPosition) + val relativeWorldPosition = HexMath().hex2WorldCoords(relativeHexPosition) // This is some crazy voodoo magic so I'll explain. val images = mutableListOf() @@ -233,7 +233,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() { roadImage.image = image val relativeHexPosition = tileInfo.position.cpy().sub(neighbor.position) - val relativeWorldPosition = HexMath().Hex2WorldCoords(relativeHexPosition) + val relativeWorldPosition = HexMath().hex2WorldCoords(relativeHexPosition) // This is some crazy voodoo magic so I'll explain. image.moveBy(25f, 25f) // Move road to center of tile @@ -327,7 +327,7 @@ open class TileGroup(var tileInfo: TileInfo) : Group() { newImage.center(this) newImage.y += yFromCenter - if (!unit.isIdle()) newImage.color.a = 0.5f + if (!unit.isIdle() && unit.civInfo.isPlayerCivilization()) newImage.color.a = 0.5f } return newImage } diff --git a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt index 7bc9d7664c..3679128340 100644 --- a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt @@ -13,7 +13,6 @@ import com.unciv.logic.city.SpecialConstruction import com.unciv.logic.map.MapUnit import com.unciv.logic.map.RoadStatus import com.unciv.logic.map.TileInfo -import com.unciv.models.gamebasics.unit.UnitType import com.unciv.ui.cityscreen.CityScreen import com.unciv.ui.utils.* @@ -25,7 +24,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) { val whiteHalo = if(unit.isFortified()) ImageGetter.getImage("OtherIcons/Shield.png") else ImageGetter.getImage("OtherIcons/Circle.png") whiteHalo.setSize(30f,30f) - val unitImage = if(unit.baseUnit().unitType== UnitType.Civilian) civilianUnitImage + val unitImage = if(unit.baseUnit().unitType.isCivilian()) civilianUnitImage else militaryUnitImage if(unitImage==null) //Stuff has changed since we requested this, the unit is no longer here... return diff --git a/core/src/com/unciv/ui/worldscreen/Minimap.kt b/core/src/com/unciv/ui/worldscreen/Minimap.kt index db75314f36..d44a524d32 100644 --- a/core/src/com/unciv/ui/worldscreen/Minimap.kt +++ b/core/src/com/unciv/ui/worldscreen/Minimap.kt @@ -10,6 +10,7 @@ import com.unciv.UnCivGame import com.unciv.logic.HexMath import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.map.TileInfo +import com.unciv.models.gamebasics.tile.TerrainType import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.onClick @@ -32,7 +33,7 @@ class Minimap(val tileMapHolder: TileMapHolder) : ScrollPane(null){ for (tileInfo in tileMapHolder.tileMap.values) { val hex = ImageGetter.getImage("TerrainIcons/Hexagon.png") - val positionalVector = HexMath().Hex2WorldCoords(tileInfo.position) + val positionalVector = HexMath().hex2WorldCoords(tileInfo.position) val groupSize = 10f hex.setSize(groupSize,groupSize) hex.setPosition(positionalVector.x * 0.5f * groupSize, @@ -73,9 +74,10 @@ class Minimap(val tileMapHolder: TileMapHolder) : ScrollPane(null){ val exploredTiles = cloneCivilization.exploredTiles for(tileInfo in tileMapHolder.tileMap.values) { val hex = tileImages[tileInfo]!! + val isWaterTile = tileInfo.getBaseTerrain().type==TerrainType.Water if (!(exploredTiles.contains(tileInfo.position) || UnCivGame.Current.viewEntireMapForDebug)) hex.color = Color.BLACK - else if (tileInfo.isCityCenter()) hex.color = tileInfo.getOwner()!!.getNation().getSecondaryColor() - else if (tileInfo.getCity() != null) hex.color = tileInfo.getOwner()!!.getNation().getColor() + else if (tileInfo.isCityCenter() && !isWaterTile) hex.color = tileInfo.getOwner()!!.getNation().getSecondaryColor() + else if (tileInfo.getCity() != null && !isWaterTile) hex.color = tileInfo.getOwner()!!.getNation().getColor() else hex.color = tileInfo.getBaseTerrain().getColor().lerp(Color.GRAY, 0.5f) // Todo add to baseterrain as function } } diff --git a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt index a8c500d7af..a13b770899 100644 --- a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt @@ -81,7 +81,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: - val positionalVector = HexMath().Hex2WorldCoords(tileInfo.position) + val positionalVector = HexMath().hex2WorldCoords(tileInfo.position) val groupSize = 50 group.setPosition(worldScreen.stage.width / 2 + positionalVector.x * 0.8f * groupSize.toFloat(), worldScreen.stage.height / 2 + positionalVector.y * 0.8f * groupSize.toFloat()) @@ -156,7 +156,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: val unitType = unit.baseUnit().unitType val attackableTiles: List = when{ - unitType==UnitType.Civilian -> unit.getDistanceToTiles().keys.toList() + unitType.isCivilian() -> unit.getDistanceToTiles().keys.toList() else -> UnitAutomation().getAttackableEnemies(unit, unit.getDistanceToTiles()).map { it.tileToAttack } } @@ -165,7 +165,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: it.getUnits().isNotEmpty() && it.getUnits().first().owner != unit.owner && (playerViewableTilePositions.contains(it.position) || UnCivGame.Current.viewEntireMapForDebug)}) { - if(unit.baseUnit().unitType== UnitType.Civilian) tileGroups[tile]!!.hideCircle() + if(unit.baseUnit().unitType.isCivilian()) tileGroups[tile]!!.hideCircle() else { tileGroups[tile]!!.showCircle(colorFromRGB(237, 41, 57)) tileGroups[tile]!!.showCrosshair() diff --git a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt index 865343a4e6..c0eb55ca5c 100644 --- a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt +++ b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt @@ -31,7 +31,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() { fun update() { val unitTable = worldScreen.bottomBar.unitTable if (unitTable.selectedUnit == null - || unitTable.selectedUnit!!.baseUnit().unitType == UnitType.Civilian){ + || unitTable.selectedUnit!!.baseUnit().unitType.isCivilian()){ hide() return } // no attacker @@ -102,7 +102,7 @@ class BattleTable(val worldScreen: WorldScreen): Table() { else if (damageToDefender>defender.getHealth()) damageToDefender=defender.getHealth() - if(attacker.isMelee() && (defender.getUnitType()==UnitType.Civilian + if(attacker.isMelee() && (defender.getUnitType().isCivilian() || defender.getUnitType()==UnitType.City && defender.isDefeated())) { add("") add("{Captured!}".tr()) diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index 14a8cec1e3..57d6338376 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -42,7 +42,7 @@ class UnitActions { },true) } - if(unit.baseUnit().unitType!= UnitType.Civilian + if(!unit.baseUnit().unitType.isCivilian() && !unit.hasUnique("No defensive terrain bonus") && !unit.isFortified()) { actionList += UnitAction("Fortify", { unit.action = "Fortify 0" }, unit.currentMovement != 0f) } @@ -59,7 +59,7 @@ class UnitActions { actionList += UnitAction("Stop exploration", { unit.action = null }, true) } - if(unit.baseUnit().unitType!= UnitType.Civilian && unit.promotions.canBePromoted()){ + if(!unit.baseUnit().unitType.isCivilian() && unit.promotions.canBePromoted()){ actionList += UnitAction("Promote", {UnCivGame.Current.screen = PromotionPickerScreen(unit)}, unit.currentMovement != 0f) diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt index 0498fb7cf5..c92c7ee81d 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt @@ -4,7 +4,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.logic.map.MapUnit import com.unciv.logic.map.TileInfo -import com.unciv.models.gamebasics.unit.UnitType import com.unciv.ui.tilegroups.TileGroup import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.WorldScreen @@ -65,13 +64,13 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ unitNameLabel.setText(nameLabelText) var unitLabelText = "Movement".tr()+": " + unit.getMovementString() - if (unit.baseUnit().unitType != UnitType.Civilian) + if (!unit.baseUnit().unitType.isCivilian()) unitLabelText += "\n"+"Strength".tr()+": " + unit.baseUnit().strength if (unit.baseUnit().rangedStrength!=0) unitLabelText += "\n"+"Ranged strength".tr()+": "+unit.baseUnit().rangedStrength - if (unit.baseUnit().unitType != UnitType.Civilian) + if (!unit.baseUnit().unitType.isCivilian()) unitLabelText += "\n"+"XP".tr()+": "+unit.promotions.XP+"/"+unit.promotions.xpForNextPromotion() if(unit.isFortified() && unit.getFortificationTurns()>0)