mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-29 00:55:43 +00:00
Delete LegacyRansomValidity and convert test to Scala types (#5236)
Remove the proto wrapper LegacyRansomValidity and its only caller (the proto overload of AvailableResolveRansomOfferCommandFactory). Convert the test from proto types to Scala types, replacing ScalaPB's .update() lens syntax with helper functions. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+6
-108
@@ -1,37 +1,18 @@
|
||||
package net.eagle0.eagle.library.actions.availability
|
||||
|
||||
import net.eagle0.eagle.api.available_command.ResolveRansomOfferAvailableCommand
|
||||
import net.eagle0.eagle.common.diplomacy_offer.{
|
||||
DiplomacyOffer as DiplomacyOfferProto,
|
||||
HostageOfferedInExchange as HostageOfferedInExchangeProto,
|
||||
InvitationDetails,
|
||||
PrisonerOfferedInExchange as PrisonerOfferedInExchangeProto,
|
||||
PrisonerToBeRansomed as PrisonerToBeRansomedProto,
|
||||
RansomOfferDetails as RansomOfferDetailsProto
|
||||
}
|
||||
import net.eagle0.eagle.common.diplomacy_offer_status.DiplomacyOfferStatus.{
|
||||
DIPLOMACY_OFFER_STATUS_REJECTED,
|
||||
DIPLOMACY_OFFER_STATUS_UNRESOLVED
|
||||
}
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.library.util.ransom_validity.RansomValidity
|
||||
import net.eagle0.eagle.library.util.LegacyRansomValidity
|
||||
import net.eagle0.eagle.library.EagleInternalException
|
||||
import net.eagle0.eagle.model.proto_converters.diplomacy_offer.status.StatusConverter
|
||||
import net.eagle0.eagle.model.state.diplomacy_offer.{DiplomacyOffer, Invitation, RansomOffer}
|
||||
import net.eagle0.eagle.model.state.diplomacy_offer.{Invitation, RansomOffer}
|
||||
import net.eagle0.eagle.model.state.diplomacy_offer.status.{Rejected, Unresolved}
|
||||
import net.eagle0.eagle.model.state.game_state.GameState as ScalaGameState
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.FactionId
|
||||
|
||||
object AvailableResolveRansomOfferCommandFactory {
|
||||
|
||||
// ==================== Scala overload ====================
|
||||
|
||||
// Don't show an offer if the same faction has an outstanding offer that trades away the prisoner to be ransomed,
|
||||
// or either the offering or targeted faction has an incoming invitation that must be resolved first
|
||||
private def hasOutstandingConflictScala(
|
||||
private def hasOutstandingConflict(
|
||||
offer: RansomOffer,
|
||||
gameState: ScalaGameState
|
||||
gameState: GameState
|
||||
): Boolean = {
|
||||
val prisonerHeroId = offer.prisonerToBeRansomed.prisonerHeroId
|
||||
|
||||
@@ -69,9 +50,8 @@ object AvailableResolveRansomOfferCommandFactory {
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.DiplomacyOfferInfo
|
||||
|
||||
/** Scala overload - returns pure Scala type */
|
||||
def availableCommand(
|
||||
gameState: ScalaGameState,
|
||||
gameState: GameState,
|
||||
factionId: FactionId
|
||||
): Option[AvailableCommand] = {
|
||||
val provinces = gameState.provinces.values.toVector
|
||||
@@ -80,7 +60,7 @@ object AvailableResolveRansomOfferCommandFactory {
|
||||
.incomingDiplomacyOffers
|
||||
.collect { case ro: RansomOffer => ro }
|
||||
.filter(offer => RansomValidity.isStillValid(offer, provinces))
|
||||
.filter(offer => !hasOutstandingConflictScala(offer, gameState))
|
||||
.filter(offer => !hasOutstandingConflict(offer, gameState))
|
||||
.filter(_.status == Unresolved) match {
|
||||
case items if items.isEmpty => None
|
||||
case offers =>
|
||||
@@ -98,86 +78,4 @@ object AvailableResolveRansomOfferCommandFactory {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Proto overload ====================
|
||||
|
||||
// Don't show an offer if the same faction has an outstanding offer that trades away the prisoner to be ransomed,
|
||||
// or either the offering or targeted faction has an incoming invitation that must be resolved first
|
||||
private def hasOutstandingConflict(
|
||||
offer: DiplomacyOfferProto,
|
||||
gs: GameState
|
||||
): Boolean = offer.offerDetails match {
|
||||
case RansomOfferDetailsProto(
|
||||
Some(prisonerToBeRansomed),
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_ /* unknownFieldSet */
|
||||
) =>
|
||||
gs.factions.values
|
||||
.flatMap(_.incomingDiplomacyOffers)
|
||||
.exists { diploOffer =>
|
||||
diploOffer.offerDetails match {
|
||||
case RansomOfferDetailsProto(
|
||||
_,
|
||||
prisonersOffered,
|
||||
_,
|
||||
_,
|
||||
_ /* unknownFieldSet */
|
||||
) =>
|
||||
prisonersOffered
|
||||
.exists(
|
||||
_.heroId == prisonerToBeRansomed.prisonerHeroId
|
||||
) && diploOffer.status != DIPLOMACY_OFFER_STATUS_REJECTED
|
||||
case _ => false
|
||||
}
|
||||
} || gs
|
||||
.factions(offer.originatingFactionId)
|
||||
.incomingDiplomacyOffers
|
||||
.filter(_.status != DIPLOMACY_OFFER_STATUS_REJECTED)
|
||||
.exists { invitation =>
|
||||
invitation.offerDetails match {
|
||||
case InvitationDetails(_ /* unknownFieldSet */ ) => true
|
||||
case _ => false
|
||||
}
|
||||
} || gs
|
||||
.factions(offer.targetFactionId)
|
||||
.incomingDiplomacyOffers
|
||||
.filter(_.status != DIPLOMACY_OFFER_STATUS_REJECTED)
|
||||
.exists {
|
||||
_.offerDetails match {
|
||||
case InvitationDetails(_ /* unknownFieldSet */ ) => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
case _ => throw new EagleInternalException("Not a ransom offer")
|
||||
}
|
||||
|
||||
def availableCommand(
|
||||
gameState: GameState,
|
||||
factionId: FactionId
|
||||
): Option[ResolveRansomOfferAvailableCommand] =
|
||||
gameState
|
||||
.factions(factionId)
|
||||
.incomingDiplomacyOffers
|
||||
.collect { diplomacyOffer =>
|
||||
diplomacyOffer.offerDetails match {
|
||||
case _: RansomOfferDetailsProto => diplomacyOffer
|
||||
}
|
||||
}
|
||||
.filter(offer => LegacyRansomValidity.isStillValid(offer, gameState))
|
||||
.filter(offer => !hasOutstandingConflict(offer, gameState))
|
||||
.filter(_.status == DIPLOMACY_OFFER_STATUS_UNRESOLVED) match {
|
||||
case items if items.isEmpty => None
|
||||
case offers: Seq[DiplomacyOffer] =>
|
||||
Some(
|
||||
ResolveRansomOfferAvailableCommand(
|
||||
offers = offers.map {
|
||||
_.withEligibleStatuses(
|
||||
EligibleDiplomacyStatuses.acceptRejectStatuses.map(StatusConverter.toProto)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,15 +697,8 @@ scala_library(
|
||||
],
|
||||
deps = [
|
||||
":eligible_diplomacy_statuses",
|
||||
":pkg",
|
||||
"//src/main/protobuf/net/eagle0/eagle/api:available_command_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/common:diplomacy_offer_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:game_state_scala_proto",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library:eagle_internal_exception",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:legacy_ransom_validity",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/ransom_validity",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters/diplomacy_offer/status",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/diplomacy_offer",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/diplomacy_offer/status",
|
||||
|
||||
@@ -237,25 +237,6 @@ scala_library(
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "legacy_ransom_validity",
|
||||
srcs = ["LegacyRansomValidity.scala"],
|
||||
visibility = [
|
||||
"//src/main/scala/net/eagle0/eagle/library:__subpackages__",
|
||||
"//src/test/scala/net/eagle0/eagle/library:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//src/main/protobuf/net/eagle0/eagle/common:diplomacy_offer_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/common:unaffiliated_hero_type_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:game_state_scala_proto",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util/ransom_validity",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters/diplomacy_offer",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/diplomacy_offer",
|
||||
],
|
||||
)
|
||||
|
||||
scala_library(
|
||||
name = "map_generator",
|
||||
srcs = ["MapGenerator.scala"],
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
package net.eagle0.eagle.library.util
|
||||
|
||||
import net.eagle0.eagle.common.diplomacy_offer.DiplomacyOffer
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.library.util.ransom_validity.RansomValidity
|
||||
import net.eagle0.eagle.model.proto_converters.diplomacy_offer.DiplomacyOfferConverter
|
||||
import net.eagle0.eagle.model.proto_converters.province.ProvinceConverter
|
||||
|
||||
object LegacyRansomValidity {
|
||||
def isStillValid(offer: DiplomacyOffer, gs: GameState): Boolean =
|
||||
RansomValidity.isStillValid(
|
||||
DiplomacyOfferConverter.fromProto(offer),
|
||||
gs.provinces.values.map(ProvinceConverter.fromProto).toVector
|
||||
)
|
||||
}
|
||||
+275
-253
@@ -1,112 +1,155 @@
|
||||
package net.eagle0.eagle.library.actions.availability
|
||||
|
||||
import net.eagle0.eagle.common.date.Date
|
||||
import net.eagle0.eagle.common.diplomacy_offer.{
|
||||
DiplomacyOffer,
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand
|
||||
import net.eagle0.eagle.model.state.command.available.AvailableCommand.DiplomacyOfferInfo
|
||||
import net.eagle0.eagle.model.state.date.Date
|
||||
import net.eagle0.eagle.model.state.diplomacy_offer.{DiplomacyOffer, Invitation, RansomOffer}
|
||||
import net.eagle0.eagle.model.state.diplomacy_offer.status.{Accepted, Rejected, Unresolved}
|
||||
import net.eagle0.eagle.model.state.diplomacy_offer.RansomOfferDetails.{
|
||||
HostageOfferedInExchange,
|
||||
InvitationDetails,
|
||||
PrisonerOfferedInExchange,
|
||||
PrisonerToBeRansomed,
|
||||
RansomOfferDetails
|
||||
PrisonerToBeRansomed
|
||||
}
|
||||
import net.eagle0.eagle.common.diplomacy_offer_status.DiplomacyOfferStatus.{
|
||||
DIPLOMACY_OFFER_STATUS_ACCEPTED,
|
||||
DIPLOMACY_OFFER_STATUS_REJECTED,
|
||||
DIPLOMACY_OFFER_STATUS_UNRESOLVED
|
||||
}
|
||||
import net.eagle0.eagle.common.recruitment_info.RecruitmentInfo
|
||||
import net.eagle0.eagle.common.recruitment_info.RecruitmentStatus.{
|
||||
RECRUITMENT_STATUS_PRISONER,
|
||||
RECRUITMENT_STATUS_TRAVELER
|
||||
}
|
||||
import net.eagle0.eagle.common.unaffiliated_hero_type.UnaffiliatedHeroType.{
|
||||
UNAFFILIATED_HERO_PRISONER,
|
||||
UNAFFILIATED_HERO_TRAVELER
|
||||
}
|
||||
import net.eagle0.eagle.internal.faction.Faction
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.internal.province.Province
|
||||
import net.eagle0.eagle.internal.unaffiliated_hero.UnaffiliatedHero
|
||||
import net.eagle0.eagle.library.util.IDable.{mapifyFactions, mapifyProvinces}
|
||||
import net.eagle0.eagle.model.state.faction.concrete.FactionC
|
||||
import net.eagle0.eagle.model.state.faction.FactionT
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.province.concrete.ProvinceC
|
||||
import net.eagle0.eagle.model.state.province.ProvinceT
|
||||
import net.eagle0.eagle.model.state.run_status.RunStatus
|
||||
import net.eagle0.eagle.model.state.unaffiliated_hero.concrete.UnaffiliatedHeroC
|
||||
import net.eagle0.eagle.model.state.unaffiliated_hero.RecruitmentInfo
|
||||
import net.eagle0.eagle.model.state.unaffiliated_hero.UnaffiliatedHeroType.{Prisoner, Traveler}
|
||||
import net.eagle0.eagle.model.state.RoundPhase.PlayerCommands
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
import org.scalatest.Inside.inside
|
||||
|
||||
class AvailableResolveRansomOfferCommandFactoryTest extends AnyFlatSpec with Matchers {
|
||||
private val actingFid = 19
|
||||
private val firstOfferingFid = 22
|
||||
private val secondOfferingFid = 6
|
||||
|
||||
private val firstOffer = DiplomacyOffer(
|
||||
private val firstOffer = RansomOffer(
|
||||
originatingFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
messengerHeroId = 1,
|
||||
messengerOriginProvinceId = 2,
|
||||
offerDetails = RansomOfferDetails(
|
||||
prisonerToBeRansomed = Some(
|
||||
PrisonerToBeRansomed(
|
||||
prisonerHeroId = 86,
|
||||
provinceIdForPrisoner = 1
|
||||
)
|
||||
),
|
||||
prisonersOffered = Vector(PrisonerOfferedInExchange(heroId = 105, provinceIdWithHero = 2)),
|
||||
hostagesOffered = Vector(HostageOfferedInExchange(heroId = 101, provinceIdWithHero = 2)),
|
||||
goldOffered = 150
|
||||
offerTextId = "test_offer",
|
||||
prisonerToBeRansomed = PrisonerToBeRansomed(
|
||||
prisonerHeroId = 86,
|
||||
provinceIdForPrisoner = 1
|
||||
),
|
||||
status = DIPLOMACY_OFFER_STATUS_UNRESOLVED
|
||||
prisonersOffered =
|
||||
Vector(PrisonerOfferedInExchange(heroId = 105, factionIdForPrisoner = -1, provinceIdWithHero = 2)),
|
||||
hostagesOffered = Vector(HostageOfferedInExchange(heroId = 101, provinceIdWithHero = 2)),
|
||||
goldOffered = 150,
|
||||
status = Unresolved
|
||||
)
|
||||
|
||||
private val gameState = GameState(
|
||||
currentDate = Some(Date(year = 1501, month = 6)),
|
||||
randomSeed = 1L,
|
||||
factions = mapifyFactions(
|
||||
Faction(
|
||||
id = actingFid,
|
||||
incomingDiplomacyOffers = Vector(firstOffer)
|
||||
),
|
||||
Faction(id = firstOfferingFid),
|
||||
Faction(id = secondOfferingFid)
|
||||
),
|
||||
provinces = mapifyProvinces(
|
||||
Province(
|
||||
id = 1,
|
||||
rulingFactionId = Some(actingFid),
|
||||
unaffiliatedHeroes = Vector(
|
||||
UnaffiliatedHero(
|
||||
heroId = 86,
|
||||
`type` = UNAFFILIATED_HERO_PRISONER,
|
||||
recruitmentInfo = Some(RecruitmentInfo(status = RECRUITMENT_STATUS_PRISONER))
|
||||
)
|
||||
private def makeProvinces(
|
||||
province1RulingFactionId: Option[Int] = Some(actingFid),
|
||||
province1Prisoners: Vector[UnaffiliatedHeroC] = Vector(
|
||||
UnaffiliatedHeroC(
|
||||
heroId = 86,
|
||||
unaffiliatedHeroType = Prisoner,
|
||||
recruitmentInfo = RecruitmentInfo.Prisoner
|
||||
)
|
||||
),
|
||||
Province(
|
||||
id = 2,
|
||||
rulingFactionId = Some(firstOfferingFid),
|
||||
gold = 250,
|
||||
rulingFactionHeroIds = Vector(101),
|
||||
unaffiliatedHeroes = Vector(
|
||||
UnaffiliatedHero(
|
||||
heroId = 105,
|
||||
`type` = UNAFFILIATED_HERO_PRISONER,
|
||||
recruitmentInfo = Some(RecruitmentInfo(status = RECRUITMENT_STATUS_PRISONER))
|
||||
)
|
||||
province2Gold: Int = 250,
|
||||
province2RulingFactionId: Option[Int] = Some(firstOfferingFid),
|
||||
province2HeroIds: Vector[Int] = Vector(101),
|
||||
province2Prisoners: Vector[UnaffiliatedHeroC] = Vector(
|
||||
UnaffiliatedHeroC(
|
||||
heroId = 105,
|
||||
unaffiliatedHeroType = Prisoner,
|
||||
recruitmentInfo = RecruitmentInfo.Prisoner
|
||||
)
|
||||
),
|
||||
Province(id = 3, rulingFactionId = Some(secondOfferingFid))
|
||||
)
|
||||
)
|
||||
|
||||
"availableCommand" should "return a command with the available ransom offers" in {
|
||||
val cmd = AvailableResolveRansomOfferCommandFactory
|
||||
.availableCommand(gameState, actingFid)
|
||||
.get
|
||||
|
||||
val expectedOffer = firstOffer.withEligibleStatuses(
|
||||
Vector(
|
||||
DIPLOMACY_OFFER_STATUS_ACCEPTED,
|
||||
DIPLOMACY_OFFER_STATUS_REJECTED
|
||||
)
|
||||
): Map[Int, ProvinceT] = Map(
|
||||
1 -> ProvinceC(
|
||||
id = 1,
|
||||
rulingFactionId = province1RulingFactionId,
|
||||
unaffiliatedHeroes = province1Prisoners
|
||||
),
|
||||
2 -> ProvinceC(
|
||||
id = 2,
|
||||
rulingFactionId = province2RulingFactionId,
|
||||
gold = province2Gold,
|
||||
rulingFactionHeroIds = province2HeroIds,
|
||||
unaffiliatedHeroes = province2Prisoners
|
||||
),
|
||||
3 -> ProvinceC(id = 3, rulingFactionId = Some(secondOfferingFid))
|
||||
)
|
||||
|
||||
private def makeFactions(
|
||||
actingFactionOffers: Vector[DiplomacyOffer] = Vector(firstOffer),
|
||||
firstOfferingFactionOffers: Vector[DiplomacyOffer] = Vector(),
|
||||
secondOfferingFactionOffers: Vector[DiplomacyOffer] = Vector()
|
||||
): Map[Int, FactionT] = Map(
|
||||
actingFid -> FactionC(
|
||||
id = actingFid,
|
||||
factionHeadId = 100,
|
||||
name = "Acting Faction",
|
||||
leaderIds = Vector(100),
|
||||
incomingDiplomacyOffers = actingFactionOffers
|
||||
),
|
||||
firstOfferingFid -> FactionC(
|
||||
id = firstOfferingFid,
|
||||
factionHeadId = 200,
|
||||
name = "First Offering Faction",
|
||||
leaderIds = Vector(200),
|
||||
incomingDiplomacyOffers = firstOfferingFactionOffers
|
||||
),
|
||||
secondOfferingFid -> FactionC(
|
||||
id = secondOfferingFid,
|
||||
factionHeadId = 300,
|
||||
name = "Second Offering Faction",
|
||||
leaderIds = Vector(300),
|
||||
incomingDiplomacyOffers = secondOfferingFactionOffers
|
||||
)
|
||||
cmd.offers should contain theSameElementsAs Vector(expectedOffer)
|
||||
}
|
||||
)
|
||||
|
||||
private def makeGameState(
|
||||
factions: Map[Int, FactionT] = makeFactions(),
|
||||
provinces: Map[Int, ProvinceT] = makeProvinces()
|
||||
): GameState = GameState(
|
||||
gameId = 1,
|
||||
currentRoundId = 1,
|
||||
currentPhase = PlayerCommands,
|
||||
currentDate = Some(Date(year = 1501, month = Date.Month.June)),
|
||||
actionResultCount = 0,
|
||||
provinces = provinces,
|
||||
heroes = Map(),
|
||||
battalions = Map(),
|
||||
destroyedBattalions = Map(),
|
||||
factions = factions,
|
||||
factionCommandCounts = Map(),
|
||||
killedHeroes = Map(),
|
||||
destroyedFactions = Map(),
|
||||
outstandingBattles = Vector(),
|
||||
battleCounter = 0,
|
||||
deferredNotifications = Vector(),
|
||||
runStatus = RunStatus.Running,
|
||||
victor = None,
|
||||
battalionTypes = Vector(),
|
||||
randomSeed = 1L,
|
||||
chronicleEntries = Vector()
|
||||
)
|
||||
|
||||
private val gameState = makeGameState()
|
||||
|
||||
"availableCommand" should "return a command with the available ransom offers" in
|
||||
inside(AvailableResolveRansomOfferCommandFactory.availableCommand(gameState, actingFid)) {
|
||||
case Some(AvailableCommand.ResolveRansomOfferAvailable(offers)) =>
|
||||
offers should have size 1
|
||||
val expectedOffer = DiplomacyOfferInfo(
|
||||
offeringFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
heroId = Some(1),
|
||||
eligibleStatuses = Vector(Accepted, Rejected)
|
||||
)
|
||||
offers should contain theSameElementsAs Vector(expectedOffer)
|
||||
}
|
||||
|
||||
it should "return nothing if there are no ransom offers" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
@@ -116,216 +159,195 @@ class AvailableResolveRansomOfferCommandFactoryTest extends AnyFlatSpec with Mat
|
||||
}
|
||||
|
||||
it should "return nothing if the origin province doesn't have enough gold" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(_.provinces(2).gold := 149),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
val gs = makeGameState(provinces = makeProvinces(province2Gold = 149))
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return nothing if the origin province no longer has the hostage" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(_.provinces(2).rulingFactionHeroIds := Vector(102)),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
val gs = makeGameState(provinces = makeProvinces(province2HeroIds = Vector(102)))
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return nothing if the origin province no longer has the prisoner" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.provinces(2).unaffiliatedHeroes := Vector(
|
||||
UnaffiliatedHero(
|
||||
val gs = makeGameState(
|
||||
provinces = makeProvinces(
|
||||
province2Prisoners = Vector(
|
||||
UnaffiliatedHeroC(
|
||||
heroId = 105,
|
||||
`type` = UNAFFILIATED_HERO_TRAVELER,
|
||||
recruitmentInfo = Some(RecruitmentInfo(status = RECRUITMENT_STATUS_TRAVELER))
|
||||
unaffiliatedHeroType = Traveler,
|
||||
recruitmentInfo = RecruitmentInfo.Traveler
|
||||
)
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
)
|
||||
)
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return nothing if the origin province no longer belongs to the offering faction" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.provinces(2).optionalRulingFactionId := None
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
val gs = makeGameState(provinces = makeProvinces(province2RulingFactionId = None))
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return nothing if the target province no longer has the prisoner to be ransomed" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.provinces(1).unaffiliatedHeroes := Vector(
|
||||
UnaffiliatedHero(
|
||||
val gs = makeGameState(
|
||||
provinces = makeProvinces(
|
||||
province1Prisoners = Vector(
|
||||
UnaffiliatedHeroC(
|
||||
heroId = 86,
|
||||
`type` = UNAFFILIATED_HERO_TRAVELER,
|
||||
recruitmentInfo = Some(RecruitmentInfo(status = RECRUITMENT_STATUS_TRAVELER))
|
||||
unaffiliatedHeroType = Traveler,
|
||||
recruitmentInfo = RecruitmentInfo.Traveler
|
||||
)
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
)
|
||||
)
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return nothing if the target province no longer belongs to the target faction" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.provinces(1).rulingFactionId := secondOfferingFid
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
val gs = makeGameState(provinces = makeProvinces(province1RulingFactionId = Some(secondOfferingFid)))
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return nothing if there is an outstanding offer to trade away the prisoner to be ransomed" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.factions(secondOfferingFid).incomingDiplomacyOffers := Vector(
|
||||
DiplomacyOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerOriginProvinceId = 1,
|
||||
offerDetails = RansomOfferDetails(
|
||||
prisonerToBeRansomed = Some(PrisonerToBeRansomed()),
|
||||
prisonersOffered = Vector(
|
||||
PrisonerOfferedInExchange(
|
||||
heroId = 86,
|
||||
factionIdForPrisoner = firstOfferingFid,
|
||||
provinceIdWithHero = 1
|
||||
)
|
||||
),
|
||||
hostagesOffered = Vector(),
|
||||
goldOffered = 0
|
||||
),
|
||||
status = DIPLOMACY_OFFER_STATUS_UNRESOLVED
|
||||
)
|
||||
val conflictingOffer = RansomOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerHeroId = 2,
|
||||
messengerOriginProvinceId = 1,
|
||||
offerTextId = "conflicting_offer",
|
||||
prisonerToBeRansomed = PrisonerToBeRansomed(prisonerHeroId = 0, provinceIdForPrisoner = 0),
|
||||
prisonersOffered = Vector(
|
||||
PrisonerOfferedInExchange(
|
||||
heroId = 86,
|
||||
factionIdForPrisoner = firstOfferingFid,
|
||||
provinceIdWithHero = 1
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
hostagesOffered = Vector(),
|
||||
goldOffered = 0,
|
||||
status = Unresolved
|
||||
)
|
||||
val gs = makeGameState(
|
||||
factions = makeFactions(secondOfferingFactionOffers = Vector(conflictingOffer))
|
||||
)
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return a command if the outstanding offer to trade away the prisoner to be ransomed was rejected" in {
|
||||
AvailableResolveRansomOfferCommandFactory
|
||||
.availableCommand(
|
||||
gameState.update(
|
||||
_.factions(secondOfferingFid).incomingDiplomacyOffers := Vector(
|
||||
DiplomacyOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerOriginProvinceId = 1,
|
||||
offerDetails = RansomOfferDetails(
|
||||
prisonerToBeRansomed = Some(PrisonerToBeRansomed()),
|
||||
prisonersOffered = Vector(
|
||||
PrisonerOfferedInExchange(
|
||||
heroId = 86,
|
||||
factionIdForPrisoner = firstOfferingFid,
|
||||
provinceIdWithHero = 1
|
||||
)
|
||||
),
|
||||
hostagesOffered = Vector(),
|
||||
goldOffered = 0
|
||||
),
|
||||
status = DIPLOMACY_OFFER_STATUS_REJECTED
|
||||
)
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
)
|
||||
.get
|
||||
.offers shouldBe Vector(
|
||||
firstOffer.withEligibleStatuses(
|
||||
Vector(
|
||||
DIPLOMACY_OFFER_STATUS_ACCEPTED,
|
||||
DIPLOMACY_OFFER_STATUS_REJECTED
|
||||
val conflictingOffer = RansomOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerHeroId = 2,
|
||||
messengerOriginProvinceId = 1,
|
||||
offerTextId = "conflicting_offer",
|
||||
prisonerToBeRansomed = PrisonerToBeRansomed(prisonerHeroId = 0, provinceIdForPrisoner = 0),
|
||||
prisonersOffered = Vector(
|
||||
PrisonerOfferedInExchange(
|
||||
heroId = 86,
|
||||
factionIdForPrisoner = firstOfferingFid,
|
||||
provinceIdWithHero = 1
|
||||
)
|
||||
)
|
||||
),
|
||||
hostagesOffered = Vector(),
|
||||
goldOffered = 0,
|
||||
status = Rejected
|
||||
)
|
||||
val gs = makeGameState(
|
||||
factions = makeFactions(secondOfferingFactionOffers = Vector(conflictingOffer))
|
||||
)
|
||||
|
||||
inside(AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid)) {
|
||||
case Some(AvailableCommand.ResolveRansomOfferAvailable(offers)) =>
|
||||
offers shouldBe Vector(
|
||||
DiplomacyOfferInfo(
|
||||
offeringFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
heroId = Some(1),
|
||||
eligibleStatuses = Vector(Accepted, Rejected)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it should "return nothing if there is an outstanding invitation to the offering faction" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.factions(firstOfferingFid).incomingDiplomacyOffers := Vector(
|
||||
DiplomacyOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = DIPLOMACY_OFFER_STATUS_UNRESOLVED,
|
||||
offerDetails = InvitationDetails()
|
||||
)
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
val invitation = Invitation(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerHeroId = 3,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = Unresolved,
|
||||
offerTextId = "invitation"
|
||||
)
|
||||
val gs = makeGameState(
|
||||
factions = makeFactions(firstOfferingFactionOffers = Vector(invitation))
|
||||
)
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return an ransom offer if the outstanding invitation to the offering faction was rejected" in {
|
||||
AvailableResolveRansomOfferCommandFactory
|
||||
.availableCommand(
|
||||
gameState.update(
|
||||
_.factions(firstOfferingFid).incomingDiplomacyOffers := Vector(
|
||||
DiplomacyOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = DIPLOMACY_OFFER_STATUS_REJECTED,
|
||||
offerDetails = InvitationDetails()
|
||||
)
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
)
|
||||
.get
|
||||
.offers shouldBe Vector(
|
||||
firstOffer.withEligibleStatuses(
|
||||
Vector(
|
||||
DIPLOMACY_OFFER_STATUS_ACCEPTED,
|
||||
DIPLOMACY_OFFER_STATUS_REJECTED
|
||||
)
|
||||
)
|
||||
it should "return a ransom offer if the outstanding invitation to the offering faction was rejected" in {
|
||||
val invitation = Invitation(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerHeroId = 3,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = Rejected,
|
||||
offerTextId = "invitation"
|
||||
)
|
||||
val gs = makeGameState(
|
||||
factions = makeFactions(firstOfferingFactionOffers = Vector(invitation))
|
||||
)
|
||||
|
||||
inside(AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid)) {
|
||||
case Some(AvailableCommand.ResolveRansomOfferAvailable(offers)) =>
|
||||
offers shouldBe Vector(
|
||||
DiplomacyOfferInfo(
|
||||
offeringFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
heroId = Some(1),
|
||||
eligibleStatuses = Vector(Accepted, Rejected)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
it should "return nothing if there is an outstanding invitation to the acting faction" in {
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(
|
||||
gameState.update(
|
||||
_.factions(actingFid).incomingDiplomacyOffers :+=
|
||||
DiplomacyOffer(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = DIPLOMACY_OFFER_STATUS_UNRESOLVED,
|
||||
offerDetails = InvitationDetails()
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
) shouldBe empty
|
||||
val invitation = Invitation(
|
||||
originatingFactionId = actingFid,
|
||||
targetFactionId = secondOfferingFid,
|
||||
messengerHeroId = 3,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = Unresolved,
|
||||
offerTextId = "invitation"
|
||||
)
|
||||
val gs = makeGameState(
|
||||
factions = makeFactions(actingFactionOffers = Vector(firstOffer, invitation))
|
||||
)
|
||||
AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid) shouldBe empty
|
||||
}
|
||||
|
||||
it should "return an invitation if the outstanding invitation to the acting faction was rejected" in {
|
||||
AvailableResolveRansomOfferCommandFactory
|
||||
.availableCommand(
|
||||
gameState.update(
|
||||
_.factions(actingFid).incomingDiplomacyOffers :+=
|
||||
DiplomacyOffer(
|
||||
originatingFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = DIPLOMACY_OFFER_STATUS_REJECTED,
|
||||
offerDetails = InvitationDetails()
|
||||
)
|
||||
),
|
||||
actingFid
|
||||
)
|
||||
.get
|
||||
.offers shouldBe Vector(
|
||||
firstOffer.withEligibleStatuses(
|
||||
Vector(
|
||||
DIPLOMACY_OFFER_STATUS_ACCEPTED,
|
||||
DIPLOMACY_OFFER_STATUS_REJECTED
|
||||
)
|
||||
)
|
||||
it should "return a ransom offer if the outstanding invitation to the acting faction was rejected" in {
|
||||
val invitation = Invitation(
|
||||
originatingFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
messengerHeroId = 3,
|
||||
messengerOriginProvinceId = 1,
|
||||
status = Rejected,
|
||||
offerTextId = "invitation"
|
||||
)
|
||||
val gs = makeGameState(
|
||||
factions = makeFactions(actingFactionOffers = Vector(firstOffer, invitation))
|
||||
)
|
||||
|
||||
inside(AvailableResolveRansomOfferCommandFactory.availableCommand(gs, actingFid)) {
|
||||
case Some(AvailableCommand.ResolveRansomOfferAvailable(offers)) =>
|
||||
offers shouldBe Vector(
|
||||
DiplomacyOfferInfo(
|
||||
offeringFactionId = firstOfferingFid,
|
||||
targetFactionId = actingFid,
|
||||
heroId = Some(1),
|
||||
eligibleStatuses = Vector(Accepted, Rejected)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,15 +604,21 @@ scala_test(
|
||||
name = "available_resolve_ransom_offer_command_factory_test",
|
||||
srcs = ["AvailableResolveRansomOfferCommandFactoryTest.scala"],
|
||||
deps = [
|
||||
"//src/main/protobuf/net/eagle0/eagle/api:available_command_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:faction_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:game_state_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:hero_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:province_scala_proto",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/availability:available_resolve_ransom_offer_command_factory",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/availability:pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:idable",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:round_phase",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/command/available",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/date",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/diplomacy_offer",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/diplomacy_offer/status",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/faction",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/faction/concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province/concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/run_status",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/unaffiliated_hero",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/unaffiliated_hero/concrete",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user