Improve BaseUnit hasUnique(FoundCity) handling (#10063)

This commit is contained in:
SomeTroglodyte 2023-09-05 14:40:55 +02:00 committed by GitHub
parent f7069851c7
commit a2fa4cebf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 21 additions and 17 deletions

View File

@ -18,8 +18,8 @@ import com.unciv.models.ruleset.ModOptionsConstants
import com.unciv.models.ruleset.Ruleset
import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unique.UniqueTriggerActivation
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stats
import com.unciv.models.translations.equalsPlaceholderText
@ -416,7 +416,7 @@ object GameStarter {
ruleset: Ruleset
) {
val startingEra = gameInfo.gameParameters.startingEra
val settlerLikeUnits = ruleset.units.filter { it.value.hasUnique(UniqueType.FoundCity) }
val settlerLikeUnits = ruleset.units.filter { it.value.isCityFounder() }
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
val startingLocation = startingLocations[civ]!!
@ -539,7 +539,7 @@ object GameStarter {
): HashMap<Civilization, Tile> {
val civsOrderedByAvailableLocations = getCivsOrderedByAvailableLocations(civs, tileMap)
for (minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size / 6 downTo 0) {
val freeTiles = getFreeTiles(tileMap, landTilesInBigEnoughGroup, minimumDistanceBetweenStartingLocations)
@ -581,12 +581,12 @@ object GameStarter {
): HashMap<Civilization, Tile>? {
val startingLocations = HashMap<Civilization, Tile>()
for (civ in civsOrderedByAvailableLocations) {
val startingLocation = getCivStartingLocation(civ, tileMap, freeTiles, startScores)
startingLocation ?: break
startingLocations[civ] = startingLocation
val distanceToNext = minimumDistanceBetweenStartingLocations /
(if (civ.isCityState()) 2 else 1) // We allow city states to squeeze in tighter
freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position, distanceToNext)

View File

@ -1026,7 +1026,7 @@ object NextTurnAutomation {
val sortedUnits = civInfo.units.getCivUnits().sortedBy { unit -> getUnitPriority(unit, isAtWar) }
for (unit in sortedUnits) UnitAutomation.automateUnitMoves(unit)
}
private fun getUnitPriority(unit: MapUnit, isAtWar: Boolean): Int {
if (unit.isCivilian() && !unit.isGreatPersonOfType("War")) return 1 // Civilian
if (unit.baseUnit.isAirUnit()) return 2
@ -1078,13 +1078,13 @@ object NextTurnAutomation {
if (civInfo.getHappiness() <= civInfo.cities.size) return
val settlerUnits = civInfo.gameInfo.ruleset.units.values
.filter { it.hasUnique(UniqueType.FoundCity) && it.isBuildable(civInfo) }
.filter { it.isCityFounder() && it.isBuildable(civInfo) }
if (settlerUnits.isEmpty()) return
if (!civInfo.units.getCivUnits().none { it.hasUnique(UniqueType.FoundCity) }) return
if (civInfo.cities.any {
val currentConstruction = it.cityConstructions.getCurrentConstruction()
currentConstruction is BaseUnit && currentConstruction.hasUnique(UniqueType.FoundCity)
currentConstruction is BaseUnit && currentConstruction.isCityFounder()
}) return
if (civInfo.units.getCivUnits().none { it.isMilitary() }) return // We need someone to defend him first

View File

@ -8,9 +8,9 @@ import com.unciv.models.ruleset.RulesetObject
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.ui.screens.civilopediascreen.FormattedLine
import com.unciv.ui.components.Fonts
import com.unciv.ui.components.extensions.colorFromRGB
import com.unciv.ui.screens.civilopediascreen.FormattedLine
class Era : RulesetObject() {
var eraNumber: Int = -1
@ -88,7 +88,7 @@ class Era : RulesetObject() {
val startingSettlerName: String =
if (startingSettlerUnit in ruleset.units) startingSettlerUnit
else ruleset.units.values
.firstOrNull { it.hasUnique(UniqueType.FoundCity) }
.firstOrNull { it.isCityFounder() }
?.name
?: throw UncivShowableException("No Settler unit found for era $name")
val startingWorkerName: String =

View File

@ -56,7 +56,7 @@ object UniqueTriggerActivation {
val unit = ruleSet.units[unitName]
if ((chosenCity == null && tile == null)
|| unit == null
|| unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger())
|| unit.isCityFounder() && civInfo.isOneCityChallenger())
return false
val limit = unit.getMatchingUniques(UniqueType.MaxNumberBuildable)
@ -83,7 +83,7 @@ object UniqueTriggerActivation {
UniqueType.OneTimeAmountFreeUnits -> {
val unitName = unique.params[1]
val unit = ruleSet.units[unitName]
if ((chosenCity == null && tile == null) || unit == null || (unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger()))
if ((chosenCity == null && tile == null) || unit == null || (unit.isCityFounder() && civInfo.isOneCityChallenger()))
return false
val limit = unit.getMatchingUniques(UniqueType.MaxNumberBuildable)
@ -118,7 +118,7 @@ object UniqueTriggerActivation {
}
UniqueType.OneTimeFreeUnitRuins -> {
var unit = civInfo.getEquivalentUnit(unique.params[0])
if ( unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger()) {
if ( unit.isCityFounder() && civInfo.isOneCityChallenger()) {
val replacementUnit = ruleSet.units.values
.firstOrNull {
it.getMatchingUniques(UniqueType.BuildImprovements)

View File

@ -215,7 +215,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
//movement penalty
if (boughtWith != null && !civInfo.gameInfo.gameParameters.godMode && !unit.hasUnique(UniqueType.MoveImmediatelyOnceBought))
unit.currentMovement = 0f
if (this.isCivilian()) return true // tiny optimization makes save files a few bytes smaller
addConstructionBonuses(unit, cityConstructions)
@ -300,6 +300,10 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
}
}
/** Determine whether this is a City-founding unit - abstract, **without any game context**.
* Use other methods for MapUnits or when there is a better StateForConditionals available. */
fun isCityFounder() = hasUnique(UniqueType.FoundCity, StateForConditionals.IgnoreConditionals)
fun isGreatPerson() = getMatchingUniques(UniqueType.GreatPerson).any()
fun isGreatPersonOfType(type: String) = getMatchingUniques(UniqueType.GreatPerson).any { it.params[0] == type }

View File

@ -173,7 +173,7 @@ class RulesetValidator(val ruleset: Ruleset) {
checkUniques(ruleset.globalUniques, lines, rulesetSpecific, tryFixUnknownUniques)
if (ruleset.units.values.none { it.hasUnique(UniqueType.FoundCity, StateForConditionals.IgnoreConditionals) })
if (ruleset.units.values.none { it.isCityFounder() })
lines += "No city-founding units in ruleset!"
for (unit in ruleset.units.values) {
@ -348,7 +348,7 @@ class RulesetValidator(val ruleset: Ruleset) {
lines += "Nonexistent building $building built by settlers when starting in ${era.name}"
// todo the whole 'starting unit' thing needs to be redone, there's no reason we can't have a single list containing all the starting units.
if (era.startingSettlerUnit !in ruleset.units
&& ruleset.units.values.none { it.hasUnique(UniqueType.FoundCity) })
&& ruleset.units.values.none { it.isCityFounder() })
lines += "Nonexistent unit ${era.startingSettlerUnit} marked as starting unit when starting in ${era.name}"
if (era.startingWorkerCount != 0 && era.startingWorkerUnit !in ruleset.units
&& ruleset.units.values.none { it.hasUnique(UniqueType.BuildImprovements) })