def type_effect_events(damage, data: "EventData"): if data.type_multiplier > 1: event = Event( EventType.FINAL_MOVE_SUPER_EFFECTIVE, EventData(attacker=data.attacker, defender=data.defender, move=data.move, damage=damage)) elif data.type_multiplier == 0: event = Event( EventType.FINAL_MOVE_DOESNT_AFFECT, EventData(attacker=data.attacker, defender=data.defender, move=data.move, damage=damage)) elif data.type_multiplier < 1: event = Event( EventType.FINAL_MOVE_NOT_VERY_EFFECTIVE, EventData(attacker=data.attacker, defender=data.defender, move=data.move, damage=damage)) else: event = None return event
def critical_check(e_d: "EventData"): if e_d.chance is None or e_d.chance < 100 * random(): normal_damage = e_d.move.normal_damage return Event( EventType.ATTACK_DAMAGE_NORMAL, EventData(defender=e_d.defender, attacker=e_d.attacker, function=normal_damage, type_multiplier=e_d.type_multiplier, other_multiplier=1, move=e_d.move, damage=e_d.move.calculate_unmodified_damage( e_d.attacker, e_d.defender))) else: crit_damage = e_d.move.critical_damage return Event( EventType.ATTACK_DAMAGE_CRIT, EventData(defender=e_d.defender, attacker=e_d.attacker, function=crit_damage, type_multiplier=e_d.type_multiplier, other_multiplier=1, move=e_d.move, damage=e_d.move.calculate_unmodified_damage( e_d.attacker, e_d.defender)))
def typemult_check(e_d: "EventData"): if e_d.type_multiplier == 0: return Event( EventType.FINAL_MOVE_DOESNT_AFFECT, EventData(defender=e_d.defender, attacker=e_d.attacker)) else: return Event( EventType.ATTACK_CRIT_CHECK, EventData(function=MultiHit.critical_check, defender=e_d.defender, attacker=e_d.attacker, damage=e_d.damage, move=e_d.move, chance=e_d.move.crit_chance, type_multiplier=e_d.type_multiplier))
def one_hit_kill(e_d: "EventData"): return Event( EventType.ONE_HIT_KILL_DAMAGE, EventData(defender=e_d.defender, attacker=e_d.attacker, function=OneHitKO.one_hit_kill_dmg, damage=e_d.defender.get_hp()))
def two_turn_use(self: "Move", attacker: "Pokemon", defender: "Pokemon"): return Event( EventType.TWO_TURN_MOVE, EventData(function=TwoTurn.turn_one_complete, attacker=attacker, move=self, defender=defender))
def call(event_data: "EventData"): # Set the status if event_data.defender.no_nonvolatile_status(): event_data.defender.set_nonvol_status( SleepEffect(event_data.defender)) return Event(EventType.FINAL_SLEEP_INFLICTED, EventData(defender=event_data.defender))
def absorb_health(data: EventData): healed = data.defender.heal(data.damage) if healed > 0: return Event( EventType.FINAL_HEALTH_ABSORBED, EventData(defender=data.defender, damage=healed, move=data.move))
def affect(self, attacker: "Pokemon", defender: "Pokemon", world: "Combat"): return Event( EventType.PARALYZE_INFLICTING, EventData(chance=self.chance, defender=defender, attacker=attacker, function=self.call))
def call(event_data: "EventData"): # Set the status if rng r = random.randint(0, 100) if event_data.chance is None or r < event_data.chance: if event_data.defender.no_nonvolatile_status(): event_data.defender.set_nonvol_status( ParalyzeEffect(event_data.defender)) return Event(EventType.FINAL_PARALYZE_INFLICTED, EventData(defender=event_data.defender))
def attack_hit_check(event_data: "EventData"): if event_data.chance is None or event_data.chance >= 100 * random(): return event_data.move.attack_hits(event_data) else: return Event( EventType.FINAL_ATTACK_MISS, EventData(defender=event_data.defender, attacker=event_data.attacker, move=event_data.move, damage=event_data))
def multi_hit_hits(ed: "EventData"): times = [2, 2, 3, 3, 4, 5][randint(0, 5)] return Event( EventType.MULTI_HIT_TIMES, EventData(other_multiplier=times, attacker=ed.attacker, defender=ed.defender, function=MultiHit.multi_hit_times, damage=ed.damage, move=ed.move))
def normal_use(self: "Move", attacker: "Pokemon", defender: "Pokemon"): attacker.last_move_used = self return Event( EventType.ATTACK_ACCURACY_CHECK, EventData(function=self.attack_hit_check, defender=defender, attacker=attacker, damage=self.power, move=self, chance=self.accuracy, type_multiplier=type_multiplier(self.types, defender.types)))
def multi_hit_damages(e_d: "EventData"): return Event( EventType.ATTACK_TYPE_MULT_CHECK, EventData( function=MultiHit.typemult_check, defender=e_d.defender, attacker=e_d.attacker, damage=e_d.damage, move=e_d.move, type_multiplier=type_multiplier(e_d.move.types, e_d.defender.types), ))
def attack_hits(event_data: "EventData"): typemult_check = event_data.move.type_mult_check return Event( EventType.ATTACK_TYPE_MULT_CHECK, EventData( function=typemult_check, defender=event_data.defender, attacker=event_data.attacker, damage=event_data.damage, move=event_data.move, type_multiplier=type_multiplier(event_data.move.types, event_data.defender.types), ))
def damage_adds(self, damage: int, attacker: "Pokemon"): events = [] if self.recoil_percent is not None: events.append( Event( EventType.RECOIL_DAMAGE, EventData( function=NormalAttackFlow.recoil_damage, move=self, defender=attacker, damage=damage * self.recoil_percent, ))) if self.absorb_percent is not None: events.append( Event( EventType.ABSORB_HEALTH, EventData(function=NormalAttackFlow.absorb_health, move=self, defender=attacker, damage=damage * self.absorb_percent))) return events
def handle(self, event: "Event"): if event.type == EventType.ATTACK_ACCURACY_CHECK: pass # TODO: Prevent pokemon from doing anything except sleep talk etc. if event.type == EventType.TURN_END: self.increment_turns() if self.turns > self.__max_turns: def call(event_data: EventData): self.pokemon.remove_nonvol_status() return event, [ Event(EventType.STATUS_REMOVE, EventData(function=call, defender=self.pokemon)) ]
def damage_events(e_d: "EventData", event_type: "EventType", type_effect=True): potential_dmg = e_d.move.calculate_real_damage_with_multiplier(e_d) damage = e_d.defender.damage(potential_dmg) events = [ Event( event_type, EventData(damage=e_d.damage, defender=e_d.defender, move=e_d.move)) ] if type_effect: events.append(NormalAttackFlow.type_effect_events(damage, e_d)) # Create events for possible other effects of the attack (absorb, recoil, status chances, ...) events.extend( NormalAttackFlow.damage_adds(e_d.move, damage, e_d.attacker)) events.extend(NormalAttackFlow.move_effects(e_d)) return events
def call(event_data: "EventData"): damage = event_data.defender.damage(event_data.damage) if damage > 0: return Event( EventType.FINAL_ATTACK_DID_DAMAGE, EventData(defender=event_data.defender, damage=damage))
def affect(self, attacker: "Pokemon", defender: "Pokemon", world: "Combat"): return Event( EventType.SLEEP_INFLICTING, EventData(defender=defender, attacker=attacker, function=self.call))
def recoil_damage(data: EventData): took = data.defender.damage(data.damage) if took > 0: return Event( EventType.FINAL_TOOK_RECOIL_DAMAGE, EventData(defender=data.defender, damage=took, move=data.move))
def one_hit_kill_dmg(e_d: "EventData"): return Event( EventType.FINAL_ONE_HIT_KILL_DAMAGES, EventData(defender=e_d.defender, attacker=e_d.attacker, damage=e_d.damage))
def affect(self, attacker: "Pokemon", defender: "Pokemon", world: "Combat"): return Event( EventType.ATTACK_DOES_EXACT_DAMAGE, EventData(function=self.call, defender=defender, attacker=attacker))