diff --git a/android/Images/ImprovementIcons/Moai.png b/android/Images/ImprovementIcons/Moai.png new file mode 100644 index 00000000..e4311c47 Binary files /dev/null and b/android/Images/ImprovementIcons/Moai.png differ diff --git a/android/assets/jsons/TileImprovements.json b/android/assets/jsons/TileImprovements.json index a11982ea..66e96bec 100644 --- a/android/assets/jsons/TileImprovements.json +++ b/android/assets/jsons/TileImprovements.json @@ -146,17 +146,18 @@ }, //Civilization unique improvements - /* { name:"Moai", uniqueTo:"Polynesia", culture:1, turnsToBuild:4, - improvingTech:"Construction", - uniques:["+1 additional Culture for each adjacent Moai","+1 Gold after researching Flight"], - terrainsCanBeBuiltOn:["Hill"], + uniques:["+1 additional Culture for each adjacent Moai","Can only be built on Coastal tiles"], + techRequired:"Construction", + improvingTech:"Flight", + improvingTechStats:{gold:1} //It can be colored in orange }, + /* { name:"Terrace Farm", uniqueTo:"Inca", diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 7e1a8a2e..f4861d63 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -174,7 +174,7 @@ class GameInfo { val waterUnits = unitList.filter { it.unitType.isWaterUnit() } val unit:String - if(waterUnits.isNotEmpty() && tileToPlace.neighbors.any{ it.baseTerrain==Constants.coast } && Random().nextBoolean()) + if(waterUnits.isNotEmpty() && tileToPlace.isCoastalTile() && Random().nextBoolean()) unit=waterUnits.random().name else unit = landUnits.random().name diff --git a/core/src/com/unciv/logic/GameStarter.kt b/core/src/com/unciv/logic/GameStarter.kt index 9f906728..83898c6a 100644 --- a/core/src/com/unciv/logic/GameStarter.kt +++ b/core/src/com/unciv/logic/GameStarter.kt @@ -131,7 +131,7 @@ class GameStarter{ if (startBias.startsWith("Avoid ")) { val tileToAvoid = startBias.removePrefix("Avoid ") preferredTiles = preferredTiles.filter { it.baseTerrain != tileToAvoid && it.terrainFeature != tileToAvoid } - } else if (startBias == Constants.coast) preferredTiles = preferredTiles.filter { it.neighbors.any { n -> n.baseTerrain == startBias } } + } else if (startBias == Constants.coast) preferredTiles = preferredTiles.filter { it.isCoastalTile() } else preferredTiles = preferredTiles.filter { it.baseTerrain == startBias || it.terrainFeature == startBias } } diff --git a/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt b/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt index b736be35..491d0d52 100644 --- a/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt @@ -1,6 +1,5 @@ package com.unciv.logic.automation -import com.unciv.Constants import com.unciv.UnCivGame import com.unciv.logic.battle.MapUnitCombatant import com.unciv.logic.civilization.CivilizationInfo @@ -78,7 +77,7 @@ class SpecificUnitAutomation{ .take(5) .toList() var rank = top5Tiles.asSequence().map { nearbyTileRankings[it]!! }.sum() - if (tileInfo.neighbors.any { it.baseTerrain == Constants.coast }) rank += 5 + if (tileInfo.isCoastalTile()) rank += 5 val luxuryResourcesInCityArea = tileInfo.getTilesAtDistance(2).filter { it.resource!=null } .map { it.getTileResource() }.filter { it.resourceType==ResourceType.Luxury }.distinct() diff --git a/core/src/com/unciv/logic/automation/WorkerAutomation.kt b/core/src/com/unciv/logic/automation/WorkerAutomation.kt index ef5af5b1..914ab303 100644 --- a/core/src/com/unciv/logic/automation/WorkerAutomation.kt +++ b/core/src/com/unciv/logic/automation/WorkerAutomation.kt @@ -46,7 +46,7 @@ class WorkerAutomation(val unit: MapUnit) { val citiesToNumberOfUnimprovedTiles = HashMap() for (city in unit.civInfo.cities) { citiesToNumberOfUnimprovedTiles[city.name] = - city.getTiles().count { it.isLand && tileNeedToImprove(it, unit.civInfo) } + city.getTiles().count { it.isLand && tileCanBeImproved(it, unit.civInfo) } } val mostUndevelopedCity = unit.civInfo.cities @@ -118,7 +118,7 @@ class WorkerAutomation(val unit: MapUnit) { val workableTiles = currentTile.getTilesInDistance(4) .filter { (it.civilianUnit== null || it == currentTile) - && tileNeedToImprove(it, unit.civInfo) } + && tileCanBeImproved(it, unit.civInfo) } .sortedByDescending { getPriority(it, unit.civInfo) }.toMutableList() // the tile needs to be actually reachable - more difficult than it seems, @@ -134,14 +134,25 @@ class WorkerAutomation(val unit: MapUnit) { else return currentTile } - private fun tileNeedToImprove(tile: TileInfo, civInfo: CivilizationInfo): Boolean { + private fun tileCanBeImproved(tile: TileInfo, civInfo: CivilizationInfo): Boolean { if (!tile.isLand || tile.getBaseTerrain().impassable) return false val city=tile.getCity() if (city == null || city.civInfo != civInfo) return false - return (tile.improvement == null || (tile.hasViewableResource(civInfo) && !tile.containsGreatImprovement() && tile.getTileResource().improvement != tile.improvement)) - && (tile.containsUnfinishedGreatImprovement() || tile.canBuildImprovement(chooseImprovement(tile, civInfo), civInfo)) + + if(tile.improvement==null){ + if(tile.improvementInProgress!=null) return true + val chosenImprovement = chooseImprovement(tile, civInfo) + if(chosenImprovement!=null) return true + } + else{ + if(!tile.containsGreatImprovement() && tile.hasViewableResource(civInfo) + && tile.getTileResource().improvement != tile.improvement) + return true + } + + return false // cou;dn't find anything to construct here } private fun getPriority(tileInfo: TileInfo, civInfo: CivilizationInfo): Int { diff --git a/core/src/com/unciv/logic/map/TileInfo.kt b/core/src/com/unciv/logic/map/TileInfo.kt index 3efaab93..d7dc8bcf 100644 --- a/core/src/com/unciv/logic/map/TileInfo.kt +++ b/core/src/com/unciv/logic/map/TileInfo.kt @@ -205,16 +205,20 @@ open class TileInfo { return stats } - fun canBuildImprovement(improvement: TileImprovement?, civInfo: CivilizationInfo): Boolean { - if (improvement == null) return false + fun canBuildImprovement(improvement: TileImprovement, civInfo: CivilizationInfo): Boolean { if (isCityCenter() || improvement.name == this.improvement) return false - val topTerrain = if (terrainFeature == null) getBaseTerrain() else getTerrainFeature() + if(improvement.uniqueTo!=null && improvement.uniqueTo!=civInfo.civName) return false if (improvement.techRequired != null && !civInfo.tech.isResearched(improvement.techRequired!!)) return false + + val topTerrain = if (terrainFeature == null) getBaseTerrain() else getTerrainFeature() if (improvement.terrainsCanBeBuiltOn.contains(topTerrain!!.name)) return true + if (improvement.name == "Road" && this.roadStatus === RoadStatus.None) return true if (improvement.name == "Railroad" && this.roadStatus !== RoadStatus.Railroad) return true if(improvement.name == "Remove Road" && this.roadStatus===RoadStatus.Road) return true if(improvement.name == "Remove Railroad" && this.roadStatus===RoadStatus.Railroad) return true + + if("Can only be built on Coastal tiles" in improvement.uniques && isCoastalTile()) return true if (topTerrain.unbuildable && !(topTerrain.name==Constants.forest && improvement.name=="Camp")) return false return hasViewableResource(civInfo) && getTileResource().improvement == improvement.name @@ -222,6 +226,8 @@ open class TileInfo { fun hasImprovementInProgress() = improvementInProgress!=null + fun isCoastalTile() = neighbors.any { it.baseTerrain==Constants.coast } + fun hasViewableResource(civInfo: CivilizationInfo): Boolean { return resource != null && (getTileResource().revealedBy == null || civInfo.tech.isResearched(getTileResource().revealedBy!!)) } diff --git a/core/src/com/unciv/models/gamebasics/Building.kt b/core/src/com/unciv/models/gamebasics/Building.kt index c926b74c..eea546b9 100644 --- a/core/src/com/unciv/models/gamebasics/Building.kt +++ b/core/src/com/unciv/models/gamebasics/Building.kt @@ -245,7 +245,7 @@ class Building : NamedStats(), IConstruction{ return "Must not be on hill" if("Can only be built in coastal cities" in uniques - && !construction.cityInfo.getCenterTile().neighbors.any { it.baseTerrain==Constants.coast }) + && !construction.cityInfo.getCenterTile().isCoastalTile()) return "Can only be built in coastal cities" if("Can only be built in annexed cities" in uniques diff --git a/core/src/com/unciv/models/gamebasics/tile/TileImprovement.kt b/core/src/com/unciv/models/gamebasics/tile/TileImprovement.kt index 0c3dd5ab..05e65bd3 100644 --- a/core/src/com/unciv/models/gamebasics/tile/TileImprovement.kt +++ b/core/src/com/unciv/models/gamebasics/tile/TileImprovement.kt @@ -15,8 +15,12 @@ class TileImprovement : NamedStats(), ICivilopedia { var improvingTech: String? = null var improvingTechStats: Stats? = null + var uniqueTo:String? = null + var uniques = ArrayList() private val turnsToBuild: Int = 0 // This is the base cost. + + fun getTurnsToBuild(civInfo: CivilizationInfo): Int { var realTurnsToBuild = turnsToBuild.toFloat() if (civInfo.containsBuildingUnique("Worker construction increased 25%")) diff --git a/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt b/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt index ef25e080..e68daa11 100644 --- a/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/gamebasics/unit/BaseUnit.kt @@ -127,7 +127,7 @@ class BaseUnit : INamed, IConstruction, ICivilopedia { fun getRejectionReason(construction: CityConstructions): String { val civRejectionReason = getRejectionReason(construction.cityInfo.civInfo) if(civRejectionReason!="") return civRejectionReason - if(unitType.isWaterUnit() && construction.cityInfo.getCenterTile().neighbors.none { it.baseTerrain==Constants.coast }) + if(unitType.isWaterUnit() && !construction.cityInfo.getCenterTile().isCoastalTile()) return "Can't build water units by the coast" return "" } diff --git a/docs/Credits.md b/docs/Credits.md index b743404f..292afcb9 100644 --- a/docs/Credits.md +++ b/docs/Credits.md @@ -145,6 +145,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https: * [Ruins](https://thenounproject.com/term/ruins/175277/) By Creative Stall for Ancient runs * [Ruins](https://thenounproject.com/term/ruins/3849/) By Paulo Volkova for City ruins * [Fishing Net](https://thenounproject.com/term/fishing-net/1073133/) By Made for Fishing Boats +* [Moai](https://thenounproject.com/search/?q=moai&i=2878111) By Template ## Buildings