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
def apply_action(self): g = Game.getgame() from . import cards g.pick_history = [] g.deck = cards.Deck(cards.kof_card_definition) g.ehclasses = [] g.current_player = None for i, p in enumerate(g.players): p.identity = Identity() p.identity.type = (Identity.TYPE.HAKUREI, Identity.TYPE.MORIYA)[i % 2] # choose girls --> from thb.characters import get_characters chars = get_characters('common', 'kof') A, B = roll(g, self.items) order = [A, B, B, A, A, B, B, A, A, B] choices, imperial_choices = build_choices( g, self.items, candidates=chars, players=[A, B], num=10, akaris=4, shared=True, ) chosen = {A: [], B: []} with InputTransaction('ChooseGirl', g.players, mapping=choices) as trans: for p, c in imperial_choices: c.chosen = p chosen[p].append(c) trans.notify('girl_chosen', (p, c)) order.remove(p) for p in order: c = user_input([p], ChooseGirlInputlet(g, choices), 10, 'single', trans) c = c or first(choices[p], lambda c: not c.chosen) c.chosen = p chosen[p].append(c) trans.notify('girl_chosen', (p, c)) # reveal akaris for themselves for p in [A, B]: for c in chosen[p]: c.akari = False p.reveal(c) del c.chosen list_shuffle(chosen[A], A) list_shuffle(chosen[B], B) with InputTransaction('ChooseGirl', g.players, mapping=chosen) as trans: ilet = ChooseGirlInputlet(g, chosen) ilet.with_post_process(lambda p, rst: trans.notify('girl_chosen', (p, rst)) or rst) rst = user_input([A, B], ilet, type='all', trans=trans) def s(p): c = rst[p] or chosen[p][0] chosen[p].remove(c) p.choices = chosen[p] p.remaining = [2] p = g.next_character(p, c) return p A, B = s(A), s(B) order = [1, 0] if A is g.players[0] else [0, 1] for p in [A, B]: g.process_action(RevealIdentity(p, g.players)) g.emit_event('game_begin', g) g.process_action(DistributeCards(A, amount=4)) g.process_action(DistributeCards(B, amount=3)) for i in order: g.emit_event('character_debut', (None, g.players[i])) for i, idx in enumerate(cycle(order)): p = g.players[idx] if i >= 6000: break if p.dead: KOFCharacterSwitchHandler.do_switch_dead() p = g.players[idx] # player changed assert not p.dead try: g.emit_event('player_turn', p) g.process_action(PlayerTurn(p)) except InterruptActionFlow: pass
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