mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-18 07:59:03 +01:00
201 lines
6.5 KiB
JavaScript
201 lines
6.5 KiB
JavaScript
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
|
|
|
export default class BeastformDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
constructor(configData) {
|
|
super();
|
|
|
|
this.configData = configData;
|
|
this.selected = null;
|
|
this.evolved = { form: null };
|
|
this.hybrid = null;
|
|
|
|
this._dragDrop = this._createDragDropHandlers();
|
|
}
|
|
|
|
static DEFAULT_OPTIONS = {
|
|
tag: 'form',
|
|
classes: ['daggerheart', 'views', 'dh-style', 'beastform-selection'],
|
|
position: {
|
|
width: 'auto',
|
|
height: 'auto'
|
|
},
|
|
actions: {
|
|
selectBeastform: this.selectBeastform,
|
|
submitBeastform: this.submitBeastform
|
|
},
|
|
form: {
|
|
handler: this.updateBeastform,
|
|
submitOnChange: true,
|
|
submitOnClose: false
|
|
},
|
|
dragDrop: [{ dragSelector: '.beastform-container', dropSelector: '.advanced-form-container' }]
|
|
};
|
|
|
|
get title() {
|
|
return game.i18n.localize('DAGGERHEART.ITEMS.Beastform.dialogTitle');
|
|
}
|
|
|
|
/** @override */
|
|
static PARTS = {
|
|
beastform: {
|
|
template: 'systems/daggerheart/templates/dialogs/beastformDialog.hbs'
|
|
}
|
|
};
|
|
|
|
_createDragDropHandlers() {
|
|
return this.options.dragDrop.map(d => {
|
|
d.callbacks = {
|
|
dragstart: this._onDragStart.bind(this),
|
|
drop: this._onDrop.bind(this)
|
|
};
|
|
return new foundry.applications.ux.DragDrop.implementation(d);
|
|
});
|
|
}
|
|
|
|
_attachPartListeners(partId, htmlElement, options) {
|
|
super._attachPartListeners(partId, htmlElement, options);
|
|
|
|
this._dragDrop.forEach(d => d.bind(htmlElement));
|
|
}
|
|
|
|
async _prepareContext(_options) {
|
|
const context = await super._prepareContext(_options);
|
|
|
|
context.selected = this.selected;
|
|
context.selectedBeastformEffect = this.selected?.effects?.find?.(x => x.type === 'beastform');
|
|
|
|
context.evolved = this.evolved;
|
|
context.hybrid = this.hybrid;
|
|
|
|
const maximumDragTier = Math.max(
|
|
this.selected?.system?.evolved?.maximumTier ?? 0,
|
|
this.selected?.system?.hybrid?.maximumTier ?? 0
|
|
);
|
|
|
|
const compendiumBeastforms = await game.packs.get(`daggerheart.beastforms`)?.getDocuments();
|
|
context.beastformTiers = [...(compendiumBeastforms ? compendiumBeastforms : []), ...game.items].reduce(
|
|
(acc, x) => {
|
|
const tier = CONFIG.DH.GENERAL.tiersAlternate[x.system.tier];
|
|
if (x.type !== 'beastform' || tier.id > this.configData.tierLimit) return acc;
|
|
|
|
if (!acc[tier.id]) acc[tier.id] = { label: game.i18n.localize(tier.label), values: {} };
|
|
|
|
acc[tier.id].values[x.uuid] = {
|
|
selected: this.selected?.uuid == x.uuid,
|
|
value: x,
|
|
draggable: maximumDragTier ? x.system.tier <= maximumDragTier : false
|
|
};
|
|
|
|
return acc;
|
|
},
|
|
{}
|
|
); // Also get from compendium when added
|
|
|
|
context.canSubmit = this.canSubmit();
|
|
|
|
return context;
|
|
}
|
|
|
|
canSubmit() {
|
|
if (this.selected) {
|
|
switch (this.selected.system.beastformType) {
|
|
case 'normal':
|
|
return true;
|
|
case 'evolved':
|
|
return this.evolved.form;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static updateBeastform(event, _, formData) {
|
|
this.selected = foundry.utils.mergeObject(this.selected, formData.object);
|
|
|
|
this.render();
|
|
}
|
|
|
|
static async selectBeastform(_, target) {
|
|
this.element.querySelectorAll('.beastform-container ').forEach(element => {
|
|
if (element.dataset.uuid === target.dataset.uuid && this.selected?.uuid !== target.dataset.uuid) {
|
|
element.classList.remove('inactive');
|
|
} else {
|
|
element.classList.add('inactive');
|
|
}
|
|
});
|
|
|
|
const uuid = this.selected?.uuid === target.dataset.uuid ? null : target.dataset.uuid;
|
|
this.selected = uuid ? await foundry.utils.fromUuid(uuid) : null;
|
|
|
|
if (this.selected && this.selected.system.beastformType !== CONFIG.DH.ITEM.beastformTypes.normal.id) {
|
|
this.element.querySelector('.advanced-container').classList.add('expanded');
|
|
} else {
|
|
this.element.querySelector('.advanced-container').classList.remove('expanded');
|
|
}
|
|
|
|
if (this.selected) {
|
|
if (this.selected.system.beastformType !== 'evolved') this.evolved.form = null;
|
|
if (this.selected.system.beastformType !== 'hybrid') this.hybrid = null;
|
|
}
|
|
|
|
this.render();
|
|
}
|
|
|
|
static async submitBeastform() {
|
|
await this.close({ submitted: true });
|
|
}
|
|
|
|
/** @override */
|
|
_onClose(options = {}) {
|
|
if (!options.submitted) this.selected = null;
|
|
}
|
|
|
|
static async configure(configData) {
|
|
return new Promise(resolve => {
|
|
const app = new this(configData);
|
|
app.addEventListener(
|
|
'close',
|
|
() => resolve({ selected: app.selected, evolved: app.evolved, hybrid: app.hybrid }),
|
|
{ once: true }
|
|
);
|
|
app.render({ force: true });
|
|
});
|
|
}
|
|
|
|
async _onDragStart(event) {
|
|
const target = event.currentTarget;
|
|
if (!this.selected) {
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
|
|
const draggedForm = await foundry.utils.fromUuid(target.dataset.uuid);
|
|
if (this.selected.system.beastformType === 'evolved') {
|
|
if (draggedForm.system.tier > this.selected.system.evolved.maximumTier) {
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
}
|
|
if (this.selected.system.beastformType === 'hybrid') {
|
|
if (draggedForm.system.tier > this.selected.system.hybrid.maximumTier) {
|
|
event.preventDefault();
|
|
return;
|
|
}
|
|
}
|
|
|
|
event.dataTransfer.setData('text/plain', JSON.stringify(target.dataset));
|
|
event.dataTransfer.setDragImage(target, 60, 0);
|
|
}
|
|
|
|
async _onDrop(event) {
|
|
event.stopPropagation();
|
|
const data = foundry.applications.ux.TextEditor.getDragEventData(event);
|
|
const item = await fromUuid(data.uuid);
|
|
|
|
if (event.target.closest('.advanced-form-container.evolved')) {
|
|
this.evolved.form = item;
|
|
}
|
|
|
|
this.render();
|
|
}
|
|
}
|