Check for trigger uniques when starting and recaluating population (#9673)

* Check for trigger uniques when starting and recaluating population

* Adding imports

* whoops

* Moved where starting techs are added, added a parameter, and fixed the check for GUI
This commit is contained in:
SeventhM 2023-06-28 00:48:33 -07:00 committed by GitHub
parent ee855b8d77
commit 73fa87e6b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 49 deletions

View File

@ -79,6 +79,7 @@ object GUI {
}
fun isMyTurn(): Boolean {
if (!UncivGame.isCurrentInitialized() || !isWorldLoaded()) return false
return UncivGame.Current.worldScreen!!.isPlayersTurn
}

View File

@ -19,6 +19,8 @@ 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.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueTriggerActivation
import com.unciv.models.ruleset.unit.BaseUnit
import com.unciv.models.stats.Stats
import com.unciv.models.translations.equalsPlaceholderText
@ -167,9 +169,14 @@ object GameStarter {
private fun addCivTechs(gameInfo: GameInfo, ruleset: Ruleset, gameSetupInfo: GameSetupInfo) {
for (civInfo in gameInfo.civilizations.filter { !it.isBarbarian() }) {
for(tech in ruleset.technologies.values.filter { it.hasUnique(UniqueType.StartingTech) })
{
civInfo.tech.addTechnology(tech.name, false)
}
if (!civInfo.isHuman())
for (tech in gameInfo.getDifficulty().aiFreeTechs)
civInfo.tech.addTechnology(tech)
civInfo.tech.addTechnology(tech, false)
// generic start with technology unique
for (unique in civInfo.getMatchingUniques(UniqueType.StartsWithTech)) {
@ -178,19 +185,19 @@ object GameStarter {
// check if the technology is in the ruleset and not already researched
if (ruleset.technologies.containsKey(techName) && !civInfo.tech.isResearched(techName))
civInfo.tech.addTechnology(techName)
civInfo.tech.addTechnology(techName, false)
}
// add all techs to spectators
if (civInfo.isSpectator())
for (tech in ruleset.technologies.values)
if (!civInfo.tech.isResearched(tech.name))
civInfo.tech.addTechnology(tech.name)
civInfo.tech.addTechnology(tech.name, false)
for (tech in ruleset.technologies.values
.filter { ruleset.eras[it.era()]!!.eraNumber < ruleset.eras[gameSetupInfo.gameParameters.startingEra]!!.eraNumber })
if (!civInfo.tech.isResearched(tech.name))
civInfo.tech.addTechnology(tech.name)
civInfo.tech.addTechnology(tech.name, false)
civInfo.popupAlerts.clear() // Since adding technologies generates popups...
}
@ -330,8 +337,6 @@ object GameStarter {
ruleset: Ruleset,
chosenPlayers: List<Player>
) {
val startingTechs = ruleset.technologies.values.filter { it.hasUnique(UniqueType.StartingTech) }
if (!newGameParameters.noBarbarians && ruleset.nations.containsKey(Constants.barbarians)) {
val barbarianCivilization = Civilization(Constants.barbarians)
gameInfo.civilizations.add(barbarianCivilization)
@ -349,8 +354,6 @@ object GameStarter {
Constants.spectator ->
civ.playerType = player.playerType
in usedMajorCivs -> {
for (tech in startingTechs)
civ.tech.techsResearched.add(tech.name) // can't be .addTechnology because the civInfo isn't assigned yet
civ.playerType = player.playerType
civ.playerId = player.playerId
}
@ -422,6 +425,12 @@ object GameStarter {
val startingUnits = getStartingUnitsForEraAndDifficulty(civ, gameInfo, ruleset, startingEra)
adjustStartingUnitsForCityStatesAndOneCityChallenge(civ, gameInfo, startingUnits, settlerLikeUnits)
placeStartingUnits(civ, startingLocation, startingUnits, ruleset, ruleset.eras[startingEra]!!.startingMilitaryUnit, settlerLikeUnits)
//Trigger any global or nation uniques that should triggered.
//We may need the starting location for some uniques, which is why we're doing it now
for (unique in ruleset.globalUniques.uniqueObjects + civ.nation.uniqueObjects)
if(unique.isTriggerable)
UniqueTriggerActivation.triggerCivwideUnique(unique,civ, tile = startingLocation)
}
}

View File

@ -31,10 +31,6 @@ class CityStateFunctions(val civInfo: Civilization) {
/** Attempts to initialize the city state, returning true if successful. */
fun initCityState(ruleset: Ruleset, startingEra: String, unusedMajorCivs: Collection<String>): Boolean {
val startingTechs = ruleset.technologies.values.filter { it.hasUnique(UniqueType.StartingTech) }
for (tech in startingTechs)
civInfo.tech.techsResearched.add(tech.name) // can't be .addTechnology because the civInfo isn't assigned yet
val allMercantileResources = ruleset.tileResources.values.filter { it.hasUnique(UniqueType.CityStateOnlyResource) }.map { it.name }
val uniqueTypes = HashSet<UniqueType>() // We look through these to determine what kinds of city states we have

View File

@ -214,7 +214,10 @@ class PolicyManager : IsPartOfGameInfoSerialization {
civInfo.cache.updateCivResources()
// This ALSO has the side-effect of updating the CivInfo statForNextTurn so we don't need to call it explicitly
for (cityInfo in civInfo.cities) cityInfo.cityStats.update()
for (cityInfo in civInfo.cities) {
cityInfo.cityStats.update()
cityInfo.reassignPopulationDeferred()
}
if (!canAdoptPolicy()) shouldOpenPolicyPicker = false
}

View File

@ -276,7 +276,7 @@ class TechManager : IsPartOfGameInfoSerialization {
addTechnology(techName)
}
fun addTechnology(techName: String) {
fun addTechnology(techName: String, showNotification: Boolean = true) {
val isNewTech = techsResearched.add(techName)
// this is to avoid concurrent modification problems
@ -302,10 +302,10 @@ class TechManager : IsPartOfGameInfoSerialization {
updateTransientBooleans()
for (city in civInfo.cities) {
city.cityStats.update()
city.updateCitizens = true
city.reassignPopulationDeferred()
}
if (!civInfo.isSpectator())
if (!civInfo.isSpectator() && showNotification)
civInfo.addNotification("Research of [$techName] has completed!", TechAction(techName),
NotificationCategory.General,
NotificationIcon.Science)
@ -313,21 +313,15 @@ class TechManager : IsPartOfGameInfoSerialization {
civInfo.popupAlerts.add(PopupAlert(AlertType.TechResearched, techName))
val revealedResources = getRuleset().tileResources.values.filter { techName == it.revealedBy }
var mayNeedUpdateResources = revealedResources.isNotEmpty() // default for AI
if (civInfo.playerType == PlayerType.Human) {
mayNeedUpdateResources = false
for (revealedResource in revealedResources) {
// notifyExploredResources scans the player's owned tiles and returns false if none
// found with a revealed resource - keep this knowledge to avoid the update call.
mayNeedUpdateResources = mayNeedUpdateResources ||
civInfo.gameInfo.notifyExploredResources(civInfo, revealedResource.name, 5)
civInfo.gameInfo.notifyExploredResources(civInfo, revealedResource.name, 5)
}
}
// At least in the case of a human player hurrying research, this civ's resource availability
// may now be out of date - e.g. when an owned tile by luck already has an appropriate improvement.
// That can be seen on WorldScreenTopBar, so better update unless we know there's no resource change.
if (mayNeedUpdateResources)
civInfo.cache.updateCivResources()
// In the case of a player hurrying research, this civ's resource availability may now be out of date
// - e.g. when an owned tile by luck already has an appropriate improvement or when a tech provides a resource.
// That can be seen on WorldScreenTopBar, so better update.
civInfo.cache.updateCivResources()
obsoleteOldUnits(techName)
@ -341,7 +335,7 @@ class TechManager : IsPartOfGameInfoSerialization {
MayaLongCountAction(), NotificationCategory.General, MayaCalendar.notificationIcon)
}
moveToNewEra()
moveToNewEra(showNotification)
updateResearchProgress()
}
@ -396,34 +390,36 @@ class TechManager : IsPartOfGameInfoSerialization {
}
}
private fun moveToNewEra() {
private fun moveToNewEra(showNotification: Boolean = true) {
val previousEra = civInfo.getEra()
updateEra()
val currentEra = civInfo.getEra()
if (previousEra != currentEra) {
if(!civInfo.isSpectator())
civInfo.addNotification(
"You have entered the [$currentEra]!",
NotificationCategory.General,
NotificationIcon.Science
)
if (civInfo.isMajorCiv()) {
for (knownCiv in civInfo.getKnownCivs()) {
knownCiv.addNotification(
"[${civInfo.civName}] has entered the [$currentEra]!",
NotificationCategory.General, civInfo.civName, NotificationIcon.Science
)
}
}
for (policyBranch in getRuleset().policyBranches.values.filter {
it.era == currentEra.name && civInfo.policies.isAdoptable(it)
}) {
if (!civInfo.isSpectator())
if(showNotification) {
if(!civInfo.isSpectator())
civInfo.addNotification(
"[${policyBranch.name}] policy branch unlocked!",
"You have entered the [$currentEra]!",
NotificationCategory.General,
NotificationIcon.Culture
NotificationIcon.Science
)
if (civInfo.isMajorCiv()) {
for (knownCiv in civInfo.getKnownCivs()) {
knownCiv.addNotification(
"[${civInfo.civName}] has entered the [$currentEra]!",
NotificationCategory.General, civInfo.civName, NotificationIcon.Science
)
}
}
for (policyBranch in getRuleset().policyBranches.values.filter {
it.era == currentEra.name && civInfo.policies.isAdoptable(it)
}) {
if (!civInfo.isSpectator())
civInfo.addNotification(
"[${policyBranch.name}] policy branch unlocked!",
NotificationCategory.General,
NotificationIcon.Culture
)
}
}
val erasPassed = getRuleset().eras.values