コード例 #1
0
ファイル: youmu.py プロジェクト: feng2606/thbattle
    def apply_action(self):
        g = Game.getgame()
        card = self.associated_card
        target = self.target
        equips = target.equips
        g = Game.getgame()
        cat = card.equipment_category
        if cat == 'weapon':
            weapons = [e for e in equips if e.equipment_category == 'weapon']
            if len(weapons) > 1:
                e = user_input(
                    [target],
                    ChooseIndividualCardInputlet(self, weapons),
                ) or random_choose_card([weapons])
                g.process_action(DropCards(target, [e]))
                weapons.remove(e)

            weapons.append(card)
            cls = set([i.__class__ for i in weapons])
            l = set([HakuroukenCard, RoukankenCard])
            if cls == l and not target.has_skill(Xianshiwangzhi):
                g.process_action(XianshiwangzhiAwake(target, target))

        else:
            for oc in equips:
                if oc.equipment_category == cat:
                    g.process_action(DropCards(target, [oc]))
                    break

        migrate_cards([card], target.equips)
        return True
コード例 #2
0
ファイル: sakuya.py プロジェクト: AojiaoZero/thbattle
 def apply_action(self):
     tags = self.target.tags
     tags['lunaclock'] = True
     Game.getgame().process_action(ActionStage(self.target))
     tags['lunaclock'] = False
     tags['turn_count'] += 1
     return True
コード例 #3
0
ファイル: youmu.py プロジェクト: 17night/thbattle
    def apply_action(self):
        g = Game.getgame()
        card = self.associated_card
        target = self.target
        equips = target.equips
        g = Game.getgame()
        cat = card.equipment_category

        with MigrateCardsTransaction(self) as trans:
            if cat == 'weapon':
                weapons = [e for e in equips if e.equipment_category == 'weapon']
                if len(weapons) > 1:
                    e = user_input(
                        [target], ChooseIndividualCardInputlet(self, weapons),
                    ) or random_choose_card([weapons])
                    migrate_cards([e], g.deck.droppedcards, unwrap=True, trans=trans)

            else:
                for oc in equips:
                    if oc.equipment_category == cat:
                        migrate_cards([oc], g.deck.droppedcards, unwrap=True, trans=trans)
                        break

            migrate_cards([card], target.equips, trans=trans)

        return True
コード例 #4
0
ファイル: rumia.py プロジェクト: feisuzhu/thbattle
    def handle(self, evt_type, arg):
        if evt_type == 'character_debut':
            old, new = arg
            if new.has_skill(DarknessKOF):
                g = Game.getgame()
                g.process_action(DarknessKOFAction(new, new))

        elif evt_type == 'action_shootdown' and isinstance(arg, LaunchCard):
            src = arg.source
            if not src:
                return arg

            g = Game.getgame()
            opp = g.get_opponent(arg.source)
            if opp.tags['darkness_kof_tag'] < g.turn_count:
                return arg

            card = arg.card
            if not card.is_card(PhysicalCard):
                return arg

            if card.is_card(RejectCard):
                return arg

            # XXX: DollControl's second target do not count as target
            # but in KOF the second target is always the launcher,
            # and never be the opp, so the handle can be same.
            if opp in arg.target_list:
                raise DarknessKOFLimit

        return arg
コード例 #5
0
ファイル: tewi.py プロジェクト: feng2606/thbattle
 def handle(self, evt_type, arg):
     if evt_type == 'card_migration':
         act, l, _from, to = arg  # (action, cardlist, from, to)
         p = _from.owner
         if p and p.has_skill(Luck) and not p.dead and not (p.cards or p.showncards):
             Game.getgame().process_action(LuckDrawCards(p, 2))
     return arg
コード例 #6
0
ファイル: shinmyoumaru.py プロジェクト: feisuzhu/thbattle
    def handle(self, p, trans):
        if not p.has_skill(VengeOfTsukumogami):
            return True

        if not isinstance(trans.action, DropCards):
            return True

        for cards, _from, to, is_bh in trans.get_movements():
            if _from is None or _from.type != 'equips':
                continue

            if _from.owner is p:
                continue

            if to.type != 'droppedcard':
                continue

            self.target = tgt = _from.owner
            for c in cards:
                self.card = c

                if tgt.dead:
                    break

                if not user_input([p], ChooseOptionInputlet(self, (False, True))):
                    break

                Game.getgame().process_action(VengeOfTsukumogamiAction(p, tgt, c))

        return True
コード例 #7
0
ファイル: thbfaith.py プロジェクト: AojiaoZero/thbattle
    def handle(self, evt_type, act):
        if evt_type != 'action_after': return act
        if not isinstance(act, PlayerDeath): return act

        g = Game.getgame()

        tgt = act.target
        force = tgt.force
        if len(force.pool) <= 1:
            forces = g.forces[:]
            forces.remove(force)
            g.winners = forces[0][:]
            raise GameEnded

        g = Game.getgame()

        pool = tgt.force.pool
        assert pool

        mapping = {tgt: pool}
        with InputTransaction('ChooseGirl', [tgt], mapping=mapping) as trans:
            c = user_input([tgt], ChooseGirlInputlet(g, mapping), timeout=30, trans=trans)
            c = c or [_c for _c in pool if not _c.chosen][0]
            c.chosen = tgt
            pool.remove(c)
            trans.notify('girl_chosen', c)

        tgt = g.switch_character(tgt, c)
        g.process_action(DrawCards(tgt, 4))

        if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
            g.process_action(RedrawCards(tgt, tgt))

        return act
コード例 #8
0
ファイル: yugi.py プロジェクト: TimLang/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, BaseAttack) and not marked(act, 'freaking_power'):
            src = act.source
            if not src.has_skill(FreakingPower): return act
            if not user_input([src], ChooseOptionInputlet(self, (False, True))):
                return act
            tgt = act.target
            Game.getgame().process_action(FreakingPowerAction(act))

        elif evt_type == 'action_after' and isinstance(act, Damage):
            g = Game.getgame()

            pact = g.action_stack[-1]
            if not marked(pact, 'freaking_power'):
                return act

            src, tgt = pact.source, act.target
            if tgt.dead: return act

            catnames = ('cards', 'showncards', 'equips')
            card = user_input([src], ChoosePeerCardInputlet(self, tgt, catnames))
            if card:
                g.players.exclude(tgt).reveal(card)
                g.process_action(DropCards(src, tgt, [card]))

        return act
コード例 #9
0
    def apply_action(self):
        tgt, victim = self.target, self.victim
        if tgt.dead: return False

        g = Game.getgame()

        sel = ShipwreckChooseCard(tgt, victim)
        g.process_action(sel)
        c = sel.card

        tgt.reveal(c)
        migrate_cards([c], tgt.cards, unwrap=True)

        n = self.dropn
        if n <= 0:
            g.process_action(ShipwreckBrokenScoop(tgt, victim))
            return True

        g = Game.getgame()
        cards = user_choose_cards(self, tgt, ('cards', 'showncards'))
        if not cards:
            from itertools import chain
            cards = list(chain(tgt.cards, tgt.showncards))[min(-n, 0):]

        g.process_action(ShipwreckEffect(tgt, victim, cards))

        return True
コード例 #10
0
ファイル: thbbook.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, PlayerDeath):
            g = Game.getgame()

            tgt = act.target
            if tgt is not g.koakuma: return act

            hakurei, moriya = g.forces
            books = lambda force: sum(p.tags['books'] for p in force)
            nh, nm = books(hakurei), books(moriya)
            if nh > nm:
                g.winners = hakurei
            elif nh < nm:
                g.winners = moriya
            else:
                g.winners = hakurei + moriya

            g.game_end()

        elif evt_type == 'action_after' and isinstance(act, Damage):
            g = Game.getgame()

            hakurei, moriya = g.forces
            books = lambda force: sum(p.tags['books'] for p in force)

            if books(hakurei) >= g.total_books:
                g.winners = hakurei
                g.game_end()

            elif books(moriya) >= g.total_books:
                g.winners = moriya
                g.game_end()

        return act
コード例 #11
0
ファイル: yuuka.py プロジェクト: feisuzhu/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, PlayerDeath):
            src = act.source
            if not src or not src.has_skill(S****t):
                return act

            dist = LaunchCard.calc_distance(src, AttackCard())
            candidates = [k for k, v in dist.items() if v <= 0 and k is not src]

            if not candidates:
                return act

            pl = user_choose_players(self, src, candidates)
            if pl:
                Game.getgame().process_action(SadistAction(src, pl[0]))

        elif evt_type == 'action_before' and isinstance(act, Damage):
            src = act.source
            tgt = act.target

            if not src or src is tgt:
                return act

            if not src.has_skill(S****t):
                return act

            if tgt.life == 1:
                act.amount += 1

        return act
コード例 #12
0
ファイル: equipment.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, spellcard.Sinsack):
            tgt = act.target
            if tgt.has_skill(KeystoneSkill):
                Game.getgame().process_action(Keystone(act))

        return act
コード例 #13
0
ファイル: sp_flandre.py プロジェクト: feisuzhu/thbattle
    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
コード例 #14
0
ファイル: equipment.py プロジェクト: feisuzhu/thbattle
    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
コード例 #15
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            g = Game.getgame()
            src, tgt = act.source, act.target
            if not (src and src.has_skill(Disarm)): return act
            if tgt.dead: return act
            pact = g.action_stack[-1]
            pcard = getattr(pact, 'associated_card', None)
            if not pcard: return act

            if not pcard.is_card(AttackCard) and not (pcard.is_card(DuelCard) and pact.source is src):
                return act

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

            cl = list(tgt.cards) + list(tgt.showncards)
            g.process_action(ShowCards(tgt, cl, [src]))

            if g.SERVER_SIDE:
                l = [c.is_card(AttackCard) or 'spellcard' in c.category for c in cl]
            else:
                l = [False for c in cl]

            l = sync_primitive(l, g.players)
            cl = list(itertools.compress(cl, l))
            g.process_action(DisarmHideAction(src, tgt, cl))

        elif evt_type == 'action_after' and isinstance(act, FinalizeStage):
            tgt = act.target
            g = Game.getgame()
            g.process_action(DisarmReturningAction(tgt, tgt))

        return act
