tie dialog title with context details
This commit is contained in:
parent
aa75a5b84f
commit
9e602e8ca4
8 changed files with 109 additions and 46 deletions
|
|
@ -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,23 +177,16 @@ class CampaignController:
|
|||
for pid in active
|
||||
]
|
||||
counters = [war.get_influence_tokens(pid) for pid in active]
|
||||
dialog = TieDialog(
|
||||
parent=self.app.view,
|
||||
players=players,
|
||||
counters=counters,
|
||||
context_type=ctx.context_type,
|
||||
context_id=ctx.context_id,
|
||||
context_name=None,
|
||||
data = TiePresenter.build_dialog_data(
|
||||
war, ctx, campaign=war.get_campaign(ctx.context_id)
|
||||
)
|
||||
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}",
|
||||
context_name=data.title,
|
||||
)
|
||||
if not dialog.exec():
|
||||
TieResolver.cancel_tie_break(war, ctx)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
52
src/warchron/controller/presenter.py
Normal file
52
src/warchron/controller/presenter.py
Normal 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"
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,23 +171,17 @@ class WarController:
|
|||
for pid in active
|
||||
]
|
||||
counters = [war.get_influence_tokens(pid) for pid in active]
|
||||
dialog = TieDialog(
|
||||
parent=self.app.view,
|
||||
players=players,
|
||||
counters=counters,
|
||||
context_type=ctx.context_type,
|
||||
context_id=ctx.context_id,
|
||||
context_name=None,
|
||||
data = TiePresenter.build_dialog_data(
|
||||
war,
|
||||
ctx,
|
||||
)
|
||||
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}",
|
||||
context_name=data.title,
|
||||
)
|
||||
if not dialog.exec():
|
||||
TieResolver.cancel_tie_break(war, ctx)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ from collections import defaultdict
|
|||
|
||||
from warchron.constants import ContextType
|
||||
from warchron.model.war import War
|
||||
from warchron.model.campaign import Campaign
|
||||
from warchron.model.battle import Battle
|
||||
from warchron.model.exception import DomainError
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
|
|
@ -26,7 +28,8 @@ class ScoreService:
|
|||
continue
|
||||
yield from rnd.battles.values()
|
||||
elif context_type == ContextType.CAMPAIGN:
|
||||
campaign = war.get_campaign(context_id)
|
||||
campaign: Campaign | None = war.get_campaign(context_id)
|
||||
if campaign:
|
||||
for rnd in campaign.rounds:
|
||||
if not rnd.is_over:
|
||||
continue
|
||||
|
|
@ -34,6 +37,8 @@ class ScoreService:
|
|||
elif context_type == ContextType.BATTLE:
|
||||
battle = war.get_battle(context_id)
|
||||
campaign = war.get_campaign_by_sector(battle.sector_id)
|
||||
if not campaign:
|
||||
raise DomainError(f"No campaign found for secor {battle.sector_id}")
|
||||
rnd = campaign.get_round_by_battle(context_id)
|
||||
if rnd and rnd.is_over:
|
||||
yield battle
|
||||
|
|
|
|||
|
|
@ -10,7 +10,11 @@ from warchron.model.war_event import (
|
|||
InfluenceSpent,
|
||||
TieResolved,
|
||||
)
|
||||
from warchron.model.exception import ForbiddenOperation, RequiresConfirmation
|
||||
from warchron.model.exception import (
|
||||
ForbiddenOperation,
|
||||
RequiresConfirmation,
|
||||
DomainError,
|
||||
)
|
||||
from warchron.model.war_participant import WarParticipant
|
||||
from warchron.model.objective import Objective
|
||||
from warchron.model.campaign_participant import CampaignParticipant
|
||||
|
|
@ -80,6 +84,10 @@ class War:
|
|||
if ev.context_type == ContextType.BATTLE:
|
||||
battle = self.get_battle(ev.context_id)
|
||||
campaign = self.get_campaign_by_sector(battle.sector_id)
|
||||
if not campaign:
|
||||
raise DomainError(
|
||||
f"No campaign found for sector {battle.sector_id}"
|
||||
)
|
||||
round = campaign.get_round_by_battle(ev.context_id)
|
||||
round.is_over = False
|
||||
elif ev.context_type == ContextType.CAMPAIGN:
|
||||
|
|
@ -313,12 +321,12 @@ class War:
|
|||
return None
|
||||
|
||||
# TODO replace multiloops by internal has_* method
|
||||
def get_campaign_by_sector(self, sector_id: str) -> Campaign:
|
||||
def get_campaign_by_sector(self, sector_id: str) -> Campaign | None:
|
||||
for camp in self.campaigns:
|
||||
for sect in camp.sectors.values():
|
||||
if sect.id == sector_id:
|
||||
return camp
|
||||
raise KeyError(f"Sector {sector_id} not found in any Campaign")
|
||||
return None
|
||||
|
||||
def get_campaign_by_campaign_participant(
|
||||
self, participant_id: str
|
||||
|
|
@ -396,6 +404,8 @@ class War:
|
|||
description: str | None,
|
||||
) -> None:
|
||||
camp = self.get_campaign_by_sector(sector_id)
|
||||
if not camp:
|
||||
raise DomainError(f"No campaign found for sector {sector_id}")
|
||||
camp.update_sector(
|
||||
sector_id,
|
||||
name=name,
|
||||
|
|
@ -409,6 +419,8 @@ class War:
|
|||
|
||||
def remove_sector(self, sector_id: str) -> None:
|
||||
camp = self.get_campaign_by_sector(sector_id)
|
||||
if not camp:
|
||||
raise DomainError(f"No campaign found for sector {sector_id}")
|
||||
camp.remove_sector(sector_id)
|
||||
|
||||
# Campaign participant methods
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class TieDialog(QDialog):
|
|||
self.ui: Ui_tieDialog = Ui_tieDialog()
|
||||
self.ui.setupUi(self) # type: ignore
|
||||
self.setWindowIcon(Icons.get(IconName.WARCHRONICO))
|
||||
self.ui.tieContext.setText(self._get_context_title(context_type, context_name))
|
||||
self.ui.tieContext.setText(context_name)
|
||||
grid = self.ui.playersGridLayout
|
||||
icon_path = (RESOURCES_DIR / Icons._paths[IconName.TOKENS]).as_posix()
|
||||
token_html = (
|
||||
|
|
@ -71,17 +71,3 @@ class TieDialog(QDialog):
|
|||
|
||||
def get_bids(self) -> Dict[str, bool]:
|
||||
return {pid: checkbox.isChecked() for pid, checkbox in self._checkboxes.items()}
|
||||
|
||||
@staticmethod
|
||||
def _get_context_title(
|
||||
context_type: ContextType, context_name: str | None = None
|
||||
) -> str:
|
||||
if context_name:
|
||||
return f"{context_name} tie"
|
||||
titles = {
|
||||
ContextType.BATTLE: "Battle tie",
|
||||
ContextType.CAMPAIGN: "Campaign tie",
|
||||
ContextType.WAR: "War tie",
|
||||
ContextType.CHOICE: "Choice tie",
|
||||
}
|
||||
return titles.get(context_type, "Tie")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue