示例#1
0
文件: yuuka.py 项目: 17night/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
示例#2
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
示例#3
0
    def handle(self, evt_type, act):
        if evt_type == 'action_after' and isinstance(act, Damage):
            src = act.source
            if not src: return act
            if not src.has_skill(DestructionImpulse): return act

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

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

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

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

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

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

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

            g.process_action(DestructionImpulseAction(tgt, p))

        return act
示例#4
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
示例#5
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
示例#6
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
示例#7
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
示例#8
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