Example #1
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
Example #2
0
    def is_valid(self):
        src = self.source
        card = self.associated_card.associated_cards[0]
        if card.is_card(AttackCard) and src.tags['vitality'] < 1:
            if not AttackCardVitalityHandler.is_disabled(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()
Example #3
0
    def is_valid(self):
        src = self.source
        card = self.associated_card.associated_cards[0]
        if card.is_card(AttackCard) and src.tags["vitality"] < 1:
            if not AttackCardVitalityHandler.is_disabled(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()
Example #4
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act, BaseAttack):
            if hasattr(act, 'roukanken_tag'):
                return act

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

            # if tgt is g.current_player: return act
            if not tgt.has_skill(Reversal):
                return act

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

            def nhand(p):
                return len(p.cards) + len(p.showncards)

            g.process_action(DrawCards(tgt, 1))
            if nhand(tgt) > nhand(src):
                g.process_action(LaunchCard(src, [tgt], ReversalDuel(src)))
                act.cancelled = True

        return act
Example #5
0
    def handle(self, evt_type, act):
        if evt_type == 'action_shootdown' and isinstance(act, ActionStageLaunchCard):
            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
Example #6
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
Example #7
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            if not src: return act
            if not src.has_skill(DestructionImpulse): return act

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

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

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

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

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

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

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

            g.process_action(DestructionImpulseAction(tgt, p))

        return act
Example #8
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
Example #9
0
    def handle(self, evt_type, act):
        if evt_type == 'action_shootdown' and isinstance(
                act, ActionStageLaunchCard):
            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(AttackCard):
                if c.is_card(PhysicalCard) or 'treat_as' in c.category:
                    raise DiscarderAttackOnly
                else:
                    return act

            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
Example #10
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
Example #11
0
            def resp(evt_type, act):
                if evt_type == 'action_before' and isinstance(act, Demolition):
                    g.pause(1.5)
                    dialog(Cirno, u'哈哈,早知道你会用这一招,怎能让你轻易得逞!', 17)
                    g.process_action(
                        LaunchCard(cirno, [cirno], cirnoreject,
                                   Reject(cirno, act)))

                elif evt_type == 'action_before' and isinstance(
                        act, Reject) and act.associated_card is cirnoreject:
                    g.pause(1.5)
                    dialog(Meirin, u'这又是怎么回事……好像|G城管执法|r并没有起作用?', 38)
                    dialog(Sakuya, u'咦,这笨蛋居然知道用|G好人卡|r啊……', 19)
                    dialog(Cirno, u'什么笨蛋,老娘是天才,天~才~', 18)
                    text = (u'|G好人卡|r的效果是|R抵消符卡效果|r,也就是说,你的|G城管执法|r的效果被无效化了。\n'
                            u'(在PC版中鼠标移动到卡牌/人物上,或者手机版中长按卡牌/人物头像,就会弹出说明,很有用的)')
                    dialog(Sakuya, text, 20)
                    dialog(Sakuya,
                           u'但是,|G好人卡|r的“无效符卡”的效果,本身也是符卡效果,是可以被|G好人卡|r抵消的!',
                           21)

                    meirinreject = g.deck.inject(RejectCard, Card.CLUB, 4)
                    g.process_action(DrawCards(meirin, 1))

                    while not act.cancelled:
                        dialog(Meirin, u'我知道了,我也用|G好人卡|r去抵消她的|G好人卡|r效果就好了!',
                               39)

                        rej = RejectHandler()
                        rej.target_act = act
                        with InputTransaction('AskForRejectAction',
                                              [meirin]) as trans:
                            p, rst = ask_for_action(rej, [meirin],
                                                    ('cards', 'showncards'),
                                                    [],
                                                    trans=trans)

                        if not p: continue
                        cards, _ = rst
                        assert cards[0] is meirinreject
                        g.process_action(
                            LaunchCard(meirin, [cirno], meirinreject,
                                       Reject(meirin, act)))

                return act
Example #12
0
    def apply_action(self):
        src = self.source
        tags = src.tags
        tgt, victim = self.target_list

        tags['incite_tag'] = tags['turn_count']

        g = Game.getgame()
        if g.process_action(Pindian(src, tgt)):
            g.process_action(LaunchCard(tgt, [victim], InciteAttack(tgt)))

        else:
            if user_input([tgt], ChooseOptionInputlet(self, (False, True))):
                g.process_action(LaunchCard(tgt, [src], InciteFailAttack(tgt)))
            else:
                g.process_action(InciteSilentFailAction(src, tgt))

        return True
Example #13
0
    def is_valid(self):
        src = self.source
        tags = src.tags
        if tags['turn_count'] <= tags['incite_tag']:
            return False

        tgt, victim = self.target_list
        Pindian(src, tgt).action_shootdown_exception()
        return LaunchCard(tgt, [victim], InciteAttack(tgt)).can_fire()
Example #14
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
Example #15
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
Example #16
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
Example #17
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
Example #18
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]
        if not pl:
            return False

        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
