mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-18 07:59:03 +01:00
Compare commits
No commits in common. "f47a869af35461022a9bb7b27f3cb05f888b4bbc" and "e83202681ecddec76a6dbd33bf098fb9169f176e" have entirely different histories.
f47a869af3
...
e83202681e
6 changed files with 138 additions and 126 deletions
|
|
@ -610,10 +610,6 @@
|
||||||
"title": "{name} Resource",
|
"title": "{name} Resource",
|
||||||
"rerollDice": "Reroll Dice"
|
"rerollDice": "Reroll Dice"
|
||||||
},
|
},
|
||||||
"Summon": {
|
|
||||||
"title": "Summon Tokens",
|
|
||||||
"hint": "Drag tokens from the list below into the scene to summon them."
|
|
||||||
},
|
|
||||||
"TagTeamSelect": {
|
"TagTeamSelect": {
|
||||||
"title": "Tag Team Roll",
|
"title": "Tag Team Roll",
|
||||||
"leaderTitle": "Initiating Character",
|
"leaderTitle": "Initiating Character",
|
||||||
|
|
|
||||||
|
|
@ -5,46 +5,44 @@ export default class DHSummonDialog extends HandlebarsApplicationMixin(Applicati
|
||||||
super(summonData);
|
super(summonData);
|
||||||
// Initialize summons and index
|
// Initialize summons and index
|
||||||
this.summons = summonData.summons || [];
|
this.summons = summonData.summons || [];
|
||||||
|
this.index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PARTS = {
|
get_title() {
|
||||||
main: { template: 'systems/daggerheart/templates/dialogs/summon/summonDialog.hbs' }
|
return game.i18n.localize("DAGGERHEART.DIALOGS.SUMMON.title");
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
static DEFAULT_OPTIONS= {
|
static DEFAULT_OPTIONS= {
|
||||||
tag: 'form',
|
...super.DEFAULT_OPTIONS,
|
||||||
window: {
|
template: 'systems/daggerheart/module/applications/dialogs/summon/summonDialog.hbs',
|
||||||
title: "DAGGERHEART.APPLICATIONS.Summon.title",
|
|
||||||
resizable: false
|
|
||||||
},
|
|
||||||
position: {
|
|
||||||
width: 400,
|
width: 400,
|
||||||
height: 'auto'
|
height: 'auto',
|
||||||
},
|
|
||||||
classes: ['daggerheart', 'dialog', 'summon-dialog'],
|
classes: ['daggerheart', 'dialog', 'summon-dialog'],
|
||||||
dragDrop: [{dragSelector: '.summon-token'}],
|
dragDrop: [{ dragSelector: '.summon-token', dropSelector: null, handler:'onDrop'}]
|
||||||
};
|
};
|
||||||
|
|
||||||
async _prepareContext() {
|
async _prepareContext() {
|
||||||
const context = await super._prepareContext();
|
const context = await super._prepareContext();
|
||||||
context.summons=await Promise.all(this.summons.map(async(entry)=>{
|
context.summons=this.summons;
|
||||||
const actor = await fromUuid(entry.actorUUID);
|
context.index=this.index;
|
||||||
return {
|
|
||||||
...entry,
|
|
||||||
name: actor?.name || game.i18n.localize("DAGGERHEART.GENERAL.Unknown"),
|
|
||||||
img: actor?.img || 'icons/svg/mystery-man.svg',
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDragStart(event) {
|
getData(options={}) {
|
||||||
const uuid = event.currentTarget.dataset.uuid;
|
const data = super.getData(options);
|
||||||
if(!uuid) return;
|
data.summons=this.summons;
|
||||||
const dragData = { type: 'Actor', uuid: uuid };
|
data.index=this.index;
|
||||||
event.dataTransfer.effectAllowed = 'all';
|
return data;
|
||||||
event.dataTransfer.setData('text/plain', JSON.stringify(dragData));
|
}
|
||||||
|
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 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,54 @@
|
||||||
import DHBaseAction from './baseAction.mjs';
|
import DHBaseAction from './baseAction.mjs';
|
||||||
|
|
||||||
export default class DHSummonAction extends DHBaseAction {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,94 +1,61 @@
|
||||||
const fields = foundry.data.fields;
|
|
||||||
import DHSummonDialog from '../../../applications/dialogs/summonDialog.mjs';
|
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
|
* Action Workflow order
|
||||||
*/
|
*/
|
||||||
static order = 120;
|
static order = 120;
|
||||||
|
|
||||||
constructor(options = {}, context = {}) {
|
constructor(options = {}, context = {}) {
|
||||||
const summonFields = new fields.SchemaField({
|
const summonFields = {
|
||||||
|
summon: new fields.ArrayField(new fields.SchemaField({
|
||||||
actorUUID: new fields.DocumentUUIDField({
|
actorUUID: new fields.DocumentUUIDField({
|
||||||
type: 'Actor',
|
type: 'Actor',
|
||||||
required: true
|
required: true }),
|
||||||
}),
|
|
||||||
count: new fields.NumberField({
|
count: new fields.NumberField({
|
||||||
required: true,
|
required: true,
|
||||||
default: 1,
|
default: 1,
|
||||||
min: 1,
|
min: 1,
|
||||||
integer: true
|
integer: true })
|
||||||
})
|
}), { required: false, initial: [] })
|
||||||
});
|
};
|
||||||
super(summonFields, options, context);
|
super(summonFields, options, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async execute() {
|
/**
|
||||||
if(!canvas.scene){
|
* 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"));
|
ui.notifications.warn(game.i18n.localize("DAGGERHEART.ACTIONS.TYPES.summon.error"));
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
const validSummons = this.summon.filter(entry => entry.actorUUID);
|
return true;
|
||||||
if (validSummons.length === 0) {
|
|
||||||
console.log("No actors configured for this Summon action.");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Logic to perform the summon action - incomplete implementation
|
||||||
|
*/
|
||||||
|
|
||||||
for (const entry of validSummons) {
|
get defaultValues() {
|
||||||
const actor = await fromUuid(entry.actorUUID);
|
return {
|
||||||
}
|
summon: { actorUUID: "", count: 1 }
|
||||||
|
};
|
||||||
// //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}.`);
|
|
||||||
}
|
}
|
||||||
|
get canSummon() {
|
||||||
|
return game.user.can('TOKEN_CREATE');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,12 @@
|
||||||
{{localize "DAGGERHEART.ACTIONS.TYPES.summon.name"}}
|
{{localize "DAGGERHEART.ACTIONS.TYPES.summon.name"}}
|
||||||
</legend>
|
</legend>
|
||||||
<p class="hint">{{localize "DAGGERHEART.ACTIONS.Settings.summon.hint"}}</p>
|
<p class="hint">{{localize "DAGGERHEART.ACTIONS.Settings.summon.hint"}}</p>
|
||||||
|
{{!-- {{#each source as |entry index|}}
|
||||||
|
<div class="nest-inputs summon-entry">
|
||||||
|
{{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}}
|
||||||
|
</div>
|
||||||
|
{{/each}} --}}
|
||||||
|
|
||||||
<div class="drag-area summon-actor-drop">
|
<div class="drag-area summon-actor-drop">
|
||||||
<div class="actors-list summon-entry">
|
<div class="actors-list summon-entry">
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,24 @@
|
||||||
<fieldset class="one-column" data-key="summon">
|
<fieldset class="one-column" data-key="summon">
|
||||||
<legend>
|
<legend>
|
||||||
{{localize "DAGGERHEART.APPLICATIONS.Summon.title"}}
|
{{localize "DAGGERHEART.DIALOGS.Summon.title"}}
|
||||||
</legend>
|
</legend>
|
||||||
<p class="hint">{{localize "DAGGERHEART.APPLICATIONS.Summon.hint"}}</p>
|
<p class="hint">{{localize "DAGGERHEART.DIALOGS.Summon.hint"}}</p>
|
||||||
|
|
||||||
<div class="summons-list">
|
<div class="summons-list">
|
||||||
|
|
||||||
<ul class="actor-summon-item">
|
|
||||||
{{#each summons as |entry index|}}
|
{{#each summons as |entry index|}}
|
||||||
<li class="summon-token" draggable="true" data-uuid="{{entry.actorUUID}}">
|
<ul class="actor-summon-item">
|
||||||
<div class="actor-summon-line">
|
<div class="actor-summon-line">
|
||||||
<img class="image" src="{{entry.img}}" />
|
<img class="image" src="{{entry.img}}" />
|
||||||
{{#if (gte entry.count 1)}}
|
{{#if (gte entry.count 1)}}
|
||||||
<h4 class="h4">
|
<h4 class="h4">
|
||||||
{{entry.name}}
|
{{entry.name}} (x{{entry.count}})
|
||||||
</h4>
|
</h4>
|
||||||
<span>Count: {{entry.count}}</span>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<h4 class="h4 disabled">
|
<h4 class="h4 disabled">
|
||||||
{{entry.name}}
|
{{entry.name}}
|
||||||
</h4>
|
</h4>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
</ul>
|
||||||
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue