예제 #1
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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
 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
예제 #5
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
예제 #6
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
예제 #7
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
예제 #8
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
예제 #9
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
예제 #10
0
    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
예제 #11
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
예제 #12
0
    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
예제 #13
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
예제 #14
0
    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
예제 #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
파일: 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
예제 #17
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
예제 #18
0
    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
    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
예제 #20
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
예제 #21
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
예제 #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
    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
파일: 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
예제 #27
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
예제 #28
0
    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
파일: alice.py 프로젝트: GavinHill/thbattle
    def apply_action(self):
        g = Game.getgame()
        cl = self.cards
        track_ids = set([c.track_id for c in cl])

        src, tgt = self.source, self.target
        for c in cl:
            c = user_input([src], ChoosePeerCardInputlet(self, tgt, ('cards', 'showncards', 'equips')))
            c = c or random_choose_card([tgt.cards, tgt.showncards, tgt.equips])
            if not c: return True
            g.players.reveal(c)
            g.process_action(DollBlastEffect(src, tgt, c, c.track_id in track_ids))

        return True
예제 #32
0
def random_choose_card(categories):
    from itertools import chain
    allcards = list(chain.from_iterable(categories))
    if not allcards:
        return None

    g = Game.getgame()
    c = g.random.choice(allcards)
    v = sync_primitive(c.syncid, g.players)
    cl = g.deck.lookupcards([v])
    if len(cl)!=1:
        print cl
    assert len(cl) == 1
    return cl[0]
예제 #33
0
def user_choose_players_logic(input, act, target, candidates):
    try:
        g = Game.getgame()
        check_type([[int, Ellipsis]] * 3, input)
        _, _, pids = input
        check(pids)
        pl = [g.player_fromid(i) for i in pids]
        from game import AbstractPlayer
        check(all(p in candidates for p in pl))
        pl, valid = act.choose_player_target(pl)
        check(valid)
        return pl
    except CheckFailed:
        return None
예제 #34
0
    def apply_action(self):
        g = Game.getgame()
        tgt = self.target
        c = user_choose_cards(self, tgt, ('cards', 'showncards', 'equips'))
        if c:
            c = c[0]
        else:
            c = random_choose_card([tgt.cards, tgt.showncards, tgt.equips])
            g.players.reveal(c)
        if not c:
            return False

        g.process_action(Reforge(tgt, tgt, c))
        return True
예제 #35
0
 def apply_action(self):
     src, tgt = self.source, self.target
     cl = VirtualCard.unwrap([self.associated_card])
     assert len(cl) == 1
     g = Game.getgame()
     ttags(src)['teach_used'] = True
     g.process_action(Reforge(src, src, cl[0]))
     if src.has_skill(Teach):
         cl = user_choose_cards(self, src,
                                ('cards', 'showncards', 'equips'))
         c = cl[0] if cl else random_choose_card(
             [src.cards, src.showncards, src.equips])
         g.process_action(TeachTargetEffect(src, tgt, c))
     return True
예제 #36
0
    def apply_action(self):
        if not self.cards:
            return False

        g = Game.getgame()
        cards = self.cards
        g.players.reveal(cards)
        g.emit_event('showcards', (self.target, [copy(c) for c in cards]))
        # user_input(
        #     [p for p in g.players if not p.dead],
        #     ChooseOptionInputlet(self, (True,)),
        #     type='all', timeout=1,
        # )  # just a delay
        return True
예제 #37
0
def random_choose_card(cardlists):
    from itertools import chain
    allcards = list(chain.from_iterable(cardlists))
    if not allcards:
        return None

    g = Game.getgame()
    c = g.random.choice(allcards)
    v = sync_primitive(c.sync_id, g.players)
    cl = g.deck.lookupcards([v])
    assert len(cl) == 1
    c = cl[0]
    c.detach()
    return c
예제 #38
0
    def apply_action(self):
        src = self.source
        tgt = self.target

        cards = user_choose_cards(self, tgt, ('cards', 'showncards'))
        g = Game.getgame()
        if cards:
            self.peer_action = 'drop'
            g.process_action(DropCards(src, tgt, cards))
        else:
            self.peer_action = 'draw'
            g.process_action(DrawCards(src, 1))

        return True
예제 #39
0
파일: alice.py 프로젝트: yuzishui/thbattle
    def handle(self, evt_type, arg):
        if evt_type == 'choose_target':
            lca, tl = arg
            if 'equipment' not in lca.card.category: return arg

            src = lca.source
            if src.dead or not src.has_skill(LittleLegion): return arg
            if not user_input([src], ChooseOptionInputlet(self,
                                                          (False, True))):
                return arg
            g = Game.getgame()
            g.process_action(LittleLegionDrawCards(src, 1))

        return arg
예제 #40
0
 def apply_action(self):
     cl = self.associated_card.associated_cards
     src = self.source
     tgt = self.target
     l = src.tags.get('daiyousei_spnum', 0)
     n = len(cl)
     if l < 3 <= l + n:
         g = Game.getgame()
         g.process_action(Heal(src, src))
     src.tags['daiyousei_spnum'] = l + n
     tgt.reveal(cl)
     migrate_cards([self.associated_card], tgt.cards, unwrap=True)
     self.cards = cl
     return True
예제 #41
0
파일: basic.py 프로젝트: zzkklep/thbattle
    def apply_action(self):
        g = Game.getgame()
        tgt = self.target
        if tgt.dead:
            return False

        cards = user_choose_cards(self, tgt, ('cards', 'showncards', 'equips'))

        if cards:
            g.process_action(DropCards(tgt, tgt, cards))
        else:
            g.process_action(Damage(None, tgt))

        return True
예제 #42
0
 def fatetell_postprocess(self):
     g = Game.getgame()
     tgt = self.target
     if not self.cancelled and self.succeeded:
         g.process_action(DropCards(None, tgt, [self.associated_card]))
     else:
         pl = g.players
         stop = pl.index(tgt)
         next = stop - len(pl) + 1
         while next < stop:
             if not pl[next].dead:
                 migrate_cards([self.associated_card], pl[next].fatetell)
                 return
             next += 1
예제 #43
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before':
            if not isinstance(act, LaunchCard):
                return act

            c = act.card

            if not c.is_card(LunaString):
                return act

            g = Game.getgame()
            g.process_action(LunaStringPlaceCard(act.source, c))

        return act
예제 #44
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, PlayerDeath):
            g = Game.getgame()

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

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

            tgt = act.target
            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', (tgt, c))

            tgt = g.switch_character(tgt, c)

            c = getattr(g, 'current_player', None)

            g.process_action(DistributeCards(tgt, 4))

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

        return act
예제 #45
0
    def apply_action(self):
        # WHOLE BUNCH OF MEGA HACK
        old = self.target
        g = Game.getgame()
        old_life, maxlife_delta = old.life, old.maxlife - old.__class__.maxlife

        ActionStage.force_break()

        assert g.current_player is old
        tgt = KOFCharacterSwitchHandler.switch(old)
        g.current_player = tgt

        tgt.life = old_life
        tgt.maxlife += maxlife_delta

        for l in ('cards', 'showncards', 'equips', 'fatetell', 'special'):
            s, t = getattr(old, l), getattr(tgt, l)
            for i in list(s):
                i.move_to(t)

        for s in old.skills:
            if 'character' not in s.skill_category:
                tgt.skills.append(s)

        for act in g.action_stack:
            # Meh... good enough
            if act.source is old:
                act.source = tgt

            if act.target is old:
                act.target = tgt

            if isinstance(act, LaunchCard):
                act.target_list[:] = [
                    tgt if p is old else p for p in act.target_list
                ]

        tgt.tags = old.tags

        tgt.choices.append(CharChoice(old.__class__))

        if tgt.life > tgt.maxlife:
            g.process_action(LifeLost(tgt, tgt, tgt.life - tgt.maxlife))

        self.transition = [old, tgt]

        g.emit_event('character_debut', (old, tgt))

        return True
예제 #46
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
예제 #47
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, PlayerDeath):
            g = Game.getgame()
            p = getattr(g, 'current_player', None)

            if not p: return act
            if p is act.target: return act
            if not p.has_skill(Summon): return act
            if p.tags['summon_used']: return act
            if not user_input([p], ChooseOptionInputlet(self, (False, True))):
                return act

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

        return act
예제 #48
0
    def apply_action(self):
        src = self.source
        tgt = self.target

        cards = user_choose_cards(self, tgt, ('cards', 'showncards', 'equips'))
        g = Game.getgame()
        if cards:
            self.peer_action = 'card'
            g.players.exclude(tgt).reveal(cards)
            migrate_cards(cards, src.cards)
        else:
            self.peer_action = 'life'
            g.process_action(LifeLost(src, tgt, 1))

        return True
예제 #49
0
    def apply_action(self):
        g = Game.getgame()
        card = self.associated_card
        tgt = self.target
        equips = tgt.equips
        g = Game.getgame()

        _s, _t, _c, rst = g.emit_event('wear_equipment',
                                       (self, tgt, card, 'default'))
        assert _s is self
        assert _t is tgt
        assert _c is card
        assert rst in ('default', 'handled')

        if rst == 'handled':
            return True

        for oc in list(equips):
            if oc.equipment_category == card.equipment_category:
                g.process_action(DropCards(tgt, tgt, [oc]))

        migrate_cards([card], tgt.equips)

        return True
