From df916f9c29e5c77c349a1e232d752aade0e0d389 Mon Sep 17 00:00:00 2001 From: Dan Crosby Date: Wed, 4 Feb 2026 09:11:03 -0800 Subject: [PATCH] Enable battalion diversity quest generation (PR 3/3) (#5838) * Enable battalion diversity quest generation (PR 3/3) Adds quest creation logic for BattalionDiversityQuest to QuestCreationUtils. Quest availability: - Only if province currently has 1-2 battalion types - This encourages players to diversify their army composition Co-Authored-By: Claude Opus 4.5 * Clarify PR dependency structure in quest docs PR 2 (client) and PR 3 (generation) both depend on PR 1 (types), but are independent of each other. They can be developed in parallel and merged in either order after PR 1. Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- docs/ADDING_NEW_QUESTS.md | 9 +++++++- .../quest_creation/QuestCreationUtils.scala | 23 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/ADDING_NEW_QUESTS.md b/docs/ADDING_NEW_QUESTS.md index 9db9682edf..d4cfe61487 100644 --- a/docs/ADDING_NEW_QUESTS.md +++ b/docs/ADDING_NEW_QUESTS.md @@ -12,7 +12,14 @@ When adding new quest types, use a three-PR strategy to ensure clients never see 3. **PR 3 - Quest Generation (Server)**: Add the actual quest creation logic to `QuestCreationUtils.scala`. -This order ensures that when the server starts generating the new quest type, all clients already know how to display it. +**PR Dependencies:** +``` +PR 1 (types) + ├── PR 2 (client) + └── PR 3 (generation) +``` + +PR 2 and PR 3 both depend on PR 1, but are independent of each other. They can be developed in parallel after PR 1 is merged, and merged in either order. The key constraint is that PR 3 should not be deployed before PR 2, so clients understand the quest type before the server starts generating it. ## Files to Modify diff --git a/src/main/scala/net/eagle0/eagle/library/util/quest_creation/QuestCreationUtils.scala b/src/main/scala/net/eagle0/eagle/library/util/quest_creation/QuestCreationUtils.scala index 7a62210c4d..084fa0aa30 100644 --- a/src/main/scala/net/eagle0/eagle/library/util/quest_creation/QuestCreationUtils.scala +++ b/src/main/scala/net/eagle0/eagle/library/util/quest_creation/QuestCreationUtils.scala @@ -32,6 +32,7 @@ import net.eagle0.eagle.model.state.quest.{ AllianceQuest, AlmsAcrossRealmQuest, AlmsToProvinceQuest, + BattalionDiversityQuest, DefeatFactionQuest, DevelopProvincesQuest, DismissSpecificVassalQuest, @@ -130,7 +131,8 @@ object QuestCreationUtils { QuestCreatorFrom(suppressRiotByForceQuests), QuestCreatorFrom(fightBeastsAloneQuests), developProvincesQuests, - mobilizeProvincesQuests + mobilizeProvincesQuests, + battalionDiversityQuests ) ) { case (questCreator, fr) => @@ -770,4 +772,23 @@ object QuestCreationUtils { } end if } + + private def battalionDiversityQuests( + province: ProvinceT, + @unused allProvinces: Vector[ProvinceT], + @unused factions: Vector[FactionT], + battalions: Vector[BattalionT], + functionalRandom: FunctionalRandom + ): RandomState[Vector[Quest]] = { + // Only available if province currently has 1-2 battalion types + val currentBattalionTypes = province.battalionIds + .flatMap(bid => battalions.find(_.id == bid)) + .map(_.typeId) + .distinct + .size + + if currentBattalionTypes >= 1 && currentBattalionTypes <= 2 then + RandomState(Vector(BattalionDiversityQuest), functionalRandom) + else RandomState(Vector(), functionalRandom) + } }