mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-29 04:25:42 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96566f9322 | ||
|
|
0b5146f5b1 | ||
|
|
8cd2548f07 |
@@ -128,6 +128,10 @@ Change APIs to vend Scala `GameState` and `ActionResultT` instead of proto versi
|
||||
| `VigorXPApplier.scala` | Wraps proto results | Convert to work with T |
|
||||
| `ResolveBattleAction.scala` | 2 converter calls | Convert after dependencies |
|
||||
| `PerformForcedTurnBackAction.scala` | 1 converter call | Convert after dependencies |
|
||||
| `EndFreeForAllDecisionPhaseAction.scala` | ~~fromProtoState~~ | **Complete** - now takes Scala GameState |
|
||||
| `EndBattleRequestPhaseAction.scala` | ~~fromProtoState~~ | **Complete** - now takes Scala GameState |
|
||||
| `EndDefenseDecisionPhaseAction.scala` | ~~fromProtoState~~ | **Complete** - now takes Scala GameState |
|
||||
| `EndPleaseRecruitMePhaseAction.scala` | `fromProtoState` | **BLOCKED** - Scala 3.7.2 compiler crash (lambdaLift phase) |
|
||||
| `InMemoryHistory.scala` | Stores proto results | Vend Scala types, remove proto entirely |
|
||||
| `PersistedHistory.scala` | Stores proto results | Vend Scala types, convert internally for disk |
|
||||
| `GameController.scala` | Uses proto for client communication | Keep proto (gRPC boundary) |
|
||||
|
||||
@@ -127,7 +127,7 @@ object RoundPhaseAdvancer {
|
||||
actionResultProtoApplier.applyActionResult(
|
||||
currentState,
|
||||
ActionResultProtoConverter.toProto(
|
||||
EndPleaseRecruitMePhaseAction.fromProtoState(currentState).immediateExecute
|
||||
EndPleaseRecruitMePhaseAction(GameStateConverter.fromProto(currentState)).immediateExecute
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -187,7 +187,7 @@ object RoundPhaseAdvancer {
|
||||
// There may eventually be VassalAttackDecisions, but for now we're leaving that on the player
|
||||
actionResultProtoApplier.applyActionResults(
|
||||
currentState,
|
||||
EndFreeForAllDecisionPhaseAction(currentState).results.map(
|
||||
EndFreeForAllDecisionPhaseAction(GameStateConverter.fromProto(currentState)).results.map(
|
||||
ActionResultProtoConverter.toProto(_)
|
||||
)
|
||||
)
|
||||
@@ -279,7 +279,7 @@ object RoundPhaseAdvancer {
|
||||
actionResultProtoApplier.applyActionResult(
|
||||
currentState,
|
||||
ActionResultProtoConverter.toProto(
|
||||
EndDefenseDecisionPhaseAction.fromProtoState(currentState).immediateExecute
|
||||
EndDefenseDecisionPhaseAction(GameStateConverter.fromProto(currentState)).immediateExecute
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -319,7 +319,7 @@ object RoundPhaseAdvancer {
|
||||
requestResults :+ actionResultProtoApplier.applyActionResult(
|
||||
latestState,
|
||||
ActionResultProtoConverter.toProto(
|
||||
EndBattleRequestPhaseAction.fromProtoState(latestState).immediateExecute
|
||||
EndBattleRequestPhaseAction(GameStateConverter.fromProto(latestState)).immediateExecute
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -283,21 +283,15 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:protoless_simple_action",
|
||||
],
|
||||
deps = [
|
||||
"//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/actions/impl/common:protoless_simple_action",
|
||||
"//src/main/scala/net/eagle0/eagle/library/util:eagle_require",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:action_result_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_battalion_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_faction_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_hero_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:notification_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province",
|
||||
"//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",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/generated_text_request",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types:end_battle_request_phase_result_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:round_phase",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -463,22 +457,15 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:protoless_simple_action",
|
||||
],
|
||||
deps = [
|
||||
"//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/actions/impl/common:protoless_simple_action",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:action_result_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_battalion_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_faction_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_hero_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:notification_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province",
|
||||
"//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",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/generated_text_request",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types:end_defense_decision_phase_result_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:army_converter",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:army",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:round_phase",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -496,28 +483,13 @@ scala_library(
|
||||
],
|
||||
deps = [
|
||||
":withdrawn_army_returns_home_action",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:action_result_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/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:action",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:action_with_resulting_state",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:deterministic_sequential_results_action",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:protoless_sequential_results_action",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:action_result_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_battalion_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_hero_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:notification_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/concrete:action_result_concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/concrete:changed_battalion_concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/concrete:changed_hero_concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/generated_text_request",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types:end_free_for_all_decision_phase_result_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:round_phase",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/hero:gender",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -631,7 +603,6 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:protoless_simple_action",
|
||||
],
|
||||
deps = [
|
||||
"//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/actions/impl/common:protoless_simple_action",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:action_result_trait",
|
||||
@@ -644,8 +615,8 @@ scala_library(
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/concrete:notification_concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/generated_text_request",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types:end_please_recruit_me_phase_result_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:notification_converter",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:round_phase",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/game_state",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
package net.eagle0.eagle.library.actions.impl.action
|
||||
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.library.actions.impl.common.ProtolessSimpleAction
|
||||
import net.eagle0.eagle.library.util.EagleRequire.internalRequire
|
||||
import net.eagle0.eagle.model.action_result.changed_province.concrete.ChangedProvinceC
|
||||
import net.eagle0.eagle.model.action_result.concrete.ActionResultC
|
||||
import net.eagle0.eagle.model.action_result.types.EndBattleRequestPhaseResultType
|
||||
import net.eagle0.eagle.model.action_result.ActionResultT
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.RoundPhase
|
||||
import net.eagle0.eagle.ProvinceId
|
||||
|
||||
@@ -23,7 +23,7 @@ case class EndBattleRequestPhaseAction(
|
||||
}
|
||||
|
||||
object EndBattleRequestPhaseAction {
|
||||
def fromProtoState(gameState: GameState): EndBattleRequestPhaseAction = {
|
||||
def apply(gameState: GameState): EndBattleRequestPhaseAction = {
|
||||
internalRequire(
|
||||
gameState.provinces.forall {
|
||||
case (_, province) =>
|
||||
|
||||
+12
-12
@@ -1,14 +1,13 @@
|
||||
package net.eagle0.eagle.library.actions.impl.action
|
||||
|
||||
import net.eagle0.eagle.{FactionId, ProvinceId}
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.library.actions.impl.common.ProtolessSimpleAction
|
||||
import net.eagle0.eagle.model.action_result.changed_province.concrete.ChangedProvinceC
|
||||
import net.eagle0.eagle.model.action_result.concrete.ActionResultC
|
||||
import net.eagle0.eagle.model.action_result.types.EndDefenseDecisionPhaseResultType
|
||||
import net.eagle0.eagle.model.action_result.ActionResultT
|
||||
import net.eagle0.eagle.model.proto_converters.ArmyConverter
|
||||
import net.eagle0.eagle.model.state.{MovingArmy, RoundPhase}
|
||||
import net.eagle0.eagle.model.state.{HostileArmyGroupStatus, MovingArmy, RoundPhase}
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
|
||||
/** Resolution for a single province that paid tribute to hostile armies */
|
||||
case class PayingProvinceResolution(
|
||||
@@ -52,19 +51,21 @@ case class EndDefenseDecisionPhaseAction(
|
||||
}
|
||||
|
||||
object EndDefenseDecisionPhaseAction {
|
||||
def fromProtoState(gameState: GameState): EndDefenseDecisionPhaseAction = {
|
||||
def apply(gameState: GameState): EndDefenseDecisionPhaseAction = {
|
||||
val resolutions = gameState.provinces.values.flatMap { province =>
|
||||
val tributePaidArmyGroups = province.hostileArmies.filter(
|
||||
_.status.asMessage.sealedValue.isTributePaid
|
||||
)
|
||||
val tributePaidArmyGroups = province.hostileArmies.filter { ag =>
|
||||
ag.status match {
|
||||
case _: HostileArmyGroupStatus.TributePaid => true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
if tributePaidArmyGroups.isEmpty then None
|
||||
else {
|
||||
val returningArmies = for {
|
||||
ag <- tributePaidArmyGroups
|
||||
armyProto <- ag.armies
|
||||
} yield {
|
||||
val army = ArmyConverter.fromProto(armyProto)
|
||||
ag <- tributePaidArmyGroups
|
||||
army <- ag.armies
|
||||
} yield
|
||||
// Swap destination/origin, clear flee province, set arrival to next round
|
||||
MovingArmy(
|
||||
id = army.id,
|
||||
@@ -76,7 +77,6 @@ object EndDefenseDecisionPhaseAction {
|
||||
suppliesLoss = army.suppliesLoss,
|
||||
startingPositionIndex = army.startingPositionIndex
|
||||
)
|
||||
}
|
||||
|
||||
Some(
|
||||
PayingProvinceResolution(
|
||||
|
||||
+2
-3
@@ -1,11 +1,10 @@
|
||||
package net.eagle0.eagle.library.actions.impl.action
|
||||
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.library.actions.impl.common.ProtolessSequentialResultsAction
|
||||
import net.eagle0.eagle.model.action_result.concrete.ActionResultC
|
||||
import net.eagle0.eagle.model.action_result.types.EndFreeForAllDecisionPhaseResultType
|
||||
import net.eagle0.eagle.model.action_result.ActionResultT
|
||||
import net.eagle0.eagle.model.proto_converters.province.ProvinceConverter
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.RoundPhase
|
||||
|
||||
case class EndFreeForAllDecisionPhaseAction(gameState: GameState) extends ProtolessSequentialResultsAction {
|
||||
@@ -13,7 +12,7 @@ case class EndFreeForAllDecisionPhaseAction(gameState: GameState) extends Protol
|
||||
override def results: Vector[ActionResultT] =
|
||||
WithdrawnArmiesReturnHomeAction(
|
||||
gameState.currentRoundId,
|
||||
gameState.provinces.values.map(ProvinceConverter.fromProto).toVector
|
||||
gameState.provinces.values.toVector
|
||||
).results :+ ActionResultC(
|
||||
actionResultType = EndFreeForAllDecisionPhaseResultType,
|
||||
newRoundPhase = Some(RoundPhase.FreeForAllBattleRequest)
|
||||
|
||||
+2
-5
@@ -1,12 +1,11 @@
|
||||
package net.eagle0.eagle.library.actions.impl.action
|
||||
|
||||
import net.eagle0.eagle.internal.game_state.GameState
|
||||
import net.eagle0.eagle.library.actions.impl.common.ProtolessSimpleAction
|
||||
import net.eagle0.eagle.model.action_result.concrete.ActionResultC
|
||||
import net.eagle0.eagle.model.action_result.types.EndPleaseRecruitMePhaseResultType
|
||||
import net.eagle0.eagle.model.action_result.ActionResultT
|
||||
import net.eagle0.eagle.model.action_result.NotificationT
|
||||
import net.eagle0.eagle.model.proto_converters.NotificationConverter
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.RoundPhase
|
||||
|
||||
case class EndPleaseRecruitMePhaseAction(
|
||||
@@ -24,10 +23,8 @@ case class EndPleaseRecruitMePhaseAction(
|
||||
}
|
||||
|
||||
object EndPleaseRecruitMePhaseAction {
|
||||
def fromProtoState(gameState: GameState): EndPleaseRecruitMePhaseAction =
|
||||
def apply(gameState: GameState): EndPleaseRecruitMePhaseAction =
|
||||
EndPleaseRecruitMePhaseAction(
|
||||
deferredNotifications = gameState.deferredNotifications
|
||||
.map(n => NotificationConverter.fromProto(n, deferred = true))
|
||||
.toVector
|
||||
)
|
||||
}
|
||||
|
||||
@@ -166,31 +166,21 @@ scala_test(
|
||||
name = "end_defense_decision_phase_action_test",
|
||||
srcs = ["EndDefenseDecisionPhaseActionTest.scala"],
|
||||
deps = [
|
||||
"//src/main/protobuf/net/eagle0/eagle/common:action_result_type_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/common:combat_unit_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:action_result_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:army_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/protobuf/net/eagle0/eagle/internal:supplies_scala_proto",
|
||||
"//src/main/protobuf/net/eagle0/eagle/internal:unaffiliated_hero_scala_proto",
|
||||
"//src/main/scala/net/eagle0/eagle:eagle_pkg",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/applier:action_result_proto_applier_impl",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/action:end_defense_decision_phase_action",
|
||||
"//src/main/scala/net/eagle0/eagle/library/actions/impl/common:action_with_resulting_state",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:action_result_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_battalion_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_faction_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:changed_hero_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result:notification_trait",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/generated_text_request",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types/base:action_result_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/proto_converters:action_result_proto_converter",
|
||||
"//src/test/scala/net/eagle0/eagle/library/actions/impl:action_impl_pkg",
|
||||
"//src/test/scala/net/eagle0/eagle/library/util/validations:testing_noop_validator",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/changed_province/concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/action_result/types:end_defense_decision_phase_result_type",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:army",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:combat_unit",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:round_phase",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:supplies",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state:tribute_amount",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/date",
|
||||
"//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/concrete",
|
||||
"//src/main/scala/net/eagle0/eagle/model/state/run_status",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
+113
-143
@@ -1,83 +1,86 @@
|
||||
package net.eagle0.eagle.library.actions.impl.action
|
||||
|
||||
import net.eagle0.eagle.{FactionId, ProvinceId}
|
||||
import net.eagle0.eagle.common.action_result_type.ActionResultType.END_DEFENSE_DECISION_PHASE
|
||||
import net.eagle0.eagle.common.combat_unit.CombatUnit
|
||||
import net.eagle0.eagle.common.date.Date
|
||||
import net.eagle0.eagle.internal.army.{Army, HostileArmyGroup, MovingArmy, TributePaid}
|
||||
import net.eagle0.eagle.internal.changed_province.ChangedProvince
|
||||
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.supplies.Supplies
|
||||
import net.eagle0.eagle.library.actions.applier.ActionResultProtoApplierImpl
|
||||
import net.eagle0.eagle.library.util.validations.TestingNoopValidator
|
||||
import net.eagle0.eagle.model.proto_converters.ActionResultProtoConverter
|
||||
import net.eagle0.eagle.model.action_result.changed_province.concrete.ChangedProvinceC
|
||||
import net.eagle0.eagle.model.action_result.types.EndDefenseDecisionPhaseResultType
|
||||
import net.eagle0.eagle.model.state.{
|
||||
Army,
|
||||
CombatUnit,
|
||||
HostileArmyGroup,
|
||||
HostileArmyGroupStatus,
|
||||
MovingArmy,
|
||||
RoundPhase,
|
||||
Supplies,
|
||||
TributeAmount
|
||||
}
|
||||
import net.eagle0.eagle.model.state.date.Date
|
||||
import net.eagle0.eagle.model.state.faction.concrete.FactionC
|
||||
import net.eagle0.eagle.model.state.game_state.GameState
|
||||
import net.eagle0.eagle.model.state.province.concrete.ProvinceC
|
||||
import net.eagle0.eagle.model.state.run_status.RunStatus
|
||||
import org.scalatest.flatspec.AnyFlatSpec
|
||||
import org.scalatest.matchers.should.Matchers
|
||||
|
||||
class EndDefenseDecisionPhaseActionTest extends AnyFlatSpec with Matchers {
|
||||
val actionResultProtoApplier = new ActionResultProtoApplierImpl(
|
||||
validator = TestingNoopValidator
|
||||
)
|
||||
|
||||
private val defendingProvinceId: ProvinceId = 1
|
||||
private val defenderFid: FactionId = 3
|
||||
private val attacker1Fid: FactionId = 7
|
||||
private val attacker2Fid: FactionId = 8
|
||||
|
||||
private val tributeArmy1: HostileArmyGroup = HostileArmyGroup(
|
||||
status = TributePaid(),
|
||||
factionId = attacker1Fid,
|
||||
armies = Vector(
|
||||
MovingArmy(
|
||||
originProvince = 7,
|
||||
destinationProvince = defendingProvinceId,
|
||||
army = Some(
|
||||
Army(
|
||||
factionId = attacker1Fid,
|
||||
units = Vector(
|
||||
CombatUnit(heroId = 7, battalionId = Some(17))
|
||||
)
|
||||
)
|
||||
id = 1,
|
||||
originProvinceId = 7,
|
||||
destinationProvinceId = defendingProvinceId,
|
||||
arrivalRound = 19,
|
||||
army = Army(
|
||||
factionId = attacker1Fid,
|
||||
units = Vector(CombatUnit(factionId = attacker1Fid, heroId = 7, battalionId = Some(17)))
|
||||
),
|
||||
supplies = Some(Supplies(gold = 100, food = 200))
|
||||
supplies = Supplies(gold = 100, food = 200),
|
||||
suppliesLoss = 0,
|
||||
startingPositionIndex = None
|
||||
),
|
||||
MovingArmy(
|
||||
originProvince = 27,
|
||||
destinationProvince = defendingProvinceId,
|
||||
army = Some(
|
||||
Army(
|
||||
factionId = attacker1Fid,
|
||||
units = Vector(CombatUnit(heroId = 27, battalionId = None))
|
||||
)
|
||||
id = 2,
|
||||
originProvinceId = 27,
|
||||
destinationProvinceId = defendingProvinceId,
|
||||
arrivalRound = 19,
|
||||
army = Army(
|
||||
factionId = attacker1Fid,
|
||||
units = Vector(CombatUnit(factionId = attacker1Fid, heroId = 27, battalionId = None))
|
||||
),
|
||||
supplies = Some(Supplies(gold = 0, food = 0))
|
||||
supplies = Supplies(gold = 0, food = 0),
|
||||
suppliesLoss = 0,
|
||||
startingPositionIndex = None
|
||||
)
|
||||
)
|
||||
),
|
||||
status = HostileArmyGroupStatus.TributePaid(TributeAmount(gold = 50, food = 50))
|
||||
)
|
||||
|
||||
private val tributeArmy2: HostileArmyGroup = HostileArmyGroup(
|
||||
status = TributePaid(),
|
||||
factionId = attacker2Fid,
|
||||
armies = Vector(
|
||||
MovingArmy(
|
||||
originProvince = 8,
|
||||
destinationProvince = defendingProvinceId,
|
||||
army = Some(
|
||||
Army(
|
||||
factionId = attacker2Fid,
|
||||
units = Vector(
|
||||
CombatUnit(heroId = 8, battalionId = Some(18))
|
||||
)
|
||||
)
|
||||
id = 3,
|
||||
originProvinceId = 8,
|
||||
destinationProvinceId = defendingProvinceId,
|
||||
arrivalRound = 19,
|
||||
army = Army(
|
||||
factionId = attacker2Fid,
|
||||
units = Vector(CombatUnit(factionId = attacker2Fid, heroId = 8, battalionId = Some(18)))
|
||||
),
|
||||
supplies = Some(Supplies(gold = 100, food = 200))
|
||||
supplies = Supplies(gold = 100, food = 200),
|
||||
suppliesLoss = 0,
|
||||
startingPositionIndex = None
|
||||
)
|
||||
)
|
||||
),
|
||||
status = HostileArmyGroupStatus.TributePaid(TributeAmount(gold = 25, food = 25))
|
||||
)
|
||||
|
||||
private val defendingProvince = Province(
|
||||
private val defendingProvince: ProvinceC = ProvinceC(
|
||||
id = defendingProvinceId,
|
||||
rulingFactionId = Some(defenderFid),
|
||||
rulingHeroId = Some(9),
|
||||
@@ -85,115 +88,82 @@ class EndDefenseDecisionPhaseActionTest extends AnyFlatSpec with Matchers {
|
||||
)
|
||||
|
||||
private val gameState: GameState = GameState(
|
||||
gameId = 1L,
|
||||
currentPhase = RoundPhase.DefenseDecision,
|
||||
currentRoundId = 19,
|
||||
currentDate = Some(Date(year = 1501, month = 6)),
|
||||
currentDate = Some(Date(year = 1501, month = Date.Month.June)),
|
||||
actionResultCount = 0,
|
||||
randomSeed = 1L,
|
||||
provinces = Map(
|
||||
defendingProvinceId -> defendingProvince,
|
||||
7 -> Province(id = 7),
|
||||
27 -> Province(id = 27),
|
||||
8 -> Province(id = 8)
|
||||
7 -> ProvinceC(id = 7),
|
||||
27 -> ProvinceC(id = 27),
|
||||
8 -> ProvinceC(id = 8)
|
||||
),
|
||||
heroes = Map.empty,
|
||||
battalions = Map.empty,
|
||||
destroyedBattalions = Map.empty,
|
||||
factions = Map(
|
||||
defenderFid -> Faction(id = defenderFid, leaders = Vector(19))
|
||||
)
|
||||
defenderFid -> FactionC(id = defenderFid, factionHeadId = 19, name = "Defenders", leaderIds = Vector(19))
|
||||
),
|
||||
factionCommandCounts = Map.empty,
|
||||
killedHeroes = Map.empty,
|
||||
destroyedFactions = Map.empty,
|
||||
outstandingBattles = Vector.empty,
|
||||
battleCounter = 0,
|
||||
deferredNotifications = Vector.empty,
|
||||
runStatus = RunStatus.Running,
|
||||
victor = None,
|
||||
battalionTypes = Vector.empty,
|
||||
chronicleEntries = Vector.empty
|
||||
)
|
||||
|
||||
private def executeAction() = {
|
||||
val actionResult = EndDefenseDecisionPhaseAction.fromProtoState(gameState).immediateExecute
|
||||
val protoResult = ActionResultProtoConverter.toProto(actionResult)
|
||||
Vector(actionResultProtoApplier.applyActionResult(gameState, protoResult))
|
||||
"execute" should "end the phase and proceed to TRUCE_TURN_BACK" in {
|
||||
val actionResult = EndDefenseDecisionPhaseAction(gameState).immediateExecute
|
||||
|
||||
actionResult.actionResultType shouldBe EndDefenseDecisionPhaseResultType
|
||||
actionResult.newRoundPhase should contain(RoundPhase.TruceTurnBack)
|
||||
}
|
||||
|
||||
"execute" should "end the phase and proceed to BATTLE_REQUEST" in {
|
||||
val results = executeAction()
|
||||
val lastAr = results.last.actionResult
|
||||
it should "remove tribute paid armies from the province" in {
|
||||
val actionResult = EndDefenseDecisionPhaseAction(gameState).immediateExecute
|
||||
|
||||
lastAr.`type` shouldBe END_DEFENSE_DECISION_PHASE
|
||||
val changedDefendingProvince = actionResult.changedProvinces
|
||||
.find(_.provinceId == defendingProvinceId)
|
||||
.map(_.asInstanceOf[ChangedProvinceC])
|
||||
changedDefendingProvince should not be empty
|
||||
changedDefendingProvince.get.removedHostileArmyFactionIds should contain allOf (attacker1Fid, attacker2Fid)
|
||||
}
|
||||
|
||||
it should "clear the tribute paid armies" in {
|
||||
val results = executeAction().map(_.actionResult)
|
||||
it should "add returning armies to their origin provinces" in {
|
||||
val actionResult = EndDefenseDecisionPhaseAction(gameState).immediateExecute
|
||||
|
||||
val allCps = results.flatMap(_.changedProvinces)
|
||||
// Province 7 should have incoming army returning
|
||||
val province7Changes = actionResult.changedProvinces
|
||||
.find(_.provinceId == 7)
|
||||
.map(_.asInstanceOf[ChangedProvinceC])
|
||||
province7Changes should not be empty
|
||||
province7Changes.get.newIncomingArmies should have size 1
|
||||
province7Changes.get.newIncomingArmies.head.originProvinceId shouldBe defendingProvinceId
|
||||
province7Changes.get.newIncomingArmies.head.destinationProvinceId shouldBe 7
|
||||
province7Changes.get.newIncomingArmies.head.arrivalRound shouldBe 20
|
||||
|
||||
allCps.should(
|
||||
contain(
|
||||
ChangedProvince(
|
||||
id = defendingProvinceId,
|
||||
removedHostileArmyFactionIds = Vector(tributeArmy1.factionId, tributeArmy2.factionId)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
// Province 27 should have incoming army returning
|
||||
val province27Changes = actionResult.changedProvinces
|
||||
.find(_.provinceId == 27)
|
||||
.map(_.asInstanceOf[ChangedProvinceC])
|
||||
province27Changes should not be empty
|
||||
province27Changes.get.newIncomingArmies should have size 1
|
||||
province27Changes.get.newIncomingArmies.head.originProvinceId shouldBe defendingProvinceId
|
||||
province27Changes.get.newIncomingArmies.head.destinationProvinceId shouldBe 27
|
||||
|
||||
it should "move the tribute demanding armies back to their originating provinces" in {
|
||||
val results = executeAction().map(_.actionResult)
|
||||
|
||||
val allCps = results.flatMap(_.changedProvinces)
|
||||
|
||||
allCps.should(
|
||||
contain.allElementsOf(
|
||||
Vector(
|
||||
ChangedProvince(
|
||||
id = 7,
|
||||
addedIncomingArmies = Vector(
|
||||
MovingArmy(
|
||||
originProvince = defendingProvinceId,
|
||||
destinationProvince = 7,
|
||||
arrivalRound = 20,
|
||||
army = Some(
|
||||
Army(
|
||||
factionId = attacker1Fid,
|
||||
units = Vector(
|
||||
CombatUnit(heroId = 7, battalionId = Some(17))
|
||||
)
|
||||
)
|
||||
),
|
||||
supplies = Some(Supplies(gold = 100, food = 200))
|
||||
)
|
||||
)
|
||||
),
|
||||
ChangedProvince(
|
||||
id = 27,
|
||||
addedIncomingArmies = Vector(
|
||||
MovingArmy(
|
||||
originProvince = defendingProvinceId,
|
||||
destinationProvince = 27,
|
||||
arrivalRound = 20,
|
||||
army = Some(
|
||||
Army(
|
||||
factionId = attacker1Fid,
|
||||
units = Vector(
|
||||
CombatUnit(heroId = 27, battalionId = None)
|
||||
)
|
||||
)
|
||||
),
|
||||
supplies = None // (0, 0) supplies converts to None in proto
|
||||
)
|
||||
)
|
||||
),
|
||||
ChangedProvince(
|
||||
id = 8,
|
||||
addedIncomingArmies = Vector(
|
||||
MovingArmy(
|
||||
originProvince = defendingProvinceId,
|
||||
destinationProvince = 8,
|
||||
arrivalRound = 20,
|
||||
army = Some(
|
||||
Army(
|
||||
factionId = attacker2Fid,
|
||||
units = Vector(
|
||||
CombatUnit(heroId = 8, battalionId = Some(18))
|
||||
)
|
||||
)
|
||||
),
|
||||
supplies = Some(Supplies(gold = 100, food = 200))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
// Province 8 should have incoming army returning
|
||||
val province8Changes = actionResult.changedProvinces
|
||||
.find(_.provinceId == 8)
|
||||
.map(_.asInstanceOf[ChangedProvinceC])
|
||||
province8Changes should not be empty
|
||||
province8Changes.get.newIncomingArmies should have size 1
|
||||
province8Changes.get.newIncomingArmies.head.originProvinceId shouldBe defendingProvinceId
|
||||
province8Changes.get.newIncomingArmies.head.destinationProvinceId shouldBe 8
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user