From 3483a6d34f4810ef7b5d0e2fa1475e211d9dc36b Mon Sep 17 00:00:00 2001 From: ThaumRystra <9525416+ThaumRystra@users.noreply.github.com> Date: Tue, 30 Apr 2024 13:03:33 +0200 Subject: [PATCH] Fixed actions using their own parent as ammo creating an infinite loop --- .../action/applyProperties/applyDamageProperty.ts | 8 ++++---- .../api/engine/action/functions/spendResources.ts | 6 +++++- app/imports/api/engine/action/tasks/Task.ts | 1 + .../api/engine/action/tasks/applyItemAsAmmoTask.ts | 11 ++++++++--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts b/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts index eb6cccf0..db469c60 100644 --- a/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts +++ b/app/imports/api/engine/action/applyProperties/applyDamageProperty.ts @@ -42,7 +42,7 @@ export default async function applyDamageProperty( // roll the dice only and store that string recalculateCalculation(prop.amount, action, 'compile', inputProvider); - const { result: rolled } = await resolve('roll', prop.amount.valueNode, scope, context); + const { result: rolled } = await resolve('roll', prop.amount.valueNode, scope, context, inputProvider); if (rolled.parseType !== 'constant') { logValue.push(toString(rolled)); } @@ -52,7 +52,7 @@ export default async function applyDamageProperty( context.errors = []; // Resolve the roll to a final value - const { result: reduced } = await resolve('reduce', rolled, scope, context); + const { result: reduced } = await resolve('reduce', rolled, scope, context, inputProvider); result.appendParserContextErrors(context, damageTargets); // Store the result @@ -102,11 +102,11 @@ export default async function applyDamageProperty( recalculateCalculation(prop.save.damageFunction, action, 'compile', inputProvider); context.errors = []; const { result: saveDamageRolled } = await resolve( - 'roll', prop.save.damageFunction.valueNode, scope, context + 'roll', prop.save.damageFunction.valueNode, scope, context, inputProvider ); saveRoll = toString(saveDamageRolled); const { result: saveDamageResult } = await resolve( - 'reduce', saveDamageRolled, scope, context + 'reduce', saveDamageRolled, scope, context, inputProvider ); result.appendParserContextErrors(context, damageTargets); // If we didn't end up with a constant of finite amount, give up diff --git a/app/imports/api/engine/action/functions/spendResources.ts b/app/imports/api/engine/action/functions/spendResources.ts index 66f6310a..b002d180 100644 --- a/app/imports/api/engine/action/functions/spendResources.ts +++ b/app/imports/api/engine/action/functions/spendResources.ts @@ -5,6 +5,7 @@ import recalculateCalculation from '/imports/api/engine/action/functions/recalcu import TaskResult from '/imports/api/engine/action/tasks/TaskResult'; import applyTask from '/imports/api/engine/action/tasks/applyTask'; import { getSingleProperty } from '/imports/api/engine/loadCreatures'; +import { hasAncestorRelationship } from '/imports/api/parenting/parentingFunctions'; export default async function spendResources( action: EngineAction, prop, targetIds: string[], result: TaskResult, userInput @@ -69,8 +70,11 @@ export default async function spendResources( params: { value: quantity, item, + // If the item is an ancestor or descendant of this prop, skip the item's children to avoid + // an infinite loop + skipChildren: hasAncestorRelationship(item, prop), }, }, userInput); } } -} \ No newline at end of file +} diff --git a/app/imports/api/engine/action/tasks/Task.ts b/app/imports/api/engine/action/tasks/Task.ts index eb920ec5..18328870 100644 --- a/app/imports/api/engine/action/tasks/Task.ts +++ b/app/imports/api/engine/action/tasks/Task.ts @@ -31,6 +31,7 @@ export type ItemAsAmmoTask = BaseTask & { params: { value: number; item: any; + skipChildren: boolean; }; } diff --git a/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts b/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts index 6a178f65..092b6321 100644 --- a/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts +++ b/app/imports/api/engine/action/tasks/applyItemAsAmmoTask.ts @@ -1,6 +1,6 @@ import { EngineAction } from '/imports/api/engine/action/EngineActions'; import { - applyDefaultAfterPropTasks, applyTriggers + applyDefaultAfterPropTasks, applyAfterTasksSkipChildren, applyTriggers } from '/imports/api/engine/action/functions/applyTaskGroups'; import { getEffectiveActionScope @@ -31,7 +31,7 @@ export default async function applyItemAsAmmoTask(task: ItemAsAmmoTask, action: }; value = scope['~ammoConsumed']?.value || 0; - const itemChildren = await getPropertyChildren(action.creatureId, item); + const itemChildren = task.params.skipChildren ? [] : await getPropertyChildren(action.creatureId, item); // Do the quantity adjustment // Check if property has quantity @@ -53,5 +53,10 @@ export default async function applyItemAsAmmoTask(task: ItemAsAmmoTask, action: }); await applyTriggers(action, item, [action.creatureId], 'ammo.after', userInput); - return applyDefaultAfterPropTasks(action, item, task.targetIds, userInput); + + if (task.params.skipChildren) { + return applyAfterTasksSkipChildren(action, item, task.targetIds, userInput); + } else { + return applyDefaultAfterPropTasks(action, item, task.targetIds, userInput); + } } \ No newline at end of file