fix uncaucht choice/battle exceptions
This commit is contained in:
parent
f5ad45f671
commit
0081e52e9a
5 changed files with 156 additions and 126 deletions
|
|
@ -357,12 +357,20 @@ class AppController:
|
||||||
except RequiresConfirmation as e:
|
except RequiresConfirmation as e:
|
||||||
reply = QMessageBox.question(
|
reply = QMessageBox.question(
|
||||||
self.view,
|
self.view,
|
||||||
"Confirm deletion",
|
"Confirm update",
|
||||||
str(e),
|
str(e),
|
||||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||||
)
|
)
|
||||||
if reply == QMessageBox.StandardButton.Yes:
|
if reply == QMessageBox.StandardButton.Yes:
|
||||||
e.action()
|
try:
|
||||||
|
e.action()
|
||||||
|
except DomainError as inner:
|
||||||
|
QMessageBox.warning(
|
||||||
|
self.view,
|
||||||
|
"Update forbidden",
|
||||||
|
str(inner),
|
||||||
|
)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
self.is_dirty = True
|
self.is_dirty = True
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ class RoundController:
|
||||||
self.app = app
|
self.app = app
|
||||||
|
|
||||||
def _fill_round_details(self, round_id: str) -> None:
|
def _fill_round_details(self, round_id: str) -> None:
|
||||||
|
# self.app.view.clear_round_page()
|
||||||
rnd = self.app.model.get_round(round_id)
|
rnd = self.app.model.get_round(round_id)
|
||||||
camp = self.app.model.get_campaign_by_round(round_id)
|
camp = self.app.model.get_campaign_by_round(round_id)
|
||||||
war = self.app.model.get_war_by_round(round_id)
|
war = self.app.model.get_war_by_round(round_id)
|
||||||
|
|
@ -57,125 +58,144 @@ class RoundController:
|
||||||
for part in participants:
|
for part in participants:
|
||||||
choice = rnd.get_choice(part.id)
|
choice = rnd.get_choice(part.id)
|
||||||
if not choice:
|
if not choice:
|
||||||
choice = self.app.model.create_choice(
|
try:
|
||||||
round_id=rnd.id, participant_id=part.id
|
choice = self.app.model.create_choice(
|
||||||
|
round_id=rnd.id, participant_id=part.id
|
||||||
|
)
|
||||||
|
except DomainError as e:
|
||||||
|
QMessageBox.warning(
|
||||||
|
self.app.view,
|
||||||
|
"Create forbidden",
|
||||||
|
str(e),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
priority_name = (
|
||||||
|
camp.get_sector_name(choice.priority_sector_id)
|
||||||
|
if choice.priority_sector_id is not None
|
||||||
|
else ""
|
||||||
)
|
)
|
||||||
priority_name = (
|
secondary_name = (
|
||||||
camp.get_sector_name(choice.priority_sector_id)
|
camp.get_sector_name(choice.secondary_sector_id)
|
||||||
if choice.priority_sector_id is not None
|
if choice.secondary_sector_id is not None
|
||||||
else ""
|
else ""
|
||||||
)
|
)
|
||||||
secondary_name = (
|
priority_icon = None
|
||||||
camp.get_sector_name(choice.secondary_sector_id)
|
secondary_icon = None
|
||||||
if choice.secondary_sector_id is not None
|
fallback_icon = None
|
||||||
else ""
|
alloc = Pairing.get_round_allocation(
|
||||||
)
|
war,
|
||||||
priority_icon = None
|
rnd,
|
||||||
secondary_icon = None
|
part.id,
|
||||||
fallback_icon = None
|
)
|
||||||
alloc = Pairing.get_round_allocation(
|
if alloc.priority != ChoiceStatus.NONE:
|
||||||
war,
|
priority_icon = QIcon(
|
||||||
rnd,
|
Icons.get_pixmap(IconName[alloc.priority.name])
|
||||||
part.id,
|
)
|
||||||
)
|
if alloc.secondary != ChoiceStatus.NONE:
|
||||||
if alloc.priority != ChoiceStatus.NONE:
|
secondary_icon = QIcon(
|
||||||
priority_icon = QIcon(Icons.get_pixmap(IconName[alloc.priority.name]))
|
Icons.get_pixmap(IconName[alloc.secondary.name])
|
||||||
if alloc.secondary != ChoiceStatus.NONE:
|
)
|
||||||
secondary_icon = QIcon(Icons.get_pixmap(IconName[alloc.secondary.name]))
|
if alloc.fallback:
|
||||||
if alloc.fallback:
|
fallback_icon = QIcon(Icons.get_pixmap(IconName.FALLBACK))
|
||||||
fallback_icon = QIcon(Icons.get_pixmap(IconName.FALLBACK))
|
choices_for_display.append(
|
||||||
choices_for_display.append(
|
ChoiceDTO(
|
||||||
ChoiceDTO(
|
id=choice.participant_id,
|
||||||
id=choice.participant_id,
|
participant_name=self.app.model.get_participant_name(
|
||||||
participant_name=self.app.model.get_participant_name(
|
part.war_participant_id
|
||||||
part.war_participant_id
|
),
|
||||||
),
|
priority_sector=priority_name,
|
||||||
priority_sector=priority_name,
|
secondary_sector=secondary_name,
|
||||||
secondary_sector=secondary_name,
|
comment=choice.comment,
|
||||||
comment=choice.comment,
|
priority_icon=priority_icon,
|
||||||
priority_icon=priority_icon,
|
secondary_icon=secondary_icon,
|
||||||
secondary_icon=secondary_icon,
|
fallback_icon=fallback_icon,
|
||||||
fallback_icon=fallback_icon,
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
self.app.view.display_round_choices(choices_for_display)
|
self.app.view.display_round_choices(choices_for_display)
|
||||||
battles_for_display: List[BattleDTO] = []
|
battles_for_display: List[BattleDTO] = []
|
||||||
for sect in sectors:
|
for sect in sectors:
|
||||||
battle = rnd.get_battle(sect.id)
|
battle = rnd.get_battle(sect.id)
|
||||||
|
|
||||||
if not battle:
|
if not battle:
|
||||||
battle = self.app.model.create_battle(
|
try:
|
||||||
round_id=rnd.id, sector_id=sect.id
|
battle = self.app.model.create_battle(
|
||||||
)
|
round_id=rnd.id, sector_id=sect.id
|
||||||
state_icon = Icons.get(IconName.ONGOING)
|
)
|
||||||
if battle.is_finished():
|
except DomainError as e:
|
||||||
state_icon = Icons.get(IconName.DONE)
|
QMessageBox.warning(
|
||||||
if battle.player_1_id:
|
self.app.view,
|
||||||
camp_part = camp.participants[battle.player_1_id]
|
"Create forbidden",
|
||||||
player_1_name = self.app.model.get_participant_name(
|
str(e),
|
||||||
camp_part.war_participant_id
|
)
|
||||||
)
|
else:
|
||||||
p1_id = battle.player_1_id
|
state_icon = Icons.get(IconName.ONGOING)
|
||||||
else:
|
if battle.is_finished():
|
||||||
player_1_name = ""
|
state_icon = Icons.get(IconName.DONE)
|
||||||
if battle.player_2_id:
|
if battle.player_1_id:
|
||||||
camp_part = camp.participants[battle.player_2_id]
|
camp_part = camp.participants[battle.player_1_id]
|
||||||
player_2_name = self.app.model.get_participant_name(
|
player_1_name = self.app.model.get_participant_name(
|
||||||
camp_part.war_participant_id
|
camp_part.war_participant_id
|
||||||
)
|
)
|
||||||
p2_id = battle.player_2_id
|
p1_id = battle.player_1_id
|
||||||
else:
|
else:
|
||||||
player_2_name = ""
|
player_1_name = ""
|
||||||
if battle.winner_id:
|
if battle.player_2_id:
|
||||||
camp_part = camp.participants[battle.winner_id]
|
camp_part = camp.participants[battle.player_2_id]
|
||||||
winner_name = self.app.model.get_participant_name(
|
player_2_name = self.app.model.get_participant_name(
|
||||||
camp_part.war_participant_id
|
camp_part.war_participant_id
|
||||||
)
|
)
|
||||||
else:
|
p2_id = battle.player_2_id
|
||||||
winner_name = ""
|
else:
|
||||||
p1_icon = None
|
player_2_name = ""
|
||||||
p2_icon = None
|
if battle.winner_id:
|
||||||
# TODO use uniform draw/tie icon logic with choice, war, campaign...
|
camp_part = camp.participants[battle.winner_id]
|
||||||
if battle.is_draw():
|
winner_name = self.app.model.get_participant_name(
|
||||||
p1_icon = Icons.get(IconName.DRAW)
|
camp_part.war_participant_id
|
||||||
p2_icon = Icons.get(IconName.DRAW)
|
)
|
||||||
context = TieContext(
|
else:
|
||||||
ContextType.BATTLE,
|
winner_name = ""
|
||||||
battle.sector_id,
|
p1_icon = None
|
||||||
[p1_id, p2_id],
|
p2_icon = None
|
||||||
)
|
# TODO use uniform draw/tie icon logic with choice, war, campaign...
|
||||||
if TieResolver.was_tie_broken_by_tokens(war, context):
|
if battle.is_draw():
|
||||||
effective_winner = ResultChecker.get_effective_winner_id(
|
p1_icon = Icons.get(IconName.DRAW)
|
||||||
war, ContextType.BATTLE, battle.sector_id, None
|
p2_icon = Icons.get(IconName.DRAW)
|
||||||
|
context = TieContext(
|
||||||
|
ContextType.BATTLE,
|
||||||
|
battle.sector_id,
|
||||||
|
[p1_id, p2_id],
|
||||||
|
)
|
||||||
|
if TieResolver.was_tie_broken_by_tokens(war, context):
|
||||||
|
effective_winner = ResultChecker.get_effective_winner_id(
|
||||||
|
war, ContextType.BATTLE, battle.sector_id, None
|
||||||
|
)
|
||||||
|
p1_war = None
|
||||||
|
if battle.player_1_id is not None:
|
||||||
|
p1_war = camp.campaign_to_war_part_id(battle.player_1_id)
|
||||||
|
pixmap = Icons.get_pixmap(IconName.TIEBREAK_TOKEN)
|
||||||
|
if effective_winner == p1_war:
|
||||||
|
p1_icon = QIcon(pixmap)
|
||||||
|
else:
|
||||||
|
p2_icon = QIcon(pixmap)
|
||||||
|
elif battle.winner_id:
|
||||||
|
if battle.winner_id == battle.player_1_id:
|
||||||
|
p1_icon = Icons.get(IconName.WIN)
|
||||||
|
elif battle.winner_id == battle.player_2_id:
|
||||||
|
p2_icon = Icons.get(IconName.WIN)
|
||||||
|
battles_for_display.append(
|
||||||
|
BattleDTO(
|
||||||
|
id=battle.sector_id,
|
||||||
|
sector_name=camp.get_sector_name(battle.sector_id),
|
||||||
|
player_1=player_1_name,
|
||||||
|
player_2=player_2_name,
|
||||||
|
winner=winner_name,
|
||||||
|
score=battle.score,
|
||||||
|
victory_condition=battle.victory_condition,
|
||||||
|
comment=battle.comment,
|
||||||
|
state_icon=state_icon,
|
||||||
|
player1_icon=p1_icon,
|
||||||
|
player2_icon=p2_icon,
|
||||||
)
|
)
|
||||||
p1_war = None
|
|
||||||
if battle.player_1_id is not None:
|
|
||||||
p1_war = camp.campaign_to_war_part_id(battle.player_1_id)
|
|
||||||
pixmap = Icons.get_pixmap(IconName.TIEBREAK_TOKEN)
|
|
||||||
if effective_winner == p1_war:
|
|
||||||
p1_icon = QIcon(pixmap)
|
|
||||||
else:
|
|
||||||
p2_icon = QIcon(pixmap)
|
|
||||||
elif battle.winner_id:
|
|
||||||
if battle.winner_id == battle.player_1_id:
|
|
||||||
p1_icon = Icons.get(IconName.WIN)
|
|
||||||
elif battle.winner_id == battle.player_2_id:
|
|
||||||
p2_icon = Icons.get(IconName.WIN)
|
|
||||||
battles_for_display.append(
|
|
||||||
BattleDTO(
|
|
||||||
id=battle.sector_id,
|
|
||||||
sector_name=camp.get_sector_name(battle.sector_id),
|
|
||||||
player_1=player_1_name,
|
|
||||||
player_2=player_2_name,
|
|
||||||
winner=winner_name,
|
|
||||||
score=battle.score,
|
|
||||||
victory_condition=battle.victory_condition,
|
|
||||||
comment=battle.comment,
|
|
||||||
state_icon=state_icon,
|
|
||||||
player1_icon=p1_icon,
|
|
||||||
player2_icon=p2_icon,
|
|
||||||
)
|
)
|
||||||
)
|
|
||||||
self.app.view.display_round_battles(battles_for_display)
|
self.app.view.display_round_battles(battles_for_display)
|
||||||
self.app.view.endRoundBtn.setEnabled(not rnd.is_over)
|
self.app.view.endRoundBtn.setEnabled(not rnd.is_over)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,8 +144,8 @@ class Campaign:
|
||||||
|
|
||||||
def cleanup() -> None:
|
def cleanup() -> None:
|
||||||
for rnd in rounds_blocking:
|
for rnd in rounds_blocking:
|
||||||
rnd.clear_participant_references(participant_id)
|
|
||||||
rnd.remove_choice(participant_id)
|
rnd.remove_choice(participant_id)
|
||||||
|
rnd.clear_participant_references(participant_id)
|
||||||
del self.participants[participant_id]
|
del self.participants[participant_id]
|
||||||
|
|
||||||
rounds_str = ", ".join(
|
rounds_str = ", ".join(
|
||||||
|
|
@ -263,8 +263,8 @@ class Campaign:
|
||||||
|
|
||||||
def cleanup_and_update() -> None:
|
def cleanup_and_update() -> None:
|
||||||
for rnd in affected_rounds:
|
for rnd in affected_rounds:
|
||||||
rnd.clear_sector_references(sector_id)
|
|
||||||
rnd.remove_battle(sector_id)
|
rnd.remove_battle(sector_id)
|
||||||
|
rnd.clear_sector_references(sector_id)
|
||||||
apply_update()
|
apply_update()
|
||||||
|
|
||||||
rounds_str = ", ".join(
|
rounds_str = ", ".join(
|
||||||
|
|
@ -299,8 +299,8 @@ class Campaign:
|
||||||
|
|
||||||
def cleanup() -> None:
|
def cleanup() -> None:
|
||||||
for rnd in rounds_blocking:
|
for rnd in rounds_blocking:
|
||||||
rnd.clear_sector_references(sector_id)
|
|
||||||
rnd.remove_battle(sector_id)
|
rnd.remove_battle(sector_id)
|
||||||
|
rnd.clear_sector_references(sector_id)
|
||||||
del self.sectors[sector_id]
|
del self.sectors[sector_id]
|
||||||
|
|
||||||
rounds_str = ", ".join(
|
rounds_str = ", ".join(
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,6 @@ class Round:
|
||||||
|
|
||||||
def create_choice(self, participant_id: str) -> Choice:
|
def create_choice(self, participant_id: str) -> Choice:
|
||||||
if self.is_over:
|
if self.is_over:
|
||||||
# TODO catch me if you can
|
|
||||||
raise ForbiddenOperation("Can't create choice in a closed round.")
|
raise ForbiddenOperation("Can't create choice in a closed round.")
|
||||||
if participant_id not in self.choices:
|
if participant_id not in self.choices:
|
||||||
choice = Choice(
|
choice = Choice(
|
||||||
|
|
@ -97,13 +96,16 @@ class Round:
|
||||||
comment: str | None,
|
comment: str | None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if self.is_over:
|
if self.is_over:
|
||||||
# TODO catch me if you can
|
|
||||||
raise ForbiddenOperation("Can't update choice in a closed round.")
|
raise ForbiddenOperation("Can't update choice in a closed round.")
|
||||||
if self.has_battle_with_participant(participant_id):
|
|
||||||
# TODO catch me if you can (inner)
|
|
||||||
raise ForbiddenOperation("Can't update choice already assigned to battle.")
|
|
||||||
choice = self.get_choice(participant_id)
|
choice = self.get_choice(participant_id)
|
||||||
if choice:
|
if choice:
|
||||||
|
if self.has_battle_with_participant(participant_id) and (
|
||||||
|
priority_sector_id != choice.priority_sector_id
|
||||||
|
or secondary_sector_id != choice.secondary_sector_id
|
||||||
|
):
|
||||||
|
raise ForbiddenOperation(
|
||||||
|
"Can't update choice already assigned to battle."
|
||||||
|
)
|
||||||
choice.set_priority(priority_sector_id)
|
choice.set_priority(priority_sector_id)
|
||||||
choice.set_secondary(secondary_sector_id)
|
choice.set_secondary(secondary_sector_id)
|
||||||
choice.set_comment(comment)
|
choice.set_comment(comment)
|
||||||
|
|
@ -124,10 +126,8 @@ class Round:
|
||||||
if participant_id not in self.choices:
|
if participant_id not in self.choices:
|
||||||
return
|
return
|
||||||
if self.is_over:
|
if self.is_over:
|
||||||
# TODO catch me if you can (inner)
|
|
||||||
raise ForbiddenOperation("Can't remove choice in a closed round.")
|
raise ForbiddenOperation("Can't remove choice in a closed round.")
|
||||||
if self.has_battle_with_participant(participant_id):
|
if self.has_battle_with_participant(participant_id):
|
||||||
# TODO catch me if you can (inner)
|
|
||||||
raise ForbiddenOperation("Can't remove choice already assigned to battle.")
|
raise ForbiddenOperation("Can't remove choice already assigned to battle.")
|
||||||
self.war.revert_choice_ties(
|
self.war.revert_choice_ties(
|
||||||
self.id,
|
self.id,
|
||||||
|
|
@ -176,7 +176,6 @@ class Round:
|
||||||
|
|
||||||
def create_battle(self, sector_id: str) -> Battle:
|
def create_battle(self, sector_id: str) -> Battle:
|
||||||
if self.is_over:
|
if self.is_over:
|
||||||
# TODO catch me if you can
|
|
||||||
raise ForbiddenOperation("Can't create battle in a closed round.")
|
raise ForbiddenOperation("Can't create battle in a closed round.")
|
||||||
if sector_id not in self.battles:
|
if sector_id not in self.battles:
|
||||||
battle = Battle(sector_id=sector_id, player_1_id=None, player_2_id=None)
|
battle = Battle(sector_id=sector_id, player_1_id=None, player_2_id=None)
|
||||||
|
|
@ -196,7 +195,6 @@ class Round:
|
||||||
from warchron.model.pairing import Pairing
|
from warchron.model.pairing import Pairing
|
||||||
|
|
||||||
if self.is_over:
|
if self.is_over:
|
||||||
# TODO catch me if you can
|
|
||||||
raise ForbiddenOperation("Can't update battle in a closed round.")
|
raise ForbiddenOperation("Can't update battle in a closed round.")
|
||||||
bat = self.get_battle(sector_id)
|
bat = self.get_battle(sector_id)
|
||||||
if not bat:
|
if not bat:
|
||||||
|
|
@ -274,11 +272,9 @@ class Round:
|
||||||
if sector_id not in self.battles:
|
if sector_id not in self.battles:
|
||||||
return
|
return
|
||||||
if self.is_over:
|
if self.is_over:
|
||||||
# TODO catch me if you can
|
|
||||||
raise ForbiddenOperation("Can't remove battle in a closed round.")
|
raise ForbiddenOperation("Can't remove battle in a closed round.")
|
||||||
bat = self.battles[sector_id]
|
bat = self.battles[sector_id]
|
||||||
if bat and bat.is_finished():
|
if bat and bat.is_finished():
|
||||||
# TODO catch me if you can
|
|
||||||
raise ForbiddenOperation("Can't remove finished battle.")
|
raise ForbiddenOperation("Can't remove finished battle.")
|
||||||
self.war.revert_battle_ties(self.id, sector_id=sector_id)
|
self.war.revert_battle_ties(self.id, sector_id=sector_id)
|
||||||
del self.battles[sector_id]
|
del self.battles[sector_id]
|
||||||
|
|
|
||||||
|
|
@ -599,6 +599,12 @@ class View(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||||
def show_round_details(self, *, index: int | None) -> None:
|
def show_round_details(self, *, index: int | None) -> None:
|
||||||
self.roundNb.setText(f"Round {index}")
|
self.roundNb.setText(f"Round {index}")
|
||||||
|
|
||||||
|
def clear_round_page(self) -> None:
|
||||||
|
choices_table = self.choicesTable
|
||||||
|
choices_table.clearContents()
|
||||||
|
battles_table = self.battlesTable
|
||||||
|
battles_table.clearContents()
|
||||||
|
|
||||||
def display_round_choices(self, participants: List[ChoiceDTO]) -> None:
|
def display_round_choices(self, participants: List[ChoiceDTO]) -> None:
|
||||||
table = self.choicesTable
|
table = self.choicesTable
|
||||||
table.setSortingEnabled(False)
|
table.setSortingEnabled(False)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue