Forts and citadels (with AI) (#2325)
* Enabled Forts & Citadels * Friendly territory checks * Citadel damage & notifications * Sprites, Icons, Translation & Atlas * Obsolete tests are removed * NullReferenceException code is fixed * Refactoring: using the static object * AI for the forts and citadels * Display defence stats * Exclude enemies tiles as candidates Co-authored-by: r3versi <fluo392@gmail.com>
This commit is contained in:
parent
10762a3873
commit
29a077a803
19 changed files with 197 additions and 111 deletions
BIN
android/Images/ImprovementIcons/Citadel.png
Normal file
BIN
android/Images/ImprovementIcons/Citadel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
android/Images/ImprovementIcons/Fort.png
Normal file
BIN
android/Images/ImprovementIcons/Fort.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 951 B |
|
@ -79,7 +79,16 @@
|
|||
"improvingTech": "Compass",
|
||||
"improvingTechStats": {"gold": 1}
|
||||
},
|
||||
|
||||
|
||||
// Military improvement
|
||||
{
|
||||
name: "Fort",
|
||||
terrainsCanBeBuiltOn: ["Plains","Grassland","Desert","Hill","Tundra","Snow"],
|
||||
turnsToBuild: 6,
|
||||
techRequired: "Engineering",
|
||||
uniques: ["Gives a defensive bonus of 50%"]
|
||||
},
|
||||
|
||||
// Transportation
|
||||
{
|
||||
"name": "Road",
|
||||
|
@ -151,7 +160,12 @@
|
|||
"improvingTech": "Economics",
|
||||
"improvingTechStats": {"gold": 1}
|
||||
},
|
||||
|
||||
{
|
||||
name: "Citadel",
|
||||
uniques: ["Gives a defensive bonus of 100%", "Deal 30 damage to adjacent enemy units"]
|
||||
// TODO (G&K): adds every tile around it to your territory
|
||||
},
|
||||
|
||||
//Civilization unique improvements
|
||||
{
|
||||
"name": "Moai",
|
||||
|
|
|
@ -1324,8 +1324,7 @@
|
|||
"name": "Great General",
|
||||
"unbuildable": true,
|
||||
"unitType": "Civilian",
|
||||
"uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%"],
|
||||
//todo : should be able to build mega-fort
|
||||
"uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", "Can build improvement: Citadel"],
|
||||
"movement": 2
|
||||
},
|
||||
{
|
||||
|
@ -1334,8 +1333,7 @@
|
|||
"unitType": "Civilian",
|
||||
"uniqueTo": "Mongolia",
|
||||
"replaces": "Great General",
|
||||
"uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", "Heal adjacent units for an additional 15 HP per turn"],
|
||||
//todo : should be able to build mega-fort
|
||||
"uniques": ["Can start an 8-turn golden age","Bonus for units in 2 tile radius 15%", "Heal adjacent units for an additional 15 HP per turn", "Can build improvement: Citadel"],
|
||||
"movement": 5
|
||||
}
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
|
||||
# Tutorial tasks
|
||||
|
||||
Move a unit!\nClick on a unit > Click on a destination > Click the arrow popup = Sposta un'unità!\nClicca su un'unità > Clicca su una destinazione > Clicca sul popup con la freccia
|
||||
|
|
|
@ -44,7 +44,7 @@ object Constants {
|
|||
const val researchAgreement = "Research Agreement"
|
||||
const val openBorders = "Open Borders"
|
||||
const val random = "Random"
|
||||
val greatImprovements = listOf("Academy", "Landmark", "Manufactory", "Customs house")
|
||||
val greatImprovements = listOf("Academy", "Landmark", "Manufactory", "Customs house", "Citadel")
|
||||
|
||||
val unitActionSetUp = "Set Up"
|
||||
val unitActionSleep = "Sleep"
|
||||
|
|
|
@ -212,7 +212,7 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
|||
|
||||
// If this city is the closest city to another civ, that makes it a likely candidate for attack
|
||||
if (civInfo.getKnownCivs().filter { it.cities.isNotEmpty() }
|
||||
.any { NextTurnAutomation().getClosestCities(civInfo, it).city1 == cityInfo })
|
||||
.any { NextTurnAutomation.getClosestCities(civInfo, it).city1 == cityInfo })
|
||||
modifier *= 1.5f
|
||||
|
||||
addChoice(relativeCostEffectiveness, defensiveBuilding.name, modifier)
|
||||
|
|
|
@ -282,21 +282,6 @@ class NextTurnAutomation{
|
|||
}
|
||||
}
|
||||
|
||||
fun getMinDistanceBetweenCities(civ1: CivilizationInfo, civ2: CivilizationInfo): Int {
|
||||
return getClosestCities(civ1,civ2).aerialDistance
|
||||
}
|
||||
|
||||
data class CityDistance(val city1:CityInfo, val city2:CityInfo, val aerialDistance: Int)
|
||||
fun getClosestCities(civ1: CivilizationInfo, civ2: CivilizationInfo): CityDistance {
|
||||
val cityDistances = arrayListOf<CityDistance>()
|
||||
for (civ1city in civ1.cities)
|
||||
for (civ2city in civ2.cities)
|
||||
cityDistances.add(CityDistance(civ1city, civ2city,
|
||||
civ1city.getCenterTile().aerialDistanceTo(civ2city.getCenterTile())))
|
||||
|
||||
return cityDistances.minBy { it.aerialDistance }!!
|
||||
}
|
||||
|
||||
private fun offerDeclarationOfFriendship(civInfo: CivilizationInfo) {
|
||||
val civsThatWeCanDeclareFriendshipWith = civInfo.getKnownCivs()
|
||||
.asSequence()
|
||||
|
@ -509,4 +494,22 @@ class NextTurnAutomation{
|
|||
diplomacyManager.removeFlag(DiplomacyFlags.SettledCitiesNearUs)
|
||||
}
|
||||
|
||||
companion object
|
||||
{
|
||||
fun getMinDistanceBetweenCities(civ1: CivilizationInfo, civ2: CivilizationInfo): Int {
|
||||
return getClosestCities(civ1,civ2).aerialDistance
|
||||
}
|
||||
|
||||
data class CityDistance(val city1:CityInfo, val city2:CityInfo, val aerialDistance: Int)
|
||||
|
||||
fun getClosestCities(civ1: CivilizationInfo, civ2: CivilizationInfo): CityDistance {
|
||||
val cityDistances = arrayListOf<CityDistance>()
|
||||
for (civ1city in civ1.cities)
|
||||
for (civ2city in civ2.cities)
|
||||
cityDistances.add(CityDistance(civ1city, civ2city,
|
||||
civ1city.getCenterTile().aerialDistanceTo(civ2city.getCenterTile())))
|
||||
|
||||
return cityDistances.minBy { it.aerialDistance }!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,16 +61,27 @@ class SpecificUnitAutomation {
|
|||
return
|
||||
}
|
||||
|
||||
//if no unit to follow, take refuge in city.
|
||||
// try to build a citadel
|
||||
if (WorkerAutomation(unit).evaluateFortPlacement(unit.currentTile, unit.civInfo))
|
||||
UnitActions.getGreatPersonBuildImprovementAction(unit)?.action?.invoke()
|
||||
|
||||
//if no unit to follow, take refuge in city or build citadel there.
|
||||
val reachableTest : (TileInfo) -> Boolean = {it.civilianUnit == null &&
|
||||
unit.movement.canMoveTo(it)
|
||||
&& unit.movement.canReach(it)}
|
||||
val cityToGarrison = unit.civInfo.cities.asSequence().map { it.getCenterTile() }
|
||||
.sortedBy { it.aerialDistanceTo(unit.currentTile) }
|
||||
.firstOrNull {
|
||||
it.civilianUnit == null && unit.movement.canMoveTo(it)
|
||||
&& unit.movement.canReach(it)
|
||||
}
|
||||
.firstOrNull { reachableTest(it) }
|
||||
|
||||
if (cityToGarrison != null) {
|
||||
unit.movement.headTowards(cityToGarrison)
|
||||
// try to find a good place for citadel nearby
|
||||
val potentialTilesNearCity = cityToGarrison.getTilesInDistanceRange(3..4)
|
||||
val tileForCitadel = potentialTilesNearCity.firstOrNull { reachableTest(it) &&
|
||||
WorkerAutomation(unit).evaluateFortPlacement(it, unit.civInfo) }
|
||||
if (tileForCitadel != null)
|
||||
unit.movement.headTowards(tileForCitadel)
|
||||
else
|
||||
unit.movement.headTowards(cityToGarrison)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,8 @@ class WorkerAutomation(val unit: MapUnit) {
|
|||
tile.containsGreatImprovement() -> null
|
||||
tile.containsUnfinishedGreatImprovement() -> null
|
||||
|
||||
// Defence is more important that civilian improvements
|
||||
evaluateFortPlacement(tile,civInfo) -> "Fort"
|
||||
// I think we can assume that the unique improvement is better
|
||||
uniqueImprovement!=null && tile.canBuildImprovement(uniqueImprovement,civInfo) -> uniqueImprovement.name
|
||||
|
||||
|
@ -208,4 +210,73 @@ class WorkerAutomation(val unit: MapUnit) {
|
|||
return unit.civInfo.gameInfo.ruleSet.tileImprovements[improvementString]!!
|
||||
}
|
||||
|
||||
private fun isAcceptableTileForFort(tile: TileInfo, civInfo: CivilizationInfo): Boolean
|
||||
{
|
||||
// don't build fort in the city
|
||||
if (tile.isCityCenter()) return false
|
||||
// don't build fort if it is already here
|
||||
if (tile.improvement == "Fort") return false
|
||||
// don't build on resource tiles
|
||||
if (tile.hasViewableResource(civInfo)) return false
|
||||
// don't build on great improvements
|
||||
if (tile.containsGreatImprovement() || tile.containsUnfinishedGreatImprovement()) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun evaluateFortPlacement(tile: TileInfo, civInfo: CivilizationInfo): Boolean {
|
||||
// build on our land only
|
||||
if ((tile.owningCity?.civInfo != civInfo) ||
|
||||
!isAcceptableTileForFort(tile, civInfo)) return false
|
||||
|
||||
val isHills = tile.getBaseTerrain().name == Constants.hill
|
||||
// if this place is not perfect, let's see if there is a better one
|
||||
val nearestTiles = tile.getTilesInDistance(2).filter{it.owningCity?.civInfo == civInfo}.toList()
|
||||
for (closeTile in nearestTiles) {
|
||||
// don't build forts too close to the cities
|
||||
if (closeTile.isCityCenter()) return false
|
||||
// don't build forts too close to other forts
|
||||
if (closeTile.improvement == "Fort" || closeTile.improvement == "Citadel"
|
||||
|| closeTile.improvementInProgress == "Fort") return false
|
||||
// there is another better tile for the fort
|
||||
if (!isHills && tile.getBaseTerrain().name == Constants.hill &&
|
||||
isAcceptableTileForFort(closeTile, civInfo)) return false
|
||||
}
|
||||
|
||||
val enemyCivs = civInfo.getKnownCivs()
|
||||
.filterNot { it == civInfo || it.cities.isEmpty() || !civInfo.getDiplomacyManager(it).canAttack() }
|
||||
// no potential enemies
|
||||
if (enemyCivs.isEmpty()) return false
|
||||
|
||||
val threatMapping : (CivilizationInfo) -> Int = {
|
||||
// the war is already a good nudge to build forts
|
||||
(if (civInfo.isAtWarWith(it)) 20 else 0) +
|
||||
// let's check also the force of the enemy
|
||||
when (Automation().threatAssessment(civInfo, it)) {
|
||||
ThreatLevel.VeryLow -> 1 // do not build forts
|
||||
ThreatLevel.Low -> 6 // too close, let's build until it is late
|
||||
ThreatLevel.Medium -> 10
|
||||
ThreatLevel.High -> 15 // they are strong, let's built until they reach us
|
||||
ThreatLevel.VeryHigh -> 20
|
||||
} }
|
||||
val enemyCivsIsCloseEnough = enemyCivs.filter { NextTurnAutomation.getMinDistanceBetweenCities(civInfo, it) <= threatMapping(it) }
|
||||
// no threat, let's not build fort
|
||||
if (enemyCivsIsCloseEnough.isEmpty()) return false
|
||||
|
||||
// make list of enemy cities as sources of threat
|
||||
val enemyCities = mutableListOf<TileInfo>()
|
||||
enemyCivsIsCloseEnough.forEach { enemyCities.addAll(it.cities.map { city -> city.getCenterTile() } ) }
|
||||
|
||||
// find closest enemy city
|
||||
val closestEnemyCity = enemyCities.minBy { it.aerialDistanceTo(tile) }!!
|
||||
val distanceToEnemy = tile.aerialDistanceTo(closestEnemyCity)
|
||||
|
||||
// find closest our city to defend from this enemy city
|
||||
val closestOurCity = tile.owningCity!!.getCenterTile()
|
||||
val distanceBetweenCities = closestEnemyCity.aerialDistanceTo(closestOurCity)
|
||||
|
||||
// let's build fort on the front line, not behind the city
|
||||
return distanceBetweenCities > distanceToEnemy
|
||||
}
|
||||
|
||||
}
|
|
@ -160,6 +160,7 @@ class BattleDamage{
|
|||
|
||||
fun getDefenceModifiers(attacker: ICombatant, defender: MapUnitCombatant): HashMap<String, Float> {
|
||||
val modifiers = HashMap<String, Float>()
|
||||
val tile = defender.getTile()
|
||||
|
||||
if (defender.unit.isEmbarked()) {
|
||||
// embarked units get no defensive modifiers apart from this unique
|
||||
|
@ -172,11 +173,17 @@ class BattleDamage{
|
|||
|
||||
modifiers.putAll(getGeneralModifiers(defender, attacker))
|
||||
|
||||
modifiers.putAll(getTileSpecificModifiers(defender, defender.getTile()))
|
||||
modifiers.putAll(getTileSpecificModifiers(defender, tile))
|
||||
|
||||
if (!defender.unit.hasUnique("No defensive terrain bonus")) {
|
||||
val tileDefenceBonus = defender.getTile().getDefensiveBonus()
|
||||
if (tileDefenceBonus > 0) modifiers["Terrain"] = tileDefenceBonus
|
||||
val tileDefenceBonus = tile.getDefensiveBonus()
|
||||
if (tileDefenceBonus > 0)
|
||||
modifiers["Terrain"] = tileDefenceBonus
|
||||
|
||||
val improvement = tile.getTileImprovement()
|
||||
if (improvement != null && tile.isFriendlyTerritory(defender.getCivInfo()))
|
||||
if (improvement.hasUnique("Gives a defensive bonus of 50%")) modifiers[improvement.name] = 0.50f
|
||||
else if (improvement.hasUnique("Gives a defensive bonus of 100%")) modifiers[improvement.name] = 1.0f
|
||||
}
|
||||
|
||||
if(attacker.isRanged()) {
|
||||
|
@ -196,10 +203,9 @@ class BattleDamage{
|
|||
|
||||
private fun getTileSpecificModifiers(unit: MapUnitCombatant, tile: TileInfo): HashMap<String,Float> {
|
||||
val modifiers = HashMap<String,Float>()
|
||||
val isFriendlyTerritory = tile.getOwner()!=null && !unit.getCivInfo().isAtWarWith(tile.getOwner()!!)
|
||||
if(isFriendlyTerritory && unit.getCivInfo().containsBuildingUnique("+15% combat strength for units fighting in friendly territory"))
|
||||
if(tile.isFriendlyTerritory(unit.getCivInfo()) && unit.getCivInfo().containsBuildingUnique("+15% combat strength for units fighting in friendly territory"))
|
||||
modifiers["Himeji Castle"] = 0.15f
|
||||
if(!isFriendlyTerritory && unit.unit.hasUnique("+20% bonus outside friendly territory"))
|
||||
if(!tile.isFriendlyTerritory(unit.getCivInfo()) && unit.unit.hasUnique("+20% bonus outside friendly territory"))
|
||||
modifiers["Foreign Land"] = 0.2f
|
||||
|
||||
|
||||
|
|
|
@ -527,7 +527,7 @@ class CivilizationInfo {
|
|||
}
|
||||
|
||||
fun giftMilitaryUnitTo(otherCiv: CivilizationInfo) {
|
||||
val city = NextTurnAutomation().getClosestCities(this, otherCiv).city1
|
||||
val city = NextTurnAutomation.getClosestCities(this, otherCiv).city1
|
||||
val militaryUnit = city.cityConstructions.getConstructableUnits()
|
||||
.filter { !it.unitType.isCivilian() && it.unitType.isLandUnit() }
|
||||
.toList().random()
|
||||
|
|
|
@ -235,7 +235,7 @@ class DiplomacyManager() {
|
|||
*
|
||||
* This includes friendly and allied city-states and the open border treaties.
|
||||
*/
|
||||
fun isConsideredAllyTerritory(): Boolean {
|
||||
fun isConsideredFriendlyTerritory(): Boolean {
|
||||
if(civInfo.isCityState() && relationshipLevel() >= RelationshipLevel.Friend)
|
||||
return true
|
||||
return hasOpenBorders
|
||||
|
|
|
@ -411,25 +411,19 @@ class MapUnit {
|
|||
|
||||
/** Returns the health points [MapUnit] will receive if healing on [tileInfo] */
|
||||
fun rankTileForHealing(tileInfo: TileInfo): Int {
|
||||
val tileOwner = tileInfo.getOwner()
|
||||
val isAlliedTerritory = when {
|
||||
tileOwner == null -> false
|
||||
tileOwner == civInfo -> true
|
||||
!civInfo.knows(tileOwner) -> false
|
||||
else -> tileOwner.getDiplomacyManager(civInfo).isConsideredAllyTerritory()
|
||||
}
|
||||
val isFriendlyTerritory = tileInfo.isFriendlyTerritory(civInfo)
|
||||
|
||||
var healing = when {
|
||||
tileInfo.isCityCenter() -> 20
|
||||
tileInfo.isWater && isAlliedTerritory && type.isWaterUnit() -> 15 // Water unit on friendly water
|
||||
tileInfo.isWater && isFriendlyTerritory && type.isWaterUnit() -> 15 // Water unit on friendly water
|
||||
tileInfo.isWater -> 0 // All other water cases
|
||||
tileOwner == null -> 10 // Neutral territory
|
||||
isAlliedTerritory -> 15 // Allied territory
|
||||
tileInfo.getOwner() == null -> 10 // Neutral territory
|
||||
isFriendlyTerritory -> 15 // Allied territory
|
||||
else -> 5 // Enemy territory
|
||||
}
|
||||
|
||||
if (hasUnique("This unit and all others in adjacent tiles heal 5 additional HP. This unit heals 5 additional HP outside of friendly territory.")
|
||||
&& !isAlliedTerritory
|
||||
&& !isFriendlyTerritory
|
||||
// Additional healing from medic is only applied when the unit is able to heal
|
||||
&& healing > 0)
|
||||
healing += 5
|
||||
|
@ -439,7 +433,7 @@ class MapUnit {
|
|||
|
||||
fun endTurn() {
|
||||
doPostTurnAction()
|
||||
if(currentMovement== getMaxMovement().toFloat() // didn't move this turn
|
||||
if (currentMovement == getMaxMovement().toFloat() // didn't move this turn
|
||||
|| getUniques().contains("Unit will heal every turn, even if it performs an action")){
|
||||
heal()
|
||||
}
|
||||
|
@ -447,6 +441,8 @@ class MapUnit {
|
|||
if (action!!.endsWith(" until healed")) {
|
||||
action = null // wake up when healed
|
||||
}
|
||||
|
||||
getCitadelDamage()
|
||||
}
|
||||
|
||||
fun startTurn() {
|
||||
|
@ -662,5 +658,25 @@ class MapUnit {
|
|||
return sum
|
||||
}
|
||||
|
||||
private fun getCitadelDamage() {
|
||||
// Check for Citadel damage
|
||||
val applyCitadelDamage = currentTile.neighbors
|
||||
.filter{ it.getOwner() != null && civInfo.isAtWarWith(it.getOwner()!!) }
|
||||
.map{ it.getTileImprovement() }
|
||||
.filter{ it != null && it.hasUnique("Deal 30 damage to adjacent enemy units") }
|
||||
.any()
|
||||
|
||||
if (applyCitadelDamage) {
|
||||
health -= 30
|
||||
|
||||
if (health <= 0) {
|
||||
civInfo.addNotification("An enemy [Citadel] has destroyed our [$name]", currentTile.position, Color.RED)
|
||||
destroy()
|
||||
} else {
|
||||
civInfo.addNotification("An enemy [Citadel] has attacked our [$name]", currentTile.position, Color.RED)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//endregion
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.unciv.logic.map
|
||||
package com.unciv.logic.map
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.unciv.Constants
|
||||
|
@ -132,9 +132,20 @@ open class TileInfo {
|
|||
return containingCity.civInfo
|
||||
}
|
||||
|
||||
fun isFriendlyTerritory(civInfo: CivilizationInfo): Boolean {
|
||||
val tileOwner = getOwner()
|
||||
return when {
|
||||
tileOwner == null -> false
|
||||
tileOwner == civInfo -> true
|
||||
!civInfo.knows(tileOwner) -> false
|
||||
else -> tileOwner.getDiplomacyManager(civInfo).isConsideredFriendlyTerritory()
|
||||
}
|
||||
}
|
||||
|
||||
fun getTerrainFeature(): Terrain? =
|
||||
if (terrainFeature == null) null else ruleset.terrains[terrainFeature!!]
|
||||
|
||||
|
||||
fun isWorked(): Boolean {
|
||||
val city = getCity()
|
||||
return city!=null && city.workedTiles.contains(position)
|
||||
|
@ -337,8 +348,17 @@ open class TileInfo {
|
|||
milUnitString += " - "+militaryUnit!!.civInfo.civName.tr()
|
||||
lineList += milUnitString
|
||||
}
|
||||
if(getDefensiveBonus()!=0f){
|
||||
var defencePercentString = (getDefensiveBonus()*100).toInt().toString()+"%"
|
||||
var defenceBonus = getDefensiveBonus()
|
||||
val tileImprovement = getTileImprovement()
|
||||
if (tileImprovement != null) {
|
||||
defenceBonus += when {
|
||||
tileImprovement.hasUnique("Gives a defensive bonus of 50%") -> 0.5f
|
||||
tileImprovement.hasUnique("Gives a defensive bonus of 100%") -> 1.0f
|
||||
else -> 0.0f
|
||||
}
|
||||
}
|
||||
if(defenceBonus != 0.0f){
|
||||
var defencePercentString = (defenceBonus*100).toInt().toString()+"%"
|
||||
if(!defencePercentString.startsWith("-")) defencePercentString = "+$defencePercentString"
|
||||
lineList += "[$defencePercentString] to unit defence".tr()
|
||||
}
|
||||
|
|
|
@ -64,5 +64,7 @@ class TileImprovement : NamedStats() {
|
|||
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
|
||||
fun hasUnique(unique: String) = uniques.contains(unique)
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table(){
|
|||
"Construct Academy" -> return ImageGetter.getImprovementIcon("Academy")
|
||||
"Start Golden Age" -> return ImageGetter.getUnitIcon("Great Artist")
|
||||
"Construct Landmark" -> return ImageGetter.getImprovementIcon("Landmark")
|
||||
"Construct Citadel" -> return ImageGetter.getImprovementIcon("Citadel")
|
||||
"Hurry Wonder" -> return ImageGetter.getUnitIcon("Great Engineer")
|
||||
"Construct Manufactory" -> return ImageGetter.getImprovementIcon("Manufactory")
|
||||
"Conduct Trade Mission" -> return ImageGetter.getUnitIcon("Great Merchant")
|
||||
|
|
|
@ -153,6 +153,8 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
|
|||
* [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
|
||||
* [Fort](https://thenounproject.com/term/fort/1697645/) By Adrien Coquet
|
||||
* [Citadel](https://thenounproject.com/term/fort/1697646/) By Adrien Coquet
|
||||
|
||||
## Buildings
|
||||
|
||||
|
|
|
@ -45,64 +45,6 @@ class TranslationTests {
|
|||
allUnitActionsHaveTranslation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allTerrainsHaveTranslation() {
|
||||
val strings: Set<String> = ruleset.terrains.keys
|
||||
val allStringsHaveTranslation = allStringAreTranslated(strings)
|
||||
Assert.assertTrue("This test will only pass when there is a translation for all buildings",
|
||||
allStringsHaveTranslation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allTerrainUniquesHaveTranslation() {
|
||||
val strings: MutableSet<String> = HashSet()
|
||||
for (terrain in ruleset.terrains.values) {
|
||||
strings.addAll(terrain.uniques)
|
||||
}
|
||||
val allStringsHaveTranslation = allStringAreTranslated(strings)
|
||||
Assert.assertTrue("This test will only pass when there is a translation for all terrain uniques",
|
||||
allStringsHaveTranslation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allImprovementsHaveTranslation() {
|
||||
val strings: Set<String> = ruleset.tileImprovements.keys
|
||||
val allStringsHaveTranslation = allStringAreTranslated(strings)
|
||||
Assert.assertTrue("This test will only pass when there is a translation for all improvements",
|
||||
allStringsHaveTranslation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allImprovementUniquesHaveTranslation() {
|
||||
val strings: MutableSet<String> = HashSet()
|
||||
for (improvement in ruleset.tileImprovements.values) {
|
||||
strings.addAll(improvement.uniques)
|
||||
}
|
||||
val allStringsHaveTranslation = allStringAreTranslated(strings)
|
||||
Assert.assertTrue("This test will only pass when there is a translation for all improvements uniques",
|
||||
allStringsHaveTranslation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allTechnologiesHaveTranslation() {
|
||||
val strings: Set<String> = ruleset.technologies.keys
|
||||
val allStringsHaveTranslation = allStringAreTranslated(strings)
|
||||
Assert.assertTrue("This test will only pass when there is a translation for all technologies",
|
||||
allStringsHaveTranslation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun allTechnologiesQuotesHaveTranslation() {
|
||||
val strings: MutableSet<String> = HashSet()
|
||||
for (tech in ruleset.technologies.values) {
|
||||
strings.add(tech.quote)
|
||||
}
|
||||
val allStringsHaveTranslation = allStringAreTranslated(strings)
|
||||
Assert.assertTrue("This test will only pass when there is a translation for all technologies quotes",
|
||||
allStringsHaveTranslation)
|
||||
}
|
||||
|
||||
|
||||
private fun allStringAreTranslated(strings: Set<String>): Boolean {
|
||||
var allStringsHaveTranslation = true
|
||||
for (key in strings) {
|
||||
|
|
Loading…
Reference in a new issue