mirror of
https://github.com/yairm210/Unciv.git
synced 2025-01-05 21:11:35 +07:00
Improve BaseUnit hasUnique(FoundCity) handling (#10063)
This commit is contained in:
parent
f7069851c7
commit
a2fa4cebf4
@ -18,8 +18,8 @@ import com.unciv.models.ruleset.ModOptionsConstants
|
|||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
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.UniqueTriggerActivation
|
||||||
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.models.ruleset.unit.BaseUnit
|
import com.unciv.models.ruleset.unit.BaseUnit
|
||||||
import com.unciv.models.stats.Stats
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.models.translations.equalsPlaceholderText
|
import com.unciv.models.translations.equalsPlaceholderText
|
||||||
@ -416,7 +416,7 @@ object GameStarter {
|
|||||||
ruleset: Ruleset
|
ruleset: Ruleset
|
||||||
) {
|
) {
|
||||||
val startingEra = gameInfo.gameParameters.startingEra
|
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() }) {
|
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() && !it.isSpectator() }) {
|
||||||
val startingLocation = startingLocations[civ]!!
|
val startingLocation = startingLocations[civ]!!
|
||||||
@ -539,7 +539,7 @@ object GameStarter {
|
|||||||
): HashMap<Civilization, Tile> {
|
): HashMap<Civilization, Tile> {
|
||||||
|
|
||||||
val civsOrderedByAvailableLocations = getCivsOrderedByAvailableLocations(civs, tileMap)
|
val civsOrderedByAvailableLocations = getCivsOrderedByAvailableLocations(civs, tileMap)
|
||||||
|
|
||||||
for (minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size / 6 downTo 0) {
|
for (minimumDistanceBetweenStartingLocations in tileMap.tileMatrix.size / 6 downTo 0) {
|
||||||
val freeTiles = getFreeTiles(tileMap, landTilesInBigEnoughGroup, minimumDistanceBetweenStartingLocations)
|
val freeTiles = getFreeTiles(tileMap, landTilesInBigEnoughGroup, minimumDistanceBetweenStartingLocations)
|
||||||
|
|
||||||
@ -581,12 +581,12 @@ object GameStarter {
|
|||||||
): HashMap<Civilization, Tile>? {
|
): HashMap<Civilization, Tile>? {
|
||||||
val startingLocations = HashMap<Civilization, Tile>()
|
val startingLocations = HashMap<Civilization, Tile>()
|
||||||
for (civ in civsOrderedByAvailableLocations) {
|
for (civ in civsOrderedByAvailableLocations) {
|
||||||
|
|
||||||
val startingLocation = getCivStartingLocation(civ, tileMap, freeTiles, startScores)
|
val startingLocation = getCivStartingLocation(civ, tileMap, freeTiles, startScores)
|
||||||
startingLocation ?: break
|
startingLocation ?: break
|
||||||
|
|
||||||
startingLocations[civ] = startingLocation
|
startingLocations[civ] = startingLocation
|
||||||
|
|
||||||
val distanceToNext = minimumDistanceBetweenStartingLocations /
|
val distanceToNext = minimumDistanceBetweenStartingLocations /
|
||||||
(if (civ.isCityState()) 2 else 1) // We allow city states to squeeze in tighter
|
(if (civ.isCityState()) 2 else 1) // We allow city states to squeeze in tighter
|
||||||
freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position, distanceToNext)
|
freeTiles.removeAll(tileMap.getTilesInDistance(startingLocation.position, distanceToNext)
|
||||||
|
@ -1026,7 +1026,7 @@ object NextTurnAutomation {
|
|||||||
val sortedUnits = civInfo.units.getCivUnits().sortedBy { unit -> getUnitPriority(unit, isAtWar) }
|
val sortedUnits = civInfo.units.getCivUnits().sortedBy { unit -> getUnitPriority(unit, isAtWar) }
|
||||||
for (unit in sortedUnits) UnitAutomation.automateUnitMoves(unit)
|
for (unit in sortedUnits) UnitAutomation.automateUnitMoves(unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUnitPriority(unit: MapUnit, isAtWar: Boolean): Int {
|
private fun getUnitPriority(unit: MapUnit, isAtWar: Boolean): Int {
|
||||||
if (unit.isCivilian() && !unit.isGreatPersonOfType("War")) return 1 // Civilian
|
if (unit.isCivilian() && !unit.isGreatPersonOfType("War")) return 1 // Civilian
|
||||||
if (unit.baseUnit.isAirUnit()) return 2
|
if (unit.baseUnit.isAirUnit()) return 2
|
||||||
@ -1078,13 +1078,13 @@ object NextTurnAutomation {
|
|||||||
if (civInfo.getHappiness() <= civInfo.cities.size) return
|
if (civInfo.getHappiness() <= civInfo.cities.size) return
|
||||||
|
|
||||||
val settlerUnits = civInfo.gameInfo.ruleset.units.values
|
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 (settlerUnits.isEmpty()) return
|
||||||
if (!civInfo.units.getCivUnits().none { it.hasUnique(UniqueType.FoundCity) }) return
|
if (!civInfo.units.getCivUnits().none { it.hasUnique(UniqueType.FoundCity) }) return
|
||||||
|
|
||||||
if (civInfo.cities.any {
|
if (civInfo.cities.any {
|
||||||
val currentConstruction = it.cityConstructions.getCurrentConstruction()
|
val currentConstruction = it.cityConstructions.getCurrentConstruction()
|
||||||
currentConstruction is BaseUnit && currentConstruction.hasUnique(UniqueType.FoundCity)
|
currentConstruction is BaseUnit && currentConstruction.isCityFounder()
|
||||||
}) return
|
}) return
|
||||||
|
|
||||||
if (civInfo.units.getCivUnits().none { it.isMilitary() }) return // We need someone to defend him first
|
if (civInfo.units.getCivUnits().none { it.isMilitary() }) return // We need someone to defend him first
|
||||||
|
@ -8,9 +8,9 @@ import com.unciv.models.ruleset.RulesetObject
|
|||||||
import com.unciv.models.ruleset.unique.StateForConditionals
|
import com.unciv.models.ruleset.unique.StateForConditionals
|
||||||
import com.unciv.models.ruleset.unique.UniqueTarget
|
import com.unciv.models.ruleset.unique.UniqueTarget
|
||||||
import com.unciv.models.ruleset.unique.UniqueType
|
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.Fonts
|
||||||
import com.unciv.ui.components.extensions.colorFromRGB
|
import com.unciv.ui.components.extensions.colorFromRGB
|
||||||
|
import com.unciv.ui.screens.civilopediascreen.FormattedLine
|
||||||
|
|
||||||
class Era : RulesetObject() {
|
class Era : RulesetObject() {
|
||||||
var eraNumber: Int = -1
|
var eraNumber: Int = -1
|
||||||
@ -88,7 +88,7 @@ class Era : RulesetObject() {
|
|||||||
val startingSettlerName: String =
|
val startingSettlerName: String =
|
||||||
if (startingSettlerUnit in ruleset.units) startingSettlerUnit
|
if (startingSettlerUnit in ruleset.units) startingSettlerUnit
|
||||||
else ruleset.units.values
|
else ruleset.units.values
|
||||||
.firstOrNull { it.hasUnique(UniqueType.FoundCity) }
|
.firstOrNull { it.isCityFounder() }
|
||||||
?.name
|
?.name
|
||||||
?: throw UncivShowableException("No Settler unit found for era $name")
|
?: throw UncivShowableException("No Settler unit found for era $name")
|
||||||
val startingWorkerName: String =
|
val startingWorkerName: String =
|
||||||
|
@ -56,7 +56,7 @@ object UniqueTriggerActivation {
|
|||||||
val unit = ruleSet.units[unitName]
|
val unit = ruleSet.units[unitName]
|
||||||
if ((chosenCity == null && tile == null)
|
if ((chosenCity == null && tile == null)
|
||||||
|| unit == null
|
|| unit == null
|
||||||
|| unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger())
|
|| unit.isCityFounder() && civInfo.isOneCityChallenger())
|
||||||
return false
|
return false
|
||||||
|
|
||||||
val limit = unit.getMatchingUniques(UniqueType.MaxNumberBuildable)
|
val limit = unit.getMatchingUniques(UniqueType.MaxNumberBuildable)
|
||||||
@ -83,7 +83,7 @@ object UniqueTriggerActivation {
|
|||||||
UniqueType.OneTimeAmountFreeUnits -> {
|
UniqueType.OneTimeAmountFreeUnits -> {
|
||||||
val unitName = unique.params[1]
|
val unitName = unique.params[1]
|
||||||
val unit = ruleSet.units[unitName]
|
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
|
return false
|
||||||
|
|
||||||
val limit = unit.getMatchingUniques(UniqueType.MaxNumberBuildable)
|
val limit = unit.getMatchingUniques(UniqueType.MaxNumberBuildable)
|
||||||
@ -118,7 +118,7 @@ object UniqueTriggerActivation {
|
|||||||
}
|
}
|
||||||
UniqueType.OneTimeFreeUnitRuins -> {
|
UniqueType.OneTimeFreeUnitRuins -> {
|
||||||
var unit = civInfo.getEquivalentUnit(unique.params[0])
|
var unit = civInfo.getEquivalentUnit(unique.params[0])
|
||||||
if ( unit.hasUnique(UniqueType.FoundCity) && civInfo.isOneCityChallenger()) {
|
if ( unit.isCityFounder() && civInfo.isOneCityChallenger()) {
|
||||||
val replacementUnit = ruleSet.units.values
|
val replacementUnit = ruleSet.units.values
|
||||||
.firstOrNull {
|
.firstOrNull {
|
||||||
it.getMatchingUniques(UniqueType.BuildImprovements)
|
it.getMatchingUniques(UniqueType.BuildImprovements)
|
||||||
|
@ -215,7 +215,7 @@ class BaseUnit : RulesetObject(), INonPerpetualConstruction {
|
|||||||
//movement penalty
|
//movement penalty
|
||||||
if (boughtWith != null && !civInfo.gameInfo.gameParameters.godMode && !unit.hasUnique(UniqueType.MoveImmediatelyOnceBought))
|
if (boughtWith != null && !civInfo.gameInfo.gameParameters.godMode && !unit.hasUnique(UniqueType.MoveImmediatelyOnceBought))
|
||||||
unit.currentMovement = 0f
|
unit.currentMovement = 0f
|
||||||
|
|
||||||
if (this.isCivilian()) return true // tiny optimization makes save files a few bytes smaller
|
if (this.isCivilian()) return true // tiny optimization makes save files a few bytes smaller
|
||||||
|
|
||||||
addConstructionBonuses(unit, cityConstructions)
|
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 isGreatPerson() = getMatchingUniques(UniqueType.GreatPerson).any()
|
||||||
fun isGreatPersonOfType(type: String) = getMatchingUniques(UniqueType.GreatPerson).any { it.params[0] == type }
|
fun isGreatPersonOfType(type: String) = getMatchingUniques(UniqueType.GreatPerson).any { it.params[0] == type }
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ class RulesetValidator(val ruleset: Ruleset) {
|
|||||||
|
|
||||||
checkUniques(ruleset.globalUniques, lines, rulesetSpecific, tryFixUnknownUniques)
|
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!"
|
lines += "No city-founding units in ruleset!"
|
||||||
|
|
||||||
for (unit in ruleset.units.values) {
|
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}"
|
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.
|
// 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
|
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}"
|
lines += "Nonexistent unit ${era.startingSettlerUnit} marked as starting unit when starting in ${era.name}"
|
||||||
if (era.startingWorkerCount != 0 && era.startingWorkerUnit !in ruleset.units
|
if (era.startingWorkerCount != 0 && era.startingWorkerUnit !in ruleset.units
|
||||||
&& ruleset.units.values.none { it.hasUnique(UniqueType.BuildImprovements) })
|
&& ruleset.units.values.none { it.hasUnique(UniqueType.BuildImprovements) })
|
||||||
|
Loading…
Reference in New Issue
Block a user