Reject stale battle save effects
This commit is contained in:
@@ -105,6 +105,7 @@ try {
|
|||||||
['too high buff bonus', { battleBuffs: [{ ...validState.battleBuffs[0], criticalBonus: 100 }] }],
|
['too high buff bonus', { battleBuffs: [{ ...validState.battleBuffs[0], criticalBonus: 100 }] }],
|
||||||
['unknown buff unit id', { battleBuffs: [{ ...validState.battleBuffs[0], unitId: 'ghost-unit' }] }],
|
['unknown buff unit id', { battleBuffs: [{ ...validState.battleBuffs[0], unitId: 'ghost-unit' }] }],
|
||||||
['duplicate buff unit id', { battleBuffs: [validState.battleBuffs[0], { ...validState.battleBuffs[0] }] }],
|
['duplicate buff unit id', { battleBuffs: [validState.battleBuffs[0], { ...validState.battleBuffs[0] }] }],
|
||||||
|
['defeated buff target', { units: patchUnit(0, { hp: 0 }), attackIntents: [], battleBuffs: [{ ...validState.battleBuffs[0], unitId: 'liu-bei' }] }],
|
||||||
['invalid status kind', { battleStatuses: [{ ...validState.battleStatuses[0], kind: 'poison' }] }],
|
['invalid status kind', { battleStatuses: [{ ...validState.battleStatuses[0], kind: 'poison' }] }],
|
||||||
['too many status turns', { battleStatuses: [{ ...validState.battleStatuses[0], turns: 10 }] }],
|
['too many status turns', { battleStatuses: [{ ...validState.battleStatuses[0], turns: 10 }] }],
|
||||||
['too long status label', { battleStatuses: [{ ...validState.battleStatuses[0], label: 'x'.repeat(33) }] }],
|
['too long status label', { battleStatuses: [{ ...validState.battleStatuses[0], label: 'x'.repeat(33) }] }],
|
||||||
@@ -112,6 +113,7 @@ try {
|
|||||||
['too high status power', { battleStatuses: [{ ...validState.battleStatuses[0], power: 100 }] }],
|
['too high status power', { battleStatuses: [{ ...validState.battleStatuses[0], power: 100 }] }],
|
||||||
['unknown status unit id', { battleStatuses: [{ ...validState.battleStatuses[0], unitId: 'ghost-unit' }] }],
|
['unknown status unit id', { battleStatuses: [{ ...validState.battleStatuses[0], unitId: 'ghost-unit' }] }],
|
||||||
['duplicate status unit kind', { battleStatuses: [validState.battleStatuses[0], { ...validState.battleStatuses[0] }] }],
|
['duplicate status unit kind', { battleStatuses: [validState.battleStatuses[0], { ...validState.battleStatuses[0] }] }],
|
||||||
|
['defeated status target', { units: patchUnit(2, { hp: 0 }), attackIntents: [], battleStatuses: [{ ...validState.battleStatuses[0], unitId: 'rebel-1' }] }],
|
||||||
['invalid stats shape', { battleStats: { 'liu-bei': { damageDealt: 10 } } }],
|
['invalid stats shape', { battleStats: { 'liu-bei': { damageDealt: 10 } } }],
|
||||||
['invalid stats value', { battleStats: { 'liu-bei': { ...validState.battleStats['liu-bei'], actions: 1.5 } } }],
|
['invalid stats value', { battleStats: { 'liu-bei': { ...validState.battleStats['liu-bei'], actions: 1.5 } } }],
|
||||||
['too high stats value', { battleStats: { 'liu-bei': { ...validState.battleStats['liu-bei'], damageDealt: 1000000 } } }],
|
['too high stats value', { battleStats: { 'liu-bei': { ...validState.battleStats['liu-bei'], damageDealt: 1000000 } } }],
|
||||||
|
|||||||
@@ -163,6 +163,10 @@ export function isValidBattleSaveState(state: unknown, options: BattleSaveValida
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!areEffectsTargetingLiveUnits(state.battleBuffs, state.battleStatuses, units)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!isOptionalItemStockRecord(state.itemStocks, options) ||
|
!isOptionalItemStockRecord(state.itemStocks, options) ||
|
||||||
!isOptionalBuffArray(state.battleBuffs, options) ||
|
!isOptionalBuffArray(state.battleBuffs, options) ||
|
||||||
@@ -282,6 +286,21 @@ function areAttackIntentsTargetingLiveUnits(attackIntents: BattleSaveAttackInten
|
|||||||
return attackIntents.every((intent) => liveUnitIds.has(intent.attackerId) && liveUnitIds.has(intent.targetId));
|
return attackIntents.every((intent) => liveUnitIds.has(intent.attackerId) && liveUnitIds.has(intent.targetId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function areEffectsTargetingLiveUnits(
|
||||||
|
battleBuffs: unknown,
|
||||||
|
battleStatuses: unknown,
|
||||||
|
units: SavedBattleUnitState[]
|
||||||
|
) {
|
||||||
|
const liveUnitIds = new Set(units.filter((unit) => unit.hp > 0).map((unit) => unit.id));
|
||||||
|
const buffTargetsAreLive =
|
||||||
|
battleBuffs === undefined ||
|
||||||
|
(Array.isArray(battleBuffs) && battleBuffs.every((buff) => isRecord(buff) && liveUnitIds.has(String(buff.unitId))));
|
||||||
|
const statusTargetsAreLive =
|
||||||
|
battleStatuses === undefined ||
|
||||||
|
(Array.isArray(battleStatuses) && battleStatuses.every((status) => isRecord(status) && liveUnitIds.has(String(status.unitId))));
|
||||||
|
return buffTargetsAreLive && statusTargetsAreLive;
|
||||||
|
}
|
||||||
|
|
||||||
function isSavedBattleUnitState(value: unknown, options: BattleSaveValidationOptions): value is SavedBattleUnitState {
|
function isSavedBattleUnitState(value: unknown, options: BattleSaveValidationOptions): value is SavedBattleUnitState {
|
||||||
if (!isRecord(value) || typeof value.id !== 'string' || value.id.length === 0 || !isEquipmentSet(value.equipment, options)) {
|
if (!isRecord(value) || typeof value.id !== 'string' || value.id.length === 0 || !isEquipmentSet(value.equipment, options)) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user