From 7871ad2109b8f0acc46583b06eea027ac4bb705f Mon Sep 17 00:00:00 2001 From: shinoi2 Date: Tue, 19 Dec 2023 14:38:47 +0800 Subject: [PATCH] Rewrite death process --- fireplace/card.py | 12 ++++++++---- fireplace/cards/classic/neutral_rare.py | 2 +- fireplace/cards/gangs/mage.py | 2 +- fireplace/cards/tgt/warlock.py | 2 +- fireplace/cards/ungoro/hunter.py | 2 +- fireplace/cards/wog/mage.py | 2 +- fireplace/dsl/selector.py | 10 +++++++--- fireplace/game.py | 9 +++++---- tests/test_naxxramas.py | 14 ++++++++++++++ 9 files changed, 39 insertions(+), 16 deletions(-) diff --git a/fireplace/card.py b/fireplace/card.py index 0ade8777e..1d52fbbad 100644 --- a/fireplace/card.py +++ b/fireplace/card.py @@ -570,7 +570,11 @@ def deathrattles(self): @property def dead(self): - return self.zone == Zone.GRAVEYARD or self.to_be_destroyed + return ( + self.zone == Zone.GRAVEYARD or + self.to_be_destroyed or + getattr(self, self.health_attribute) <= 0 + ) @property def delayed_destruction(self): @@ -578,7 +582,7 @@ def delayed_destruction(self): @property def to_be_destroyed(self): - return getattr(self, self.health_attribute) == 0 or self._to_be_destroyed + return self._to_be_destroyed @to_be_destroyed.setter def to_be_destroyed(self, value): @@ -698,7 +702,7 @@ def attack(self, target): @property def health(self): - return max(0, self.max_health - self.damage) + return self.max_health - self.damage @property def targets(self): @@ -1082,7 +1086,7 @@ def __init__(self, *args): @property def durability(self): - return max(0, self.max_durability - self.damage) + return self.max_durability - self.damage @property def max_durability(self): diff --git a/fireplace/cards/classic/neutral_rare.py b/fireplace/cards/classic/neutral_rare.py index 9bb6a8420..ea102df5a 100644 --- a/fireplace/cards/classic/neutral_rare.py +++ b/fireplace/cards/classic/neutral_rare.py @@ -188,4 +188,4 @@ class NEW1_037: class NEW1_041: """Stampeding Kodo""" - play = Destroy(RANDOM(ENEMY_MINIONS + (ATK <= 2))) + play = Destroy(RANDOM(ENEMY_MINIONS - DEAD + (ATK <= 2))) diff --git a/fireplace/cards/gangs/mage.py b/fireplace/cards/gangs/mage.py index df3363886..a42926c22 100644 --- a/fireplace/cards/gangs/mage.py +++ b/fireplace/cards/gangs/mage.py @@ -65,4 +65,4 @@ class CFM_620: class CFM_623: """Greater Arcane Missiles""" - play = Hit(RANDOM(ENEMY_CHARACTERS), 3) * 3 + play = Hit(RANDOM_ENEMY_CHARACTER, 3) * 3 diff --git a/fireplace/cards/tgt/warlock.py b/fireplace/cards/tgt/warlock.py index 4d3b1e918..2b72b1564 100644 --- a/fireplace/cards/tgt/warlock.py +++ b/fireplace/cards/tgt/warlock.py @@ -64,4 +64,4 @@ class AT_024: class AT_025: """Dark Bargain""" requirements = {PlayReq.REQ_MINIMUM_ENEMY_MINIONS: 1} - play = Destroy(RANDOM(ENEMY_MINIONS) * 2), Discard(RANDOM(FRIENDLY_HAND) * 2) + play = Destroy(RANDOM_ENEMY_MINION * 2), Discard(RANDOM(FRIENDLY_HAND) * 2) diff --git a/fireplace/cards/ungoro/hunter.py b/fireplace/cards/ungoro/hunter.py index 0e885cb24..b2f88c1b2 100644 --- a/fireplace/cards/ungoro/hunter.py +++ b/fireplace/cards/ungoro/hunter.py @@ -42,7 +42,7 @@ class UNG_915: class UNG_919: """Swamp King Dred""" events = Play(OPPONENT, MINION).after( - Find(Play.CARD + IN_PLAY - MORTALLY_WOUNDED) & ( + Find(Play.CARD + IN_PLAY - DEAD) & ( Find(SELF - FROZEN) & Attack(SELF, Play.CARD) ) diff --git a/fireplace/cards/wog/mage.py b/fireplace/cards/wog/mage.py index 62ceeb31b..d3976e765 100644 --- a/fireplace/cards/wog/mage.py +++ b/fireplace/cards/wog/mage.py @@ -16,7 +16,7 @@ class OG_083: class OG_085: """Demented Frostcaller""" - events = OWN_SPELL_PLAY.after(Freeze(RANDOM(ENEMY_CHARACTERS - MORTALLY_WOUNDED - FROZEN))) + events = OWN_SPELL_PLAY.after(Freeze(RANDOM(ENEMY_CHARACTERS - DEAD - FROZEN))) class OG_120: diff --git a/fireplace/dsl/selector.py b/fireplace/dsl/selector.py index 46de9d700..d4ba1e302 100644 --- a/fireplace/dsl/selector.py +++ b/fireplace/dsl/selector.py @@ -347,7 +347,11 @@ def __mul__(self, other): RANDOM = RandomSelector -MORTALLY_WOUNDED = CURRENT_HEALTH <= 0 +DEAD = FuncSelector( + lambda entities, source: [ + e for e in entities + if hasattr(e, "dead") and e.dead + ]) # Selects the highest and lowest attack entities, respectively HIGHEST_ATK = lambda sel: ( @@ -518,8 +522,8 @@ def CONTROLLED_BY(selector): RANDOM_FRIENDLY_MINION = RANDOM(FRIENDLY_MINIONS) RANDOM_OTHER_FRIENDLY_MINION = RANDOM(FRIENDLY_MINIONS - SELF) RANDOM_FRIENDLY_CHARACTER = RANDOM(FRIENDLY_CHARACTERS) -RANDOM_ENEMY_MINION = RANDOM(ENEMY_MINIONS - MORTALLY_WOUNDED) -RANDOM_ENEMY_CHARACTER = RANDOM(ENEMY_CHARACTERS - MORTALLY_WOUNDED) +RANDOM_ENEMY_MINION = RANDOM(ENEMY_MINIONS - DEAD) +RANDOM_ENEMY_CHARACTER = RANDOM(ENEMY_CHARACTERS - DEAD) DAMAGED_CHARACTERS = ALL_CHARACTERS + DAMAGED CTHUN = FRIENDLY + ID("OG_280") diff --git a/fireplace/game.py b/fireplace/game.py index d2a74cc5e..d7d4fcdd0 100644 --- a/fireplace/game.py +++ b/fireplace/game.py @@ -154,17 +154,18 @@ def process_deaths(self): cards = [] destroy_cards = [] for card in self.live_entities: - if card.to_be_destroyed: + if card.dead: cards.append(card) - if card._to_be_destroyed: + if card.to_be_destroyed: card.zone = Zone.GRAVEYARD destroy_cards.append(card) if cards: self.action_start(type, self, 0, None) for card in cards: - if card.to_be_destroyed or card in destroy_cards: - card.zone = Zone.GRAVEYARD + if card.dead: + if card not in destroy_cards: + card.zone = Zone.GRAVEYARD self.check_for_end_game() self.refresh_auras() self.trigger(self, [Death(card)], event_args=None) diff --git a/tests/test_naxxramas.py b/tests/test_naxxramas.py index d9a66070a..5b163546a 100644 --- a/tests/test_naxxramas.py +++ b/tests/test_naxxramas.py @@ -28,6 +28,20 @@ def test_avenge_board_clear(): assert game.player1.field[0].atk == 4 assert game.player1.field[0].health == 2 + game = prepare_game() + avenge = game.player1.give("FP1_020") + wisp1 = game.player1.give(WISP) + wisp2 = game.player1.give(WISP) + avenge.play() + wisp1.play() + wisp2.play() + game.end_turn() + + nether = game.player2.give("EX1_312") + nether.play() + assert avenge in game.player1.secrets + assert len(game.player1.field) == 0 + def test_baron_rivendare(): game = prepare_game()