Resolved #5790 - kudos to @xlenstra for finding the problem and providing reproduction! (#5812)

This commit is contained in:
Yair Morgenstern 2021-12-17 08:47:07 +02:00 committed by GitHub
parent 12404a6ba6
commit 7aa7b8a4b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 15 deletions

View File

@ -2,6 +2,7 @@ package com.unciv.ui.newgamescreen
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
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.translations.tr import com.unciv.models.translations.tr
@ -23,7 +24,7 @@ class ModCheckboxTable(
for (mod in modRulesets.sortedBy { it.name }) { for (mod in modRulesets.sortedBy { it.name }) {
val checkBox = mod.name.toCheckBox(mod.name in mods) val checkBox = mod.name.toCheckBox(mod.name in mods)
checkBox.onChange { checkBox.onChange {
if (checkBoxChanged(checkBox, mod)) { if (checkBoxChanged(checkBox, it!!, mod)) {
//todo: persist ExpanderTab states here //todo: persist ExpanderTab states here
onUpdate(mod.name) onUpdate(mod.name)
} }
@ -48,7 +49,22 @@ class ModCheckboxTable(
} }
} }
private fun checkBoxChanged(checkBox: CheckBox, mod: Ruleset): Boolean {
fun popupToastError(rulesetErrorList:Ruleset.RulesetErrorList) {
val initialText =
if (rulesetErrorList.isError()) "The mod combination you selected is incorrectly defined!".tr()
else "{The mod combination you selected has problems.}\n{You can play it, but don't expect everything to work!}".tr()
val toastMessage = "$initialText\n\n${rulesetErrorList.getErrorText()}"
lastToast?.close()
lastToast = ToastPopup(toastMessage, screen, 5000L)
}
private fun checkBoxChanged(
checkBox: CheckBox,
changeEvent: ChangeListener.ChangeEvent,
mod: Ruleset
): Boolean {
if (checkBox.isChecked) { if (checkBox.isChecked) {
// First the quick standalone check // First the quick standalone check
val modLinkErrors = mod.checkModLinks() val modLinkErrors = mod.checkModLinks()
@ -57,7 +73,7 @@ class ModCheckboxTable(
val toastMessage = val toastMessage =
"The mod you selected is incorrectly defined!".tr() + "\n\n${modLinkErrors.getErrorText()}" "The mod you selected is incorrectly defined!".tr() + "\n\n${modLinkErrors.getErrorText()}"
lastToast = ToastPopup(toastMessage, screen, 5000L) lastToast = ToastPopup(toastMessage, screen, 5000L)
checkBox.isChecked = false changeEvent.cancel() // Cancel event to reset to previous state - see Button.setChecked()
return false return false
} }
@ -66,23 +82,31 @@ class ModCheckboxTable(
// Check over complete combination of selected mods // Check over complete combination of selected mods
val complexModLinkCheck = RulesetCache.checkCombinedModLinks(mods, baseRuleset) val complexModLinkCheck = RulesetCache.checkCombinedModLinks(mods, baseRuleset)
if (complexModLinkCheck.isWarnUser()) { if (complexModLinkCheck.isWarnUser()) {
lastToast?.close() popupToastError(complexModLinkCheck)
val toastMessage = (
if (complexModLinkCheck.isError()) "The mod combination you selected is incorrectly defined!".tr()
else "{The mod combination you selected has problems.}\n{You can play it, but don't expect everything to work!}".tr()
) +
"\n\n${complexModLinkCheck.getErrorText()}"
lastToast = ToastPopup(toastMessage, screen, 5000L)
if (complexModLinkCheck.isError()) { if (complexModLinkCheck.isError()) {
checkBox.isChecked = false changeEvent.cancel() // Cancel event to reset to previous state - see Button.setChecked()
mods.remove(mod.name)
return false return false
} }
} }
} else { } else {
/**
* Turns out we need to check ruleset when REMOVING a mod as well, since if mod A references something in mod B (like a promotion),
* and then we remove mod B, then the entire ruleset is now broken!
*/
mods.remove(mod.name) mods.remove(mod.name)
val complexModLinkCheck = RulesetCache.checkCombinedModLinks(mods, baseRuleset)
if (complexModLinkCheck.isWarnUser()) {
popupToastError(complexModLinkCheck)
if (complexModLinkCheck.isError()) {
changeEvent.cancel() // Cancel event to reset to previous state - see Button.setChecked()
mods.add(mod.name)
return false
}
}
} }
return true return true

View File

@ -69,10 +69,10 @@ fun Actor.onClick(function: () -> Unit): Actor {
return this return this
} }
fun Actor.onChange(function: () -> Unit): Actor { fun Actor.onChange(function: (event: ChangeListener.ChangeEvent?) -> Unit): Actor {
this.addListener(object : ChangeListener() { this.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) { override fun changed(event: ChangeEvent?, actor: Actor?) {
function() function(event)
} }
}) })
return this return this