77 lines
2.8 KiB
Python
77 lines
2.8 KiB
Python
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from warchron.controller.app_controller import AppController
|
|
|
|
from warchron.constants import ContextType
|
|
from warchron.model.exception import ForbiddenOperation
|
|
from warchron.model.war_event import TieResolved
|
|
from warchron.model.war import War
|
|
from warchron.model.campaign import Campaign
|
|
from warchron.model.battle import Battle
|
|
from warchron.model.round import Round
|
|
from warchron.model.closure_service import ClosureService
|
|
from warchron.model.tie_manager import TieResolver
|
|
from warchron.controller.dtos import TieContext
|
|
|
|
|
|
class ClosureWorkflow:
|
|
|
|
def __init__(self, controller: "AppController"):
|
|
self.app = controller
|
|
|
|
|
|
class RoundClosureWorkflow(ClosureWorkflow):
|
|
|
|
def start(self, war: War, campaign: Campaign, round: Round) -> None:
|
|
ClosureService.check_round_closable(round)
|
|
ties = TieResolver.find_round_ties(round, war)
|
|
while ties:
|
|
contexts = [
|
|
RoundClosureWorkflow.build_battle_context(campaign, b) for b in ties
|
|
]
|
|
resolvable = []
|
|
for ctx in contexts:
|
|
if TieResolver.can_tie_be_resolved(war, ctx.participants):
|
|
resolvable.append(ctx)
|
|
else:
|
|
war.events.append(
|
|
TieResolved(
|
|
participant_id=None,
|
|
context_type=ctx.context_type,
|
|
context_id=ctx.context_id,
|
|
)
|
|
)
|
|
if not resolvable:
|
|
break
|
|
bids_map = self.app.rounds.resolve_ties(war, contexts)
|
|
for ctx in contexts:
|
|
bids = bids_map[ctx.context_id]
|
|
TieResolver.apply_bids(
|
|
war,
|
|
ctx.context_type,
|
|
ctx.context_id,
|
|
bids,
|
|
)
|
|
TieResolver.try_tie_break(
|
|
war,
|
|
ctx.context_type,
|
|
ctx.context_id,
|
|
ctx.participants,
|
|
)
|
|
ties = TieResolver.find_round_ties(round, war)
|
|
for battle in round.battles.values():
|
|
ClosureService.apply_battle_outcomes(war, campaign, battle)
|
|
ClosureService.finalize_round(round)
|
|
|
|
@staticmethod
|
|
def build_battle_context(campaign: Campaign, battle: Battle) -> TieContext:
|
|
if battle.player_1_id is None or battle.player_2_id is None:
|
|
raise ForbiddenOperation("Missing player(s) in this battle context.")
|
|
p1 = campaign.participants[battle.player_1_id].war_participant_id
|
|
p2 = campaign.participants[battle.player_2_id].war_participant_id
|
|
return TieContext(
|
|
context_type=ContextType.BATTLE,
|
|
context_id=battle.sector_id,
|
|
participants=[p1, p2],
|
|
)
|