コード例 #16
0
ファイル: yukari.py プロジェクト: AojiaoZero/thbattle
    def apply_action(self):
        self.act.cancelled = True
        _from, _to = self.pl
        tgt = self.target
        from itertools import chain
        allcards = list(chain.from_iterable([_from.equips, _from.fatetell]))

        if not allcards:
            # Dropped by Exinwan
            return False

        card = user_input([tgt], ChooseIndividualCardInputlet(self, allcards))
        if not card:
            card = random_choose_card([_from.equips, _from.fatetell])

        if card.resides_in is _from.fatetell:
            if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                migrate_cards([card], _to.fatetell)
            else:
                migrate_cards([card], _to.cards, unwrap=True)

        elif card.resides_in is _from.equips:
            cats = set([c.equipment_category for c in _to.equips])
            migrate_cards([card], _to.cards)
            if card.equipment_category not in cats:
                if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                    Game.getgame().process_action(
                        LaunchCard(_to, [_to], card)
                    )
        else:
            assert False, 'WTF?!'

        return True
コード例 #17
0
ファイル: patchouli.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, arg):
        if evt_type == 'choose_target':
            act, tl = arg
            src = act.source

            if not src.has_skill(Library):
                return arg

            if 'instant_spellcard' in act.card.category:
                Game.getgame().process_action(LibraryDrawCards(src, 1))

            return arg

        # elif evt_type == 'action_before' and isinstance(arg, Reject):
        #     act = arg.target_act
        #     src = act.source
        #     if arg.source is src: return arg
        #     if not src.has_skill(Library): return arg

        #     Game.getgame().process_action(LibraryDrawCards(src, 1))

        #     return arg

        elif evt_type == 'calcdistance':
            src, card, dist = arg
            if not src.has_skill(Library): return arg
            if 'spellcard' not in card.category: return arg
            for p in dist:
                dist[p] -= 10000

        return arg
コード例 #18
0
ファイル: equipment.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, DropCardStage):
            tgt = act.target
            if tgt.has_skill(SuwakoHatSkill):
                Game.getgame().process_action(SuwakoHatEffect(tgt, act))

        return act
コード例 #19
0
ファイル: basic.py プロジェクト: feisuzhu/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, BaseAttack):
            pact = ForEach.get_actual_action(act) or act
            if getattr(pact, 'in_wine', False):
                act.damage += 1

        elif evt_type == 'post_choose_target':
            act, tl = arg = act

            from ..cards import AttackCard
            if act.card.is_card(AttackCard):
                src = act.source
                if src.tags['wine']:
                    Game.getgame().process_action(SoberUp(src, src))
                    act.card_action.in_wine = True

            return arg

        elif evt_type == 'action_apply' and isinstance(act, PlayerTurn):
            src = act.target
            if src.tags['wine']:
                Game.getgame().process_action(SoberUp(src, src))

        elif evt_type == 'action_before' and isinstance(act, Damage):
            if act.cancelled: return act
            if act.amount < 1: return act
            tgt = act.target
            if act.amount >= tgt.life and tgt.tags['wine']:
                g = Game.getgame()
                g.process_action(WineRevive(act))

        return act
コード例 #20
0
ファイル: ran.py プロジェクト: AojiaoZero/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, InstantSpellCardAction):
            if isinstance(act, Reject): return act
            g = Game.getgame()
            target = g.current_turn

            for p in g.players.exclude(target):
                if p.dead: continue
                if not p.has_skill(ExtremeIntelligence): continue
                if p.tags['ran_ei'] >= p.tags['turn_count'] + 1: continue

                try:
                    tl = act.target_list
                except AttributeError:
                    tl = [act.target]
                if any(t.dead for t in tl): return act

                if not user_input([p], ChooseOptionInputlet(self, (False, True))):
                    continue

                g.process_action(ExtremeIntelligenceAction(p, act.target, act))

        elif evt_type == 'game_begin':
            g = Game.getgame()
            for p in g.players:
                if isinstance(p, Ran):
                    p.tags['ran_ei'] = 0  # for ui

        return act
