def handle(self, evt_type, act): if evt_type == 'action_shootdown' and isinstance(act, ActionStageLaunchCard): 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 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_shootdown' and isinstance( act, ActionStageLaunchCard): 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(AttackCard): if c.is_card(PhysicalCard) or 'treat_as' in c.category: raise DiscarderAttackOnly else: return act 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 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, act): if evt_type == 'action_after' and isinstance(act, Damage): src = act.source tgt = act.target if not (src and src.has_skill(FerryFee)): return act if not (tgt.cards or tgt.showncards or tgt.equips): return act dist = LaunchCard.calc_distance(src, FerryFee(src)) if not dist.get(tgt, 10000) <= 0: return act if user_input([src], ChooseOptionInputlet(self, (False, True))): catnames = ('cards', 'showncards', 'equips') card = user_input([src], ChoosePeerCardInputlet(self, tgt, catnames)) card = card or random_choose_card([tgt.cards, tgt.showncards, tgt.equips]) if not card: return act g = Game.getgame() g.process_action(FerryFeeEffect(src, tgt, card)) return act
def handle(self, evt_type, act): if evt_type == 'action_apply' and isinstance(act, ActionStage): g = Game.getgame() for p in g.players: if p.dead: continue if not p.has_skill(Sentry): continue tgt = act.target if p is tgt: continue self.target = tgt # for ui dist = LaunchCard.calc_distance(p, AttackCard()) if dist.get(tgt, 1) > 0: continue if not user_input([p], ChooseOptionInputlet(self, (False, True))): continue g.process_action(SentryAction(p, tgt)) return act
def handle(self, evt_type, act): if evt_type == 'action_after' and isinstance(act, Damage): src = act.source tgt = act.target if not (src and src.has_skill(FerryFee)): return act if not (tgt.cards or tgt.showncards or tgt.equips): return act dist = LaunchCard.calc_distance(src, FerryFee(src)) if not dist.get(tgt, 10000) <= 0: return act if user_input([src], ChooseOptionInputlet(self, (False, True))): catnames = ('cards', 'showncards', 'equips') card = user_input([src], ChoosePeerCardInputlet(self, tgt, catnames)) card = card or random_choose_card( [tgt.cards, tgt.showncards, tgt.equips]) if not card: return act g = Game.getgame() g.process_action(FerryFeeEffect(src, tgt, card)) return act
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, ActionStageLaunchCard): src, tgt = act.source, act.target if not src or not tgt: return act ttags(src)['solid_shield_launch_count'] += 1 if ttags(src)['solid_shield_launch_count'] != 1: return act if src is tgt: return act c = act.card if not (c.is_card(AttackCard) or 'instant_spellcard' in c.category): return act g = Game.getgame() for p in g.players.rotate_to(src): if p is src: continue if p is tgt: continue if not p.has_skill(SolidShield): continue dist = LaunchCard.calc_distance(p, SolidShield(p)) if dist[tgt] > 0: continue cond = c.is_card( AttackCard) or 'instant_spellcard' in c.category cond = cond and (c.is_card(DollControlCard) or len(act.target_list) == 1) # HACK HERE! if not cond: return act if user_input([p], ChooseOptionInputlet(self, (False, True))): g.process_action(SolidShieldAction(p, src, act)) break 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 handle(self, evt_type, arg): if self.processing: return arg elif evt_type == 'calcdistance': src, c, dist = arg if not src.has_skill(Telegnosis): return arg if not c.is_card(AttackCard): return arg try: self.processing = True for p in dist: if p is src: continue d = LaunchCard.calc_distance(p, AttackCard()) if d[src] <= 0: dist[p] = 0 finally: self.processing = False return arg
def handle(self, evt_type, act): if evt_type == 'action_before' and isinstance(act, ActionStageLaunchCard): src, tgt = act.source, act.target if not src or not tgt: return act ttags(src)['solid_shield_launch_count'] += 1 if ttags(src)['solid_shield_launch_count'] != 1: return act if src is tgt: return act c = act.card if not (c.is_card(AttackCard) or 'instant_spellcard' in c.category): return act g = Game.getgame() for p in g.players.rotate_to(src): if p is src: continue if p is tgt: continue if not p.has_skill(SolidShield): continue dist = LaunchCard.calc_distance(p, SolidShield(p)) if dist[tgt] > 0: continue cond = c.is_card(AttackCard) or 'instant_spellcard' in c.category cond = cond and (c.is_card(DollControlCard) or len(act.target_list) == 1) # HACK HERE! if not cond: return act if user_input([p], ChooseOptionInputlet(self, (False, True))): g.process_action(SolidShieldAction(p, src, act)) break 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