Example #19
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
Example #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
Example #21
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
Example #22
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
Example #23
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            tgt = act.target
            if not (src and src.has_skill(FerryFee)): return act
            if not (tgt.cards or tgt.showncards or tgt.equips): return act
            dist = LaunchCard.calc_distance(src, FerryFee(src))
            if not dist.get(tgt, 10000) <= 0: return act
            if user_input([src], ChooseOptionInputlet(self, (False, True))):
                catnames = ('cards', 'showncards', 'equips')
                card = user_input([src], ChoosePeerCardInputlet(self, tgt, catnames))
                card = card or random_choose_card([tgt.cards, tgt.showncards, tgt.equips])
                if not card: return act
                g = Game.getgame()
                g.process_action(FerryFeeEffect(src, tgt, card))

        return act
Example #24
0
    def handle(self, evt_type, act):
        if evt_type == 'action_shootdown' and isinstance(act, LaunchCard):
            if act.bypass_check: return act
            c = act.card
            if not c.is_card(AttackCard): return act

            src, tgt  = act.source, act.target
            if not src.tags['scarlet_mist'] == 'nerf':
                return act

            dist = LaunchCard.calc_raw_distance(src, DummyCard())
            if dist[tgt] > 1:
                raise ScarletMistAttackLimit

        elif evt_type == 'post_calcdistance':
            src, c, dist = act

            if not c.is_card(AttackCard):
                return act

            if src.tags['scarlet_mist'] != 'buff':
                return act

            for k in dist:
                dist[k] = 0

        elif evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            if not (src and src.tags['scarlet_mist'] == 'buff'): return act
            if src.life >= src.maxlife: return act

            g = Game.getgame()
            pact = g.action_stack[-1]
            if not isinstance(pact, Attack): return act
            if not pact.associated_card: return act

            g.process_action(Heal(src, src, act.amount))

        elif evt_type == 'action_apply' and isinstance(act, PrepareStage):
            tgt = act.target
            if not tgt.has_skill(ScarletMist): return act
            if not tgt.tags['scarlet_mist']: return act
            g = Game.getgame()
            g.process_action(ScarletMistEndAction(None, None))

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

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

        return True
Example #26
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 thb.characters.baseclasses import Character
                # from thb.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 thb.cards.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=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
Example #27
0
    def handle(self, evt_type, act):
        if evt_type == 'action_shootdown' and isinstance(act, LaunchCard):
            if act.bypass_check: return act
            c = act.card
            if not c.is_card(AttackCard): return act

            src, tgt = act.source, act.target
            if not src.tags['scarlet_mist'] == 'nerf':
                return act

            dist = LaunchCard.calc_raw_distance(src, DummyCard())
            if dist[tgt] > 1:
                raise ScarletMistAttackLimit

        elif evt_type == 'post_calcdistance':
            src, c, dist = act

            if not c.is_card(AttackCard):
                return act

            if src.tags['scarlet_mist'] != 'buff':
                return act

            for k in dist:
                dist[k] = 0

        elif evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            if not (src and src.tags['scarlet_mist'] == 'buff'): return act
            if src.life >= src.maxlife: return act

            g = Game.getgame()
            pact = g.action_stack[-1]
            if not isinstance(pact, Attack): return act
            if not pact.associated_card: return act

            g.process_action(Heal(src, src, act.amount))

        elif evt_type == 'action_apply' and isinstance(act, PrepareStage):
            tgt = act.target
            if not tgt.has_skill(ScarletMist): return act
            if not tgt.tags['scarlet_mist']: return act
            g = Game.getgame()
            g.process_action(ScarletMistEndAction(None, None))

        return act
Example #28
0
    def handle(self, evt_type, act):
        if evt_type != 'action_after': return act
        if not isinstance(act, LaunchCard): return act

        g = Game.getgame()

        card = act.card
        if not card: return act
        if 'basic' not in card.category: return act
        if card.color != Card.RED: return act

        if card.is_card(VirtualCard):
            rawcards = VirtualCard.unwrap([card])
        else:
            rawcards = [card]

        if not all(c.resides_in is None or c.resides_in.type == 'droppedcard'
                   for c in rawcards):
            return act

        tgt = act.source
        self.target = tgt  # for ui

        if tgt.dead: return act

        for p in g.players:
            if p.dead or p is tgt: continue
            if not p.has_skill(ImperishableNight): continue
            if p is g.current_player: continue

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

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

            if cards:
                g.players.reveal(cards)
                skill = skill_wrap(p, [ImperishableNight], cards, {})
                assert skill_check(skill)  # should not fail
                g.deck.register_vcard(skill)
                rst = g.process_action(LaunchCard(p, [tgt], skill))
                assert rst

        return act
Example #29
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
Example #30
0
    def handle(self, evt_type, act):
        if evt_type == 'action_before' and isinstance(act,
                                                      ActionStageLaunchCard):
            src, tgt = act.source, act.target
            if not src or not tgt: return act
            ttags(src)['solid_shield_launch_count'] += 1
            if ttags(src)['solid_shield_launch_count'] != 1:
                return act

            if src is tgt: return act

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

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

                if p is tgt:
                    continue

                if not p.has_skill(SolidShield):
                    continue

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

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

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

        return act
Example #31
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            tgt = act.target
            if not (src and src.has_skill(FerryFee)): return act
            if not (tgt.cards or tgt.showncards or tgt.equips): return act
            dist = LaunchCard.calc_distance(src, FerryFee(src))
            if not dist.get(tgt, 10000) <= 0: return act
            if user_input([src], ChooseOptionInputlet(self, (False, True))):
                catnames = ('cards', 'showncards', 'equips')
                card = user_input([src],
                                  ChoosePeerCardInputlet(self, tgt, catnames))
                card = card or random_choose_card(
                    [tgt.cards, tgt.showncards, tgt.equips])
                if not card: return act
                g = Game.getgame()
                g.process_action(FerryFeeEffect(src, tgt, card))

        return act
Example #32
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, ActionStage):
            g = Game.getgame()
            for p in g.players:
                if p.dead: continue
                if not p.has_skill(Sentry): continue

                tgt = act.target
                if p is tgt: continue
                self.target = tgt  # for ui

                dist = LaunchCard.calc_distance(p, AttackCard())
                if dist.get(tgt, 1) > 0: continue
                if not user_input([p], ChooseOptionInputlet(self, (False, True))):
                    continue

                g.process_action(SentryAction(p, tgt))

        return act
Example #33
0
    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
Example #34
0
    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
Example #35
0
    def handle(self, evt_type, act):
        if evt_type == 'action_apply' and isinstance(act, ActionStage):
            g = Game.getgame()
            for p in g.players:
                if p.dead: continue
                if not p.has_skill(Sentry): continue

                tgt = act.target
                if p is tgt: continue
                self.target = tgt  # for ui

                dist = LaunchCard.calc_distance(p, AttackCard())
                if dist.get(tgt, 1) > 0: continue
                if not user_input([p], ChooseOptionInputlet(self, (False, True))):
                    continue

                g.process_action(SentryAction(p, tgt))

        return act
Example #36
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['vitality'] -= 1

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

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

        return True
Example #37
0
    def handle(self, evt_type, arg):
        if self.processing:
            return arg

        elif evt_type == 'calcdistance':
            src, c, dist = arg
            if not src.has_skill(Telegnosis): return arg
            if not c.is_card(AttackCard): return arg

            try:
                self.processing = True
                for p in dist:
                    if p is src: continue
                    d = LaunchCard.calc_distance(p, AttackCard())
                    if d[src] <= 0:
                        dist[p] = 0

            finally:
                self.processing = False

        return arg
Example #38
0
    def handle(self, evt_type, arg):
        if self.processing:
            return arg

        elif evt_type == 'calcdistance':
            src, c, dist = arg
            if not src.has_skill(Telegnosis): return arg
            if not c.is_card(AttackCard): return arg

            try:
                self.processing = True
                for p in dist:
                    if p is src: continue
                    d = LaunchCard.calc_distance(p, AttackCard())
                    if d[src] <= 0:
                        dist[p] = 0

            finally:
                self.processing = False

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

            if src is tgt: return act

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

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

                if p is tgt:
                    continue

                if not p.has_skill(SolidShield):
                    continue

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

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

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

        return act
Example #40
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
Example #41
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
Example #42
0
 def __init__(self, source, target, card, cause):
     LaunchCard.__init__(self, source, [target], card, bypass_check=True)
     self.cause = cause  # for ui
Example #43
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)