Skip to main content
View

Change the damage formula

Principle

The damage calculation formula is defined in the damages method. By default, it uses the standard Pokemon formula (power, attack, defense, STAB, effectiveness, etc.).

Some moves require replacing this formula entirely. For example, Dragon Rage always deals a fixed 40 HP of damage, regardless of stats.

Replacing the complete formula

To handle this behavior, override the damages method in the move's class.

Example: Fixed damage moves

# Fixed damage values for specific moves
FIXED_DAMAGE_VALUES = {
sonic_boom: 20,
dragon_rage: 40
}.freeze

# Method calculating the damages done by the actual move
# @param user [PFM::PokemonBattler] user of the move
# @param target [PFM::PokemonBattler] target of the move
# @return [Integer]
def damages(user, target)
@critical = false
@effectiveness = 1
damage = FIXED_DAMAGE_VALUES.fetch(db_symbol, 1)
log_data("Fixed Damage Move: #{damage} HP")

return damage
end
  • @critical = false disables critical hits for this move.
  • @effectiveness = 1 forces effectiveness to neutral (no "super effective" on fixed damage).
  • FIXED_DAMAGE_VALUES allows easily adding other fixed damage moves via monkey patch.

Modifying sub-steps of the formula

If you don't want to replace the complete formula but adjust a specific step, several internal methods within damages can be overridden:

  • calc_critical_hit: critical hit calculation
  • calc_sp_atk: attack stat (physical or special)
  • calc_sp_def: defense stat (physical or special)
  • calc_mod1: first modifier (pre-critical)
  • calc_ch: critical hit multiplier
  • calc_mod2: second modifier (post-critical)
  • calc_stab: STAB bonus (Same Type Attack Bonus)
  • calc_mod3: third modifier (post-STAB)

Some of these methods in turn call hooks accessible from effects.

Conclusion

  • Use damages to entirely replace the damage calculation formula.
  • Use the sub-methods (calc_critical_hit, calc_stab, etc.) to modify a specific step of the standard formula.
  • For fixed damage, remember to disable criticals (@critical = false) and effectiveness (@effectiveness = 1).