Ejemplo n.º 1
0
    def is_valid(self):
        src = self.source
        card = self.associated_card.associated_cards[0]
        if card.is_card(AttackCard) and src.tags['attack_num'] < 1:
            if not AttackCardHandler.is_freeattack(src):
                return False

        if card.usage != 'launch':
            return False

        victim = self.target
        tgts = self.target_list[1:]
        lc = LaunchCard(victim, tgts, card)
        return lc.can_fire()
Ejemplo n.º 2
0
    def is_valid(self):
        src = self.source
        card = self.associated_card.associated_cards[0]
        if card.is_card(AttackCard) and src.tags['attack_num'] < 1:
            if not AttackCardHandler.is_freeattack(src):
                return False

        if card.usage != 'launch':
            return False

        victim = self.target
        tgts = self.target_list[1:]
        lc = LaunchCard(victim, tgts, card)
        return lc.can_fire()
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    def handle(self, evt_type, arg):
        if evt_type == 'character_debut':
            old, new = arg
            if not new.has_skill(AssaultKOF):
                return arg

            g = Game.getgame()
            op = g.get_opponent(new)
            lc = LaunchCard(new, [op], AssaultAttack(new))
            if not lc.can_fire():
                return arg

            if user_input([new], ChooseOptionInputlet(self, (False, True))):
                g.process_action(lc)

        return arg
Ejemplo n.º 6
0
    def handle(self, evt_type, act):
        if evt_type == 'action_shootdown' and isinstance(act, LaunchCard):
            src = act.source
            if not src.has_skill(Discarder): return act
            g = Game.getgame()
            if src is not g.current_player: return act

            self.card = c = act.card
            if not c.is_card(PhysicalCard): return act
            if not c.is_card(AttackCard): raise DiscarderAttackOnly

            dist = LaunchCard.calc_distance(src, Discarder(src))
            dist.pop(src, '')
            nearest = max(min(dist.values()), 0)
            avail = {p for p in dist if dist[p] <= nearest}

            if not set(act.target_list) <= avail:
                raise DiscarderDistanceLimit

        elif evt_type == 'action_after' and isinstance(act, PlayerTurn):
            tgt = act.target
            if tgt.has_skill(Discarder):
                tgt.skills.remove(Discarder)
                tgt.tags['reisen_discarder'] = False  # for tag

        return act
Ejemplo n.º 7
0
    def apply_action(self):
        src, lc = self.source, self.action
        assert isinstance(lc, (LaunchCard, LaunchFatetellCard))
        lc.card_action.cancelled = True
        ttags(src)['mima_tianyi'] = True

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

            lst = lc.target_list[:]

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

        else:
            assert False, 'WTF?!'

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

        return True
Ejemplo n.º 8
0
    def apply_action(self):
        src, tgt = self.source, self.target
        g = Game.getgame()
        src.tags['suika_target'].append(tgt)
        if g.process_action(Pindian(src, tgt)):
            g.process_action(
                LaunchCard(src, [src],
                           HeavyDrinkerWine(src),
                           bypass_check=True))
            g.process_action(
                LaunchCard(tgt, [tgt],
                           HeavyDrinkerWine(src),
                           bypass_check=True))

        else:
            src.tags['suika_failed'] = src.tags['turn_count']

        return True
Ejemplo n.º 9
0
 def apply_action(self):
     src, tgt, c = self.source, self.target, self.card
     g = Game.getgame()
     g.process_action(Reforge(src, src, c))
     g.process_action(
         LaunchCard(src, [tgt],
                    XianshizhanAttackCard(src),
                    bypass_check=True))
     return True
Ejemplo n.º 10
0
    def is_valid(self):
        tags = self.source.tags
        if tags['turn_count'] <= tags['darkness_tag']:
            return False

        attacker, victim = self.target_list
        if not LaunchCard(attacker, [victim], AttackCard()).can_fire():
            return False

        return True
Ejemplo n.º 11
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, Damage):
            g = Game.getgame()
            pact = g.action_stack[-1]
            pcard = getattr(pact, 'associated_card', None)
            if not pcard: return act
            if pcard.is_card(SentryAttack):
                # Sentry effect
                src = pact.source
                if not src.dead and user_input(
                    [src], ChooseOptionInputlet(self, (False, True))):
                    # Guard
                    dmg = pcard.target_damage
                    dmg.amount = max(0, dmg.amount - 1)
                    act.cancelled = True
                else:
                    # Attack
                    pass

            elif pcard.is_card(AttackCard) and isinstance(pact, BaseAttack):
                # Sentry fire
                for p in g.players:
                    if p.dead: continue
                    if not p.has_skill(Sentry): continue
                    if p is pact.source: continue

                    tgt = pact.source
                    self.target = tgt  # for ui
                    self.act = act
                    dist = LaunchCard.calc_distance(p, AttackCard())
                    if dist.get(tgt, 1) > 0: continue
                    cl = user_choose_cards(self, p,
                                           ('cards', 'showncards', 'equips'))
                    if not cl: continue
                    c = SentryAttack.wrap(cl, p)
                    c.target_damage = act
                    g.process_action(LaunchCard(p, [tgt], c))
            else:
                return act

        return act
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    def apply_action(self):
        g = Game.getgame()
        src = self.source
        pl = [p for p in g.players if not p.dead]
        attacker, victim = user_choose_players(self, src, pl) or (None, None)
        if attacker is None:
            return False

        self.target_list = attacker, victim

        g.process_action(
            LaunchCard(src, [attacker, victim],
                       LittleLegionDollControlCard(attacker)))
        return True
