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, 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 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_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' 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 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 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