def __init__(self, stat: Stat, value: int): if stat not in NUMBER_STATS: raise StatError(f"Cannot apply IVs to stat '{stat}'.") if not 0 <= value <= self.MAX: raise StatError(f"Invalid IV value: {value}") self.stat = stat self.value = value
def get_stat_value(stat: Stat, base: int, ev: int, iv: int, level: int, nature: Nature) -> int: """ Calculates the numerical stat value of the specified stat based on the given stat information :param stat: The stat to calculate the value of (eg. ATTACK, HP) :param base: The base stat value for the specified stat :param ev: The EVs invested into the specified stat :param iv: The IVs for the specified stat :param level: The level of the Pokémon :param nature: The stat-modifying nature of the Pokémon :return: The numerical value of the specified stat based on the given stat information :raises StatError: Raises an error if the specified stat does not have a numerical value, or if any the given stat information is invalid. """ check_number_stat(stat) if not (0 <= ev <= EV.MAX): raise StatError(f"Invalid EV value: {ev}") if not (0 <= iv <= IV.MAX): raise StatError(f"Invalid IV value: {iv}") if not (1 <= level <= 100): raise StatError(f"Invalid level: {level}") if not (1 <= base <= 255): raise StatError(f"Invalid base stat: {base}") base = base * 2 ev = ev // 4 flat_mod = (level + 10) if stat == Stat.HP else 5 nature_mod = nature.get_modifier(stat) # https://bulbapedia.bulbagarden.net/wiki/Statistic#Determination_of_stats internal = ((base + iv + ev) * level) // 100 return math.floor((internal + flat_mod) * nature_mod)
def __init__(self, stat: Stat, value: int, round_off: bool = False): if stat not in NUMBER_STATS: raise StatError(f"Cannot apply EVs to stat '{stat}'.") if (not round_off and value % 4 != 0) or not (0 <= value <= self.MAX): raise StatError(f"Invalid EV value: {value}") self.stat = stat self.value = value if not round_off else ((value // 4) * 4)
def __init__(self, *yields: Tuple[Stat, int]): if any(stat not in NUMBER_STATS or not (1 <= value <= 3) for stat, value in yields): raise StatError("Invalid EV yield: %s" % ", ".join("%s=%s" % (stat, value) for stat, value in yields)) self.yields: Dict[Stat, int] = {stat: val for stat, val in yields}
def __init__(self, stat: Stat, modifier: int, adjust_to_cap: bool = False): mod_min = -6 if stat != Stat.CRITICAL else 0 mod_max = 6 if stat != Stat.CRITICAL else 3 if stat == stat.HP or (not adjust_to_cap and not (mod_min <= modifier <= mod_max)): raise StatError(f"Invalid stat modifier: {stat} | {modifier}") self.stat = stat self.modifier = mod_min if modifier < mod_min else mod_max if modifier > mod_max else modifier
def get_stat(self, stat: Stat) -> int: try: return self.stats[stat] except KeyError: raise StatError( f"Base stats do no have the requested stat: {stat}")
def get_ev(self, stat: Stat) -> int: if stat not in NUMBER_STATS: raise StatError(f"Stat '{stat}' does not have a numerical value.") return self.evs[stat]
def check_number_stat(stat: Stat): if stat not in NUMBER_STATS: raise StatError(f"Stat '{stat}' does not have a numerical value.")
def __init__(self, plus_stat: Stat, minus_stat: Stat): for s in (plus_stat, minus_stat): if s not in NUMBER_STATS or s == Stat.HP: raise StatError(f"Invalid stat for nature: '{s}'") self.plus_stat = plus_stat self.minus_stat = minus_stat