feat(mods): expose read-only battle snapshots

This commit is contained in:
AverageConsumer
2026-08-16 01:25:56 +02:00
parent d87f6b8ad1
commit fcb5d1d348
10 changed files with 583 additions and 29 deletions
+22 -12
View File
@@ -83,25 +83,35 @@ function Damage.critRoll(ruleset, attacker, moveId, rng, highCrit)
return rng(0, 255) < b
end
-- Accuracy test: rand(0..255) < floor(accuracy * 255 / 100) adjusted by
-- accuracy/evasion stages. With oneIn256Miss a max-accuracy move still
-- misses on 255.
function Damage.accuracyRoll(ruleset, move, attacker, defender, rng)
rng = rng or love.math.random
-- Exact number of the 256 RNG outcomes that pass MoveHitTest. Keeping the
-- threshold public lets read-only UIs preview the same rules the roll uses.
function Damage.accuracyThreshold(ruleset, move, attacker, defender)
-- X ACCURACY sets USING_X_ACCURACY: the move simply never misses
-- (MoveHitTest returns before any accuracy math, 1/256 included)
if attacker.xAccuracy then return true end
if attacker.xAccuracy then return 256 end
local acc = math.floor(move.accuracy * 255 / 100)
local accuracyStage = attacker.stages and attacker.stages.accuracy or 0
local evasionStage = defender.stages and defender.stages.evasion or 0
-- CalcHitChance scales by the accuracy stage and the evasion stage as
-- two separate ratio multiplications, clamping each result
acc = math.min(255, Stats.applyStage(acc,
attacker.stages and attacker.stages.accuracy or 0))
acc = math.min(255, Stats.applyStage(acc,
-(defender.stages and defender.stages.evasion or 0)))
acc = math.min(255, Stats.applyStage(acc, accuracyStage))
acc = math.min(255, Stats.applyStage(acc, -evasionStage))
if not ruleset.oneIn256Miss and move.accuracy >= 100
and (attacker.stages.accuracy or 0) >= (defender.stages.evasion or 0) then
return true
and accuracyStage >= evasionStage then
return 256
end
return acc
end
function Damage.accuracyChance(ruleset, move, attacker, defender)
return Damage.accuracyThreshold(ruleset, move, attacker, defender) * 100 / 256
end
-- Accuracy test: rand(0..255) < the shared ruleset-aware threshold.
function Damage.accuracyRoll(ruleset, move, attacker, defender, rng)
rng = rng or love.math.random
local acc = Damage.accuracyThreshold(ruleset, move, attacker, defender)
if acc == 256 then return true end
return rng(0, 255) < acc
end