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)
Exemple #2
0
    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