Suppress ready-to-join notification after quest fulfillment (#6752)

This commit is contained in:
2026-05-24 11:14:08 -04:00
committed by GitHub
parent e635e2d5cf
commit 86d396c5f5
2 changed files with 78 additions and 0 deletions
@@ -149,6 +149,7 @@ class ActionResultApplierImpl(validator: Option[Validator]) extends ActionResult
finalState: GameState
): ActionResultT = {
val readyHeroes = newlyReadyToJoinHeroes(startingState, finalState)
.filterNot(heroHasQuestFulfilledNotification(result, _))
val notificationsAndRequests = readyHeroes.map {
case ReadyToJoinHero(heroId, provinceId, factionId) =>
@@ -186,6 +187,18 @@ class ActionResultApplierImpl(validator: Option[Validator]) extends ActionResult
private case class ReadyToJoinHero(heroId: HeroId, provinceId: ProvinceId, factionId: FactionId)
private def heroHasQuestFulfilledNotification(
result: ActionResultT,
readyHero: ReadyToJoinHero
): Boolean =
result.newNotifications.exists {
_.details match {
case NotificationDetails.QuestFulfilled(heroId, provinceId, _) =>
heroId == readyHero.heroId && provinceId == readyHero.provinceId
case _ => false
}
}
private def newlyReadyToJoinHeroes(
startingState: GameState,
finalState: GameState
@@ -26,6 +26,7 @@ import net.eagle0.eagle.model.state.game_state.GameState
import net.eagle0.eagle.model.state.hero.backstory_version.BackstoryVersion
import net.eagle0.eagle.model.state.hero.concrete.HeroC
import net.eagle0.eagle.model.state.province.concrete.ProvinceC
import net.eagle0.eagle.model.state.quest.AllianceQuest
import net.eagle0.eagle.model.state.run_status.RunStatus
import net.eagle0.eagle.model.state.shardok_battle.{BattleType, ShardokBattle}
import net.eagle0.eagle.model.state.unaffiliated_hero.{RecruitmentInfo, UnaffiliatedHeroType}
@@ -185,6 +186,70 @@ class ActionResultApplierImplTest extends AnyFlatSpec with Matchers with BeforeA
result.actionResult.newGeneratedTextRequests shouldBe empty
}
it should "not add a notification when a quest fulfilled notification already exists for the hero" in {
val factionId = 11
val leaderId = 12
val heroId = 13
val provinceId = 14
val quest = AllianceQuest
val oldHero = UnaffiliatedHeroC(
heroId = heroId,
unaffiliatedHeroType = UnaffiliatedHeroType.Resident,
recruitmentInfo = RecruitmentInfo.HasQuest(quest)
)
val newHero = oldHero.copy(recruitmentInfo = RecruitmentInfo.WouldJoin)
val startingProvince = ProvinceC(
id = provinceId,
rulingFactionId = Some(factionId),
unaffiliatedHeroes = Vector(oldHero)
)
val finalProvince = startingProvince.copy(unaffiliatedHeroes = Vector(newHero))
val questNotification = NotificationC(
details = NotificationDetails.QuestFulfilled(
heroId = heroId,
provinceId = provinceId,
fulfilledQuest = quest
),
targetFactionIds = Vector(factionId),
affectedProvinceIds = Vector(provinceId),
affectedHeroIds = Vector(heroId),
deferred = false
)
val startingState = baseGameState.copy(
provinces = Map(provinceId -> startingProvince),
factions = Map(
factionId -> FactionC(
id = factionId,
factionHeadId = leaderId,
name = "Test Faction",
leaderIds = Vector(leaderId)
)
),
heroes = Map(leaderId -> HeroC(id = leaderId, factionId = Some(factionId)), heroId -> HeroC(id = heroId))
)
val actionResult = ActionResultC(
actionResultType = ActionResultType.QuestFulfilled,
changedProvinces = Vector(
ChangedProvinceC(
provinceId = provinceId,
changedUnaffiliatedHeroes = finalProvince.unaffiliatedHeroes
)
),
newNotifications = Vector(questNotification)
)
val result = applier.applyActionResult(startingState, actionResult)
result.actionResult.newNotifications should contain(questNotification)
result.actionResult.newNotifications.collect {
case notification if notification.details.isInstanceOf[NotificationDetails.HeroReadyToJoin] => notification
} shouldBe empty
result.actionResult.newGeneratedTextRequests.collect {
case request: LlmRequestT.HeroReadyToJoinMessage => request
} shouldBe empty
}
it should "add a notification when a ready hero becomes ready for a new ruling faction" in {
val oldFactionId = 10
val newFactionId = 11