def test_gf_round(self): self.assertEqual(gf_round(1), 1) self.assertEqual(gf_round(1.0), 1) self.assertTrue(isinstance(gf_round(1.0), int)) self.assertEqual(gf_round(13.1), 13) self.assertEqual(gf_round(127.5), 127) self.assertEqual(gf_round(1.75), 2) self.assertEqual(gf_round(0.9999999999999999999999), 1)
def calculate_damage(self, user, move, target): """ Return FAIL: "But it failed!" Return None: Move did not attempt to do damage Return int: Amount of damage dealt (returning 0 still means damage for Static etc.) """ if target.is_immune_to_move(user, move): if __debug__: log.i('FAIL: %s is immune to %s', target, move) return FAIL if __debug__: log.d('Calculating damage for %s attacking %s with %s', user, target, move) damage = move.damage_callback(user, target) if damage is not None: if __debug__: log.i("Using %s damage from %s's damage_callback", damage, move) return damage base_power = move.get_base_power(user, target, self) if base_power is not None: base_power = self.modify_base_power(user, move, target, base_power) if not base_power: if __debug__: log.d('base_power=%s, returning damage=None', base_power) return None assert move.category in (PHYSICAL, SPECIAL) base_power = int(max(gf_round(base_power), 1)) if __debug__: log.d('Using base_power of %s', base_power) crit = move.crit = ((move.always_crit or self.get_critical_hit(move.crit_ratio)) and not (move.never_crit or target.ability in (abilitydex['battlearmor'], abilitydex['shellarmor']))) if __debug__: if crit: log.i('Critical hit!') defensive_category = move.defensive_category or move.category attacking_stat = 'atk' if move.category is PHYSICAL else 'spa' defending_stat = 'def' if defensive_category is PHYSICAL else 'spd' attack_stat_source = user if not move.use_opponent_attack else target attack_boosts = attack_stat_source.boosts[attacking_stat] defense_boosts = target.boosts[defending_stat] if move.ignore_offensive_boosts or (crit and attack_boosts < 0): attack_boosts = 0 if move.ignore_defensive_boosts or (crit and defense_boosts > 0): defense_boosts = 0 attack = attack_stat_source.calculate_stat(attacking_stat, attack_boosts) defense = target.calculate_stat(defending_stat, defense_boosts) attack = int(user.accumulate_effect('on_modify_' + attacking_stat, user, move, self, attack)) modify = self.modify_def if defending_stat == 'def' else self.modify_spd defense = int(modify(defense, target, move)) damage = int(int(int(2 * user.level / 5 + 2) * base_power * attack / defense) / 50) + 2 if crit: damage = int(damage * 1.5) damage = int(damage * self.damage_randomizer() / 100) if move.type in user.types: damage = int(damage * move.stab) weather_mod = self.battlefield.get_effect(self.battlefield.weather) if weather_mod is not None: damage = gf_round(weather_mod.weather_modify_damage(move, damage)) effectiveness = self.get_effectiveness(user, move, target) damage *= effectiveness if __debug__: if effectiveness != 1: log.i("It's %s effective", {0.25: 'barely', 0.5: 'not very', 2: 'super', 4: 'super duper'}[effectiveness]) damage = self.modify_damage(damage, user, move, target, crit, effectiveness) damage = gf_round(damage) or 1 if __debug__: log.d('Returning damage=%s', damage) return damage