Пример #1
0
    def getInputletInstances(self):
        from thb.cards import AttackCard
        from thb.characters.youmu import Youmu
        from thb.common import CharChoice
        from thb.inputlets import ActionInputlet
        from thb.inputlets import ChooseGirlInputlet
        from thb.inputlets import ChooseIndividualCardInputlet
        from thb.inputlets import ChooseOptionInputlet
        from thb.inputlets import ChoosePeerCardInputlet
        from thb.inputlets import ProphetInputlet

        g, p = self.makeGame()

        ilets = [
            ActionInputlet(self, ['cards', 'showncards'], []),
            ChooseGirlInputlet(self, {p: [CharChoice(Youmu)]}),
            ChooseIndividualCardInputlet(self, [AttackCard()]),
            ChooseOptionInputlet(self, (False, True)),
            ChoosePeerCardInputlet(self, p, ['cards']),
            ProphetInputlet(self, [AttackCard()]),
        ]

        for i in ilets:
            i.actor = p

        return g, p, ilets
Пример #2
0
    def testChooseGirlInputlet(self):
        from game.autoenv import user_input
        from thb.common import CharChoice
        from thb.characters.youmu import Youmu
        from thb.characters.seiga import Seiga
        from thb.inputlets import ChooseGirlInputlet

        g, p = self.makeGame()
        choices = [CharChoice(Youmu), CharChoice(Seiga)]
        mapping = {p: choices}

        ilet = ChooseGirlInputlet(self, mapping)
        ilet.actor = p
        ilet.set_choice(choices[0])
        eq_(ilet.data(), 0)

        p.client.gdlist.append([r'>I:ChooseGirl:\d+', 0])
        ilet = ChooseGirlInputlet(self, mapping)
        eq_(user_input([p], ilet), choices[0])
Пример #3
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
Пример #4
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from thb.cards import Deck

        g.stats = []

        g.deck = Deck()
        g.ehclasses = []

        if params['random_force']:
            seed = get_seed_for(g.players)
            random.Random(seed).shuffle(g.players)

        g.draw_extra_card = params['draw_extra_card']

        f1 = BatchList()
        f2 = BatchList()
        g.forces = BatchList([f1, f2])

        H, M = Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA
        for p, id, f in zip(g.players, [H, H, M, M], [f1, f1, f2, f2]):
            p.identity = Identity()
            p.identity.type = id
            p.force = f
            f.append(p)

        pl = g.players
        for p in pl:
            g.process_action(RevealIdentity(p, pl))

        roll_rst = roll(g, self.items)
        f1, f2 = partition(lambda p: p.force is roll_rst[0].force, roll_rst)
        final_order = [f1[0], f2[0], f2[1], f1[1]]
        g.players[:] = final_order
        g.emit_event('reseat', None)

        # ban / choose girls -->
        from . import characters
        chars = characters.get_characters('common', '2v2')

        seed = get_seed_for(g.players)
        random.Random(seed).shuffle(chars)

        # ANCHOR(test)
        testing = list(settings.TESTING_CHARACTERS)
        testing, chars = partition(lambda c: c.__name__ in testing, chars)
        chars.extend(testing)

        chars = chars[-20:]
        choices = [CharChoice(cls) for cls in chars]

        banned = set()
        mapping = {p: choices for p in g.players}
        with InputTransaction('BanGirl', g.players, mapping=mapping) as trans:
            for p in g.players:
                c = user_input([p],
                               ChooseGirlInputlet(g, mapping),
                               timeout=30,
                               trans=trans)
                c = c or [_c for _c in choices if not _c.chosen][0]
                c.chosen = p
                banned.add(c.char_cls)
                trans.notify('girl_chosen', (p, c))

        assert len(banned) == 4

        g.stats.extend([{
            'event': 'ban',
            'attributes': {
                'gamemode': g.__class__.__name__,
                'character': i.__name__
            }
        } for i in banned])

        chars = [_c for _c in chars if _c not in banned]

        g.random.shuffle(chars)

        if Game.CLIENT_SIDE:
            chars = [None] * len(chars)

        for p in g.players:
            p.choices = [CharChoice(cls) for cls in chars[-4:]]
            p.choices[-1].as_akari = True

            del chars[-4:]

            p.reveal(p.choices)

        g.pause(1)

        mapping = {p: p.choices for p in g.players}
        with InputTransaction('ChooseGirl', g.players,
                              mapping=mapping) as trans:
            ilet = ChooseGirlInputlet(g, mapping)

            @ilet.with_post_process
            def process(p, c):
                c = c or p.choices[0]
                trans.notify('girl_chosen', (p, c))
                return c

            rst = user_input(g.players,
                             ilet,
                             timeout=30,
                             type='all',
                             trans=trans)

        # reveal
        for p, c in rst.items():
            c.as_akari = False
            g.players.reveal(c)
            g.set_character(p, c.char_cls)

        # -------
        for p in g.players:
            log.info(
                u'>> Player: %s:%s %s',
                p.__class__.__name__,
                Identity.TYPE.rlookup(p.identity.type),
                p.account.username,
            )
        # -------

        g.emit_event('game_begin', g)

        for p in g.players:
            g.process_action(DistributeCards(p, amount=4))

        for i, p in enumerate(cycle(pl)):
            if i >= 6000: break
            if not p.dead:
                g.emit_event('player_turn', p)
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        return True
Пример #5
0
 def apply_action(self):
     src, tgt = self.source, self.target
     src.choices.append(CharChoice(tgt.__class__))
     return True
