def apply_action(self): card = self.card target_list = self.target_list if not card: return False action = self.force_action or card.associated_action if not action: return False g = Game.getgame() src = self.source card = self.card drop = card.usage == 'drop' try: if drop: # should drop before action g.process_action(DropCards(src, src, cards=[card])) elif not getattr(card, 'no_drop', False): detach_cards([card]) # emit events else: card.detach() _, tl = g.emit_event('choose_target', (self, target_list)) assert _ is self if isinstance(action, Action): a = action else: assert issubclass(action, UserAction) tgt = tl[0] if tl else src a = action(source=src, target=tgt) a.target_list = tl a.associated_card = card self.card_action = a _ = g.emit_event('post_choose_target', (self, tl)) assert _ == (self, tl) g.process_action(a) return True finally: if not drop and card.detached: # card/skill still in disputed state, # means no actions have done anything to the card/skill, # drop it if not getattr(card, 'no_drop', False) and not card.unwrapped: migrate_cards([card], g.deck.droppedcards, unwrap=True, is_bh=True) else: from .cards import VirtualCard for c in VirtualCard.unwrap([card]): if c.detached: c.attach() return True
def handle(self, evt_type, act): if evt_type == 'action_shootdown' and isinstance(act, LaunchCard): src = act.source g = Game.getgame() if not src.tags['mind_hack_effect-%s' % g.turn_count]: return act if any(c for c in VirtualCard.unwrap([act.card]) if c.color == Card.BLACK and c in src.showncards): raise MindReadLimit return act
def cond(self, cl): if not (cl and len(cl) == 1): return False return bool(cl[0].associated_action) and [self.card] == VirtualCard.unwrap(cl)
def cond(self, cl): if not (cl and len(cl) == 1): return False return bool(cl[0].associated_action) and [self.card ] == VirtualCard.unwrap(cl)
def ask_for_action(initiator, actors, categories, candidates, trans=None): # initiator: Action or EH requesting this # actors: players involved # categories: card categories, eg: ['cards', 'showncards'] # candidates: players can be selection target, eg: g.players assert categories or candidates assert actors from gamepack.thb.cards import VirtualCard ilet = ActionInputlet(initiator, categories, candidates) @ilet.with_post_process def process(actor, rst): g = Game.getgame() usage = getattr(initiator, 'card_usage', 'none') try: check(rst) skills, rawcards, players, params = rst [check(not c.detached) for c in rawcards] [check(actor.has_skill(s)) for s in skills] # has_skill may be hooked if skills: cards = [skill_wrap(actor, skills, rawcards, params)] usage = cards[0].usage if usage == 'launch' else usage else: cards = rawcards usage = 'launch' if categories: if len(cards) == 1 and cards[0].is_card(VirtualCard): def walk(c): if not c.is_card(VirtualCard): return if getattr(c, 'no_reveal', False): return g.players.reveal(c.associated_cards) for c1 in c.associated_cards: walk(c1) walk(cards[0]) check(skill_check(cards[0])) else: if not getattr(initiator, 'no_reveal', False): g.players.reveal(cards) check(initiator.cond(cards)) assert not (usage == 'none' and rawcards) # should not pass check else: cards = [] if candidates: players, valid = initiator.choose_player_target(players) check(valid) ask_for_action_verify = getattr(initiator, 'ask_for_action_verify', None) if ask_for_action_verify: check(ask_for_action_verify(actor, cards, players)) return cards, players, params except CheckFailed: return None p, rst = user_input(actors, ilet, type='any', trans=trans) if rst: cards, players, params = rst if len(cards) == 1 and cards[0].is_card(VirtualCard): Game.getgame().deck.register_vcard(cards[0]) if not cards and not players: return p, None [c.detach() for c in VirtualCard.unwrap(cards)] return p, (cards, players) else: return None, None
def ask_for_action(initiator, actors, categories, candidates, trans=None): # initiator: Action or EH requesting this # actors: players involved # categories: card categories, eg: ['cards', 'showncards'] # candidates: players can be selection target, eg: g.players assert categories or candidates assert actors from gamepack.thb.cards import VirtualCard ilet = ActionInputlet(initiator, categories, candidates) @ilet.with_post_process def process(actor, rst): g = Game.getgame() usage = getattr(initiator, 'card_usage', 'none') try: check(rst) skills, rawcards, players, params = rst [check(not c.detached) for c in rawcards] [check(actor.has_skill(s)) for s in skills] # has_skill may be hooked if skills: cards = [skill_wrap(actor, skills, rawcards, params)] usage = cards[0].usage if usage == 'launch' else usage else: cards = rawcards usage = 'launch' if categories: if len(cards) == 1 and cards[0].is_card(VirtualCard): def walk(c): if not c.is_card(VirtualCard): return if getattr(c, 'no_reveal', False): return g.players.reveal(c.associated_cards) for c1 in c.associated_cards: walk(c1) walk(cards[0]) check(skill_check(cards[0])) else: if not getattr(initiator, 'no_reveal', False): g.players.reveal(cards) check(initiator.cond(cards)) assert not (usage == 'none' and rawcards ) # should not pass check else: cards = [] if candidates: players, valid = initiator.choose_player_target(players) check(valid) ask_for_action_verify = getattr(initiator, 'ask_for_action_verify', None) if ask_for_action_verify: check(ask_for_action_verify(actor, cards, players)) return cards, players, params except CheckFailed: return None p, rst = user_input(actors, ilet, type='any', trans=trans) if rst: cards, players, params = rst if len(cards) == 1 and cards[0].is_card(VirtualCard): Game.getgame().deck.register_vcard(cards[0]) if not cards and not players: return p, None [c.detach() for c in VirtualCard.unwrap(cards)] return p, (cards, players) else: return None, None