From fe5a3edfd21fb7043eea191337ffbd82794ebed3 Mon Sep 17 00:00:00 2001 From: Wickedness Date: Sun, 5 Jul 2026 13:48:19 +0900 Subject: [PATCH] Clamp battle save unit core stats --- scripts/verify-battle-save-normalization.mjs | 5 +++++ src/game/state/battleSaveState.ts | 11 +++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/verify-battle-save-normalization.mjs b/scripts/verify-battle-save-normalization.mjs index d531375..308ba2f 100644 --- a/scripts/verify-battle-save-normalization.mjs +++ b/scripts/verify-battle-save-normalization.mjs @@ -59,6 +59,11 @@ try { ['invalid unit exp threshold', { units: patchUnit(0, { exp: 100 }) }], ['invalid max-level unit exp threshold', { units: patchUnit(0, { level: 99, exp: 101 }) }], ['invalid unit hp', { units: patchUnit(0, { hp: 99, maxHp: 30 }) }], + ['invalid unit hp precision', { units: patchUnit(0, { hp: 12.5 }) }], + ['too high unit max hp', { units: patchUnit(0, { hp: 30, maxHp: 10000 }) }], + ['invalid unit attack', { units: patchUnit(0, { attack: -1 }) }], + ['invalid unit move precision', { units: patchUnit(0, { move: 3.5 }) }], + ['too high unit move', { units: patchUnit(0, { move: 100 }) }], ['duplicate live unit tile', { units: patchUnit(1, { x: validState.units[0].x, y: validState.units[0].y }) }], ['invalid unit x', { units: patchUnit(0, { x: 12 }) }], ['invalid unit direction', { units: patchUnit(0, { direction: 'down' }) }], diff --git a/src/game/state/battleSaveState.ts b/src/game/state/battleSaveState.ts index 7fa714f..3dfd549 100644 --- a/src/game/state/battleSaveState.ts +++ b/src/game/state/battleSaveState.ts @@ -92,6 +92,9 @@ const maxBattleEffectTurns = 9; const maxBattleBuffBonus = 99; const maxBattleStatusPower = 99; const maxBattleUnitStatValue = 999999; +const maxBattleUnitHp = 9999; +const maxBattleUnitAttack = 9999; +const maxBattleUnitMove = 99; const maxStatusKindsPerUnit = 2; const maxBattleItemStockById: Record = { bean: 3, @@ -273,11 +276,11 @@ function isSavedBattleUnitState(value: unknown, options: BattleSaveValidationOpt if ( !isValidCharacterProgress(value.level, value.exp) || - !isNonNegativeFiniteNumber(value.hp) || - !isPositiveInteger(value.maxHp) || + !isIntegerInRange(value.hp, 0, maxBattleUnitHp) || + !isIntegerInRange(value.maxHp, 1, maxBattleUnitHp) || Number(value.hp) > Number(value.maxHp) || - !isFiniteNumber(value.attack) || - !isNonNegativeFiniteNumber(value.move) || + !isIntegerInRange(value.attack, 0, maxBattleUnitAttack) || + !isIntegerInRange(value.move, 0, maxBattleUnitMove) || !Number.isInteger(value.x) || !Number.isInteger(value.y) ) {