Resolved #1820 - Fixed a crashing bug with the AI trying to ally with defeated city states, as well as many other minor bugs

All caused by the fact that getKnownCivs didn't filter out defeated civs
Also some minor code cleanup
This commit is contained in:
Yair Morgenstern
2020-02-01 20:26:27 +02:00
parent d7310aa90a
commit 261c3d6ced
6 changed files with 22 additions and 23 deletions

View File

@ -35,10 +35,10 @@ class NextTurnAutomation{
adoptPolicy(civInfo) adoptPolicy(civInfo)
} else { } else {
getFreeTechForCityStates(civInfo) getFreeTechForCityStates(civInfo)
updateDiplomaticRelationshipForCityStates(civInfo)
} }
chooseTechToResearch(civInfo) chooseTechToResearch(civInfo)
updateDiplomaticRelationship(civInfo)
declareWar(civInfo) declareWar(civInfo)
automateCityBombardment(civInfo) automateCityBombardment(civInfo)
useGold(civInfo) useGold(civInfo)
@ -401,20 +401,18 @@ class NextTurnAutomation{
} }
} }
private fun updateDiplomaticRelationship(civInfo: CivilizationInfo) { private fun updateDiplomaticRelationshipForCityStates(civInfo: CivilizationInfo) {
// Check if city-state invaded by other civs // Check if city-state invaded by other civs
if (civInfo.isCityState()) { for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() }) {
for (otherCiv in civInfo.getKnownCivs().filter { it.isMajorCiv() }) { if(civInfo.isAtWarWith(otherCiv)) continue
if(civInfo.isAtWarWith(otherCiv)) continue val diplomacy = civInfo.getDiplomacyManager(otherCiv)
val diplomacy = civInfo.getDiplomacyManager(otherCiv)
val unitsInBorder = otherCiv.getCivUnits().count { !it.type.isCivilian() && it.getTile().getOwner() == civInfo } val unitsInBorder = otherCiv.getCivUnits().count { !it.type.isCivilian() && it.getTile().getOwner() == civInfo }
if (unitsInBorder > 0 && diplomacy.relationshipLevel() < RelationshipLevel.Friend) { if (unitsInBorder > 0 && diplomacy.relationshipLevel() < RelationshipLevel.Friend) {
diplomacy.influence -= 10f diplomacy.influence -= 10f
if (!diplomacy.hasFlag(DiplomacyFlags.BorderConflict)) { if (!diplomacy.hasFlag(DiplomacyFlags.BorderConflict)) {
otherCiv.popupAlerts.add(PopupAlert(AlertType.BorderConflict,civInfo.civName)) otherCiv.popupAlerts.add(PopupAlert(AlertType.BorderConflict,civInfo.civName))
diplomacy.setFlag(DiplomacyFlags.BorderConflict,10) diplomacy.setFlag(DiplomacyFlags.BorderConflict,10)
}
} }
} }
} }

View File

