def is_valid(self): src = self.source card = self.associated_card.associated_cards[0] if card.is_card(AttackCard) and src.tags['attack_num'] < 1: if not AttackCardHandler.is_freeattack(src): return False if card.usage != 'launch': return False victim = self.target tgts = self.target_list[1:] lc = LaunchCard(victim, tgts, card) return lc.can_fire()
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_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, arg): if evt_type == 'character_debut': old, new = arg if not new.has_skill(AssaultKOF): return arg g = Game.getgame() op = g.get_opponent(new) lc = LaunchCard(new, [op], AssaultAttack(new)) if not lc.can_fire(): return arg if user_input([new], ChooseOptionInputlet(self, (False, True))): g.process_action(lc) return arg
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
def apply_action(self): src, lc = self.source, self.action assert isinstance(lc, (LaunchCard, LaunchFatetellCard)) lc.card_action.cancelled = True ttags(src)['mima_tianyi'] = True if isinstance(lc, LaunchCard): # HACK! RejectCard has no target, but not implemented this way. if lc.force_action and isinstance(lc.force_action, Reject): return True lst = lc.target_list[:] elif isinstance(lc, LaunchFatetellCard): lst = [lc.target] else: assert False, 'WTF?!' g = Game.getgame() for p in lst: g.process_action( LaunchCard(src, [p], TianyiAttack(src), bypass_check=True)) return True
def apply_action(self): src, tgt = self.source, self.target g = Game.getgame() src.tags['suika_target'].append(tgt) if g.process_action(Pindian(src, tgt)): g.process_action( LaunchCard(src, [src], HeavyDrinkerWine(src), bypass_check=True)) g.process_action( LaunchCard(tgt, [tgt], HeavyDrinkerWine(src), bypass_check=True)) else: src.tags['suika_failed'] = src.tags['turn_count'] return True
def apply_action(self): src, tgt, c = self.source, self.target, self.card g = Game.getgame() g.process_action(Reforge(src, src, c)) g.process_action( LaunchCard(src, [tgt], XianshizhanAttackCard(src), bypass_check=True)) return True
def is_valid(self): tags = self.source.tags if tags['turn_count'] <= tags['darkness_tag']: return False attacker, victim = self.target_list if not LaunchCard(attacker, [victim], AttackCard()).can_fire(): return False return True
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
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
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): g = Game.getgame() src = self.source pl = [p for p in g.players if not p.dead] attacker, victim = user_choose_players(self, src, pl) or (None, None) if attacker is None: return False self.target_list = attacker, victim g.process_action( LaunchCard(src, [attacker, victim], LittleLegionDollControlCard(attacker))) return True
def apply_action(self): attacker, victim = self.target_list src = self.source g = Game.getgame() tags = self.source.tags tags['darkness_tag'] = tags['turn_count'] cards = user_choose_cards(self, attacker, ('cards', 'showncards')) if cards: c = cards[0] g.process_action(LaunchCard(attacker, [victim], c)) else: g.process_action(Damage(src, attacker, 1)) return True
def is_valid(self): if self.target.dead: return False assert len(self.target_list) == 2 attacker, victim = self.target_list if not any(e.equipment_category == 'weapon' for e in attacker.equips): return False from .definition import AttackCard if not LaunchCard(attacker, [victim], AttackCard()).can_fire(): return False return True
def apply_action(self): src, tgt = self.source, self.target ttags(src)['bakadesu'] = True cl = user_choose_cards(self, tgt, ('cards', 'showncards')) g = Game.getgame() if cl: g.process_action(LaunchCard(tgt, [src], cl[0])) else: c = user_input([src], ChoosePeerCardInputlet( self, tgt, ('cards', 'showncards', 'equips'))) c = c or random_choose_card( [tgt.cards, tgt.showncards, tgt.equips]) c and g.process_action(CirnoDropCards(src, tgt, [c])) return True
def apply_action(self): src, tgt = self.source, self.target g = Game.getgame() choice = user_input([tgt], ChooseOptionInputlet(self, ('duel', 'attack'))) if choice == 'duel': cls = KanakoFaithDuel elif choice == 'attack': cls = KanakoFaithAttack else: cls = KanakoFaithAttack g.process_action(LaunchCard(tgt, [src], cls(tgt), bypass_check=True)) return True
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, SpellCardAction): if act.cancelled: return act # some other thing have done the job if act.non_responsive: return act g = Game.getgame() has_reject = False while g.SERVER_SIDE: from ..characters.baseclasses import Character from ..characters.reimu import SpiritualAttack for p in g.players: if isinstance(p, Character) and p.has_skill(SpiritualAttack): has_reject = True break if has_reject: break from .definition import RejectCard for c in flatten([[p.cards, p.showncards] for p in g.players]): if isinstance(c, RejectCard): has_reject = True break break has_reject = sync_primitive(has_reject, g.players) if not has_reject: return act self.target_act = act pl = BatchList(p for p in g.players if not p.dead) with InputTransaction('AskForRejectAction', pl) as trans: p, rst = ask_for_action(self, pl, ('cards', 'showncards'), [], trans) if not p: return act cards, _ = rst assert cards and self.cond(cards) g.process_action( LaunchCard(p, [act.target], cards[0], Reject(p, act))) return act
def apply_action(self): tl = self.target_list assert len(tl) == 2 src = self.source attacker, victim = tl cards = user_choose_cards(self, attacker, ['cards', 'showncards']) g = Game.getgame() if cards: g.players.reveal(cards) g.process_action(LaunchCard(attacker, [victim], cards[0])) else: l = [ e for e in attacker.equips if e.equipment_category == 'weapon' ] migrate_cards(l, src.cards) return True
def apply_action(self): src = self.source tgt = 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]) if not c: return False src.reveal(c) migrate_cards([c], src.cards) src.tags['borrow_tag'] = src.tags['turn_count'] if user_input([tgt], ChooseOptionInputlet(self, (False, True))): g.process_action( LaunchCard(tgt, [src], Daze(tgt), bypass_check=True)) return True
def apply_action(self): g = Game.getgame() card = self.associated_card.associated_cards[0] src = self.source victim = self.target tgts = self.target_list[1:] g.players.reveal(card) # card.move_to(victim.cards) # HACK: Silently, no events # migrate_cards([self.associated_card], victim.cards, unwrap=migrate_cards.SINGLE_LAYER) if card.is_card(AttackCard): src.tags['attack_num'] -= 1 # XXX: Use card owned by other lc = LaunchCard(victim, tgts, card) g = Game.getgame() g.process_action(lc) return True
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
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
def ask_for_action_verify(self, p, cl, tl): attacker, victim = self.target_list return LaunchCard(attacker, [victim], cl[0]).can_fire()
def is_valid(self): src, tgt = self.source, self.target if not LaunchCard(tgt, [src], AttackCard()).can_fire(): return False return not ttags(src)['bakadesu']
def ask_for_action_verify(self, p, cl, tl): act = self.target_act return LaunchCard(p, [act.target], cl[0], Reject(p, act)).can_fire()
def ask_for_action_verify(self, p, cl, tl): src, tgt = self.source, self.target return LaunchCard(tgt, [src], cl[0]).can_fire()
def ask_for_action_verify(self, p, cl, tl): c = SentryAttack.wrap(cl, p) tgt = self.target c.target_damage = self.act return LaunchCard(p, [tgt], c).can_fire()
def apply_action(self): tgt, card = self.target, self.card return Game.getgame().process_action(LaunchCard(tgt, [tgt], card))
def choose_player_target(self, tl): src = self.source trimmed, rst = DollControlCard.target(None, src, tl) return trimmed, rst and LaunchCard( src, trimmed, LittleLegionDollControlCard(src)).can_fire()
def target(g, p, tl): l = g.players.rotate_to(p) del l[0] dists = LaunchCard.calc_raw_distance(p, AttackCard()) return ([t for t in l if not t.dead and dists[t] <= 1], True)