Пример #6
0
    def apply_action(self):
        g = Game.getgame()
        params = self.params

        from thb.cards import Deck

        g.deck = Deck()
        g.ehclasses = []

        # arrange identities -->
        g.double_curtain = params['double_curtain']

        mapping = {
            'B': Identity.TYPE.BOSS,
            '!': Identity.TYPE.ATTACKER,
            '&': Identity.TYPE.ACCOMPLICE,
            '?': Identity.TYPE.CURTAIN,
        }

        if g.double_curtain:
            identities = 'B!!!&&??'
        else:
            identities = 'B!!!!&&?'

        pl = g.players[:]
        identities = [mapping[i] for i in identities]
        g.identities = identities[:]
        imperial_identities = ImperialIdentity.get_chosen(self.items, pl)
        for p, i in imperial_identities:
            pl.remove(p)
            identities.remove(i)

        g.random.shuffle(identities)

        if Game.CLIENT_SIDE:
            identities = [Identity.TYPE.HIDDEN for _ in identities]

        for p, i in imperial_identities + zip(pl, identities):
            p.identity = Identity()
            p.identity.type = i
            g.process_action(RevealIdentity(p, p))

        del identities

        is_boss = sync_primitive(
            [p.identity.type == Identity.TYPE.BOSS for p in g.players],
            g.players)
        boss_idx = is_boss.index(True)
        boss = g.boss = g.players[boss_idx]

        boss.identity = Identity()
        boss.identity.type = Identity.TYPE.BOSS
        g.process_action(RevealIdentity(boss, g.players))

        # choose girls init -->
        from .characters import get_characters
        pl = g.players.rotate_to(boss)

        choices, _ = build_choices(
            g,
            self.items,
            candidates=get_characters('common', 'id', 'id8', '-boss'),
            players=[boss],
            num=[5],
            akaris=[1],
            shared=False,
        )

        choices[boss][:0] = [CharChoice(cls) for cls in get_characters('boss')]

        with InputTransaction('ChooseGirl', [boss], mapping=choices) as trans:
            c = user_input([boss], ChooseGirlInputlet(g, choices), 30,
                           'single', trans)

            c = c or choices[boss][-1]
            c.chosen = boss
            c.akari = False
            g.players.reveal(c)
            trans.notify('girl_chosen', (boss, c))

        chars = get_characters('common', 'id', 'id8')

        try:
            chars.remove(c.char_cls)
        except:
            pass

        # mix it in advance
        # so the others could see it

        boss = g.switch_character(boss, c.char_cls)

        # boss's hp bonus
        if g.n_persons > 5:
            boss.maxlife += 1

        boss.life = boss.maxlife

        # choose boss dedicated skill
        g.process_action(ChooseBossSkillAction(boss, boss))

        # reseat
        seed = get_seed_for(g.players)
        random.Random(seed).shuffle(g.players)
        g.emit_event('reseat', None)

        # others choose girls
        pl = g.players.exclude(boss)

        choices, _ = build_choices(
            g,
            self.items,
            candidates=chars,
            players=pl,
            num=[4] * len(pl),
            akaris=[1] * len(pl),
            shared=False,
        )

        with InputTransaction('ChooseGirl', pl, mapping=choices) as trans:
            ilet = ChooseGirlInputlet(g, choices)
            ilet.with_post_process(
                lambda p, rst: trans.notify('girl_chosen', (p, rst)) or rst)
            result = user_input(pl, ilet, type='all', trans=trans)

        # mix char class with player -->
        for p in pl:
            c = result[p] or choices[p][-1]
            c.akari = False
            g.players.reveal(c)
            p = g.switch_character(p, c.char_cls)

        # -------
        for p in g.players:
            log.info(
                u'>> Player: %s:%s %s',
                p.__class__.__name__,
                Identity.TYPE.rlookup(p.identity.type),
                p.account.username,
            )
        # -------

        g.emit_event('game_begin', g)

        for p in g.players:
            g.process_action(DistributeCards(p, amount=4))

        for i, p in enumerate(cycle(g.players.rotate_to(boss))):
            if i >= 6000: break
            if not p.dead:
                try:
                    g.process_action(PlayerTurn(p))
                except InterruptActionFlow:
                    pass

        return True