Example #1
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            if not src: return act
            if not src.has_skill(IbukiGourdSkill): return act

            g = Game.getgame()
            ttags(src)['ibukigourd_did_damage'] = True

        elif evt_type == 'action_apply' and isinstance(act, FinalizeStage):
            tgt = act.target
            if not tgt.has_skill(IbukiGourdSkill): return act

            g = Game.getgame()
            if ttags(tgt)['ibukigourd_did_damage']: return act

            g.process_action(basic.Wine(tgt, tgt))

        elif evt_type == 'card_migration':
            from .definition import IbukiGourdCard
            act, cl, _from, to, _ = arg = act

            if not any(c.is_card(IbukiGourdCard) for c in cl):
                return arg

            if to.type != 'equips':
                return arg

            tgt = to.owner
            g = Game.getgame()
            g.process_action(basic.Wine(tgt, tgt))

            return arg

        return act
Example #2
0
    def sound_effect(act):
        tgt = act.target
        if ttags(tgt)['__icewing_se']:
            return None

        ttags(tgt)['__icewing_se'] = True
        return 'thb-cv-card_icewing'
Example #3
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            if not src: return act
            if not src.has_skill(DestructionImpulse): return act

            g = Game.getgame()
            ttags(src)['destruction_tag'] = True

        elif evt_type == 'action_after' and isinstance(act, PlayerTurn):
            tgt = act.target
            if not tgt.has_skill(DestructionImpulse): return act

            g = Game.getgame()
            if ttags(tgt)['destruction_tag']: return act

            dist = LaunchCard.calc_distance(tgt, DestructionImpulse(tgt))
            dist.pop(tgt, '')

            for k in dist:
                dist[k] = max(dist[k], 0)

            nearest = min(dist.values())
            candidates = [p for p, d in dist.items() if d == nearest]
            candidates = [p for p in g.players if p in candidates]  # order matters

            if len(candidates) > 1:
                pl = user_choose_players(self, tgt, candidates)
                p = pl[0] if pl else candidates[0]
            else:
                p = candidates[0]

            g.process_action(DestructionImpulseAction(tgt, p))

        return act
Example #4
0
    def clickable(game):
        me = game.me

        if not (my_turn() and (me.cards or me.showncards)):
            return False

        if ttags(me)["ran_eikof_tag"]:
            return False

        if not ttags(me)["ran_eikof_card"]:
            return False

        return True
Example #5
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, ActionStageLaunchCard):
            c = act.card
            if c.is_card(Craftsman):
                src = act.source
                ttags(src)['craftsman'] = True

        elif evt_type == 'action_shootdown':
            if not isinstance(act, ActionStageLaunchCard): return act
            c = act.card
            if not c.is_card(Craftsman): return act
            if ttags(act.source)['craftsman']:
                raise ActionLimitExceeded

        return act
Example #6
0
    def apply_action(self):
        tgt = self.target
        g = Game.getgame()
        g.process_action(DrawCards(tgt, 1))

        ttags(tgt)['miracle_times'] += 1

        if ttags(tgt)['miracle_times'] == 3:
            candidates = [p for p in g.players if not p.dead and p.life < p.maxlife]
            if candidates:
                beneficiery, = user_choose_players(self, tgt, candidates) or (None,)
                if beneficiery:
                    g.process_action(MiracleHeal(tgt, beneficiery))

        return True
Example #7
0
 def is_valid(self):
     tgt = self.target
     g = Game.getgame()
     cl = self.associated_card.associated_cards
     n = len([p for p in g.players if not p.dead]) / 2
     if not 0 < len(cl) <= n: return False
     return not ttags(tgt)['qiliao']
Example #8
0
    def clickable(game):
        me = game.me

        if ttags(me)['bakadesu']:
            return False

        return my_turn()
Example #9
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and hasattr(act, 'associated_card'):
            g = Game.getgame()
            lc = g.action_stack[-1]

            for lc in reversed(g.action_stack):
                if isinstance(lc, (LaunchCard, LaunchFatetellCard)) and lc.card_action is act:
                    break
            else:
                return act

            me = g.current_player
            if not me or not me.has_skill(Tianyi):
                return act

            while True:
                if isinstance(act, SpellCardAction): break
                if isinstance(act, ForEach) and issubclass(act.action_cls, SpellCardAction): break  # Another HACK
                return act

            if ttags(me)['mima_tianyi']:
                return act

            if not user_input([me], ChooseOptionInputlet(self, (False, True))):
                return act

            g.process_action(TianyiAction(me, lc))

        return act
Example #10
0
    def is_action_valid(g, cl, tl):
        cards = cl[0].associated_cards

        expected = ttags(g.me)['miracle_times'] + 1
        if len(cards) != expected:
            return (False, u'奇迹:请选择%d张牌!' % expected)

        return (True, u'奇迹是存在的!')
Example #11
0
    def clickable(g):
        if not my_turn():
            return False

        if ttags(g.me)['qiliao']:
            return False

        return True
Example #12
0
    def sound_effect(act):
        if not isinstance(act, actions.ActionStageLaunchCard):
            return 'thb-cv-card_attack1'

        current = G().current_player

        if act.source is not current:
            return 'thb-cv-card_attack1'

        ttags(current)['__attack_graze_count'] += 1

        return [
            'thb-cv-card_attack1',
            'thb-cv-card_attack2',
            'thb-cv-card_attack3',
            'thb-cv-card_attack4',
        ][ttags(current)['__attack_graze_count'] % 4 - 1]
Example #13
0
    def clickable(game):
        me = game.me
        if not my_turn():
            return False

        if ttags(me)['assisted_attack_disable']:
            return False

        return True
Example #14
0
    def clickable(game):
        me = game.me
        if ttags(me)['find']:
            return False

        if my_turn() and (me.cards or me.showncards or me.equips):
            return True

        return False
Example #15
0
 def apply_action(self):
     g = Game.getgame()
     cards = self.associated_card.associated_cards
     n = len(cards)
     # card will be dropped at LaunchCard
     # g.process_action(DropCards(tgt, tgt, cards))
     tgt = self.target
     g.process_action(DrawCards(tgt, n))
     ttags(tgt)['find'] = True
     return True
Example #16
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, ActionStageLaunchCard):
            if not act.card.is_card(VirtualCard):
                src = act.source
                if not src.has_skill(ExtremeIntelligenceKOF): return act
                c = act.card
                if 'instant_spellcard' not in c.category: return act
                ttags(src)['ran_eikof_card'] = c.__class__

            elif act.card.is_card(ExtremeIntelligenceKOF):
                src = act.source
                ttags(src)['ran_eikof_tag'] = True

        elif evt_type == 'action_shootdown' and isinstance(act, ActionStageLaunchCard) and act.card.is_card(ExtremeIntelligenceKOF):
            src = act.source
            tt = ttags(src)
            if tt['ran_eikof_tag'] or not tt['ran_eikof_card']:
                raise ActionLimitExceeded

        return act
Example #17
0
    def clickable(g):
        try:
            me = g.me
            if not me.cards and not me.showncards:
                return False

            if ttags(me)['craftsman'] and g.current_player is me:
                return False

            return True

        except (IndexError, AttributeError):
            return False
