Fix SendSuppliesQuest not incrementing when sending supplies (#5942)

SendSuppliesCommand was missing quest fulfillment logic. This adds
the incrementing of SendSuppliesQuest progress using the existing
QuestFulfillmentUtils pattern from RestCommand.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-08 06:59:59 -08:00
committed by GitHub
co-authored by Claude Opus 4.5
parent 5e173d55ce
commit be1f9cc67c
4 changed files with 64 additions and 17 deletions
@@ -1206,6 +1206,7 @@ scala_library(
"//src/main/scala/net/eagle0/eagle/library/settings:ship_supplies_loss",
"//src/main/scala/net/eagle0/eagle/library/settings:turns_to_resolve_shipment",
"//src/main/scala/net/eagle0/eagle/library/util:eagle_require",
"//src/main/scala/net/eagle0/eagle/library/util/quest_fulfillment:quest_fulfillment_utils",
"//src/main/scala/net/eagle0/eagle/model/action_result:action_result_trait",
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province/concrete",
"//src/main/scala/net/eagle0/eagle/model/action_result/concrete:action_result_concrete",
@@ -1215,6 +1216,9 @@ scala_library(
"//src/main/scala/net/eagle0/eagle/model/action_result/generated_text_request",
"//src/main/scala/net/eagle0/eagle/model/action_result/types",
"//src/main/scala/net/eagle0/eagle/model/state:supplies",
"//src/main/scala/net/eagle0/eagle/model/state/province",
"//src/main/scala/net/eagle0/eagle/model/state/quest",
"//src/main/scala/net/eagle0/eagle/model/state/unaffiliated_hero",
],
)
@@ -673,7 +673,9 @@ class CommandFactory extends TCommandFactory {
foodAvailable = ac.foodAvailable,
goldSent = sc.gold,
foodSent = sc.food,
currentRoundId = gameState.currentRoundId
currentRoundId = gameState.currentRoundId,
factionProvinces = gameState.provinces.values.toVector
.filter(_.rulingFactionId.contains(actingFactionId))
)
case (ac: StartEpidemicAvailable, sc: StartEpidemicSelected) =>
val targetProvince = gameState.provinces(sc.selectedProvinceId)
@@ -1,5 +1,7 @@
package net.eagle0.eagle.library.actions.impl.command
import scala.annotation.unused
import net.eagle0.eagle.{FactionId, HeroId, ProvinceId, RoundId}
import net.eagle0.eagle.library.actions.impl.common.ProtolessSimpleAction
import net.eagle0.eagle.library.settings.{
@@ -8,12 +10,16 @@ import net.eagle0.eagle.library.settings.{
ShipSuppliesLoss,
TurnsToResolveShipment
}
import net.eagle0.eagle.library.util.quest_fulfillment.QuestFulfillmentUtils
import net.eagle0.eagle.library.util.EagleRequire.commandRequire
import net.eagle0.eagle.model.action_result.changed_province.concrete.ChangedProvinceC
import net.eagle0.eagle.model.action_result.concrete.{ActionResultC, ChangedHeroC, StatDelta}
import net.eagle0.eagle.model.action_result.types.ActionResultType.SentSupplies
import net.eagle0.eagle.model.action_result.ActionResultT
import net.eagle0.eagle.model.state.{MovingSupplies, Supplies}
import net.eagle0.eagle.model.state.province.ProvinceT
import net.eagle0.eagle.model.state.quest.SendSuppliesQuest
import net.eagle0.eagle.model.state.unaffiliated_hero.UnaffiliatedHeroT
object SendSuppliesCommand {
@@ -28,7 +34,8 @@ object SendSuppliesCommand {
foodAvailable: Int,
goldSent: Int,
foodSent: Int,
currentRoundId: RoundId
currentRoundId: RoundId,
factionProvinces: Vector[ProvinceT]
): ProtolessSimpleAction = {
commandRequire(
foodSent >= 0,
@@ -62,7 +69,8 @@ object SendSuppliesCommand {
destinationProvince = destinationProvinceId,
gold = goldSent,
food = foodSent,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = factionProvinces
)
}
@@ -73,10 +81,11 @@ object SendSuppliesCommand {
destinationProvince: ProvinceId,
gold: Int,
food: Int,
currentRoundId: RoundId
currentRoundId: RoundId,
factionProvinces: Vector[ProvinceT]
) extends ProtolessSimpleAction {
override def immediateExecute: ActionResultT =
ActionResultC(
override def immediateExecute: ActionResultT = {
val baseResult = ActionResultC(
actionResultType = SentSupplies,
actingFactionId = Some(factionId),
actingHeroId = Some(actor),
@@ -111,6 +120,27 @@ object SendSuppliesCommand {
)
)
)
// Increment SendSuppliesQuest progress when sending food to the target province
sendSuppliesQuestIncrementer(baseResult)
}
private def sendSuppliesQuestCheck(
uh: UnaffiliatedHeroT,
@unused province: ProvinceT
): Boolean =
uh.quest.exists {
case q: SendSuppliesQuest =>
q.targetProvinceId == destinationProvince && q.componentsFulfilled < q.componentCount
case _ => false
}
private def sendSuppliesQuestIncrementer: ActionResultT => ActionResultT =
QuestFulfillmentUtils.withCountersIncremented(
provinces = factionProvinces,
incrementAmount = food,
check = sendSuppliesQuestCheck
)
}
}
@@ -52,7 +52,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = -5,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
ex.getMessage shouldBe "requirement failed: Food amount cannot be negative"
@@ -71,7 +72,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = 3501,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
ex.getMessage shouldBe "requirement failed: Food amount 3501 greater than available 3500"
@@ -90,7 +92,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = -3,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
ex.getMessage shouldBe "requirement failed: Gold amount cannot be negative"
@@ -109,7 +112,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = 2698,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
ex.getMessage shouldBe "requirement failed: Gold amount 2698 greater than available 2500"
@@ -128,7 +132,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
ex.getMessage shouldBe "requirement failed: Available heroes Vector(12, 15, 18) did not include 19"
@@ -147,7 +152,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
ex.getMessage shouldBe "requirement failed: Available destination provinces Vector(25, 26, 27) did not include 4"
@@ -166,7 +172,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
.immediateExecute
@@ -189,7 +196,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
.immediateExecute
@@ -229,7 +237,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
.immediateExecute
@@ -255,7 +264,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
.immediateExecute
@@ -277,7 +287,8 @@ class SendSuppliesCommandTest extends AnyFlatSpec with Matchers with BeforeAndAf
foodAvailable = foodAvailable,
goldSent = gold,
foodSent = food,
currentRoundId = currentRoundId
currentRoundId = currentRoundId,
factionProvinces = Vector.empty
)
.immediateExecute