Files
DiceCloud/app/imports/api/engine/action/tasks/applyCastSpellTask.ts
2025-01-25 20:51:20 +02:00

83 lines
2.7 KiB
TypeScript

import { EngineAction } from '/imports/api/engine/action/EngineActions';
import { CastSpellTask } from '/imports/api/engine/action/tasks/Task';
import TaskResult from './TaskResult';
import InputProvider from '/imports/api/engine/action/functions/userInput/InputProvider';
import { getSingleProperty } from '/imports/api/engine/loadCreatures';
import applyTask from '/imports/api/engine/action/tasks/applyTask';
import applyActionProperty from '../applyProperties/applyActionProperty';
export default async function applySpellProperty(
task: CastSpellTask, action: EngineAction, result: TaskResult, userInput: InputProvider
): Promise<void> {
const prop = task.prop;
const targetIds = prop.target === 'self' ? [action.creatureId] : task.targetIds;
if (!prop) {
result.appendLog({
name: 'Error casting spell',
value: 'The chosen spell was not found',
silenced: false,
}, [action.creatureId]);
return;
}
let slotLevel = prop.level || 0;
let message = '';
if (task.params.withoutSpellSlot) {
message = `Casting at level ${slotLevel}`
} else if (task.params.ritual) {
message = `Ritual casting at level ${slotLevel}`
} else {
// Get the slot being cast with
const spellSlot = task.params.slotId && getSingleProperty(action.creatureId, task.params.slotId) || undefined;
// Ensure the slot exists
if (!spellSlot) {
result.appendLog({
name: 'Error casting spell',
value: 'The chosen spell requires a spell slot to cast',
silenced: false,
}, [action.creatureId]);
return;
}
// And is the right type
if (spellSlot.type !== 'attribute' || spellSlot.attributeType !== 'spellSlot') {
result.appendLog({
name: 'Error casting spell',
value: 'The chosen slot was not actually a spell slot',
silenced: false,
}, [action.creatureId]);
return;
}
// Spend the slot
await applyTask(action, {
targetIds: [action.creatureId],
subtaskFn: 'damageProp',
params: {
operation: 'increment',
value: 1,
targetProp: spellSlot,
},
}, userInput);
slotLevel = spellSlot ? Number(spellSlot.spellSlotLevel?.value) || 0 : slotLevel;
message = `Casting using a level ${slotLevel} spell slot`;
}
// Log casting method
result.appendLog({
name: message,
silenced: prop.silent,
}, targetIds);
// Add the slot level to the scope
result.pushScope = {
'~slotLevel': { value: slotLevel },
'slotLevel': { value: slotLevel },
};
// Run the rest of the spell as if it were an action
return applyActionProperty({
prop,
targetIds: targetIds,
}, action, result, userInput);
}