Example #18
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, ActionStageLaunchCard):
            src, tgt = act.source, act.target
            if not src or not tgt: return act
            ttags(src)['solid_shield_launch_count'] += 1
            if ttags(src)['solid_shield_launch_count'] != 1:
                return act

            if src is tgt: return act

            c = act.card
            if not (c.is_card(AttackCard) or 'instant_spellcard' in c.category):
                return act

            g = Game.getgame()
            for p in g.players.rotate_to(src):
                if p is src:
                    continue

                if p is tgt:
                    continue

                if not p.has_skill(SolidShield):
                    continue

                dist = LaunchCard.calc_distance(p, SolidShield(p))
                if dist[tgt] > 0:
                    continue

                cond = c.is_card(AttackCard) or 'instant_spellcard' in c.category
                cond = cond and (c.is_card(DollControlCard) or len(act.target_list) == 1)  # HACK HERE!
                if not cond:
                    return act

                if user_input([p], ChooseOptionInputlet(self, (False, True))):
                    g.process_action(SolidShieldAction(p, src, act))
                    break

        return act
Example #19
0
    def apply_action(self):
        src, tgt = self.source, self.target
        ttags(src)['dismantle'] = True

        g = Game.getgame()
        c = user_input([src], ChoosePeerCardInputlet(self, tgt, ('equips', )))
        c = c or random_choose_card([tgt.equips])
        if not c: return False

        g.process_action(Reforge(src, tgt, c))
        g.process_action(DrawCards(tgt, 1))

        return True
Example #20
0
    def apply_action(self):
        src, tgt = self.source, self.target
        g = Game.getgame()
        pl = [p for p in g.players if not p.dead and p is not src]
        p, rst = ask_for_action(self, pl, ('cards', 'showncards'), [], timeout=6)
        if not p:
            ttags(src)['assisted_attack_disable'] = True
            return False

        (c,), _ = rst
        g.process_action(ActionStageLaunchCard(src, [tgt], AssistedAttackCard.wrap([c], src)))

        return True
Example #21
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, Damage):
            if not act.source: return act
            src, tgt = act.source, act.target
            g = Game.getgame()
            if src is not g.current_player: return act
            if src is tgt: return act
            ttags(src)['did_damage'] = True

        elif evt_type == 'action_after' and isinstance(act, Damage):
            if not act.source: return act
            src, tgt = act.source, act.target
            g = Game.getgame()
            cur = g.current_player
            if not cur: return act
            if not tgt.has_skill(ReimuExterminate): return act
            if cur.dead: return act
            if cur is tgt: return act
            g.process_action(ReimuExterminateAction(tgt, g.current_player, 'damage'))

        elif evt_type == 'action_apply' and isinstance(act, FinalizeStage):
            tgt = act.target
            if not ttags(tgt)['did_damage']:
                return act

            if tgt.dead:
                return act

            g = Game.getgame()
            for actor in g.players.rotate_to(g.current_player):
                if tgt is actor:
                    continue

                if not actor.has_skill(ReimuExterminate):
                    continue

                g.process_action(ReimuExterminateAction(actor, tgt, 'finalize'))

        return act
Example #22
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, FinalizeStage):
            tgt = act.target
            if not tgt.has_skill(KanakoFaithKOF):
                return act

            g = Game.getgame()
            op = g.get_opponent(tgt)

            if tgt.life > op.life or ttags(tgt)['kanako_faith_kof']:
                n = tgt.life - (len(tgt.cards) + len(tgt.showncards))
                if n > 0:
                    g.process_action(KanakoFaithKOFAction(tgt, n))

        elif evt_type == 'action_apply' and isinstance(act, Damage):
            src, tgt = act.source, act.target
            g = Game.getgame()

            if src and src.has_skill(KanakoFaithKOF) and tgt is g.get_opponent(src):
                ttags(src)['kanako_faith_kof'] = True

        return act
Example #23
0
    def apply_action(self):
        src, tgt = self.source, self.target
        ttags(src)['bakadesu'] = True

        cl = user_choose_cards(self, tgt, ('cards', 'showncards'))
        g = Game.getgame()
        if cl:
            g.process_action(LaunchCard(tgt, [src], cl[0]))
        else:
            c = user_input([src], ChoosePeerCardInputlet(self, tgt, ('cards', 'showncards', 'equips')))
            c = c or random_choose_card([tgt.cards, tgt.showncards, tgt.equips])
            c and g.process_action(CirnoDropCards(src, tgt, [c]))

        return True