@ -200,11 +200,9 @@ class CivInfoTransientUpdater(val civInfo: CivilizationInfo){
for (city in civInfo.cities) newDetailedCivResources.add(city.getCityResources()) for (city in civInfo.cities) newDetailedCivResources.add(city.getCityResources())
if (!civInfo.isCityState()) { if (!civInfo.isCityState()) {
for (otherCiv in civInfo.getKnownCivs()) { for (otherCiv in civInfo.getKnownCivs().filter { it.getAllyCiv() == civInfo.civName }) {
if (otherCiv.getAllyCiv() == civInfo.civName) { for (city in otherCiv.cities) {
for (city in otherCiv.cities) { newDetailedCivResources.add(city.getCityResourcesForAlly())
newDetailedCivResources.add(city.getCityResourcesForAlly())
}
} }
} }
} }

View File

@ -133,7 +133,8 @@ class CivilizationInfo {
fun getDiplomacyManager(civInfo: CivilizationInfo) = getDiplomacyManager(civInfo.civName) fun getDiplomacyManager(civInfo: CivilizationInfo) = getDiplomacyManager(civInfo.civName)
fun getDiplomacyManager(civName: String) = diplomacy[civName]!! fun getDiplomacyManager(civName: String) = diplomacy[civName]!!
fun getKnownCivs() = diplomacy.values.map { it.otherCiv() } /** Returns only undefeated civs, aka the ones we care about */
fun getKnownCivs() = diplomacy.values.map { it.otherCiv() }.filter { !it.isDefeated() }
fun knows(otherCivName: String) = diplomacy.containsKey(otherCivName) fun knows(otherCivName: String) = diplomacy.containsKey(otherCivName)
fun knows(otherCiv: CivilizationInfo) = knows(otherCiv.civName) fun knows(otherCiv: CivilizationInfo) = knows(otherCiv.civName)
@ -530,7 +531,9 @@ class CivilizationInfo {
fun updateAllyCivForCityState() { fun updateAllyCivForCityState() {
var newAllyName = "" var newAllyName = ""
if (!isCityState()) return if (!isCityState()) return
val maxInfluence = diplomacy.filter{ !it.value.otherCiv().isCityState() && !it.value.otherCiv().isDefeated() }.maxBy { it.value.influence } val maxInfluence = diplomacy
.filter{ !it.value.otherCiv().isCityState() && !it.value.otherCiv().isDefeated() }
.maxBy { it.value.influence }
if (maxInfluence != null && maxInfluence.value.influence >= 60) { if (maxInfluence != null && maxInfluence.value.influence >= 60) {
newAllyName = maxInfluence.key newAllyName = maxInfluence.key
} }

View File

@ -183,7 +183,8 @@ class TechManager {
scienceFromResearchAgreements = 0 scienceFromResearchAgreements = 0
} }
if (overflowScience != 0){ // https://forums.civfanatics.com/threads/the-mechanics-of-overflow-inflation.517970/ if (overflowScience != 0){ // https://forums.civfanatics.com/threads/the-mechanics-of-overflow-inflation.517970/
val techsResearchedKnownCivs = civInfo.getKnownCivs().count { it.isMajorCiv() && it.tech.isResearched(currentTechnologyName()!!) } val techsResearchedKnownCivs = civInfo.getKnownCivs()
.count { it.isMajorCiv() && it.tech.isResearched(currentTechnologyName()!!) }
val undefeatedCivs = UncivGame.Current.gameInfo.civilizations.count { it.isMajorCiv() && !it.isDefeated() } val undefeatedCivs = UncivGame.Current.gameInfo.civilizations.count { it.isMajorCiv() && !it.isDefeated() }
techsInProgress[currentTechnology] = techsInProgress[currentTechnology]!! + ((1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f)* overflowScience).toInt() techsInProgress[currentTechnology] = techsInProgress[currentTechnology]!! + ((1 + techsResearchedKnownCivs / undefeatedCivs.toFloat() * 0.3f)* overflowScience).toInt()
overflowScience = 0 overflowScience = 0

View File

@ -442,7 +442,6 @@ class DiplomacyManager() {
if (!otherCiv.isCityState()) { if (!otherCiv.isCityState()) {
for (thirdCiv in otherCiv.getKnownCivs()) { for (thirdCiv in otherCiv.getKnownCivs()) {
if (thirdCiv.isCityState() && thirdCiv.getAllyCiv() == otherCiv.civName if (thirdCiv.isCityState() && thirdCiv.getAllyCiv() == otherCiv.civName
&& !thirdCiv.isDefeated()
&& thirdCiv.knows(civInfo) && thirdCiv.knows(civInfo)
&& thirdCiv.getDiplomacyManager(civInfo).canDeclareWar()) { && thirdCiv.getDiplomacyManager(civInfo).canDeclareWar()) {
thirdCiv.getDiplomacyManager(civInfo).declareWar() thirdCiv.getDiplomacyManager(civInfo).declareWar()

View File

@ -290,7 +290,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
private fun updateDiplomacyButton(civInfo: CivilizationInfo) { private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
diplomacyButtonWrapper.clear() diplomacyButtonWrapper.clear()
if(!civInfo.isDefeated() && civInfo.getKnownCivs() if(!civInfo.isDefeated() && civInfo.getKnownCivs()
.filterNot { it.isDefeated() || it==viewingCiv || it.isBarbarian() } .filterNot { it==viewingCiv || it.isBarbarian() }
.any()) { .any()) {
displayTutorial(Tutorial.OtherCivEncountered) displayTutorial(Tutorial.OtherCivEncountered)
val btn = TextButton("Diplomacy".tr(), skin) val btn = TextButton("Diplomacy".tr(), skin)