예제 #50
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(
                act, BaseAttack) and not hasattr(act, 'yugifptag'):
            src = act.source
            if not src.has_skill(FreakingPowerSkill): return act
            if not user_input([src], ChooseOptionInputlet(self,
                                                          (False, True))):
                return act
            tgt = act.target
            Game.getgame().process_action(FreakingPower(act))

        elif evt_type == 'action_after' and hasattr(act, 'yugifptag'):
            if not act.succeeded: return act
            src = act.source
            tgt = act.target
            g = Game.getgame()
            catnames = ('cards', 'showncards', 'equips')
            card = user_input([src],
                              ChoosePeerCardInputlet(self, tgt, catnames))
            if card:
                g.players.exclude(tgt).reveal(card)
                g.process_action(DropCards(tgt, [card]))

        return act
예제 #51
0
파일: koakuma.py 프로젝트: zzkklep/thbattle
    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
예제 #52
0
 def handle(self, evt_type, act):
     from .basic import BaseAttack
     if not evt_type == 'action_after': return act
     if not isinstance(act, BaseAttack): return act
     if not act.succeeded: return act
     src = act.source
     tgt = act.target
     if tgt.dead: return act
     if not tgt.cards: return act
     if not src.has_skill(NenshaPhoneSkill): return act
     if not user_input([src], ChooseOptionInputlet(self, (False, True))):
         return act
     g = Game.getgame()
     g.process_action(NenshaPhone(src, tgt))
     return act
예제 #53
0
    def apply_action(self):
        g = Game.getgame()
        c = self.card
        ft = self.ft
        g.players.exclude(self.source).reveal(c)
        with MigrateCardsTransaction(self) as trans:
            migrate_cards([ft.card],
                          g.deck.droppedcards,
                          unwrap=True,
                          trans=trans,
                          is_bh=True)
            detach_cards([c], trans=trans)
            self.ft.set_card(c, self)

        return True
예제 #54
0
    def apply_action(self):
        src = self.source
        tgt = self.target
        draw = DrawCards(src, self.amount)
        g = Game.getgame()
        g.process_action(draw)
        g.process_action(ShowCards(src, draw.cards))
        if [c for c in draw.cards if c.suit != Card.CLUB]:  # any non-club
            tgt.tags['melancholy_tag'] = g.turn_count
            self.effective = True

        else:
            self.effective = False

        return True
예제 #55
0
    def handle(self, evt_type, act):
        if evt_type != 'action_before': return act
        if not isinstance(act, Damage): return act
        if act.cancelled: return act

        g = Game.getgame()
        tgt = act.target

        pl = g.attackers[:]
        if tgt not in pl: return act
        if tgt.life != min([p.life for p in pl if not p.dead]): return act

        g = Game.getgame()
        pl.remove(tgt)

        self.dmgact = act

        pl = [p for p in pl if not p.dead and len(p.faiths) and p.has_skill(Protection)]
        for p in pl:
            if user_choose_option(self, p):
                g.process_action(ProtectionAction(p, act))
                break

        return act
예제 #56
0
    def _do_effect(self, p):
        g = Game.getgame()
        amount = self.amount
        allcards = list(p.showncards) + list(p.cards) + list(p.equips)
        if len(allcards) <= amount:
            cards = allcards
        else:
            cards = user_choose_cards(self, p,
                                      ('cards', 'showncards', 'equips'))
            cards = cards or allcards[:amount]

        g.players.reveal(cards)

        g.process_action(DropCards(p, cards))
        g.process_action(DrawCards(p, amount))
예제 #57
0
def use_faith(target, amount=1):
    g = Game.getgame()
    assert amount <= len(target.faiths)
    if len(target.faiths) == amount:
        g.process_action(DropCards(target, list(target.faiths)))
        return

    for i in xrange(amount):
        c = choose_individual_card(target, target.faiths)
        if not c: break
        g.process_action(DropCards(target, [c]))
        amount -= 1

    if amount:
        g.process_action(DropCards(target, list(target.faiths)[:amount]))
예제 #58
0
    def apply_action(self):
        attacker, victim = self.target_list
        src = self.source
        g = Game.getgame()
        tags = self.source.tags
        tags['darkness_tag'] = tags['turn_count']

        cards = user_choose_cards(self, attacker, ('cards', 'showncards'))
        if cards:
            c = cards[0]
            g.process_action(LaunchCard(attacker, [victim], c))
        else:
            g.process_action(Damage(src, attacker, 1))

        return True
예제 #59
0
    def apply_action(self):
        src, tgt, cl = self.source, self.target, self.cards
        g = Game.getgame()

        c = user_input([src], ChooseIndividualCardInputlet(self, cl)) or random_choose_card([cl])
        g.process_action(Reforge(src, tgt, c))

        '''
        candidates = [i for i in g.players if not i.dead]
        p, = user_choose_players(self, src, candidates) or (src,)

        g.process_action(DrawCards(p, 1))
        '''

        return True
예제 #60
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, DrawCardStage):
            tgt = act.target

            if not tgt.has_skill(Jolly): return act

            g = Game.getgame()
            pl = user_choose_players(self, tgt, [p for p in g.players if not p.dead])
            if not pl: pl = [tgt]

            p = pl[0]

            g.process_action(JollyDrawCard(tgt, p))

        return act