diff --git a/lang/en.json b/lang/en.json index 80091d1e..7f359f09 100755 --- a/lang/en.json +++ b/lang/en.json @@ -610,10 +610,6 @@ "title": "{name} Resource", "rerollDice": "Reroll Dice" }, - "Summon": { - "title": "Summon Tokens", - "hint": "Drag tokens from the list below into the scene to summon them." - }, "TagTeamSelect": { "title": "Tag Team Roll", "leaderTitle": "Initiating Character", diff --git a/module/applications/dialogs/summonDialog.mjs b/module/applications/dialogs/summonDialog.mjs index 9dc189fd..c5ab7a3d 100644 --- a/module/applications/dialogs/summonDialog.mjs +++ b/module/applications/dialogs/summonDialog.mjs @@ -5,46 +5,44 @@ export default class DHSummonDialog extends HandlebarsApplicationMixin(Applicati super(summonData); // Initialize summons and index this.summons = summonData.summons || []; + this.index = 0; } - static PARTS = { - main: { template: 'systems/daggerheart/templates/dialogs/summon/summonDialog.hbs' } - }; - + get_title() { + return game.i18n.localize("DAGGERHEART.DIALOGS.SUMMON.title"); + } static DEFAULT_OPTIONS= { - tag: 'form', - window: { - title: "DAGGERHEART.APPLICATIONS.Summon.title", - resizable: false - }, - position: { - width: 400, - height: 'auto' - }, + ...super.DEFAULT_OPTIONS, + template: 'systems/daggerheart/module/applications/dialogs/summon/summonDialog.hbs', + width: 400, + height: 'auto', classes: ['daggerheart', 'dialog', 'summon-dialog'], - dragDrop: [{dragSelector: '.summon-token'}], + dragDrop: [{ dragSelector: '.summon-token', dropSelector: null, handler:'onDrop'}] }; async _prepareContext() { const context = await super._prepareContext(); - context.summons=await Promise.all(this.summons.map(async(entry)=>{ - const actor = await fromUuid(entry.actorUUID); - return { - ...entry, - name: actor?.name || game.i18n.localize("DAGGERHEART.GENERAL.Unknown"), - img: actor?.img || 'icons/svg/mystery-man.svg', - }; - })); + context.summons=this.summons; + context.index=this.index; return context; } - _onDragStart(event) { - const uuid = event.currentTarget.dataset.uuid; - if(!uuid) return; - const dragData = { type: 'Actor', uuid: uuid }; - event.dataTransfer.effectAllowed = 'all'; - event.dataTransfer.setData('text/plain', JSON.stringify(dragData)); + getData(options={}) { + const data = super.getData(options); + data.summons=this.summons; + data.index=this.index; + return data; + } + async prepareContext() { + const context = await super.prepareContext(); + return context; } + async onDrop(event) {//add to canvas + event.preventDefault(); + const tokenData = JSON.parse(event.dataTransfer.getData('text/plain')); + const position = { x: event.clientX, y: event.clientY }; + await canvas.scene.createEmbeddedDocuments("Token", [tokenData], { temporary: false, x: position.x, y: position.y }); + } } \ No newline at end of file diff --git a/module/data/action/summonAction.mjs b/module/data/action/summonAction.mjs index 1505ce2d..56e0446c 100644 --- a/module/data/action/summonAction.mjs +++ b/module/data/action/summonAction.mjs @@ -1,5 +1,54 @@ import DHBaseAction from './baseAction.mjs'; export default class DHSummonAction extends DHBaseAction { - static extraSchemas = [...super.extraSchemas, 'summon']; + static defineSchema() { + const fields = foundry.data.fields; + return { + ...super.defineSchema(), + summon: new fields.ArrayField(new fields.SchemaField({ + actorUUID: new fields.DocumentUUIDField({ type: 'Actor', required: true }), + count: new fields.NumberField({ required: true, default: 1, min: 1, integer: true }) + }), { required: false, initial: [] }) + }; + } + + get defaultValues() { + return { + summon: { actorUUID: "", count: 1 } + }; + } + + async trigger(event, ...args) { + if (!this.canSummon || !canvas.scene){ + ui.notifications.warn(game.i18n.localize("DAGGERHEART.ACTIONS.TYPES.summon.error")); + return; + } + await this._performAction(); + } + + get canSummon() { + return game.user.can('TOKEN_CREATE'); + } + + //Accessor for summon manager for performing the summon action + get summonManager() { + return game.dh.summon; //incomplete implementation + } + + //Logic to perform the summon action - incomplete implementation + async _performAction(event, ...args) { + const validSummons = this.summon.filter(entry => entry.actorUUID); + if (validSummons.length === 0) { + ui.notifications.warn("No actors configured for this Summon action."); + return; + } + // FOR NOW: Just log the data to prove the schema working or not + console.group("Summon Action Triggered"); + + for (const entry of validSummons) { + const actor = await fromUuid(entry.actorUUID); + console.log(`- Ready to summon ${entry.count}x [${actor?.name || "Unknown Actor"}]`); + } + console.groupEnd(); + } } diff --git a/module/data/fields/action/summonField.mjs b/module/data/fields/action/summonField.mjs index 6ba1f8a2..7bcd1145 100644 --- a/module/data/fields/action/summonField.mjs +++ b/module/data/fields/action/summonField.mjs @@ -1,94 +1,61 @@ -const fields = foundry.data.fields; import DHSummonDialog from '../../../applications/dialogs/summonDialog.mjs'; -export default class DHSummonField extends fields.ArrayField { +const fields = foundry.data.fields; + +export default class DHSummonField extends fields.SchemaField { /** * Action Workflow order */ static order = 120; constructor(options = {}, context = {}) { - const summonFields = new fields.SchemaField({ - actorUUID: new fields.DocumentUUIDField({ - type: 'Actor', - required: true - }), - count: new fields.NumberField({ - required: true, - default: 1, - min: 1, - integer: true - }) - }); + const summonFields = { + summon: new fields.ArrayField(new fields.SchemaField({ + actorUUID: new fields.DocumentUUIDField({ + type: 'Actor', + required: true }), + count: new fields.NumberField({ + required: true, + default: 1, + min: 1, + integer: true }) + }), { required: false, initial: [] }) + }; super(summonFields, options, context); } - static async execute() { - if(!canvas.scene){ - ui.notifications.warn(game.i18n.localize("DAGGERHEART.ACTIONS.TYPES.summon.error")); - return; - } - const validSummons = this.summon.filter(entry => entry.actorUUID); - if (validSummons.length === 0) { - console.log("No actors configured for this Summon action."); - return; - } - - for (const entry of validSummons) { - const actor = await fromUuid(entry.actorUUID); - } - - // //Open Summon Dialog - // const summonData = { summons: validSummons }; - // console.log(summonData); - // const dialog = new DHSummonDialog(summonData); - // dialog.render(true); - - // Create folder and add tokens to actor folder - const rootFolderName = game.i18n.localize("DAGGERHEART.APPLICATIONS.Summon.title"); - let rootFolder = game.folders.find(f => f.name === rootFolderName && f.type === 'Actor'); - if (!rootFolder) { - rootFolder = await Folder.create({ - name: rootFolderName, - type: 'Actor', - }); - } - const parentName = this.item.name ?? "Unkown Feature"; - const actionName = this.name ?? "Unkown Action"; - const subFolderName = `${parentName} - ${actionName}`; - - let subFolder = game.folders.find(f => f.name === subFolderName && f.type === 'Actor' && f.folder?.id === rootFolder.id); - if (!subFolder) { - subFolder = await Folder.create({ - name: subFolderName, - type: 'Actor', - folder: rootFolder.id - }); - const actorsToSummon = []; - for (const entry of validSummons) { - const sourceActor = await fromUuid(entry.actorUUID); - if (!sourceActor) { - console.warn('DHSummonField: Could not find actor for UUID', entry.actorUUID); - continue; - } - const actorData = sourceActor.toObject(); - delete actorData._id; // Remove _id to create a new Actor - actorData.folder = subFolder.id; - - for (let i = 0; i < entry.count; i++) { - const newActor = foundry.utils.deepClone(actorData); - if (entry.count > 1) { - newActor.name = `${actorData.name} ${i + 1}`; - } - actorsToSummon.push(newActor); - } - } - if (actorsToSummon.length > 0) { - await Actor.createDocuments(actorsToSummon); - ui.notifications.info(`Summoned ${actorsToSummon.length} actors successfully in folder ${subFolder.name}.`); - } - } else { - ui.notifications.info(`Summon actors already exist in folder ${subFolder.name}.`); - } + /** + * Summon Action Workflow part. + * Must be called within Action context or similar. + * @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods. + */ + static async execute(config) { + const selected = await DHSummonDialog.configure(config, this.item); + if (!selected) return false; + return await DHSummonField.summon.call(this, selected); } -} + /** + * Update Action Workflow config object. + * Must be called within Action context. + * @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods. + */ + prepareConfig(config) { + if (!canvas.scene){ + ui.notifications.warn(game.i18n.localize("DAGGERHEART.ACTIONS.TYPES.summon.error")); + return false; + } + return true; + } + /** + * Logic to perform the summon action - incomplete implementation + */ + + get defaultValues() { + return { + summon: { actorUUID: "", count: 1 } + }; + } + get canSummon() { + return game.user.can('TOKEN_CREATE'); + } +} \ No newline at end of file diff --git a/templates/actionTypes/summon.hbs b/templates/actionTypes/summon.hbs index 276045a8..d313fb4c 100644 --- a/templates/actionTypes/summon.hbs +++ b/templates/actionTypes/summon.hbs @@ -3,6 +3,12 @@ {{localize "DAGGERHEART.ACTIONS.TYPES.summon.name"}}

{{localize "DAGGERHEART.ACTIONS.Settings.summon.hint"}}

+ {{!-- {{#each source as |entry index|}} +
+ {{formField ../fields.actorUUID label="DAGGERHEART.ACTIONS.Settings.summon.actor" value=entry.actorUUID name=(concat "summon." index ".actorUUID") localize=true classes="summon-actor-drop"}} + {{formField ../fields.count label="DAGGERHEART.ACTIONS.Settings.summon.count" value=entry.count name=(concat "summon." index ".count") localize=true}} +
+ {{/each}} --}}
diff --git a/templates/dialogs/summon/summonDialog.hbs b/templates/dialogs/summon/summonDialog.hbs index 61817b93..9e03e129 100644 --- a/templates/dialogs/summon/summonDialog.hbs +++ b/templates/dialogs/summon/summonDialog.hbs @@ -1,28 +1,24 @@
- {{localize "DAGGERHEART.APPLICATIONS.Summon.title"}} + {{localize "DAGGERHEART.DIALOGS.Summon.title"}} -

{{localize "DAGGERHEART.APPLICATIONS.Summon.hint"}}

+

{{localize "DAGGERHEART.DIALOGS.Summon.hint"}}

- -
    - {{#each summons as |entry index|}} -
  • + {{#each summons as |entry index|}} +
      {{#if (gte entry.count 1)}}

      - {{entry.name}} + {{entry.name}} (x{{entry.count}})

      - Count: {{entry.count}} {{else}}

      {{entry.name}}

      {{/if}}
      - - {{/each}} -
    +
+ {{/each}}
\ No newline at end of file