refactor(battle): enhance RNG handling and fixed damage mechanics

- Always supply Gen 2 battle random (BattleRandom) and Gen 1 / love-style rng.
- Add EFFECT_STATIC_DAMAGE for Sonic Boom and Dragon Rage (move power; Ghost
  immunity via resettypematchup for static damage only).
- Keep Magnitude rolling via BattleRandom instead of collapsing to Magnitude 4.
- Cover RNG, static damage, and Magnitude in gen2 battle tests.
This commit is contained in:
1jamie
2026-08-12 17:45:28 -05:00
parent c3136bf8f7
commit 6ff7dd0c38
3 changed files with 173 additions and 15 deletions
+18 -4
View File
@@ -179,9 +179,10 @@ end
-- --------------------------------------------------------------- fixed damage
-- BattleCommand_LevelDamage / SuperFang / Psywave, all of which skip the
-- damage formula entirely.
function Effects.fixedDamage(effect, attacker, defender, random)
-- BattleCommand_ConstantDamage / LevelDamage / SuperFang / Psywave /
-- StaticDamage (Sonic Boom, Dragon Rage): skip the damage formula entirely.
-- `move` is optional; EFFECT_STATIC_DAMAGE reads move.power (20 / 40).
function Effects.fixedDamage(effect, attacker, defender, random, move)
if effect == "EFFECT_LEVEL_DAMAGE" then
return math.max(1, attacker.level or 1)
end
@@ -193,6 +194,9 @@ function Effects.fixedDamage(effect, attacker, defender, random)
local ceiling = math.max(1, math.floor((attacker.level or 1) * 3 / 2))
return math.max(1, (random and random(ceiling) or 0) + 1)
end
if effect == "EFFECT_STATIC_DAMAGE" then
return math.max(1, (move and move.power) or 1)
end
return nil
end
@@ -257,8 +261,18 @@ Effects.MAGNITUDE_POWER = {
-- is what damagecalc reads as the move's power -- data/moves/moves.asm stores
-- MAGNITUDE at power 1 precisely because this overwrites it. Returns the
-- power and the magnitude number the text prints.
--
-- `random` is BattleRandom (0..n-1). If none is supplied, roll via love.math
-- / math.random — never hard-code 0 (that always yields Magnitude 4).
function Effects.magnitudePower(random)
local roll = random and random(256) or 0
local roll
if type(random) == "function" then
roll = random(256) or 0
elseif love and love.math and love.math.random then
roll = love.math.random(256) - 1
else
roll = math.random(256) - 1
end
for _, row in ipairs(Effects.MAGNITUDE_POWER) do
if row[1] >= roll then return row[2], row[3] end
end