def apply_action(self): g = Game.getgame() card = self.associated_card target = self.target equips = target.equips g = Game.getgame() cat = card.equipment_category if cat == 'weapon': weapons = [e for e in equips if e.equipment_category == 'weapon'] if len(weapons) > 1: e = user_input( [target], ChooseIndividualCardInputlet(self, weapons), ) or random_choose_card([weapons]) g.process_action(DropCards(target, [e])) weapons.remove(e) weapons.append(card) cls = set([i.__class__ for i in weapons]) l = set([HakuroukenCard, RoukankenCard]) if cls == l and not target.has_skill(Xianshiwangzhi): g.process_action(XianshiwangzhiAwake(target, target)) else: for oc in equips: if oc.equipment_category == cat: g.process_action(DropCards(target, [oc])) break migrate_cards([card], target.equips) return True
def apply_action(self): tags = self.target.tags tags['lunaclock'] = True Game.getgame().process_action(ActionStage(self.target)) tags['lunaclock'] = False tags['turn_count'] += 1 return True
def apply_action(self): g = Game.getgame() card = self.associated_card target = self.target equips = target.equips g = Game.getgame() cat = card.equipment_category with MigrateCardsTransaction(self) as trans: if cat == 'weapon': weapons = [e for e in equips if e.equipment_category == 'weapon'] if len(weapons) > 1: e = user_input( [target], ChooseIndividualCardInputlet(self, weapons), ) or random_choose_card([weapons]) migrate_cards([e], g.deck.droppedcards, unwrap=True, trans=trans) else: for oc in equips: if oc.equipment_category == cat: migrate_cards([oc], g.deck.droppedcards, unwrap=True, trans=trans) break migrate_cards([card], target.equips, trans=trans) return True
def handle(self, evt_type, arg): if evt_type == 'character_debut': old, new = arg if new.has_skill(DarknessKOF): g = Game.getgame() g.process_action(DarknessKOFAction(new, new)) elif evt_type == 'action_shootdown' and isinstance(arg, LaunchCard): src = arg.source if not src: return arg g = Game.getgame() opp = g.get_opponent(arg.source) if opp.tags['darkness_kof_tag'] < g.turn_count: return arg card = arg.card if not card.is_card(PhysicalCard): return arg if card.is_card(RejectCard): return arg # XXX: DollControl's second target do not count as target # but in KOF the second target is always the launcher, # and never be the opp, so the handle can be same. if opp in arg.target_list: raise DarknessKOFLimit return arg
def handle(self, evt_type, arg): if evt_type == 'card_migration': act, l, _from, to = arg # (action, cardlist, from, to) p = _from.owner if p and p.has_skill(Luck) and not p.dead and not (p.cards or p.showncards): Game.getgame().process_action(LuckDrawCards(p, 2)) return arg
def handle(self, p, trans): if not p.has_skill(VengeOfTsukumogami): 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': return act if not isinstance(act, PlayerDeath): return act g = Game.getgame() tgt = act.target force = tgt.force if len(force.pool) <= 1: forces = g.forces[:] forces.remove(force) g.winners = forces[0][:] raise GameEnded g = Game.getgame() pool = tgt.force.pool assert pool mapping = {tgt: pool} with InputTransaction('ChooseGirl', [tgt], mapping=mapping) as trans: c = user_input([tgt], ChooseGirlInputlet(g, mapping), timeout=30, trans=trans) c = c or [_c for _c in pool if not _c.chosen][0] c.chosen = tgt pool.remove(c) trans.notify('girl_chosen', c) tgt = g.switch_character(tgt, c) g.process_action(DrawCards(tgt, 4)) if user_input([tgt], ChooseOptionInputlet(self, (False, True))): g.process_action(RedrawCards(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() 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 apply_action(self): tgt, victim = self.target, self.victim if tgt.dead: return False g = Game.getgame() sel = ShipwreckChooseCard(tgt, victim) g.process_action(sel) c = sel.card tgt.reveal(c) migrate_cards([c], tgt.cards, unwrap=True) n = self.dropn if n <= 0: g.process_action(ShipwreckBrokenScoop(tgt, victim)) return True g = Game.getgame() cards = user_choose_cards(self, tgt, ('cards', 'showncards')) if not cards: from itertools import chain cards = list(chain(tgt.cards, tgt.showncards))[min(-n, 0):] g.process_action(ShipwreckEffect(tgt, victim, cards)) return True
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, PlayerDeath): g = Game.getgame() tgt = act.target if tgt is not g.koakuma: return act hakurei, moriya = g.forces books = lambda force: sum(p.tags['books'] for p in force) nh, nm = books(hakurei), books(moriya) if nh > nm: g.winners = hakurei elif nh < nm: g.winners = moriya else: g.winners = hakurei + moriya g.game_end() elif evt_type == 'action_after' and isinstance(act, Damage): g = Game.getgame() hakurei, moriya = g.forces books = lambda force: sum(p.tags['books'] for p in force) if books(hakurei) >= g.total_books: g.winners = hakurei g.game_end() elif books(moriya) >= g.total_books: g.winners = moriya g.game_end() return act
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
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, spellcard.Sinsack): tgt = act.target if tgt.has_skill(KeystoneSkill): Game.getgame().process_action(Keystone(act)) return act
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
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(IbukiGourdSkill): return act g = Game.getgame() ttags(src)['ibukigourd_did_damage'] = True elif evt_type == 'action_apply' and isinstance(act, FinalizeStage): tgt = act.target if not tgt.has_skill(IbukiGourdSkill): return act g = Game.getgame() if ttags(tgt)['ibukigourd_did_damage']: return act g.process_action(basic.Wine(tgt, tgt)) elif evt_type == 'card_migration': from .definition import IbukiGourdCard act, cl, _from, to, _ = arg = act if not any(c.is_card(IbukiGourdCard) for c in cl): return arg if to.type != 'equips': return arg tgt = to.owner g = Game.getgame() g.process_action(basic.Wine(tgt, tgt)) return arg 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 = [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 apply_action(self): self.act.cancelled = True _from, _to = self.pl tgt = self.target from itertools import chain allcards = list(chain.from_iterable([_from.equips, _from.fatetell])) if not allcards: # Dropped by Exinwan return False card = user_input([tgt], ChooseIndividualCardInputlet(self, allcards)) if not card: card = random_choose_card([_from.equips, _from.fatetell]) if card.resides_in is _from.fatetell: if user_input([tgt], ChooseOptionInputlet(self, (False, True))): migrate_cards([card], _to.fatetell) else: migrate_cards([card], _to.cards, unwrap=True) elif card.resides_in is _from.equips: cats = set([c.equipment_category for c in _to.equips]) migrate_cards([card], _to.cards) if card.equipment_category not in cats: if user_input([tgt], ChooseOptionInputlet(self, (False, True))): Game.getgame().process_action( LaunchCard(_to, [_to], card) ) else: assert False, 'WTF?!' return True
def handle(self, evt_type, arg): if evt_type == 'choose_target': act, tl = arg src = act.source if not src.has_skill(Library): return arg if 'instant_spellcard' in act.card.category: Game.getgame().process_action(LibraryDrawCards(src, 1)) return arg # elif evt_type == 'action_before' and isinstance(arg, Reject): # act = arg.target_act # src = act.source # if arg.source is src: return arg # if not src.has_skill(Library): return arg # Game.getgame().process_action(LibraryDrawCards(src, 1)) # return arg elif evt_type == 'calcdistance': src, card, dist = arg if not src.has_skill(Library): return arg if 'spellcard' not in card.category: return arg for p in dist: dist[p] -= 10000 return arg
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, DropCardStage): tgt = act.target if tgt.has_skill(SuwakoHatSkill): Game.getgame().process_action(SuwakoHatEffect(tgt, act)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, BaseAttack): pact = ForEach.get_actual_action(act) or act if getattr(pact, 'in_wine', False): act.damage += 1 elif evt_type == 'post_choose_target': act, tl = arg = act from ..cards import AttackCard if act.card.is_card(AttackCard): src = act.source if src.tags['wine']: Game.getgame().process_action(SoberUp(src, src)) act.card_action.in_wine = True return arg elif evt_type == 'action_apply' and isinstance(act, PlayerTurn): src = act.target if src.tags['wine']: Game.getgame().process_action(SoberUp(src, src)) elif evt_type == 'action_before' and isinstance(act, Damage): if act.cancelled: return act if act.amount < 1: return act tgt = act.target if act.amount >= tgt.life and tgt.tags['wine']: g = Game.getgame() g.process_action(WineRevive(act)) return act
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, InstantSpellCardAction): if isinstance(act, Reject): return act g = Game.getgame() target = g.current_turn for p in g.players.exclude(target): if p.dead: continue if not p.has_skill(ExtremeIntelligence): continue if p.tags['ran_ei'] >= p.tags['turn_count'] + 1: continue try: tl = act.target_list except AttributeError: tl = [act.target] if any(t.dead for t in tl): return act if not user_input([p], ChooseOptionInputlet(self, (False, True))): continue g.process_action(ExtremeIntelligenceAction(p, act.target, act)) elif evt_type == 'game_begin': g = Game.getgame() for p in g.players: if isinstance(p, Ran): p.tags['ran_ei'] = 0 # for ui return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, LaunchCard): card = act.card if not card.is_card(HarvestCard): return act g = Game.getgame() pl = [p for p in g.players if p.has_skill(AkiTribute) and not p.dead] assert len(pl) <= 1, 'Multiple AkiTributes!' if not pl: return act p = pl[0] tl = act.target_list if not p in tl: return act tl.remove(p) tl.insert(0, p) elif evt_type == 'harvest_finish': g = Game.getgame() pl = [p for p in g.players if p.has_skill(AkiTribute) and not p.dead] assert len(pl) <= 1, 'Multiple AkiTributes!' if not pl: return act p = pl[0] migrate_cards([ c for c in act.cards if c.resides_in is g.deck.disputed ], p.showncards) return act
def handle(self, evt_type, act): if evt_type == 'action_apply' and isinstance(act, ActionStage): tgt = act.target if not tgt.has_skill(self.skill): return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(self.action(tgt, tgt)) return act
def handle(self, evt_type, act): if evt_type == "action_before" and isinstance(act, spellcard.SinsackCarnivalEffect): target = act.target if not act.cancelled and target.has_skill(MaidenCostumeSkill): act.cancelled = True nact = MaidenCostumeEffect(source=act.source, target=target) nact.associated_card = act.associated_card Game.getgame().process_action(nact) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, SpellCardAction) and not act.cancelled: tgt = act.target if tgt.has_skill(Knowledge): c = getattr(act, 'associated_card', None) if c and c.suit == Card.SPADE and not c.is_card(RejectCard): Game.getgame().process_action(KnowledgeAction(act)) return act
def handle(self, evt_type, arg): from .base import VirtualCard, HiddenCard from .definition import ExinwanCard if evt_type == 'card_migration': act, cards, _from, to, is_bh = arg # someone is getting the ExinwanCard if to.owner is not None: for c in VirtualCard.unwrap(cards): # Exinwan may be HiddenCard here c.exinwan_target = None return arg # move from None to None do not affect Exinwan's target # (including moving detached cards to None) if _from is None or _from.owner is None or is_bh: return arg # do not active when distributing cards if isinstance(act, DistributeCards): return arg # someone is dropping the ExinwanCard for c in VirtualCard.unwrap(cards): # Exinwan may be HiddenCard here c.exinwan_target = act.source return arg elif evt_type == 'post_card_migration': dropcl = [cl for cl, _, to, _ in arg.get_movements() if to.type == 'droppedcard'] def invalid(c): return c.is_card(VirtualCard) or c.is_card(HiddenCard) # cards to dropped area should all unwrapped assert not any(invalid(c) for cl in dropcl for c in cl) cards = [c for cl in dropcl for c in cl if c.is_card(ExinwanCard)] # no same card dropped twice in the same transaction assert len(cards) == len(set(cards)) for c in cards: tgt = getattr(c, 'exinwan_target', None) if tgt: act = ExinwanEffect(tgt, tgt) act.associated_card = c Game.getgame().process_action(act) return arg
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, PlayerTurn): tgt = act.target if tgt.dead or not tgt.has_skill(Ashes): return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(AshesAction(tgt)) return act
def handle(self, evt_type, act): if evt_type == "action_before" and isinstance(act, basic.BaseAttack): src, tgt = act.source, act.target if tgt.cards or tgt.showncards: return act if not src.has_skill(DeathSickleSkill): return act Game.getgame().process_action(DeathSickle(act)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, Damage): if not act.target.has_skill(UmbrellaSkill): return act g = Game.getgame() pact = g.action_stack[-1] if isinstance(pact, spellcard.SpellCardAction): Game.getgame().process_action(UmbrellaEffect(pact, act)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, DrawCardStage): if act.cancelled: return act tgt = act.target if not tgt.has_skill(CriticalStrike): return act if not user_input([tgt], ChooseOptionInputlet(self, (False, True))): return act Game.getgame().process_action(CriticalStrikeAction(tgt, tgt)) act.amount = max(0, act.amount - 1) elif evt_type == 'action_apply' and isinstance(act, BaseAttack): src = act.source tags = src.tags if not self.in_critical_strike(src): return act tgt = act.target if isinstance(act, BaseAttack): tags['flan_targets'].append(tgt) act.damage += 1 elif evt_type == 'action_before' and isinstance(act, Damage): g = Game.getgame() pact = g.action_stack[-1] if not isinstance(pact, BaseDuel): return act src, tgt = act.source, act.target if not self.in_critical_strike(src): return act act.amount += 1 elif evt_type == 'action_shootdown': if not isinstance(act, ActionStageLaunchCard): return act c = act.card src = act.source tags = src.tags if not self.in_critical_strike(src): return act if not c.is_card(AttackCard): return act if src.has_skill(ElementalReactorSkill): return act if set(act.target_list) & set(tags['flan_targets']): raise CriticalStrikeLimit return act elif evt_type == 'action_stage_action': tgt = act if not self.in_critical_strike(tgt): return act AttackCardHandler.set_freeattack(tgt) 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): g = Game.getgame() c = self.card ft = self.ft src = self.source g.players.exclude(src).reveal(c) with MigrateCardsTransaction(self) as trans: migrate_cards([ft.card], src.cards, unwrap=True, trans=trans, is_bh=True) detach_cards([c], trans=trans) self.ft.set_card(c, self) return True
def apply_action(self): g = Game.getgame() target = self.target card = self.card act = card.delayed_action assert act a = act(source=target, target=target) a.associated_card = card self.card_action = a g.process_action(a) a.fatetell_postprocess() return True
def handle(self, evt_type, arg): if evt_type != 'post_card_migration': return arg g = Game.getgame() act = arg.action tgt = act.target or act.source or g.players[0] for p in g.players_from(tgt): for eh in self.handlers: g.handle_single_event(eh, p, arg) return arg
def apply_action(self): g = Game.getgame() p = self.target p.tags['turn_count'] += 1 g.current_turn = p g.process_action(FatetellStage(p)) g.process_action(DrawCardStage(p)) g.process_action(ActionStage(p)) g.process_action(DropCardStage(p)) return True
def apply_action(self): g = Game.getgame() src = self.source tgt = self.target c = user_input([src], ChoosePeerCardInputlet(self, tgt, ('cards', 'showncards'))) c = c or random_choose_card([tgt.cards, tgt.showncards]) if not c: return False g.players.exclude(tgt).reveal(c) g.process_action(DropCards(tgt, [c])) return True
def handle(self, evt_type, act): if not evt_type == 'action_after': return act if not isinstance(act, BaseDamage): return act g = Game.getgame() tgt = act.target if tgt is not g.mutant: return act if tgt.morphed: return act if tgt.life <= tgt.__class__.maxlife // 2: raise MutantMorph return act
def handle(self, evt_type, arg): if evt_type == 'character_debut': old, new = arg if not old: return arg if not getattr(old, 'support_cl', None): return arg g = Game.getgame() g.process_action(SupportKOFReturningAction(old, new)) elif evt_type == 'action_apply' and isinstance(arg, PlayerDeath): tgt = arg.target if not tgt.has_skill(SupportKOF): return arg if not (tgt.cards or tgt.showncards or tgt.equips): return arg if user_input([tgt], ChooseOptionInputlet(self, (False, True))): g = Game.getgame() g.process_action(SupportKOFAction(tgt, tgt)) return arg
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 handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, BaseAttack): src = act.source g = Game.getgame() for pact in reversed(g.action_stack): if isinstance(pact, LaunchCard): break else: return act if getattr(pact, 'in_wine', False): act.damage += 1 elif evt_type == 'action_before' and isinstance(act, LaunchCard): from ..cards import AttackCard if act.card.is_card(AttackCard): src = act.source if src.tags['wine']: Game.getgame().process_action(SoberUp(src, src)) act.in_wine = True elif evt_type == 'action_apply' and isinstance(act, PlayerTurn): src = act.target if src.tags['wine']: Game.getgame().process_action(SoberUp(src, src)) elif evt_type == 'action_before' and isinstance(act, Damage): if act.cancelled: return act if act.amount < 1: return act tgt = act.target if act.amount >= tgt.life and tgt.tags['wine']: g = Game.getgame() g.process_action(WineRevive(act)) return act
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, InstantSpellCardAction): if isinstance(act, Reject): return act g = Game.getgame() target = g.current_player for p in g.players.exclude(target): if p.dead: continue if not p.has_skill(ExtremeIntelligence): continue if p.tags['ran_ei'] >= p.tags['turn_count'] + 1: continue try: tl = act.target_list except AttributeError: tl = [act.target] if any(t.dead for t in tl): return act if not act.can_fire(): return act # act cannot fire again nact = ExtremeIntelligenceAction(p, act.target, act) if nact.activate_action(): g.process_action(nact) elif evt_type == 'game_begin': g = Game.getgame() for p in g.players: if isinstance(p, Ran): p.tags['ran_ei'] = 0 # for ui return act
def handle(self, evt_type, arg): if evt_type == 'card_migration': act, cards, _from, to, _ = arg if isinstance(act, (DistributeCards, DrawCardStage)): return arg if to is None or not to.owner: return arg if to.type not in ('cards', 'showncards', 'equips'): return arg if _from is not None and _from.owner is to.owner: return arg g = Game.getgame() a, b = g.players if not a.has_skill(SanaeFaithKOF): a, b = b, a if not a.has_skill(SanaeFaithKOF): return arg if b is not to.owner: return arg turn = PlayerTurn.get_current() if not turn: return arg stage = turn.current_stage if stage.target is not b or not isinstance(stage, ActionStage): return arg g = Game.getgame() g.process_action(SanaeFaithKOFDrawCards(a, 1)) return arg
def handle(self, evt_type, act): if evt_type == 'action_before': if isinstance(act, Attack): if not act.source.has_skill(Mijincihangzhan): return act act.__class__ = classmix(MijincihangzhanAttack, act.__class__) act.graze_count = 0 elif isinstance(act, BaseDuel): if not isinstance(act, MijincihangzhanDuelMixin): act.__class__ = classmix(MijincihangzhanDuelMixin, act.__class__) elif evt_type == 'action_apply' and isinstance(act, ActionStage): p = act.target p.tags['vitality'] += bool( p.has_skill(Nitoryuu) and self.weapons(p) >= 2) elif evt_type == 'card_migration': act, cards, _from, to, _ = arg = act for cl in (_from, to): if cl.type != 'equips': continue p = cl.owner if not p.has_skill(Nitoryuu): continue n = self.weapons(p) dn = len(cards) if not any( getattr(c, 'equipment_category', None) == 'weapon' for c in cards): continue if cl is _from and (dn + n) >= 2 and n <= 1: adjust = -1 elif cl is to and (n - dn) <= 1 and n >= 2: adjust = 1 else: adjust = 0 p.tags['vitality'] += adjust return arg elif evt_type == 'attack_aftergraze': act, rst = arg = act if rst: return arg if not isinstance(act, MijincihangzhanAttack): return arg g = Game.getgame() return act, not g.process_action(LaunchGraze(act.target)) return act
def __init__(self, irp, *a, **k): Control.__init__(self, *a, **k) parent = self.parent self.irp = irp assert isinstance(irp, IRP) self.x, self.y, self.width, self.height = (285, 162, 531, 58) self.confirmbtn = ConfirmButtons(parent=self, x=259, y=4, width=165, height=24, buttons=((u'确定', True), (u'结束', False))) self.progress_bar = b = BigProgressBar(parent=self, x=0, y=0, width=250) b.value = LinearInterp(1.0, 0.0, irp.timeout, on_done=lambda *a: self.cleanup()) self.label = lbl = ShadowedLabel( text=u"HEY SOMETHING'S WRONG", x=125, y=28, font_size=12, color=(255, 255, 160, 255), shadow_color=(0, 0, 0, 179), anchor_x='center', anchor_y='bottom', ) @self.confirmbtn.event def on_confirm(is_ok): irp = self.irp irp.input = self.get_result() if is_ok else None irp.complete() #self.cleanup() return def dispatch_selection_change(): self.confirmbtn.buttons[0].state = Button.DISABLED self.on_selection_change() parent.push_handlers(on_selection_change=dispatch_selection_change) g = Game.getgame() port = parent.player2portrait(g.me) port.equipcard_area.clear_selection()
def __init__(self, trans, *a, **k): self.trans = trans self.pbar = None self.selecting = False g = Game.getgame() choices = trans.mapping[g.me] n_choices = len(choices) cols = 5 if n_choices > 16 else 4 rows = max((n_choices - 1) / cols + 1, 4) w, h = 20 + cols * 160, 51 + rows * 113 + 30 Panel.__init__(self, width=w, height=h, zindex=5, *a, **k) p = self.parent pw, ph = p.width, p.height self.x, self.y = (pw - w) / 2, (ph - h) / 2 self.inputlet = None choices = self.choices = [ c for c in choices if c.char_cls and not getattr(c, 'chosen', False) ] self.selectors = selectors = [] for i, c in enumerate(choices): y, x = divmod(i, cols) x, y = 15 + 160 * x, 45 + 113 * (rows - 1 - y) gs = GirlSelector(c, selectors, parent=self, hover_pic=self.hover_pic, x=x, y=y) @gs.event def on_dblclick(gs=gs): c = gs.choice ilet = self.inputlet if not c.chosen and ilet: ilet.set_choice(c) ilet.done() self.end_selection() selectors.append(gs) self.label = Label(text='等待其他玩家操作', x=w // 2, y=51 + rows * 113, font_size=12, color=(255, 255, 160, 255), shadow=(2, 0, 0, 0, 230), anchor_x='center', anchor_y='bottom')
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, FatetellStage): self.target = tgt = act.target if not tgt.has_skill(Reborn): return act cards = user_choose_cards(self, tgt, ('cards', 'showncards', 'equips')) if cards: g = Game.getgame() g.process_action(DropCards(tgt, tgt, cards)) if not tgt.dead: # Ensure no ui action_effect_after (str | se) after drop Exinwan causing fall g.process_action(RebornAction(tgt)) return act
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): g = Game.getgame() pact = g.action_stack[-1] src, tgt = act.source, act.target if ForEach.is_group_effect(pact): return act if src is tgt: return act self.process(src, tgt) self.process(tgt, src) 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, arg): if evt_type == 'calcdistance': src, card, dist = arg if not src.has_skill(Riverside): return arg for p in dist: if p.tags['riverside_target']: dist[p] -= 10000 elif evt_type == 'action_after' and isinstance(arg, PlayerTurn): for p in Game.getgame().players: p.tags['riverside_target'] = False return arg
def apply_action(self): src = self.source g = Game.getgame() g.process_action(DrawCards(src, 1)) turn = PlayerTurn.get_current(src) try: turn.pending_stages.remove(DropCardStage) except Exception: pass return True
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, Damage): from .basic import Attack g = Game.getgame() pact = g.action_stack[-1] if not isinstance(pact, Attack): return act src = act.source if not src or not src.has_skill(DeathSickleSkill): return act tgt = act.target if len(tgt.cards) + len(tgt.showncards) == 0: g.process_action(DeathSickle(act)) return act
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
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] 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
def apply_action(self): src = self.source tgt = self.target g = Game.getgame() tgt.maxlife += self.amount if tgt.life > tgt.maxlife: g.process_action(LifeLost(src, tgt, abs(tgt.life - tgt.maxlife))) assert tgt.life == tgt.maxlife assert tgt.maxlife or tgt.dead return True
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, FinalizeStage): tgt = act.target if not tgt.has_skill(KanakoFaithKOF): return act g = Game.getgame() op = g.get_opponent(tgt) if tgt.life > op.life or ttags(tgt)['kanako_faith_kof']: n = tgt.life - (len(tgt.cards) + len(tgt.showncards)) if n > 0: g.process_action(KanakoFaithKOFAction(tgt, n)) elif evt_type == 'action_apply' and isinstance(act, Damage): src, tgt = act.source, act.target g = Game.getgame() if src and src.has_skill(KanakoFaithKOF) and tgt is g.get_opponent(src): ttags(src)['kanako_faith_kof'] = True return act
def apply_action(self): g = Game.getgame() src = self.source use_faith(src, 1) act = self.dmgact act.cancelled = True g.process_action(LifeLost(src, src, act.amount)) g.process_action(CollectFaith(g.mutant, g.mutant, 1)) return True
def apply_action(self): g = Game.getgame() src = self.source pl = [p for p in g.players if not p.dead and p.life < p.maxlife] if not pl: return False beneficiary, = user_choose_players(self, src, pl) or (None, ) if beneficiary is None: return False g.process_action(LittleLegionCoverEffect(src, beneficiary, 1)) return True
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, FatetellStage): tgt = act.target g = Game.getgame() from .definition import SinsackHatCard for c in list(tgt.equips): if not c.is_card(SinsackHatCard): continue g.process_action(SinsackHatAction(tgt, tgt, c)) return act return act
def on_game_event(self, evt_type, arg): if evt_type == 'action_after' and isinstance(arg, actions.RevealIdentity): act = arg g = Game.getgame() me = g.me if (act.target in (self.player, self.character)) and (me in act.to if isinstance(act.to, list) else me is act.to): self.update_identity(self.character or self.player) elif evt_type == 'switch_character': old, new = arg if new.player is self.player: self.character = new self.update()
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