def testChooseOptionInputlet(self): from game import autoenv from game.autoenv import user_input from client.core import TheChosenOne, PeerPlayer from thb.thb3v3 import THBattle from thb.inputlets import ChooseOptionInputlet from utils import BatchList autoenv.init('Server') g = THBattle() g.IS_DEBUG = True pl = [create_mock_player([]) for i in xrange(6)] p = pl[0] g.me = p p.client.gdlist.extend([ ['I:ChooseOption:1', True], ['I&:ChooseOption:2', False], ['I|:ChooseOption:3', True], ]) p.client.gdevent.set() g.players = BatchList(pl) hook_game(g) g.gr_groups = WeakSet() ilet = ChooseOptionInputlet(self, (False, True)) eq_(user_input([p], ilet), True) eq_(user_input([p], ilet, type='all'), {p: False}) eq_(user_input([p], ilet, type='any'), (p, True)) for p in pl: eq_(p.client.gdhistory, [ ['RI:ChooseOption:1', True], ['RI&:ChooseOption:2', False], ['RI|:ChooseOption:3', True], ]) autoenv.init('Client') g = THBattle() pl = [PeerPlayer() for i in xrange(6)] svr = MockConnection([ ['RI:ChooseOption:1', True], ['RI&:ChooseOption:2', False], ['RI|:ChooseOption:3', True], ]) p = TheChosenOne(svr) pl[0] = p g.me = p svr.gdevent.set() g.players = BatchList(pl) hook_game(g) assert autoenv.Game.getgame() is g ilet = ChooseOptionInputlet(self, (False, True)) eq_(user_input([p], ilet), True) eq_(user_input([p], ilet, type='all'), {p: False}) eq_(user_input([p], ilet, type='any'), (p, True))
def handle(self, evt_type, act): if evt_type != 'action_before': return act if not isinstance(act, InstantSpellCardAction): return act if isinstance(act, Reject): # HACK return act if ForEach.is_group_effect(act): return act src = act.source tgt = act.target if not src or tgt is src: return act if not tgt.has_skill(ReversedScales): return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act g = Game.getgame() g.process_action(ReversedScalesAction(tgt, act)) return act
def do_effect(self, src, tgt, _type): if not src.has_skill(LoongPunch): return if not (tgt.cards or tgt.showncards): return if not user_input([src], ChooseOptionInputlet(self, (False, True))): return g = Game.getgame() g.process_action(LoongPunchAction(src, tgt, _type))
def handle(self, p, trans): if not p.has_skill(VengeOfTsukumogami) or p.dead: return True if not isinstance(trans.action, DropCards): return True for cards, _from, to, is_bh, _ in trans.get_movements(): if _from is None or _from.type != 'equips': continue if _from.owner is p: continue if to.type != 'droppedcard': continue self.target = tgt = _from.owner for c in cards: self.card = c if tgt.dead: break if not user_input([p], ChooseOptionInputlet( self, (False, True))): break Game.getgame().process_action( VengeOfTsukumogamiAction(p, tgt, c)) return True
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, DropCardStage): self.n = n = act.dropn if n <= 0: return act tgt = act.target if not tgt.has_skill(AutumnWind): return act g = Game.getgame() if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act candidates = [ p for p in g.players if p is not tgt and (p.cards or p.showncards or p.equips) and not p.dead ] pl = candidates and user_choose_players(self, tgt, candidates) if not pl: return act g.process_action(AutumnWindAction(tgt, pl)) return act
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, Damage): g = Game.getgame() src, tgt = act.source, act.target if not (src and src.has_skill(Disarm)): return act if tgt.dead: return act pact = g.action_stack[-1] pcard = getattr(pact, 'associated_card', None) if not pcard: return act if not pcard.is_card(AttackCard) and not (pcard.is_card(DuelCard) and pact.source is src): return act if not user_input([src], ChooseOptionInputlet(self, (False, True))): return act cl = list(tgt.cards) + list(tgt.showncards) g.process_action(ShowCards(tgt, cl, [src])) if g.SERVER_SIDE: l = [bool(c.is_card(AttackCard) or 'spellcard' in c.category) for c in cl] else: l = [False for c in cl] l = sync_primitive(l, g.players) cl = list(itertools.compress(cl, l)) g.process_action(DisarmHideAction(src, tgt, cl)) elif evt_type == 'action_after' and isinstance(act, FinalizeStage): tgt = act.target g = Game.getgame() g.process_action(DisarmReturningAction(tgt, tgt)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance( act, BaseAttack) and not marked(act, 'freaking_power'): src = act.source if not src.has_skill(FreakingPower): return act if not user_input([src], ChooseOptionInputlet(self, (False, True))): return act tgt = act.target Game.getgame().process_action(FreakingPowerAction(act)) elif evt_type == 'action_after' and isinstance(act, Damage): g = Game.getgame() if act.cancelled: return act pact = g.action_stack[-1] if not marked(pact, 'freaking_power'): return act src, tgt = pact.source, act.target if tgt.dead: return act catnames = ('cards', 'showncards', 'equips') card = user_input([src], ChoosePeerCardInputlet(self, tgt, catnames)) if card: g.players.exclude(tgt).reveal(card) g.process_action(DropCards(src, tgt, [card])) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, Damage): if act.cancelled: return act src = act.source tgt = act.target if tgt.has_skill(FourOfAKind) and act.amount <= tgt.life: if user_input([tgt], ChooseOptionInputlet(self, (False, True))): g = Game.getgame() g.process_action(FourOfAKindAction(tgt, act)) if src and src.has_skill(FourOfAKind): g = Game.getgame() for a in reversed(g.action_stack): if isinstance(a, LaunchCard): break else: return act if src.life == 1: act.amount += 1 return act
def apply_action(self): tgt = self.target c = self.card g = Game.getgame() tgt.reveal(c) migrate_cards([c], tgt.cards, unwrap=True) choice = user_input([tgt], ChooseOptionInputlet(self, ('reforge', 'action'))) if choice == 'reforge': g.process_action(TeachTargetReforgeAction(tgt, tgt)) else: act = TeachTargetActionStage(tgt) g.process_action(act) if act.action_count == 1: return False c = random_choose_card([tgt.cards, tgt.showncards, tgt.equips]) if not c: return False g.players.reveal(c) g.process_action(Reforge(tgt, tgt, c)) return True
def apply_action(self): src = self.source tgt = self.target options = ( Card.SPADE, Card.HEART, Card.CLUB, Card.DIAMOND, ) card = self.associated_card detach_cards([card]) suit = user_input([tgt], ChooseOptionInputlet(self, options)) src.tags['surprise_tag'] = src.tags['turn_count'] assert card g = Game.getgame() g.players.reveal(card.associated_cards) migrate_cards([card], tgt.showncards, unwrap=True) if card.suit != suit: g.process_action(Damage(src, tgt)) rst = True else: rst = False return rst
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, Damage): tgt = act.target if tgt.dead: return act if not tgt.has_skill(Echo): return act g = Game.getgame() pact = g.action_stack[-1] card = getattr(pact, 'associated_card', None) if not card or not card.is_card(PhysicalCard): return act if not card.detached or card.unwrapped: return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act attack = card.is_card(AttackCard) pl = attack and user_choose_players( self, tgt, [p for p in g.players if not p.dead]) p = pl[0] if pl else tgt g.process_action(EchoAction(tgt, p, card)) return act
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
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
def handle(self, evt_type, act): if evt_type == 'action_before' and hasattr(act, 'associated_card'): g = Game.getgame() lc = g.action_stack[-1] for lc in reversed(g.action_stack): if isinstance(lc, (LaunchCard, LaunchFatetellCard)) and lc.card_action is act: break else: return act me = g.current_player if not me or not me.has_skill(Tianyi): return act while True: if isinstance(act, SpellCardAction): break if isinstance(act, ForEach) and issubclass(act.action_cls, SpellCardAction): break # Another HACK return act if ttags(me)['mima_tianyi']: return act if not user_input([me], ChooseOptionInputlet(self, (False, True))): return act g.process_action(TianyiAction(me, lc)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, Damage): if act.cancelled: return act src, tgt = act.source, act.target if not (src and src.has_skill(PerfectFreeze)): return act g = Game.getgame() for lc in reversed(g.action_stack): if isinstance(lc, LaunchCard): break else: return act if src is not lc.source: return act c = lc.card if not c.is_card(AttackCard) and not c.is_card(DuelCard): return act if not user_input([src], ChooseOptionInputlet(self, (False, True))): return act g.process_action(PerfectFreezeAction(src, tgt, act)) return act
def apply_action(self): src, tgt = self.source, 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, tgt.equips]) g.players.reveal(c) g.process_action(DropCards(src, tgt, [c])) action = 'draw' if tgt.life < tgt.maxlife: action = user_input([tgt], ChooseOptionInputlet(self, ('heal', 'draw'))) or 'draw' if action == 'heal': g.process_action(EirinHeal(src, tgt)) else: g.deck.getcards(3) g.deck.cards.rotate(3) cl = g.deck.getcards(3) g.process_action(ShowCards(tgt, cl)) drop = [c for c in cl if 'basic' in c.category] get = [c for c in cl if c not in drop] if get: migrate_cards(get, tgt.cards) if drop: migrate_cards(drop, g.deck.droppedcards) ttags(src)['sky_silk'] = True return True
def fire(self, src, tgt, cards): self.target = tgt # for ui if not user_input([src], ChooseOptionInputlet(self, (False, True))): return g = Game.getgame() g.process_action(DollBlastAction(src, tgt, cards))
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, basic.Attack): src = act.source if not src.has_skill(HouraiJewelSkill): return act if isinstance(act, HouraiJewelAttack): return act if user_input([src], ChooseOptionInputlet(self, (False, True))): act.__class__ = classmix(HouraiJewelAttack, act.__class__) return act
def handle(self, evt_type, act): if evt_type == 'action_apply' and isinstance(act, PlayerTurn): tgt = act.target if not tgt.has_skill(Prophet): return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(ProphetAction(tgt, tgt)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, FatetellStage): tgt = act.target if not tgt.has_skill(TreasureHunt): return act g = Game.getgame() while True: if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act if not g.process_action(TreasureHuntAction(tgt, tgt)): return act return act
def handle(self, evt_type, act): if evt_type == 'fatetell': tgt = act.target if not tgt.has_skill(YinYangOrbSkill): return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act g = Game.getgame() g.process_action(YinYangOrb(act)) return act
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, Heal): tgt = act.target if not tgt.has_skill(MahjongDrug): return act card = getattr(act, 'associated_card', None) if not card or not card.is_card(HealCard): return act if user_input([tgt], ChooseOptionInputlet(self, (False, True))): Game.getgame().process_action(MahjongDrugAction(tgt, tgt)) return act
def apply_action(self): src, tgt = self.source, self.target g = Game.getgame() has_card = src.cards or src.showncards or src.equips if has_card and user_input([tgt], ChooseOptionInputlet(self, ('drop', 'draw'))) == 'drop': g.process_action(KanakoFaithCounteract(tgt, src)) else: g.process_action(KanakoFaithCheers(tgt, src)) return True
def apply_action(self): g = Game.getgame() tgt = self.target place = user_input([tgt], ChooseOptionInputlet(self, ('top', 'bottom'))) sk = self.card assert sk.is_card(LunaString) c = sk.associated_cards[0] sk.associated_cards[:] = [] sk.cost_detached = True self.place = place # for ui migrate_cards([c], g.deck.cards, unwrap=True, front=(place == 'top')) return True
def process(self, src, tgt): if src is None or tgt is None: return if not src.has_skill(Rosa): return if not tgt.cards: return if user_input([src], ChooseOptionInputlet(self, (False, True))): g = Game.getgame() g.process_action(MindReadEffect(src, tgt))
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, Damage): tgt = act.target if tgt.dead: return act if not tgt.has_skill(M*******t): return act if not act.amount: return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(MasochistAction(tgt, act.amount)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, spellcard.SpellCardAction): tgt = act.target if not tgt.has_skill(MaidenCostume): return act if act.cancelled: return act if isinstance(act, spellcard.Reject): return act # can't respond to reject if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(MaidenCostumeAction(tgt, act)) return act
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, Damage): src, tgt = act.source, act.target if not src: return act if not src.has_skill(ReimuClear): return act if src is tgt: return act if src.dead or tgt.dead: return act if user_input([src], ChooseOptionInputlet(self, (False, True))): g = Game.getgame() g.process_action(ReimuClearAction(src, tgt)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, basic.BaseAttack): if act.cancelled: return act src = act.source if not src.has_skill(HakuroukenSkill): return act card = act.associated_card if not card.suit == Card.CLUB: return act if not user_input([src], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(Hakurouken(src, act.target)) return act
def handle(self, evt_type, act): from .basic import BaseAttack if not evt_type == 'action_after': return act if not isinstance(act, BaseAttack): return act if not act.succeeded: return act src = act.source tgt = act.target if tgt.dead: return act if not tgt.cards: return act if not src.has_skill(NenshaPhoneSkill): return act if not user_input([src], ChooseOptionInputlet(self, (False, True))): return act g = Game.getgame() g.process_action(NenshaPhone(src, tgt)) return act