mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
Support drag dropping currencies to actor sheets
This commit is contained in:
parent
9b4249b100
commit
71b40b1189
7 changed files with 122 additions and 106 deletions
|
|
@ -6,7 +6,6 @@ export { default as DamageReductionDialog } from './damageReductionDialog.mjs';
|
|||
export { default as DeathMove } from './deathMove.mjs';
|
||||
export { default as Downtime } from './downtime.mjs';
|
||||
export { default as ImageSelectDialog } from './imageSelectDialog.mjs';
|
||||
export { default as ItemTransferDialog } from './itemTransfer.mjs';
|
||||
export { default as MulticlassChoiceDialog } from './multiclassChoiceDialog.mjs';
|
||||
export { default as OwnershipSelection } from './ownershipSelection.mjs';
|
||||
export { default as RerollDamageDialog } from './rerollDamageDialog.mjs';
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class ItemTransferDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(item) {
|
||||
super({});
|
||||
|
||||
this.item = item;
|
||||
this.quantity = item.system.quantity;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return this.item.name;
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'dh-style', 'dialog', 'item-transfer'],
|
||||
position: { width: 300, height: 'auto' },
|
||||
window: { icon: 'fa-solid fa-hand-holding-hand' },
|
||||
actions: {
|
||||
finish: ItemTransferDialog.#finish
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false }
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
main: { template: 'systems/daggerheart/templates/dialogs/item-transfer.hbs' }
|
||||
};
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
|
||||
htmlElement.querySelector('.number-display').addEventListener('change', event => {
|
||||
this.quantity = isNaN(event.target.value) ? this.quantity : Number(event.target.value);
|
||||
this.render();
|
||||
});
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.item = this.item;
|
||||
context.quantity = this.quantity;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static async updateData(_event, _element, formData) {
|
||||
const { quantity } = foundry.utils.expandObject(formData.object);
|
||||
this.quantity = quantity;
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #finish() {
|
||||
this.close({ submitted: true });
|
||||
}
|
||||
|
||||
close(options = {}) {
|
||||
if (!options.submitted) this.quantity = null;
|
||||
|
||||
super.close();
|
||||
}
|
||||
|
||||
static async configure(item) {
|
||||
return new Promise(resolve => {
|
||||
const app = new this(item);
|
||||
app.addEventListener('close', () => resolve(app.quantity), { once: true });
|
||||
app.render({ force: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,10 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
}
|
||||
}
|
||||
],
|
||||
dragDrop: [{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }]
|
||||
dragDrop: [
|
||||
{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null },
|
||||
{ dragSelector: ".currency[data-currency] .drag-handle", dropSelector: null }
|
||||
]
|
||||
};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -254,14 +257,67 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
/* Application Drag/Drop */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
async #determineTransferQuantity({ originActor, item, currency }) {
|
||||
originActor ??= item?.actor;
|
||||
const max = item?.system.quantity ?? originActor.system.gold[currency] ?? null;
|
||||
if (!max || max === 0) return null;
|
||||
if (max === 1) return max;
|
||||
|
||||
const homebrewKey = CONFIG.DH.SETTINGS.gameSettings.Homebrew;
|
||||
const currencySetting = game.settings.get(CONFIG.DH.id, homebrewKey).currency?.[currency] ?? null;
|
||||
const name = item?.name ?? currencySetting?.label;
|
||||
|
||||
return foundry.applications.api.DialogV2.input({
|
||||
classes: ['daggerheart', 'dh-style', "item-transfer"],
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
"systems/daggerheart/templates/dialogs/item-transfer.hbs",
|
||||
{
|
||||
originActor: originActor,
|
||||
targetActor: this.document,
|
||||
itemImage: item?.img,
|
||||
currencyIcon: currencySetting?.icon,
|
||||
max,
|
||||
}
|
||||
),
|
||||
window: {
|
||||
title: name,
|
||||
icon: 'fa-solid fa-hand-holding-hand'
|
||||
},
|
||||
position: {
|
||||
width: 400,
|
||||
},
|
||||
ok: {
|
||||
label: game.i18n.localize("DAGGERHEART.APPLICATIONS.ItemTransfer.transfer"),
|
||||
callback: (_, button) => button.form.elements.quantity.value || null,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
event.stopPropagation();
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
if (data.type === 'Currency' && ['character', 'party'].includes(this.document.type)) {
|
||||
const originActor = await foundry.utils.fromUuid(data.originActor);
|
||||
if (!originActor || originActor.uuid === this.document.uuid) return;
|
||||
const currency = data.currency;
|
||||
const quantity = await this.#determineTransferQuantity({ originActor, currency });
|
||||
if (quantity) {
|
||||
originActor.update({ [`system.gold.${currency}`]: Math.max(0, originActor.system.gold[currency] - quantity) });
|
||||
this.document.update({ [`system.gold.${currency}`]: this.document.system.gold[currency] + quantity });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
return super._onDrop(event);
|
||||
}
|
||||
|
||||
async _onDropItem(event, item) {
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
const physicalActorTypes = ['character', 'party'];
|
||||
const originActor = item.actor;
|
||||
if (
|
||||
item.actor?.uuid === this.document.uuid ||
|
||||
!originActor ||
|
||||
!physicalActorTypes.includes(this.document.type)
|
||||
!['character', 'party'].includes(this.document.type)
|
||||
) {
|
||||
return super._onDropItem(event, item);
|
||||
}
|
||||
|
|
@ -270,10 +326,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
if (item.system.metadata.isInventoryItem) {
|
||||
if (item.system.metadata.isQuantifiable) {
|
||||
const actorItem = originActor.items.get(data.originId);
|
||||
const quantityTransfered =
|
||||
actorItem.system.quantity === 1
|
||||
? 1
|
||||
: await game.system.api.applications.dialogs.ItemTransferDialog.configure(item);
|
||||
const quantityTransfered = await this.#determineTransferQuantity({ item });
|
||||
|
||||
if (quantityTransfered) {
|
||||
if (quantityTransfered === actorItem.system.quantity) {
|
||||
|
|
@ -314,6 +367,16 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
* @param {DragEvent} event - The drag event
|
||||
*/
|
||||
async _onDragStart(event) {
|
||||
// Handle drag/dropping currencies
|
||||
const currencyEl = event.currentTarget.closest(".currency[data-currency]");
|
||||
if (currencyEl) {
|
||||
const currency = currencyEl.dataset.currency;
|
||||
const data = { type: 'Currency', currency, originActor: this.document.uuid };
|
||||
event.dataTransfer.setData('text/plain', JSON.stringify(data));
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle drag/dropping attacks
|
||||
const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]');
|
||||
if (attackItem) {
|
||||
const attackData = {
|
||||
|
|
@ -340,4 +403,4 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
|
||||
super._onDragStart(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +1,35 @@
|
|||
.daggerheart.dh-style.dialog.item-transfer {
|
||||
.item-transfer-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 42px;
|
||||
gap: 4px;
|
||||
.summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
|
||||
.actor-img {
|
||||
border-radius: 50%;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
object-fit: cover;
|
||||
object-position: top center;
|
||||
}
|
||||
|
||||
.number-display {
|
||||
text-align: center;
|
||||
.granted-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: var(--font-size-32);
|
||||
|
||||
img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-sheet-footer {
|
||||
padding-top: 8px;
|
||||
display: flex;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
label {
|
||||
flex: 0;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,18 @@
|
|||
<div>
|
||||
<div class="item-transfer-container">
|
||||
<input type="range" step="1" min="0" max="{{item.system.quantity}}" name="quantity" value="{{quantity}}" />
|
||||
<input type="text" value="{{quantity}}" class="number-display" />
|
||||
<div class="summary">
|
||||
<img class="actor-img" src="{{originActor.img}}" />
|
||||
<div class="granted-item">
|
||||
{{#if itemImage}}
|
||||
<img src="{{itemImage}}" />
|
||||
{{else}}
|
||||
<i inert class="currency-icon {{currencyIcon}}"></i>
|
||||
{{/if}}
|
||||
<i inert class="fa-solid fa-hand-holding"></i>
|
||||
</div>
|
||||
<img class="actor-img" src="{{targetActor.img}}" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>{{localize "DAGGERHEART.GENERAL.quantity"}}</label>
|
||||
<div class="form-fields">
|
||||
<range-picker step="1" min="1" max="{{max}}" name="quantity" value="{{max}}"></range-picker>
|
||||
</div>
|
||||
<footer class="item-sheet-footer">
|
||||
<button type="button" data-action="finish">{{localize "DAGGERHEART.APPLICATIONS.ItemTransfer.transfer"}}</button>
|
||||
</footer>
|
||||
</div>
|
||||
|
|
@ -14,10 +14,10 @@
|
|||
|
||||
{{#if this.inventory.hasCurrency}}
|
||||
<div class="currency-section">
|
||||
{{#each this.inventory.currencies as | currency |}}
|
||||
{{#each this.inventory.currencies as |currency key|}}
|
||||
{{#if currency.enabled}}
|
||||
<div class="input">
|
||||
<span>
|
||||
<div class="input currency" data-currency="{{key}}">
|
||||
<span class="drag-handle">
|
||||
<i class="{{currency.icon}}" inert></i> {{localize currency.label}}
|
||||
</span>
|
||||
<input type="text" name="{{currency.field.fieldPath}}" data-allow-delta value="{{currency.value}}" data-dtype="Number" min="0" step="1" />
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
{{#if inventory.hasCurrency}}
|
||||
<div class="currency-section">
|
||||
{{#each this.inventory.currencies as | currency |}}
|
||||
{{#each this.inventory.currencies as |currency key|}}
|
||||
{{#if currency.enabled}}
|
||||
<div class="input">
|
||||
<span>
|
||||
<div class="input currency" data-currency="{{key}}">
|
||||
<span class="drag-handle">
|
||||
<i class="{{currency.icon}}" inert></i> {{localize currency.label}}
|
||||
</span>
|
||||
<input type="text" name="{{currency.field.fieldPath}}" data-allow-delta value="{{currency.value}}" data-dtype="Number" min="0" step="1" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue