Skip to content

Commit eb8e0a3

Browse files
committed
feat: infer tourists in the known starting deck list
1 parent 601358e commit eb8e0a3

2 files changed

Lines changed: 67 additions & 9 deletions

File tree

hearthstone/entities.py

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def register_entity(self, entity: Entity) -> None:
118118
elif not self.setup_done:
119119
self.initial_entities.append(entity)
120120

121-
# Update player.starting_hero for Maestra of the Masquerade
121+
# Infer player class and card from "Maestra of the Masquerade" revealing herself
122122
if (
123123
entity.type == CardType.HERO and
124124
entity.tags.get(GameTag.CREATOR_DBID) == MAESTRA_DISGUISE_DBF_ID
@@ -132,11 +132,30 @@ def register_entity(self, entity: Entity) -> None:
132132
# one.
133133
player.initial_hero_entity_id = entity.id
134134

135-
# At this point we know that Maestra must be in the starting of the player,
136-
# because otherwise the reveal would not happen. Manually add it to the list
137-
# of starting cards
135+
# At this point we know that Maestra must be in the starting deck of the
136+
# player, because otherwise the reveal would not happen. Manually add it to
137+
# the list of starting cards
138138
player._known_starting_card_ids.add("SW_050")
139139

140+
# Infer Tourists when they reveal themselves
141+
if (
142+
entity.tags.get(GameTag.ZONE) == Zone.REMOVEDFROMGAME and
143+
entity.tags.get(GameTag.TOURIST) == 1
144+
):
145+
# This might be the fake Tourist that the game pops up to explain why a card was
146+
# present in the player's deck. Double-check that the card was created by the
147+
# Tourist VFX enchantment.
148+
creator_id = entity.tags.get(GameTag.CREATOR)
149+
creator = self.find_entity_by_id(creator_id) if creator_id else None
150+
creator_is_vfx = (
151+
getattr(creator, "card_id") == "VAC_422e"
152+
if creator is not None else False
153+
)
154+
player = entity.controller
155+
tourist_card_id = getattr(entity, "card_id")
156+
if creator_is_vfx and player is not None and tourist_card_id is not None:
157+
player._known_starting_card_ids.add(tourist_card_id)
158+
140159
def reset(self) -> None:
141160
for entity in self.entities:
142161
if entity is self:
@@ -214,15 +233,14 @@ def known_starting_deck_list(self) -> List[str]:
214233
Blade) and well-known transforms (e.g. Spellstones, Unidentified Objects, Worgens)
215234
so that the initial card id is included rather than the final card id.
216235
"""
217-
ret = list(self._known_starting_card_ids)
218-
219236
original_card_ids = [
220237
get_original_card_id(entity.initial_card_id)
221238
for entity in self.initial_deck if entity.initial_card_id
222239
]
223-
ret = ret + [card_id for card_id in original_card_ids if card_id not in ret]
224-
225-
return ret
240+
return original_card_ids + [
241+
card_id for card_id in self._known_starting_card_ids
242+
if card_id not in original_card_ids
243+
]
226244

227245
@property
228246
def entities(self) -> Iterator[Entity]:

tests/test_entities.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,46 @@ def test_known_starting_deck_list_with_souleaters_scythe(self, game, player):
308308

309309
assert player.known_starting_deck_list == [WISP, SOULEATERS_SCYTHE]
310310

311+
def test_known_starting_deck_list_with_tourist(self, game, player):
312+
HAMM = "VAC_340"
313+
TOURIST_VFX_ENCHANTMENT = "VAC_422e"
314+
315+
tourist = Card(4, None)
316+
tourist.tags.update({
317+
GameTag.ZONE: Zone.DECK,
318+
GameTag.CONTROLLER: player.player_id,
319+
})
320+
game.register_entity(tourist)
321+
322+
vfx = Card(5, None)
323+
vfx.tags.update({
324+
GameTag.ZONE: Zone.SETASIDE,
325+
GameTag.CONTROLLER: player.player_id,
326+
})
327+
game.register_entity(vfx)
328+
vfx.reveal(TOURIST_VFX_ENCHANTMENT, {
329+
GameTag.CARDTYPE: CardType.ENCHANTMENT,
330+
GameTag.ATTACHED: player.id,
331+
GameTag.CREATOR: tourist.id,
332+
})
333+
334+
# At some point we play an out-of-class card, and a fake tourist is shown
335+
fake_tourist = Card(6, HAMM)
336+
fake_tourist.tags.update({
337+
GameTag.CONTROLLER: player.player_id,
338+
GameTag.CREATOR: vfx.id,
339+
GameTag.ZONE: Zone.REMOVEDFROMGAME,
340+
GameTag.TOURIST: 1,
341+
GameTag.DRUID_TOURIST: 1,
342+
})
343+
game.register_entity(fake_tourist)
344+
345+
assert player.known_starting_deck_list == [HAMM]
346+
347+
tourist.reveal(HAMM, {})
348+
349+
assert player.known_starting_deck_list == [HAMM]
350+
311351

312352
class TestCard:
313353
def test_card(self):

0 commit comments

Comments
 (0)