コード例 #21
0
ファイル: minoriko.py プロジェクト: AojiaoZero/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, LaunchCard):
            card = act.card
            if not card.is_card(HarvestCard): return act
            g = Game.getgame()
            pl = [p for p in g.players if p.has_skill(AkiTribute) and not p.dead]
            assert len(pl) <= 1, 'Multiple AkiTributes!'
            if not pl: return act
            p = pl[0]
            tl = act.target_list
            if not p in tl: return act
            tl.remove(p)
            tl.insert(0, p)

        elif evt_type == 'harvest_finish':
            g = Game.getgame()
            pl = [p for p in g.players if p.has_skill(AkiTribute) and not p.dead]
            assert len(pl) <= 1, 'Multiple AkiTributes!'
            if not pl: return act
            p = pl[0]
            migrate_cards([
                c for c in act.cards
                if c.resides_in is g.deck.disputed
            ], p.showncards)

        return act
コード例 #22
0
ファイル: kokoro.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, ActionStage):
            tgt = act.target
            if not tgt.has_skill(self.skill): return act
            if not user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                return act
            Game.getgame().process_action(self.action(tgt, tgt))

        return act
コード例 #23
0
ファイル: equipment.py プロジェクト: hycxa/thbattle
 def handle(self, evt_type, act):
     if evt_type == "action_before" and isinstance(act, spellcard.SinsackCarnivalEffect):
         target = act.target
         if not act.cancelled and target.has_skill(MaidenCostumeSkill):
             act.cancelled = True
             nact = MaidenCostumeEffect(source=act.source, target=target)
             nact.associated_card = act.associated_card
             Game.getgame().process_action(nact)
     return act
コード例 #24
0
ファイル: patchouli.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, SpellCardAction) and not act.cancelled:
            tgt = act.target
            if tgt.has_skill(Knowledge):
                c = getattr(act, 'associated_card', None)
                if c and c.suit == Card.SPADE and not c.is_card(RejectCard):
                    Game.getgame().process_action(KnowledgeAction(act))

        return act
コード例 #25
0
ファイル: basic.py プロジェクト: feisuzhu/thbattle
    def handle(self, evt_type, arg):
        from .base import VirtualCard, HiddenCard
        from .definition import ExinwanCard

        if evt_type == 'card_migration':
            act, cards, _from, to, is_bh = arg

            # someone is getting the ExinwanCard
            if to.owner is not None:
                for c in VirtualCard.unwrap(cards):
                    # Exinwan may be HiddenCard here
                    c.exinwan_target = None

                return arg

            # move from None to None do not affect Exinwan's target
            # (including moving detached cards to None)
            if _from is None or _from.owner is None or is_bh:
                return arg

            # do not active when distributing cards
            if isinstance(act, DistributeCards):
                return arg

            # someone is dropping the ExinwanCard
            for c in VirtualCard.unwrap(cards):
                # Exinwan may be HiddenCard here
                c.exinwan_target = act.source

            return arg

        elif evt_type == 'post_card_migration':
            dropcl = [cl for cl, _, to, _ in arg.get_movements()
                      if to.type == 'droppedcard']

            def invalid(c):
                return c.is_card(VirtualCard) or c.is_card(HiddenCard)

            # cards to dropped area should all unwrapped
            assert not any(invalid(c)
                           for cl in dropcl for c in cl)

            cards = [c for cl in dropcl for c in cl
                     if c.is_card(ExinwanCard)]

            # no same card dropped twice in the same transaction
            assert len(cards) == len(set(cards))

            for c in cards:
                tgt = getattr(c, 'exinwan_target', None)
                if tgt:
                    act = ExinwanEffect(tgt, tgt)
                    act.associated_card = c
                    Game.getgame().process_action(act)

        return arg
コード例 #26
0
ファイル: mokou.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, PlayerTurn):
            tgt = act.target
            if tgt.dead or not tgt.has_skill(Ashes): return act
            if not user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                return act

            Game.getgame().process_action(AshesAction(tgt))

        return act
コード例 #27
0
ファイル: equipment.py プロジェクト: hycxa/thbattle
    def handle(self, evt_type, act):
        if evt_type == "action_before" and isinstance(act, basic.BaseAttack):
            src, tgt = act.source, act.target
            if tgt.cards or tgt.showncards:
                return act
            if not src.has_skill(DeathSickleSkill):
                return act
            Game.getgame().process_action(DeathSickle(act))

        return act
コード例 #28
0
ファイル: equipment.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, Damage):
            if not act.target.has_skill(UmbrellaSkill): return act
            g = Game.getgame()
            pact = g.action_stack[-1]

            if isinstance(pact, spellcard.SpellCardAction):
                Game.getgame().process_action(UmbrellaEffect(pact, act))

        return act
コード例 #29
0
ファイル: flandre.py プロジェクト: 17night/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, DrawCardStage):
            if act.cancelled: return act
            tgt = act.target
            if not tgt.has_skill(CriticalStrike): return act
            if not user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                return act

            Game.getgame().process_action(CriticalStrikeAction(tgt, tgt))

            act.amount = max(0, act.amount - 1)

        elif evt_type == 'action_apply' and isinstance(act, BaseAttack):
            src = act.source
            tags = src.tags
            if not self.in_critical_strike(src):
                return act

            tgt = act.target
            if isinstance(act, BaseAttack):
                tags['flan_targets'].append(tgt)
                act.damage += 1

        elif evt_type == 'action_before' and isinstance(act, Damage):
            g = Game.getgame()
            pact = g.action_stack[-1]
            if not isinstance(pact, BaseDuel):
                return act

            src, tgt = act.source, act.target

            if not self.in_critical_strike(src):
                return act

            act.amount += 1

        elif evt_type == 'action_shootdown':
            if not isinstance(act, ActionStageLaunchCard): return act
            c = act.card
            src = act.source
            tags = src.tags
            if not self.in_critical_strike(src): return act
            if not c.is_card(AttackCard): return act
            if src.has_skill(ElementalReactorSkill): return act
            if set(act.target_list) & set(tags['flan_targets']):
                raise CriticalStrikeLimit

            return act

        elif evt_type == 'action_stage_action':
            tgt = act
            if not self.in_critical_strike(tgt): return act
            AttackCardHandler.set_freeattack(tgt)

        return act
コード例 #30
0
ファイル: reisen.py プロジェクト: TimLang/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Heal):
            tgt = act.target
            if not tgt.has_skill(MahjongDrug): return act
            card = getattr(act, 'associated_card', None)
            if not card or not card.is_card(HealCard): return act

            if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                Game.getgame().process_action(MahjongDrugAction(tgt, tgt))

        return act
コード例 #31
0
ファイル: shinmyoumaru.py プロジェクト: yuzishui/thbattle
    def apply_action(self):
        g = Game.getgame()
        c = self.card
        ft = self.ft
        src = self.source
        g.players.exclude(src).reveal(c)
        with MigrateCardsTransaction(self) as trans:
            migrate_cards([ft.card], src.cards, unwrap=True, trans=trans, is_bh=True)
            detach_cards([c], trans=trans)
            self.ft.set_card(c, self)

        return True
コード例 #32
0
ファイル: actions.py プロジェクト: zzkklep/thbattle
 def apply_action(self):
     g = Game.getgame()
     target = self.target
     card = self.card
     act = card.delayed_action
     assert act
     a = act(source=target, target=target)
     a.associated_card = card
     self.card_action = a
     g.process_action(a)
     a.fatetell_postprocess()
     return True
コード例 #33
0
ファイル: actions.py プロジェクト: zzkklep/thbattle
    def handle(self, evt_type, arg):
        if evt_type != 'post_card_migration': return arg

        g = Game.getgame()
        act = arg.action
        tgt = act.target or act.source or g.players[0]

        for p in g.players_from(tgt):
            for eh in self.handlers:
                g.handle_single_event(eh, p, arg)

        return arg
コード例 #34
0
ファイル: actions.py プロジェクト: yxyxq1984/thbattle
    def apply_action(self):
        g = Game.getgame()
        p = self.target
        p.tags['turn_count'] += 1
        g.current_turn = p

        g.process_action(FatetellStage(p))
        g.process_action(DrawCardStage(p))
        g.process_action(ActionStage(p))
        g.process_action(DropCardStage(p))

        return True
コード例 #35
0
ファイル: meirin.py プロジェクト: winterfellding/thbattle
 def apply_action(self):
     g = Game.getgame()
     src = self.source
     tgt = self.target
     c = user_input([src],
                    ChoosePeerCardInputlet(self, tgt,
                                           ('cards', 'showncards')))
     c = c or random_choose_card([tgt.cards, tgt.showncards])
     if not c: return False
     g.players.exclude(tgt).reveal(c)
     g.process_action(DropCards(tgt, [c]))
     return True
コード例 #36
0
ファイル: thbraid.py プロジェクト: winterfellding/thbattle
    def handle(self, evt_type, act):
        if not evt_type == 'action_after': return act
        if not isinstance(act, BaseDamage): return act
        g = Game.getgame()
        tgt = act.target
        if tgt is not g.mutant: return act
        if tgt.morphed: return act

        if tgt.life <= tgt.__class__.maxlife // 2:
            raise MutantMorph

        return act
コード例 #37
0
ファイル: daiyousei.py プロジェクト: yuzishui/thbattle
    def handle(self, evt_type, arg):
        if evt_type == 'character_debut':
            old, new = arg
            if not old: return arg
            if not getattr(old, 'support_cl', None): return arg

            g = Game.getgame()
            g.process_action(SupportKOFReturningAction(old, new))

        elif evt_type == 'action_apply' and isinstance(arg, PlayerDeath):
            tgt = arg.target
            if not tgt.has_skill(SupportKOF): return arg

            if not (tgt.cards or tgt.showncards or tgt.equips):
                return arg

            if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                g = Game.getgame()
                g.process_action(SupportKOFAction(tgt, tgt))

        return arg
コード例 #38
0
 def apply_action(self):
     g = Game.getgame()
     tgt = self.target
     place = user_input([tgt], ChooseOptionInputlet(self, ('top', 'bottom')))
     sk = self.card
     assert sk.is_card(LunaString)
     c = sk.associated_cards[0]
     sk.associated_cards[:] = []
     sk.cost_detached = True
     self.place = place  # for ui
     migrate_cards([c], g.deck.cards, unwrap=True, front=(place == 'top'))
     return True
コード例 #39
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, BaseAttack):
            src = act.source
            g = Game.getgame()
            for pact in reversed(g.action_stack):
                if isinstance(pact, LaunchCard):
                    break
            else:
                return act

            if getattr(pact, 'in_wine', False):
                act.damage += 1

        elif evt_type == 'action_before' and isinstance(act, LaunchCard):
            from ..cards import AttackCard
            if act.card.is_card(AttackCard):
                src = act.source
                if src.tags['wine']:
                    Game.getgame().process_action(SoberUp(src, src))
                    act.in_wine = True

        elif evt_type == 'action_apply' and isinstance(act, PlayerTurn):
            src = act.target
            if src.tags['wine']:
                Game.getgame().process_action(SoberUp(src, src))

        elif evt_type == 'action_before' and isinstance(act, Damage):
            if act.cancelled: return act
            if act.amount < 1: return act
            tgt = act.target
            if act.amount >= tgt.life and tgt.tags['wine']:
                g = Game.getgame()
                g.process_action(WineRevive(act))

        return act
コード例 #40
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act,
                                                     InstantSpellCardAction):
            if isinstance(act, Reject): return act
            g = Game.getgame()
            target = g.current_player

            for p in g.players.exclude(target):
                if p.dead:
                    continue

                if not p.has_skill(ExtremeIntelligence):
                    continue

                if p.tags['ran_ei'] >= p.tags['turn_count'] + 1:
                    continue

                try:
                    tl = act.target_list
                except AttributeError:
                    tl = [act.target]

                if any(t.dead for t in tl):
                    return act

                if not act.can_fire():
                    return act  # act cannot fire again

                nact = ExtremeIntelligenceAction(p, act.target, act)

                if nact.activate_action():
                    g.process_action(nact)

        elif evt_type == 'game_begin':
            g = Game.getgame()
            for p in g.players:
                if isinstance(p, Ran):
                    p.tags['ran_ei'] = 0  # for ui

        return act
コード例 #41
0
ファイル: sanae.py プロジェクト: hermosalin/thbattle
    def handle(self, evt_type, arg):
        if evt_type == 'card_migration':
            act, cards, _from, to, _ = arg
            if isinstance(act, (DistributeCards, DrawCardStage)):
                return arg

            if to is None or not to.owner:
                return arg

            if to.type not in ('cards', 'showncards', 'equips'):
                return arg

            if _from is not None and _from.owner is to.owner:
                return arg

            g = Game.getgame()
            a, b = g.players

            if not a.has_skill(SanaeFaithKOF):
                a, b = b, a

            if not a.has_skill(SanaeFaithKOF):
                return arg

            if b is not to.owner:
                return arg

            turn = PlayerTurn.get_current()
            if not turn:
                return arg

            stage = turn.current_stage
            if stage.target is not b or not isinstance(stage, ActionStage):
                return arg

            g = Game.getgame()

            g.process_action(SanaeFaithKOFDrawCards(a, 1))

        return arg
コード例 #42
0
ファイル: youmu.py プロジェクト: yuansanjin/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before':
            if isinstance(act, Attack):
                if not act.source.has_skill(Mijincihangzhan): return act
                act.__class__ = classmix(MijincihangzhanAttack, act.__class__)
                act.graze_count = 0
            elif isinstance(act, BaseDuel):
                if not isinstance(act, MijincihangzhanDuelMixin):
                    act.__class__ = classmix(MijincihangzhanDuelMixin,
                                             act.__class__)

        elif evt_type == 'action_apply' and isinstance(act, ActionStage):
            p = act.target
            p.tags['vitality'] += bool(
                p.has_skill(Nitoryuu) and self.weapons(p) >= 2)

        elif evt_type == 'card_migration':

            act, cards, _from, to, _ = arg = act

            for cl in (_from, to):
                if cl.type != 'equips': continue
                p = cl.owner
                if not p.has_skill(Nitoryuu): continue

                n = self.weapons(p)
                dn = len(cards)
                if not any(
                        getattr(c, 'equipment_category', None) == 'weapon'
                        for c in cards):
                    continue

                if cl is _from and (dn + n) >= 2 and n <= 1:
                    adjust = -1
                elif cl is to and (n - dn) <= 1 and n >= 2:
                    adjust = 1
                else:
                    adjust = 0

                p.tags['vitality'] += adjust

            return arg

        elif evt_type == 'attack_aftergraze':
            act, rst = arg = act
            if rst: return arg
            if not isinstance(act, MijincihangzhanAttack): return arg

            g = Game.getgame()
            return act, not g.process_action(LaunchGraze(act.target))

        return act
コード例 #43
0
    def __init__(self, irp, *a, **k):
        Control.__init__(self, *a, **k)
        parent = self.parent
        self.irp = irp
        assert isinstance(irp, IRP)

        self.x, self.y, self.width, self.height = (285, 162, 531, 58)

        self.confirmbtn = ConfirmButtons(parent=self,
                                         x=259,
                                         y=4,
                                         width=165,
                                         height=24,
                                         buttons=((u'确定', True), (u'结束',
                                                                  False)))
        self.progress_bar = b = BigProgressBar(parent=self,
                                               x=0,
                                               y=0,
                                               width=250)
        b.value = LinearInterp(1.0,
                               0.0,
                               irp.timeout,
                               on_done=lambda *a: self.cleanup())

        self.label = lbl = ShadowedLabel(
            text=u"HEY SOMETHING'S WRONG",
            x=125,
            y=28,
            font_size=12,
            color=(255, 255, 160, 255),
            shadow_color=(0, 0, 0, 179),
            anchor_x='center',
            anchor_y='bottom',
        )

        @self.confirmbtn.event
        def on_confirm(is_ok):
            irp = self.irp
            irp.input = self.get_result() if is_ok else None
            irp.complete()
            #self.cleanup()
            return

        def dispatch_selection_change():
            self.confirmbtn.buttons[0].state = Button.DISABLED
            self.on_selection_change()

        parent.push_handlers(on_selection_change=dispatch_selection_change)

        g = Game.getgame()
        port = parent.player2portrait(g.me)
        port.equipcard_area.clear_selection()
コード例 #44
0
    def __init__(self, trans, *a, **k):
        self.trans = trans
        self.pbar = None
        self.selecting = False

        g = Game.getgame()
        choices = trans.mapping[g.me]
        n_choices = len(choices)

        cols = 5 if n_choices > 16 else 4
        rows = max((n_choices - 1) / cols + 1, 4)

        w, h = 20 + cols * 160, 51 + rows * 113 + 30
        Panel.__init__(self, width=w, height=h, zindex=5, *a, **k)
        p = self.parent
        pw, ph = p.width, p.height
        self.x, self.y = (pw - w) / 2, (ph - h) / 2
        self.inputlet = None
        choices = self.choices = [
            c for c in choices
            if c.char_cls and not getattr(c, 'chosen', False)
        ]
        self.selectors = selectors = []
        for i, c in enumerate(choices):
            y, x = divmod(i, cols)
            x, y = 15 + 160 * x, 45 + 113 * (rows - 1 - y)
            gs = GirlSelector(c,
                              selectors,
                              parent=self,
                              hover_pic=self.hover_pic,
                              x=x,
                              y=y)

            @gs.event
            def on_dblclick(gs=gs):
                c = gs.choice
                ilet = self.inputlet
                if not c.chosen and ilet:
                    ilet.set_choice(c)
                    ilet.done()
                    self.end_selection()

            selectors.append(gs)

        self.label = Label(text='等待其他玩家操作',
                           x=w // 2,
                           y=51 + rows * 113,
                           font_size=12,
                           color=(255, 255, 160, 255),
                           shadow=(2, 0, 0, 0, 230),
                           anchor_x='center',
                           anchor_y='bottom')
コード例 #45
0
ファイル: mokou.py プロジェクト: yuansanjin/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, FatetellStage):
            self.target = tgt = act.target
            if not tgt.has_skill(Reborn): return act
            cards = user_choose_cards(self, tgt,
                                      ('cards', 'showncards', 'equips'))
            if cards:
                g = Game.getgame()
                g.process_action(DropCards(tgt, tgt, cards))
                if not tgt.dead:  # Ensure no ui action_effect_after (str | se) after drop Exinwan causing fall
                    g.process_action(RebornAction(tgt))

        return act
コード例 #46
0
    def process(self, src, tgt):
        if src is None or tgt is None:
            return

        if not src.has_skill(Rosa):
            return

        if not tgt.cards:
            return

        if user_input([src], ChooseOptionInputlet(self, (False, True))):
            g = Game.getgame()
            g.process_action(MindReadEffect(src, tgt))
コード例 #47
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            g = Game.getgame()
            pact = g.action_stack[-1]
            src, tgt = act.source, act.target

            if ForEach.is_group_effect(pact): return act
            if src is tgt: return act

            self.process(src, tgt)
            self.process(tgt, src)

        return act
コード例 #48
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src, tgt = act.source, act.target
            if not src: return act
            if not src.has_skill(ReimuClear): return act
            if src is tgt: return act
            if src.dead or tgt.dead: return act

            if user_input([src], ChooseOptionInputlet(self, (False, True))):
                g = Game.getgame()
                g.process_action(ReimuClearAction(src, tgt))

        return act
