tie dialog title with context details

This commit is contained in:
Maxime Réaux 2026-03-18 14:30:57 +01:00
parent aa75a5b84f
commit 9e602e8ca4
8 changed files with 109 additions and 46 deletions

View file

@ -23,6 +23,7 @@ from warchron.model.tie_manager import TieContext, TieResolver
from warchron.model.score_service import ScoreService
from warchron.controller.closure_workflow import CampaignClosureWorkflow
from warchron.controller.ranking_icon import RankingIcon
from warchron.controller.presenter import TiePresenter
from warchron.view.campaign_dialog import CampaignDialog
from warchron.view.campaign_participant_dialog import CampaignParticipantDialog
from warchron.view.sector_dialog import SectorDialog
@ -176,24 +177,17 @@ class CampaignController:
for pid in active
]
counters = [war.get_influence_tokens(pid) for pid in active]
data = TiePresenter.build_dialog_data(
war, ctx, campaign=war.get_campaign(ctx.context_id)
)
dialog = TieDialog(
parent=self.app.view,
players=players,
counters=counters,
context_type=ctx.context_type,
context_id=ctx.context_id,
context_name=None,
context_name=data.title,
)
if ctx.objective_id:
objective = war.objectives[ctx.objective_id]
dialog = TieDialog(
parent=self.app.view,
players=players,
counters=counters,
context_type=ctx.context_type,
context_id=ctx.context_id,
context_name=f"Objective tie: {objective.name}",
)
if not dialog.exec():
TieResolver.cancel_tie_break(war, ctx)
raise AbortedOperation("Tie resolution cancelled")

View file

@ -132,3 +132,8 @@ class WarParticipantScoreDTO:
tokens: int
rank_icon: QIcon | None = None
objective_icons: Dict[str, QIcon] = field(default_factory=dict)
@dataclass
class TieDialogData:
title: str

View file

@ -0,0 +1,52 @@
from warchron.constants import ContextType
from warchron.controller.dtos import TieDialogData
from warchron.model.tie_manager import TieContext
from warchron.model.war import War
from warchron.model.campaign import Campaign
from warchron.model.round import Round
class TiePresenter:
@staticmethod
def build_dialog_data(
war: War,
ctx: TieContext,
campaign: Campaign | None = None,
round: Round | None = None,
) -> TieDialogData:
if ctx.context_type == ContextType.WAR:
if ctx.objective_id:
obj = war.objectives[ctx.objective_id]
return TieDialogData(f"War objective tie — {obj.name}")
return TieDialogData("War tie")
if ctx.context_type == ContextType.CAMPAIGN:
if ctx.objective_id:
obj = war.objectives[ctx.objective_id]
return TieDialogData(f"Campaign objective tie — {obj.name}")
return TieDialogData("Campaign tie")
if ctx.context_type == ContextType.BATTLE:
if campaign:
sector = campaign.sectors[ctx.context_id]
return TieDialogData(f"Battle tie — {sector.name}")
return TieDialogData("Battle tie")
if ctx.context_type == ContextType.CHOICE:
if ctx.sector_id and campaign and round:
sector = campaign.sectors[ctx.sector_id]
kind = TiePresenter._choice_kind(round, ctx)
return TieDialogData(f"Choice tie — {sector.name} ({kind})")
return TieDialogData("Choice tie")
return TieDialogData("Tie")
@staticmethod
def _choice_kind(round: Round, ctx: TieContext) -> str:
for pid in ctx.participants:
camp_pid = round.campaign.war_to_campaign_part_id(pid)
choice = round.choices.get(camp_pid)
if not choice:
continue
if choice.priority_sector_id == ctx.sector_id:
return "priority"
if choice.secondary_sector_id == ctx.sector_id:
return "secondary"
return "choice"

View file

@ -28,6 +28,7 @@ from warchron.controller.closure_workflow import (
RoundClosureWorkflow,
RoundPairingWorkflow,
)
from warchron.controller.presenter import TiePresenter
from warchron.view.choice_dialog import ChoiceDialog
from warchron.view.battle_dialog import BattleDialog
from warchron.view.tie_dialog import TieDialog
@ -243,13 +244,26 @@ class RoundController:
for pid in ctx.participants
]
counters = [war.get_influence_tokens(pid) for pid in ctx.participants]
# TODO display sector name for BATTLE or CHOICE
if ctx.context_type == ContextType.BATTLE:
# context_id = battle.sector_id
campaign = war.get_campaign_by_sector(ctx.context_id)
if campaign:
round = campaign.get_round_by_battle(ctx.context_id)
if ctx.context_type == ContextType.CHOICE:
# context_id = round.id
campaign = war.get_campaign_by_round(ctx.context_id)
if campaign:
round = war.get_round(ctx.context_id)
data = TiePresenter.build_dialog_data(
war, ctx, round=round, campaign=campaign
)
dialog = TieDialog(
parent=self.app.view,
players=players,
counters=counters,
context_type=ctx.context_type,
context_id=ctx.context_id,
context_name=data.title,
)
if not dialog.exec():
TieResolver.cancel_tie_break(war, ctx)

View file

@ -28,6 +28,7 @@ from warchron.model.tie_manager import TieContext, TieResolver
from warchron.model.score_service import ScoreService
from warchron.controller.closure_workflow import WarClosureWorkflow
from warchron.controller.ranking_icon import RankingIcon
from warchron.controller.presenter import TiePresenter
from warchron.view.war_dialog import WarDialog
from warchron.view.objective_dialog import ObjectiveDialog
from warchron.view.war_participant_dialog import WarParticipantDialog
@ -170,24 +171,18 @@ class WarController:
for pid in active
]
counters = [war.get_influence_tokens(pid) for pid in active]
data = TiePresenter.build_dialog_data(
war,
ctx,
)
dialog = TieDialog(
parent=self.app.view,
players=players,
counters=counters,
context_type=ctx.context_type,
context_id=ctx.context_id,
context_name=None,
context_name=data.title,
)
if ctx.objective_id:
objective = war.objectives[ctx.objective_id]
dialog = TieDialog(
parent=self.app.view,
players=players,
counters=counters,
context_type=ctx.context_type,
context_id=ctx.context_id,
context_name=f"Objective tie: {objective.name}",
)
if not dialog.exec():
TieResolver.cancel_tie_break(war, ctx)
raise AbortedOperation("Tie resolution cancelled")