display effective ranking in campaign participants table

This commit is contained in:
Maxime Réaux 2026-02-23 17:36:28 +01:00
parent 60992c22df
commit 0bfe27e0d3
13 changed files with 176 additions and 8 deletions

View file

@ -1,8 +1,9 @@
from typing import List, Dict, TYPE_CHECKING
from PyQt6.QtWidgets import QMessageBox, QDialog
from PyQt6.QtGui import QIcon
from warchron.constants import RefreshScope, ContextType, ItemType
from warchron.constants import RefreshScope, ContextType, ItemType, Icons, IconName
if TYPE_CHECKING:
from warchron.controller.app_controller import AppController
@ -20,10 +21,11 @@ from warchron.model.campaign_participant import CampaignParticipant
from warchron.model.sector import Sector
from warchron.model.tie_manager import TieContext, TieResolver
from warchron.model.score_service import ScoreService
from warchron.model.result_checker import ResultChecker
from warchron.controller.closure_workflow import CampaignClosureWorkflow
from warchron.view.campaign_dialog import CampaignDialog
from warchron.view.campaign_participant_dialog import CampaignParticipantDialog
from warchron.view.sector_dialog import SectorDialog
from warchron.controller.closure_workflow import CampaignClosureWorkflow
from warchron.view.tie_dialog import TieDialog
@ -31,6 +33,54 @@ class CampaignController:
def __init__(self, app: "AppController"):
self.app = app
def _compute_campaign_ranking_icons(
self, war: War, campaign: Campaign
) -> Dict[str, QIcon]:
scores = ScoreService.compute_scores(
war,
ContextType.CAMPAIGN,
campaign.id,
)
ranking = ResultChecker.get_effective_ranking(
war, ContextType.CAMPAIGN, campaign.id, scores
)
icon_map = {}
for rank, group in ranking:
vp = scores[group[0]].victory_points
tie_id = f"{campaign.id}:score:{vp}"
is_tie = len(group) > 1
broken = TieResolver.was_tie_broken_by_tokens(
war,
ContextType.CAMPAIGN,
tie_id,
)
# choose icon name
if rank == 1:
base = IconName.VP1ST
draw = IconName.VP1STDRAW
tb = IconName.VP1STTIEBREAK
elif rank == 2:
base = IconName.VP2ND
draw = IconName.VP2NDDRAW
tb = IconName.VP2NDTIEBREAK
elif rank == 3:
base = IconName.VP3RD
draw = IconName.VP3RDDRAW
tb = IconName.VP3RDTIEBREAK
else:
base = IconName.VPNTH
draw = IconName.VPNTHDRAW
tb = IconName.VPNTHTIEBREAK
if not is_tie:
icon = Icons.get(base)
elif not broken:
icon = QIcon(Icons.get_pixmap(draw))
else:
icon = QIcon(Icons.get_pixmap(tb))
for pid in group:
icon_map[pid] = icon
return icon_map
def _fill_campaign_details(self, campaign_id: str) -> None:
camp = self.app.model.get_campaign(campaign_id)
self.app.view.show_campaign_details(name=camp.name, month=camp.month)
@ -52,6 +102,9 @@ class CampaignController:
self.app.view.display_campaign_sectors(sectors_for_display)
scores = ScoreService.compute_scores(war, ContextType.CAMPAIGN, campaign_id)
rows: List[CampaignParticipantScoreDTO] = []
icon_map = {}
if camp.is_over:
icon_map = self._compute_campaign_ranking_icons(war, camp)
for camp_part in camp.get_all_campaign_participants():
war_part_id = camp_part.war_participant_id
war_part = war.get_war_participant(war_part_id)
@ -66,6 +119,7 @@ class CampaignController:
theme=camp_part.theme or "",
victory_points=score.victory_points,
narrative_points=dict(score.narrative_points),
rank_icon=icon_map.get(war_part_id),
)
)
objectives = [