export async function executeCastSpellAction(action, context) { const token = resolveCasterToken(action, context); const actor = token?.actor; if (!actor) return { success: false, consumed: false, reason: "NO_CASTER" }; const item = await resolveItem(actor, action.spellSelection); if (!item) return { success: false, consumed: false, reason: "NO_SPELL_ITEM" }; if (action.activationMode === "autoUse" && typeof item.use === "function") { await item.use({}, { configureDialog: true }); return { success: true, consumed: true }; } item.sheet?.render(true); ui.notifications.info(`${item.name} wurde für ${actor.name} geöffnet. Der Zauber wird aus dem Inventar des Characters über dessen Spellslots genutzt.`); return { success: true, consumed: true }; } function resolveCasterToken(action, context) { switch (action.casterMode ?? "affectedToken") { case "sourceToken": return context.sourceToken ?? null; case "assignedToken": return context.assignedToken ?? context.targetToken ?? null; case "affectedToken": default: return context.targetToken ?? context.tokenDocument?.object ?? null; } } async function resolveItem(actor, selection = {}) { if (selection.mode === "itemUuid" && selection.itemUuid) { const item = await fromUuid(selection.itemUuid); return item?.type === "spell" ? item : null; } if (selection.mode === "itemName" && selection.itemName) { const expected = selection.itemName.toLocaleLowerCase(); return actor.items.find(item => item.type === "spell" && item.name.toLocaleLowerCase() === expected) ?? null; } return null; }