from __future__ import annotations from typing import List from warchron.constants import ContextType from warchron.model.exception import ForbiddenOperation from warchron.model.result_checker import ResultChecker from warchron.model.war_event import InfluenceGained from warchron.model.war import War from warchron.model.campaign import Campaign from warchron.model.round import Round from warchron.model.battle import Battle class ClosureService: # Round methods @staticmethod def check_round_closable(round: Round) -> None: if round.is_over: raise ForbiddenOperation("Round already closed") if not round.all_battles_finished(): raise ForbiddenOperation( "All battles must be finished to close their round" ) @staticmethod def apply_battle_outcomes(war: War, campaign: Campaign, battle: Battle) -> None: already_granted = any( isinstance(e, InfluenceGained) and e.source == f"battle:{battle.sector_id}" for e in war.events ) if already_granted: return base_winner = None if battle.winner_id is not None: base_winner = campaign.participants[battle.winner_id].war_participant_id effective_winner = ResultChecker.get_effective_winner_id( war, ContextType.BATTLE, battle.sector_id, base_winner, ) if effective_winner is None: return sector = campaign.sectors[battle.sector_id] if sector.influence_objective_id and war.influence_token: war.events.append( InfluenceGained( participant_id=effective_winner, amount=1, source=f"battle:{battle.sector_id}", ) ) @staticmethod def finalize_round(round: Round) -> None: round.is_over = True # Campaign methods @staticmethod def check_campaign_closable(campaign: Campaign) -> None: if campaign.is_over: raise ForbiddenOperation("Campaign already closed") if not campaign.all_rounds_finished(): raise ForbiddenOperation( "All rounds must be closed to close their campaign" ) @staticmethod def finalize_campaign(campaign: Campaign) -> None: campaign.is_over = True # War methods @staticmethod def close_war(war: War) -> List[str]: if not war.all_campaigns_finished(): raise RuntimeError("All campaigns must be finished to close their war") ties: List[str] = [] # for campaign in war.campaigns: # # compute score # # if participants have same score # ties.append( # ResolutionContext( # context_type=ContextType.WAR, # context_id=war.id, # participant_ids=[ # war.participants[war_participant_id], # war.participants[war_participant_id], # ], # ) # ) if ties: return ties war.is_over = True return []