コード例 #49
0
ファイル: komachi.py プロジェクト: winterfellding/thbattle
    def handle(self, evt_type, arg):
        if evt_type == 'calcdistance':
            src, card, dist = arg
            if not src.has_skill(Riverside): return arg
            for p in dist:
                if p.tags['riverside_target']:
                    dist[p] -= 10000

        elif evt_type == 'action_after' and isinstance(arg, PlayerTurn):
            for p in Game.getgame().players:
                p.tags['riverside_target'] = False

        return arg
コード例 #50
0
ファイル: alice.py プロジェクト: yuansanjin/thbattle
    def apply_action(self):
        src = self.source

        g = Game.getgame()
        g.process_action(DrawCards(src, 1))

        turn = PlayerTurn.get_current(src)
        try:
            turn.pending_stages.remove(DropCardStage)
        except Exception:
            pass

        return True
コード例 #51
0
ファイル: equipment.py プロジェクト: hermosalin/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, Damage):
            from .basic import Attack
            g = Game.getgame()
            pact = g.action_stack[-1]
            if not isinstance(pact, Attack): return act
            src = act.source
            if not src or not src.has_skill(DeathSickleSkill): return act
            tgt = act.target
            if len(tgt.cards) + len(tgt.showncards) == 0:
                g.process_action(DeathSickle(act))

        return act
コード例 #52
0
ファイル: tenshi.py プロジェクト: zzkklep/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Fatetell):
            tgt = act.target
            if act.card.color != Card.RED: return act
            g = Game.getgame()
            if not act.card.detached:
                return act

            g = Game.getgame()
            pl = [
                p for p in g.players
                if p.has_skill(ScarletPerception) and not p.dead
            ]
            assert len(pl) <= 1

            if pl:
                p = pl[0]
                dist = LaunchCard.calc_distance(p, ScarletPerception(p))
                if dist.get(tgt, 1) <= 0:
                    g.process_action(ScarletPerceptionAction(p, tgt, act.card))

        return act
コード例 #53
0
ファイル: alice.py プロジェクト: hermosalin/thbattle
    def apply_action(self):
        g = Game.getgame()
        src = self.source
        pl = [p for p in g.players if not p.dead and p is not src]
        victim, = user_choose_players(self, src, pl) or (None, )
        if victim is None:
            return False

        lc = LaunchCard(src, [victim],
                        LittleLegionAttackCard(src),
                        bypass_check=True)
        g.process_action(lc)
        return True
コード例 #54
0
    def apply_action(self):
        src = self.source
        tgt = self.target
        g = Game.getgame()
        tgt.maxlife += self.amount

        if tgt.life > tgt.maxlife:
            g.process_action(LifeLost(src, tgt, abs(tgt.life - tgt.maxlife)))
            assert tgt.life == tgt.maxlife

        assert tgt.maxlife or tgt.dead

        return True
コード例 #55
0
ファイル: kanako.py プロジェクト: zzkklep/thbattle
    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
コード例 #56
0
    def apply_action(self):
        g = Game.getgame()
        src = self.source

        use_faith(src, 1)

        act = self.dmgact
        act.cancelled = True

        g.process_action(LifeLost(src, src, act.amount))
        g.process_action(CollectFaith(g.mutant, g.mutant, 1))

        return True
コード例 #57
0
ファイル: alice.py プロジェクト: yuansanjin/thbattle
    def apply_action(self):
        g = Game.getgame()
        src = self.source
        pl = [p for p in g.players if not p.dead and p.life < p.maxlife]
        if not pl:
            return False

        beneficiary, = user_choose_players(self, src, pl) or (None, )
        if beneficiary is None:
            return False

        g.process_action(LittleLegionCoverEffect(src, beneficiary, 1))
        return True
コード例 #58
0
ファイル: equipment.py プロジェクト: hermosalin/thbattle
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, FatetellStage):
            tgt = act.target
            g = Game.getgame()
            from .definition import SinsackHatCard
            for c in list(tgt.equips):
                if not c.is_card(SinsackHatCard):
                    continue

                g.process_action(SinsackHatAction(tgt, tgt, c))
                return act

        return act
コード例 #59
0
    def on_game_event(self, evt_type, arg):
        if evt_type == 'action_after' and isinstance(arg, actions.RevealIdentity):
            act = arg
            g = Game.getgame()
            me = g.me
            if (act.target in (self.player, self.character)) and (me in act.to if isinstance(act.to, list) else me is act.to):
                self.update_identity(self.character or self.player)

        elif evt_type == 'switch_character':
            old, new = arg
            if new.player is self.player:
                self.character = new
                self.update()
コード例 #60
0
ファイル: equipment.py プロジェクト: hermosalin/thbattle
    def fatetell_action(self, ft):
        act = self.act
        src = self.source

        g = Game.getgame()
        if ft.succeeded:
            # rej = spellcard.LaunchReject(src, act, SaigyouBranchSkill(src))
            g.process_action(
                LaunchCard(src, [act.target], MaidenCostume(src),
                           spellcard.Reject(src, act)))
            return True
        else:
            return False