Ejemplo n.º 15
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
Ejemplo n.º 16
0
    def is_valid(self):
        if self.target.dead:
            return False

        assert len(self.target_list) == 2

        attacker, victim = self.target_list

        if not any(e.equipment_category == 'weapon' for e in attacker.equips):
            return False

        from .definition import AttackCard
        if not LaunchCard(attacker, [victim], AttackCard()).can_fire():
            return False

        return True
Ejemplo n.º 17
0
    def apply_action(self):
        src, tgt = self.source, self.target
        ttags(src)['bakadesu'] = True

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

        return True
Ejemplo n.º 18
0
    def apply_action(self):
        src, tgt = self.source, self.target
        g = Game.getgame()

        choice = user_input([tgt],
                            ChooseOptionInputlet(self, ('duel', 'attack')))

        if choice == 'duel':
            cls = KanakoFaithDuel
        elif choice == 'attack':
            cls = KanakoFaithAttack
        else:
            cls = KanakoFaithAttack

        g.process_action(LaunchCard(tgt, [src], cls(tgt), bypass_check=True))

        return True
Ejemplo n.º 19
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, SpellCardAction):
            if act.cancelled: return act  # some other thing have done the job
            if act.non_responsive:
                return act

            g = Game.getgame()

            has_reject = False
            while g.SERVER_SIDE:
                from ..characters.baseclasses import Character
                from ..characters.reimu import SpiritualAttack
                for p in g.players:
                    if isinstance(p,
                                  Character) and p.has_skill(SpiritualAttack):
                        has_reject = True
                        break

                if has_reject: break

                from .definition import RejectCard
                for c in flatten([[p.cards, p.showncards] for p in g.players]):
                    if isinstance(c, RejectCard):
                        has_reject = True
                        break

                break

            has_reject = sync_primitive(has_reject, g.players)
            if not has_reject: return act

            self.target_act = act

            pl = BatchList(p for p in g.players if not p.dead)

            with InputTransaction('AskForRejectAction', pl) as trans:
                p, rst = ask_for_action(self, pl, ('cards', 'showncards'), [],
                                        trans)

            if not p: return act
            cards, _ = rst
            assert cards and self.cond(cards)
            g.process_action(
                LaunchCard(p, [act.target], cards[0], Reject(p, act)))

        return act
Ejemplo n.º 20
0
    def apply_action(self):
        tl = self.target_list
        assert len(tl) == 2
        src = self.source

        attacker, victim = tl
        cards = user_choose_cards(self, attacker, ['cards', 'showncards'])
        g = Game.getgame()

        if cards:
            g.players.reveal(cards)
            g.process_action(LaunchCard(attacker, [victim], cards[0]))
        else:
            l = [
                e for e in attacker.equips if e.equipment_category == 'weapon'
            ]
            migrate_cards(l, src.cards)
        return True
Ejemplo n.º 21
0
    def apply_action(self):
        src = self.source
        tgt = self.target
        g = Game.getgame()

        c = user_input([src],
                       ChoosePeerCardInputlet(
                           self, tgt, ('cards', 'showncards', 'equips')))
        c = c or random_choose_card([tgt.cards, tgt.showncards])
        if not c: return False
        src.reveal(c)
        migrate_cards([c], src.cards)
        src.tags['borrow_tag'] = src.tags['turn_count']

        if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
            g.process_action(
                LaunchCard(tgt, [src], Daze(tgt), bypass_check=True))

        return True
Ejemplo n.º 22
0
    def apply_action(self):
        g = Game.getgame()
        card = self.associated_card.associated_cards[0]
        src = self.source
        victim = self.target
        tgts = self.target_list[1:]

        g.players.reveal(card)
        # card.move_to(victim.cards)  # HACK: Silently, no events
        # migrate_cards([self.associated_card], victim.cards, unwrap=migrate_cards.SINGLE_LAYER)

        if card.is_card(AttackCard):
            src.tags['attack_num'] -= 1

        # XXX: Use card owned by other
        lc = LaunchCard(victim, tgts, card)

        g = Game.getgame()
        g.process_action(lc)

        return True
Ejemplo n.º 23
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, Damage):
            g = Game.getgame()
            pact = g.action_stack[-1]
            pcard = getattr(pact, 'associated_card', None)
            if not pcard: return act
            if pcard.is_card(SentryAttack):
                # Sentry effect
                src = pact.source
                if not src.dead and user_input([src], ChooseOptionInputlet(self, (False, True))):
                    # Guard
                    dmg = pcard.target_damage
                    dmg.amount = max(0, dmg.amount - 1)
                    act.cancelled = True
                else:
                    # Attack
                    pass

            elif pcard.is_card(AttackCard) and isinstance(pact, BaseAttack):
                # Sentry fire
                for p in g.players:
                    if p.dead: continue
                    if not p.has_skill(Sentry): continue
                    if p is pact.source: continue

                    tgt = pact.source
                    self.target = tgt  # for ui
                    self.act = act
                    dist = LaunchCard.calc_distance(p, AttackCard())
                    if dist.get(tgt, 1) > 0: continue
                    cl = user_choose_cards(self, p, ('cards', 'showncards', 'equips'))
                    if not cl: continue
                    c = SentryAttack.wrap(cl, p)
                    c.target_damage = act
                    g.process_action(LaunchCard(p, [tgt], c))
            else:
                return act

        return act
Ejemplo n.º 24
0
    def handle(self, evt_type, act):
        if evt_type != 'action_before': return act
        if not isinstance(act, DropCards): return act

        g = Game.getgame()
        pact = g.action_stack[-1]
        if not isinstance(pact, Demolition): return act
        if not pact.source.has_skill(Envy): return act

        src = pact.source
        tgt = pact.target
        self.card = card = pact.card

        assert len(act.cards) == 1
        assert card is act.cards[0]

        if card.resides_in is None:
            return act

        if card.resides_in.type not in ('cards', 'showncards', 'equips'):
            return act

        assert tgt is card.resides_in.owner

        if src.dead: return act
        if card.suit != Card.DIAMOND: return act

        dist = LaunchCard.calc_distance(src, EnvyRecycle())
        if not dist[tgt] <= 0: return act

        g.emit_event('ui_show_disputed', [card])

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

        act.__class__ = classmix(EnvyRecycleAction, act.__class__)
        return act
Ejemplo n.º 25
0
    def handle(self, evt_type, act):
        if evt_type != 'action_before': return act
        if not isinstance(act, DropCards): return act

        g = Game.getgame()
        pact = g.action_stack[-1]
        if not isinstance(pact, Demolition): return act
        if not pact.source.has_skill(Envy): return act

        src = pact.source
        tgt = pact.target
        self.card = card = pact.card

        assert len(act.cards) == 1
        assert card is act.cards[0]

        if card.resides_in is None:
            return act

        if card.resides_in.type not in ('cards', 'showncards', 'equips'):
            return act

        assert tgt is card.resides_in.owner

        if src.dead: return act
        if card.suit != Card.DIAMOND: return act

        dist = LaunchCard.calc_distance(src, EnvyRecycle())
        if not dist[tgt] <= 0: return act

        g.emit_event('ui_show_disputed', [card])

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

        act.__class__ = classmix(EnvyRecycleAction, act.__class__)
        return act
Ejemplo n.º 26
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
Ejemplo n.º 27
0
 def ask_for_action_verify(self, p, cl, tl):
     attacker, victim = self.target_list
     return LaunchCard(attacker, [victim], cl[0]).can_fire()
Ejemplo n.º 28
0
    def is_valid(self):
        src, tgt = self.source, self.target
        if not LaunchCard(tgt, [src], AttackCard()).can_fire():
            return False

        return not ttags(src)['bakadesu']
Ejemplo n.º 29
0
 def ask_for_action_verify(self, p, cl, tl):
     act = self.target_act
     return LaunchCard(p, [act.target], cl[0], Reject(p, act)).can_fire()
Ejemplo n.º 30
0
 def ask_for_action_verify(self, p, cl, tl):
     src, tgt = self.source, self.target
     return LaunchCard(tgt, [src], cl[0]).can_fire()
Ejemplo n.º 31
0
 def ask_for_action_verify(self, p, cl, tl):
     c = SentryAttack.wrap(cl, p)
     tgt = self.target
     c.target_damage = self.act
     return LaunchCard(p, [tgt], c).can_fire()
Ejemplo n.º 32
0
 def apply_action(self):
     tgt, card = self.target, self.card
     return Game.getgame().process_action(LaunchCard(tgt, [tgt], card))
Ejemplo n.º 33
0
 def choose_player_target(self, tl):
     src = self.source
     trimmed, rst = DollControlCard.target(None, src, tl)
     return trimmed, rst and LaunchCard(
         src, trimmed, LittleLegionDollControlCard(src)).can_fire()
Ejemplo n.º 34
0
    def target(g, p, tl):
        l = g.players.rotate_to(p)
        del l[0]

        dists = LaunchCard.calc_raw_distance(p, AttackCard())
        return ([t for t in l if not t.dead and dists[t] <= 1], True)
Ejemplo n.º 35
0
    def target(g, p, tl):
        l = g.players.rotate_to(p)
        del l[0]

        dists = LaunchCard.calc_raw_distance(p, AttackCard())
        return ([t for t in l if not t.dead and dists[t] <= 1], True)