Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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