mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 21:35:42 +00:00
Add AI quest fulfillment for 7 more quest types
New quest command choosers: - SpendOnFeastsQuestCommandChooser: Selects FeastCommand when quest active - RestProvinceQuestCommandChooser: Rests in target province - SendSuppliesQuestCommandChooser: Sends food to target province - ExecutePrisonerQuestCommandChooser: Executes specific prisoner - ReturnPrisonerQuestCommandChooser: Returns prisoner to faction - StartEpidemicQuestCommandChooser: Starts epidemic in target province - SwearBrotherhoodQuestCommandChooser: Swears brotherhood with target hero Also adds Execute and Return helper methods to ManagePrisonersCommandSelector. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -301,6 +301,7 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:alms_across_realm_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:alms_to_province_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:dismiss_specific_vassal_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:execute_prisoner_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:exile_prisoner_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:give_to_heroes_across_realm_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:give_to_heroes_in_province_quest_command_chooser",
|
||||
@@ -308,6 +309,12 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:release_all_prisoners_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:release_prisoner_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:rest_province_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:return_prisoner_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:send_supplies_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:spend_on_feasts_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:start_epidemic_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:swear_brotherhood_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:total_development_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:truce_count_quest_command_chooser",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:truce_with_faction_quest_command_chooser",
|
||||
|
||||
+14
@@ -6,6 +6,7 @@ import net.eagle0.eagle.library.util.command_choice_helpers.quest_command_select
|
||||
AlmsAcrossRealmQuestCommandChooser,
|
||||
AlmsToProvinceQuestCommandChooser,
|
||||
DismissSpecificVassalCommandChooser,
|
||||
ExecutePrisonerQuestCommandChooser,
|
||||
ExilePrisonerQuestCommandChooser,
|
||||
GiveToHeroesAcrossRealmQuestCommandChooser,
|
||||
GiveToHeroesInProvinceQuestCommandChooser,
|
||||
@@ -13,6 +14,12 @@ import net.eagle0.eagle.library.util.command_choice_helpers.quest_command_select
|
||||
QuestCommandChooser,
|
||||
ReleaseAllPrisonersQuestCommandChooser,
|
||||
ReleasePrisonerQuestCommandChooser,
|
||||
RestProvinceQuestCommandChooser,
|
||||
ReturnPrisonerQuestCommandChooser,
|
||||
SendSuppliesQuestCommandChooser,
|
||||
SpendOnFeastsQuestCommandChooser,
|
||||
StartEpidemicQuestCommandChooser,
|
||||
SwearBrotherhoodQuestCommandChooser,
|
||||
TotalDevelopmentQuestCommandChooser,
|
||||
TruceCountQuestCommandChooser,
|
||||
TruceWithFactionQuestCommandChooser,
|
||||
@@ -37,7 +44,14 @@ object FulfillQuestsCommandSelector {
|
||||
DismissSpecificVassalCommandChooser,
|
||||
ReleasePrisonerQuestCommandChooser,
|
||||
ExilePrisonerQuestCommandChooser,
|
||||
ExecutePrisonerQuestCommandChooser,
|
||||
ReturnPrisonerQuestCommandChooser,
|
||||
ReleaseAllPrisonersQuestCommandChooser,
|
||||
SpendOnFeastsQuestCommandChooser,
|
||||
RestProvinceQuestCommandChooser,
|
||||
SendSuppliesQuestCommandChooser,
|
||||
StartEpidemicQuestCommandChooser,
|
||||
SwearBrotherhoodQuestCommandChooser,
|
||||
AllianceQuestCommandChooser
|
||||
)
|
||||
|
||||
|
||||
+22
@@ -47,6 +47,28 @@ object ManagePrisonersCommandSelector {
|
||||
): Option[CommandSelection] =
|
||||
chosenCommandForPrisoner(actingFactionId, availableCommands, prisonerHeroId, PrisonerManagementOption.Exile)
|
||||
|
||||
/** Execute a specific prisoner. */
|
||||
def chosenExecuteCommand(
|
||||
actingFactionId: FactionId,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
prisonerHeroId: HeroId
|
||||
): Option[CommandSelection] =
|
||||
chosenCommandForPrisoner(actingFactionId, availableCommands, prisonerHeroId, PrisonerManagementOption.Execute)
|
||||
|
||||
/** Return a specific prisoner to a specific faction. */
|
||||
def chosenReturnCommand(
|
||||
actingFactionId: FactionId,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
prisonerHeroId: HeroId,
|
||||
toFactionId: FactionId
|
||||
): Option[CommandSelection] =
|
||||
chosenCommandForPrisoner(
|
||||
actingFactionId,
|
||||
availableCommands,
|
||||
prisonerHeroId,
|
||||
PrisonerManagementOption.Return(toFactionId)
|
||||
)
|
||||
|
||||
/** Find any prisoner that can be released and select to release them. */
|
||||
def chosenReleaseAnyPrisonerCommand(
|
||||
actingFactionId: FactionId,
|
||||
|
||||
+155
@@ -330,6 +330,161 @@ scala_library(
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "execute_prisoner_quest_command_chooser",
|
||||
srcs = ["ExecutePrisonerQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:manage_prisoners_command_selector",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/hero:hero_utils",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "rest_province_quest_command_chooser",
|
||||
srcs = ["RestProvinceQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/selected",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "return_prisoner_quest_command_chooser",
|
||||
srcs = ["ReturnPrisonerQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:manage_prisoners_command_selector",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "send_supplies_quest_command_chooser",
|
||||
srcs = ["SendSuppliesQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/selected",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "spend_on_feasts_quest_command_chooser",
|
||||
srcs = ["SpendOnFeastsQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/selected",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "start_epidemic_quest_command_chooser",
|
||||
srcs = ["StartEpidemicQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/selected",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "swear_brotherhood_quest_command_chooser",
|
||||
srcs = ["SwearBrotherhoodQuestCommandChooser.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/command_choice_helpers:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/command_choice_helpers/quest_command_selectors:__pkg__",
|
||||
],
|
||||
exports = [
|
||||
":quest_command_chooser",
|
||||
],
|
||||
deps = [
|
||||
":quest_command_chooser",
|
||||
":unaffiliated_hero_with_quest",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:command_selection",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/selected",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/quest",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "unaffiliated_hero_with_quest",
|
||||
srcs = ["UnaffiliatedHeroWithQuest.scala"],
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.command_choice_helpers.ManagePrisonersCommandSelector
|
||||
import net.eagle0.eagle.library.util.hero.HeroUtils
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.ExecutePrisonerQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object ExecutePrisonerQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] = {
|
||||
// Get all faction heads (first leader of each faction)
|
||||
val factionHeadIds = gameState.factions.values.flatMap(_.leaderIds.headOption).toSet
|
||||
|
||||
uhsWithQuests.flatMap { uhWithQuest =>
|
||||
uhWithQuest.quest match {
|
||||
case quest: ExecutePrisonerQuest =>
|
||||
// Look up both heroes
|
||||
val questioner = gameState.heroes.get(uhWithQuest.heroId)
|
||||
val prisoner = gameState.heroes.get(quest.prisonerHeroId)
|
||||
|
||||
(questioner, prisoner) match {
|
||||
case (Some(q), Some(p)) =>
|
||||
val prisonerIsFactionHead = factionHeadIds.contains(p.id)
|
||||
val questionerIsBetter = HeroUtils.power(q) > HeroUtils.power(p)
|
||||
|
||||
// Only execute if questioner is better than prisoner, or prisoner is faction head
|
||||
if prisonerIsFactionHead || questionerIsBetter then
|
||||
ManagePrisonersCommandSelector.chosenExecuteCommand(
|
||||
actingFactionId = actingFactionId,
|
||||
availableCommands = availableCommands,
|
||||
prisonerHeroId = quest.prisonerHeroId
|
||||
)
|
||||
else None
|
||||
case _ => None
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
}.headOption
|
||||
.map(_.withReason("fulfill ExecutePrisoner quest"))
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.RestAvailable
|
||||
import net.eagle0.eagle.model.state.command.selected.SelectedCommand.RestSelected
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.RestProvinceQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object RestProvinceQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] = {
|
||||
val targetProvinceIds = uhsWithQuests
|
||||
.map(_.quest)
|
||||
.collect { case q: RestProvinceQuest => q.targetProvinceId }
|
||||
.toSet
|
||||
|
||||
if targetProvinceIds.isEmpty then return None
|
||||
|
||||
availableCommands.collect { case ra: RestAvailable => ra }
|
||||
.find(ra => targetProvinceIds.contains(ra.actingProvinceId))
|
||||
.map { restAvailable =>
|
||||
CommandSelection(
|
||||
actingFactionId = actingFactionId,
|
||||
actingProvinceId = restAvailable.actingProvinceId,
|
||||
available = restAvailable,
|
||||
selected = RestSelected,
|
||||
reason = "fulfill RestProvince quest"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.command_choice_helpers.ManagePrisonersCommandSelector
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.ReturnPrisonerQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object ReturnPrisonerQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] =
|
||||
uhsWithQuests
|
||||
.map(_.quest)
|
||||
.collect { case q: ReturnPrisonerQuest => q }
|
||||
.flatMap { quest =>
|
||||
ManagePrisonersCommandSelector.chosenReturnCommand(
|
||||
actingFactionId = actingFactionId,
|
||||
availableCommands = availableCommands,
|
||||
prisonerHeroId = quest.prisonerHeroId,
|
||||
toFactionId = quest.toFactionId
|
||||
)
|
||||
}
|
||||
.headOption
|
||||
.map(_.withReason("fulfill ReturnPrisoner quest"))
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.SendSuppliesAvailable
|
||||
import net.eagle0.eagle.model.state.command.selected.SelectedCommand.SendSuppliesSelected
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.SendSuppliesQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object SendSuppliesQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] = {
|
||||
val sendSuppliesQuests = uhsWithQuests
|
||||
.map(_.quest)
|
||||
.collect { case q: SendSuppliesQuest => q }
|
||||
|
||||
if sendSuppliesQuests.isEmpty then return None
|
||||
|
||||
// Group quests by target province and find the max food needed
|
||||
val foodNeededByProvince = sendSuppliesQuests
|
||||
.groupBy(_.targetProvinceId)
|
||||
.view
|
||||
.mapValues { quests =>
|
||||
quests.map(q => q.componentCount - q.componentsFulfilled).max
|
||||
}
|
||||
.toMap
|
||||
|
||||
availableCommands.collect { case ssa: SendSuppliesAvailable => ssa }.flatMap { sendSuppliesAvailable =>
|
||||
// Find a target province that matches a quest and is available
|
||||
foodNeededByProvince.keys
|
||||
.find(sendSuppliesAvailable.availableDestinationProvinceIds.contains)
|
||||
.map { targetProvinceId =>
|
||||
val foodNeeded = foodNeededByProvince(targetProvinceId)
|
||||
val foodToSend = foodNeeded.min(sendSuppliesAvailable.foodAvailable)
|
||||
val actingHero = sendSuppliesAvailable.availableHeroIds.head
|
||||
|
||||
(sendSuppliesAvailable, targetProvinceId, foodToSend, actingHero)
|
||||
}
|
||||
}.headOption.map {
|
||||
case (sendSuppliesAvailable, targetProvinceId, foodToSend, actingHero) =>
|
||||
CommandSelection(
|
||||
actingFactionId = actingFactionId,
|
||||
actingProvinceId = sendSuppliesAvailable.actingProvinceId,
|
||||
available = sendSuppliesAvailable,
|
||||
selected = SendSuppliesSelected(
|
||||
gold = 0,
|
||||
food = foodToSend,
|
||||
actingHeroId = actingHero,
|
||||
destinationProvinceId = targetProvinceId
|
||||
),
|
||||
reason = "fulfill SendSupplies quest"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.FeastAvailable
|
||||
import net.eagle0.eagle.model.state.command.selected.SelectedCommand.FeastSelected
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.SpendOnFeastsQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object SpendOnFeastsQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] = {
|
||||
val hasSpendOnFeastsQuest = uhsWithQuests
|
||||
.map(_.quest)
|
||||
.exists(_.isInstanceOf[SpendOnFeastsQuest])
|
||||
|
||||
if !hasSpendOnFeastsQuest then return None
|
||||
|
||||
availableCommands.collectFirst { case fa: FeastAvailable => fa }.map { feastAvailable =>
|
||||
CommandSelection(
|
||||
actingFactionId = actingFactionId,
|
||||
actingProvinceId = feastAvailable.actingProvinceId,
|
||||
available = feastAvailable,
|
||||
selected = FeastSelected,
|
||||
reason = "fulfill SpendOnFeasts quest"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.StartEpidemicAvailable
|
||||
import net.eagle0.eagle.model.state.command.selected.SelectedCommand.StartEpidemicSelected
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.StartEpidemicQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object StartEpidemicQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] = {
|
||||
val targetProvinceIds = uhsWithQuests
|
||||
.map(_.quest)
|
||||
.collect { case q: StartEpidemicQuest => q.provinceId }
|
||||
.toSet
|
||||
|
||||
if targetProvinceIds.isEmpty then return None
|
||||
|
||||
availableCommands.collect { case sea: StartEpidemicAvailable => sea }.flatMap { startEpidemicAvailable =>
|
||||
// Find a target province that matches a quest and is in available options
|
||||
startEpidemicAvailable.options
|
||||
.find(opt => targetProvinceIds.contains(opt.targetProvinceId))
|
||||
.map { matchingOption =>
|
||||
CommandSelection(
|
||||
actingFactionId = actingFactionId,
|
||||
actingProvinceId = startEpidemicAvailable.actingProvinceId,
|
||||
available = startEpidemicAvailable,
|
||||
selected = StartEpidemicSelected(
|
||||
selectedProvinceId = matchingOption.targetProvinceId,
|
||||
actingHeroId = startEpidemicAvailable.availableHeroIds.head
|
||||
),
|
||||
reason = "fulfill StartEpidemic quest"
|
||||
)
|
||||
}
|
||||
}.headOption
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package net.eagle0.eagle.library.util.command_choice_helpers.quest_command_selectors
|
||||
|
||||
import net.eagle0.eagle.library.util.CommandSelection
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.SwearBrotherhoodAvailable
|
||||
import net.eagle0.eagle.model.state.command.selected.SelectedCommand.SwearBrotherhoodSelected
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.quest.SwearBrotherhoodWithHeroQuest
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object SwearBrotherhoodQuestCommandChooser extends DeterministicQuestCommandChooser {
|
||||
override def chosenDeterministicCommand(
|
||||
actingFactionId: FactionId,
|
||||
gameState: GameState,
|
||||
availableCommands: Vector[AvailableCommand],
|
||||
uhsWithQuests: Vector[UnaffiliatedHeroWithQuest]
|
||||
): Option[CommandSelection] = {
|
||||
val targetHeroIds = uhsWithQuests
|
||||
.map(_.quest)
|
||||
.collect { case q: SwearBrotherhoodWithHeroQuest => q.targetHeroId }
|
||||
.toSet
|
||||
|
||||
if targetHeroIds.isEmpty then return None
|
||||
|
||||
availableCommands.collect { case sba: SwearBrotherhoodAvailable => sba }.flatMap { swearBrotherhoodAvailable =>
|
||||
// Find a hero that matches a quest and is in available heroes
|
||||
swearBrotherhoodAvailable.availableHeroes
|
||||
.find(hab => targetHeroIds.contains(hab.heroId))
|
||||
.map { matchingHero =>
|
||||
CommandSelection(
|
||||
actingFactionId = actingFactionId,
|
||||
actingProvinceId = swearBrotherhoodAvailable.actingProvinceId,
|
||||
available = swearBrotherhoodAvailable,
|
||||
selected = SwearBrotherhoodSelected(newBrotherHeroId = matchingHero.heroId),
|
||||
reason = "fulfill SwearBrotherhood quest"
|
||||
)
|
||||
}
|
||||
}.headOption
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user