Example #24
0
    def is_valid(self):
        try:
            p = self.target
            if ttags(p)['find']:
                return False

            g = Game.getgame()
            cards = self.associated_card.associated_cards
            if not 0 < len(cards) <= len([i for i in g.players if not i.dead]):
                return False

            return True

        except AttributeError:  # well, some cards are skill?
            return False
Example #25
0
    def apply_action(self):
        src = self.source
        tl = self.target_list
        g = Game.getgame()

        for p in tl:
            g.process_action(SanaeFaithCollectCardAction(src, p))

        g.deck.shuffle(src.cards)

        for p in tl:
            g.process_action(SanaeFaithReturnCardAction(src, p))

        ttags(src)['faith'] = True

        return True
Example #26
0
    def apply_action(self):
        tgt = self.target
        ttags(tgt)['qiliao'] = True
        g = Game.getgame()

        cl = getattr(tgt, 'meirin_qiliao', None)
        if cl is None:
            cl = CardList(tgt, 'meirin_qiliao')
            tgt.meirin_qiliao = cl
            tgt.showncardlists.append(cl)

        migrate_cards([self.associated_card], cl, unwrap=True)

        g.deck.shuffle(cl)

        return True
Example #27
0
    def apply_action(self):
        src, tgt = self.source, self.target
        ttags(src)['bakadesu'] = True

        cl = user_choose_cards(self, tgt, ('cards', 'showncards'))
        g = Game.getgame()
        if cl:
            g.process_action(LaunchCard(tgt, [src], cl[0]))
        else:
            c = user_input([src],
                           ChoosePeerCardInputlet(
                               self, tgt, ('cards', 'showncards', 'equips')))
            c = c or random_choose_card(
                [tgt.cards, tgt.showncards, tgt.equips])
            c and g.process_action(CirnoDropCards(src, tgt, [c]))

        return True
Example #28
0
    def apply_action(self):
        src, tgt = self.source, self.target
        g = Game.getgame()
        pl = [p for p in g.players if not p.dead and p is not src]
        p, rst = ask_for_action(self,
                                pl, ('cards', 'showncards'), [],
                                timeout=6)
        if not p:
            ttags(src)['assisted_attack_disable'] = True
            return False

        (c, ), _ = rst
        g.process_action(
            ActionStageLaunchCard(src, [tgt], AssistedAttackCard.wrap([c],
                                                                      src)))

        return True
Example #29
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, FinalizeStage):
            g = Game.getgame()

            src = act.target
            if not src.has_skill(GuidedDeath) or src.dead:
                return act

            p = ttags(src)['guided_death_active_use']
            if p:
                g.process_action(Heal(p, p, 1))
            else:
                tl = [p for p in g.players.rotate_to(src) if p.life == 1 and p is not src]
                if not tl:
                    return act

                g.process_action(GuidedDeathEffect(src, tl))

        return act
Example #30
0
    def apply_action(self):
        src, tgt = self.source, self.target
        g = Game.getgame()

        c = user_input([src],
                       ChoosePeerCardInputlet(
                           self, tgt, ['cards', 'showncards', 'equips']))
        c = c or random_choose_card([tgt.cards, tgt.showncards, tgt.equips])
        g.players.reveal(c)

        g.process_action(DropCards(src, tgt, [c]))
        if tgt.dead: return False

        action = 'draw'
        if tgt.life < tgt.maxlife:
            action = user_input(
                [tgt], ChooseOptionInputlet(self, ('heal', 'draw'))) or 'draw'

        if action == 'heal':
            g.process_action(EirinHeal(src, tgt))
        else:
            g.deck.getcards(3)
            g.deck.cards.rotate(3)
            cl = g.deck.getcards(3)
            g.process_action(ShowCards(tgt, cl))

            drop = [c for c in cl if 'basic' in c.category]
            get = [c for c in cl if c not in drop]

            if get:
                migrate_cards(get, tgt.cards)

            if drop:
                migrate_cards(drop, g.deck.droppedcards)

        ttags(src)['sky_silk'] = True
        return True
Example #31
0
    def apply_action(self):
        src, lc = self.source, self.action
        assert isinstance(lc, (LaunchCard, LaunchFatetellCard))
        lc.card_action.cancelled = True
        ttags(src)['mima_tianyi'] = True

        if isinstance(lc, LaunchCard):
            # HACK! RejectCard has no target, but not implemented this way.
            if lc.force_action and isinstance(lc.force_action, Reject):
                return True

            lst = lc.target_list[:]

        elif isinstance(lc, LaunchFatetellCard):
            lst = [lc.target]

        else:
            assert False, 'WTF?!'

        g = Game.getgame()
        for p in lst:
            g.process_action(LaunchCard(src, [p], TianyiAttack(src), bypass_check=True))

        return True
Example #32
0
 def is_valid(self):
     src, tgt = self.source, self.target
     return (tgt.cards or tgt.showncards
             or tgt.equips) and not ttags(src)['sky_silk']
Example #33
0
 def is_valid(self):
     tgt = self.target
     return not ttags(tgt)['teach_used']
Example #34
0
 def is_valid(self):
     src, tgt = self.source, self.target
     act = ActionStageLaunchCard(src, [tgt], AttackCard())
     disabled = ttags(src)['assisted_attack_disable']
     return not disabled and act.can_fire()
Example #35
0
 def apply_action(self):
     g = Game.getgame()
     src, tgt = self.source, self.target
     ttags(src)['mind_read'] = True
     return g.process_action(MindReadEffect(src, tgt))
Example #36
0
 def is_valid(self):
     src = self.source
     return not ttags(src)['teach_used']
Example #37
0
 def clickable(g):
     return my_turn() and not ttags(g.me)['teach_used']
Example #38
0
 def clickable(g):
     return my_turn() and not ttags(g.me)['faith']
Example #39
0
 def clickable(game):
     me = game.me
     return my_turn() and not ttags(me)['mind_read']
Example #40
0
    def clickable(game):
        me = game.me
        if not my_turn() or actions.ttags(me)['sky_silk']:
            return False

        return True
Example #41
0
 def is_valid(self):
     src = self.source
     return not ttags(src)['faith']
Example #42
0
 def is_valid(self):
     tgt = self.target
     return len(self.associated_card.associated_cards
                ) == ttags(tgt)['miracle_times'] + 1
Example #43
0
 def is_valid(self):
     return not ttags(self.source)['dismantle'] and bool(self.target.equips)
Example #44
0
    def clickable(g):
        if ttags(g.me)['dismantle']:
            return False

        return my_turn()
Example #45
0
 def __init__(self, player):
     Skill.__init__(self, player)
     self.treat_as = ttags(player).get('ran_eikof_card') or DummyCard
Example #46
0
 def apply_action(self):
     tgt = self.target
     ttags(tgt)['flan_cs'] = True
     tgt.tags['flan_targets'] = []
     return True
Example #47
0
 def is_valid(self):
     tgt = self.target
     return len(self.associated_card.associated_cards) == ttags(tgt)['miracle_times'] + 1
Example #48
0
 def in_critical_strike(self, p):
     return (ttags(p)['flan_cs'] and Game.getgame().current_player is p
             and p.has_skill(CriticalStrike))
Example #49
0
 def is_valid(self):
     src, tgt = self.source, self.target
     return not ttags(src)['mind_read'] and bool(tgt.cards)
Example #50
0
    def is_valid(self):
        src, tgt = self.source, self.target
        if not LaunchCard(tgt, [src], AttackCard()).can_fire():
            return False

        return not ttags(src)['bakadesu']