Added deserialization of unit-context events, so in the future we can add the serialization and have unit-context events :D

This commit is contained in:
yairm210
2024-08-25 02:28:47 +03:00
parent 0b48d30451
commit ebc5c8c315
5 changed files with 33 additions and 9 deletions

View File

@ -89,6 +89,8 @@ object Constants {
const val repair = "Repair"
const val uniqueOrDelimiter = "\" OR \""
const val stringSplitCharacter = '␟' // U+241 - Unit separator character. Used to join texts and split them with a char that is virtually guaranteed to not be used in normal text.
const val simulationCiv1 = "SimulationCiv1"
const val simulationCiv2 = "SimulationCiv2"

View File

@ -1,6 +1,7 @@
package com.unciv.models.ruleset
import com.unciv.logic.civilization.Civilization
import com.unciv.logic.map.mapunit.MapUnit
import com.unciv.models.ruleset.unique.Conditionals
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.Unique
@ -55,11 +56,11 @@ class EventChoice : ICivilopediaText {
fun matchesConditions(stateForConditionals: StateForConditionals) =
conditionObjects.all { Conditionals.conditionalApplies(null, it, stateForConditionals) }
fun triggerChoice(civ: Civilization): Boolean {
fun triggerChoice(civ: Civilization, unit: MapUnit? = null): Boolean {
var success = false
val stateForConditionals = StateForConditionals(civ)
val stateForConditionals = StateForConditionals(civ, unit = unit)
for (unique in triggeredUniqueObjects.flatMap { it.getMultiplied(stateForConditionals) })
if (UniqueTriggerActivation.triggerUnique(unique, civ)) success = true
if (UniqueTriggerActivation.triggerUnique(unique, civ, unit = unit)) success = true
return success
}
}

View File

@ -119,10 +119,15 @@ object UniqueTriggerActivation {
val choices = event.getMatchingChoices(stateForConditionals)
?: return null
if (civInfo.isAI() || event.presentation == Event.Presentation.None) return {
choices.randomOrNull()?.triggerChoice(civInfo) ?: false
choices.randomOrNull()?.triggerChoice(civInfo, unit) ?: false
}
if (event.presentation == Event.Presentation.Alert) return {
civInfo.popupAlerts.add(PopupAlert(AlertType.Event, event.name))
/** See [AlertPopup.addEvent] for the deserializing of this string to the context */
var eventText = event.name
// Todo later version: Uncomment this to enable events with unit triggers
// if (unit != null) eventText += Constants.stringSplitCharacter + "unitId=" + unit.id
civInfo.popupAlerts.add(PopupAlert(AlertType.Event, eventText))
true
}
// if (event.presentation == Event.Presentation.Floating) return { //todo: Park them in a Queue in GameInfo???

View File

@ -16,6 +16,7 @@ import com.unciv.logic.civilization.NotificationCategory
import com.unciv.logic.civilization.NotificationIcon
import com.unciv.logic.civilization.PopupAlert
import com.unciv.logic.civilization.diplomacy.*
import com.unciv.logic.map.mapunit.MapUnit
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.fillPlaceholders
import com.unciv.models.translations.tr
@ -528,8 +529,21 @@ class AlertPopup(
/** Returns if event was triggered correctly */
private fun addEvent(): Boolean {
val event = gameInfo.ruleset.events[popupAlert.value] ?: return false
val render = RenderEvent(event, worldScreen) { close() }
// The event string is in the format "eventName" + (Constants.stringSplitCharacter + "unitId=1234")?
// We explicitly specify that this is a unitId, to enable us to add other context info in the future - for example city id
val splitString = popupAlert.value.split(Constants.stringSplitCharacter)
val eventName = splitString[0]
var unit: MapUnit? = null
for (i in 1 until splitString.size) {
if (splitString[i].startsWith("unitId=")){
val unitId = splitString[i].substringAfter("unitId=").toInt()
unit = viewingCiv.units.getUnitById(unitId)
}
}
val event = gameInfo.ruleset.events[eventName] ?: return false
val render = RenderEvent(event, worldScreen, unit) { close() }
if (!render.isValid) return false
add(render).pad(0f).row()
return true

View File

@ -2,6 +2,7 @@ package com.unciv.ui.screens.worldscreen
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.logic.map.mapunit.MapUnit
import com.unciv.models.ruleset.Event
import com.unciv.models.ruleset.EventChoice
import com.unciv.models.ruleset.unique.StateForConditionals
@ -19,6 +20,7 @@ import com.unciv.ui.screens.civilopediascreen.MarkupRenderer
class RenderEvent(
event: Event,
val worldScreen: WorldScreen,
val unit: MapUnit? = null,
val onChoice: (EventChoice) -> Unit
) : Table() {
private val gameInfo get() = worldScreen.gameInfo
@ -31,7 +33,7 @@ class RenderEvent(
init {
defaults().fillX().center().pad(5f)
val stateForConditionals = StateForConditionals(gameInfo.currentPlayerCiv)
val stateForConditionals = StateForConditionals(gameInfo.currentPlayerCiv, unit = unit)
val choices = event.getMatchingChoices(stateForConditionals)
isValid = choices != null
if (isValid) {
@ -56,7 +58,7 @@ class RenderEvent(
val button = choice.text.toTextButton()
button.onActivation {
onChoice(choice)
choice.triggerChoice(gameInfo.currentPlayerCiv)
choice.triggerChoice(gameInfo.currentPlayerCiv, unit)
}
val key = KeyCharAndCode.parse(choice.keyShortcut)
if (key != KeyCharAndCode.UNKNOWN) {