implements creating Equipment from scratch and also an Equipment/Item Browser from where to drag and drop (perhaps even buy from) new Equipment onto an Actor.
parent
ed893f6b9d
commit
c2b8a7d895
|
|
@ -0,0 +1,132 @@
|
|||
import {Equipment} from "../documents/equipment.mjs";
|
||||
|
||||
const {
|
||||
ApplicationV2,
|
||||
HandlebarsApplicationMixin
|
||||
} = foundry.applications.api
|
||||
|
||||
export class ItemBrowserDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['dsa41', 'dialog', 'item-browser'],
|
||||
tag: "form",
|
||||
position: {
|
||||
width: 640,
|
||||
height: 480
|
||||
},
|
||||
window: {
|
||||
resizable: true,
|
||||
},
|
||||
actions: {
|
||||
buy: ItemBrowserDialog.#buy
|
||||
}
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: 'systems/DSA_4-1/templates/dialog/item-browser-dialog.hbs',
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Actor}
|
||||
* @private
|
||||
*/
|
||||
_actor = null
|
||||
/**
|
||||
*
|
||||
* @type {[Equipment]}
|
||||
* @private
|
||||
*/
|
||||
_items = []
|
||||
|
||||
constructor(actor) {
|
||||
super();
|
||||
this._actor = actor
|
||||
// load compendium data
|
||||
this._items = []
|
||||
}
|
||||
|
||||
static async #buy(event, target) {
|
||||
|
||||
}
|
||||
|
||||
_canDragDrop(event, options) {
|
||||
return game.user.isGM
|
||||
}
|
||||
|
||||
_canDrag(event, options) {
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* An event that occurs when a drag workflow begins for a draggable item on the sheet.
|
||||
* @param {DragEvent} event The initiating drag start event
|
||||
* @returns {Promise<void>}
|
||||
* @protected
|
||||
*/
|
||||
async _onDragStart(event) {
|
||||
const target = event.currentTarget;
|
||||
let dragData;
|
||||
|
||||
if (target.dataset.itemId) {
|
||||
dragData = {
|
||||
type: "Item",
|
||||
uuid: target.dataset.itemId
|
||||
}
|
||||
}
|
||||
|
||||
// Set data transfer
|
||||
if (!dragData) return;
|
||||
event.dataTransfer.setData("text/plain", JSON.stringify(dragData));
|
||||
}
|
||||
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options)
|
||||
context.items = this._items
|
||||
return context
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
|
||||
if (this._items.length === 0) {
|
||||
const compendia = [
|
||||
game.packs.get('DSA_4-1.Armor'),
|
||||
game.packs.get('DSA_4-1.Weapons'),
|
||||
game.packs.get('DSA_4-1.Ammunition'),
|
||||
game.packs.get('DSA_4-1.Items')
|
||||
]
|
||||
|
||||
for (const c of compendia) {
|
||||
const it = await c.getDocuments()
|
||||
it.forEach((item) => {
|
||||
const uuid = item.uuid
|
||||
const e = new Equipment(item)
|
||||
this._items.push({
|
||||
img: item.img,
|
||||
uuid,
|
||||
type: item.type,
|
||||
name: item.name,
|
||||
price: e.system.price,
|
||||
weight: e.system.weight,
|
||||
category: e.system.category.join(", ")
|
||||
})
|
||||
console.log("importing ", item.name)
|
||||
})
|
||||
console.log("done importing from ", c)
|
||||
}
|
||||
this.render({parts: ["form"]})
|
||||
}
|
||||
|
||||
new foundry.applications.ux.DragDrop.implementation({
|
||||
dropSelector: ".window-content",
|
||||
dragSelector: ".item",
|
||||
permissions: {
|
||||
drag: this._canDrag.bind(this)
|
||||
},
|
||||
callbacks: {
|
||||
dragstart: this._onDragStart.bind(this),
|
||||
}
|
||||
}).bind(this.element)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import {Talent} from "../data/talent.mjs";
|
|||
import {Character} from "../documents/character.mjs";
|
||||
import {currency} from "../handlebar-helpers/currency.mjs";
|
||||
import {DeityDataModel} from "../data/deity.mjs";
|
||||
import {ItemBrowserDialog} from "../dialog/itemBrowserDialog.mjs";
|
||||
|
||||
function initGlobalAccess() {
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ function initGlobalAccess() {
|
|||
Wunde,
|
||||
RestingDialog,
|
||||
BattleDialog,
|
||||
ItemBrowserDialog,
|
||||
Talent,
|
||||
displayCurrency: currency
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import {RestingDialog} from "../dialog/restingDialog.mjs";
|
|||
import {LiturgyDialog} from "../dialog/liturgyDialog.mjs";
|
||||
import {TalentDialog} from "../dialog/talentDialog.mjs";
|
||||
import {AttributeDialog} from "../dialog/attributeDialog.mjs";
|
||||
import {ItemBrowserDialog} from "../dialog/itemBrowserDialog.mjs";
|
||||
import * as EquipmentDocument from "../documents/equipment.mjs";
|
||||
|
||||
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
||||
const {ActorSheetV2} = foundry.applications.sheets
|
||||
|
|
@ -51,6 +53,8 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
rest: CharacterSheet.#startResting,
|
||||
removeEffect: CharacterSheet.#removeEffect,
|
||||
rollDamage: CharacterSheet.#rollDamage,
|
||||
openItemBrowser: CharacterSheet.#openItemBrowser,
|
||||
newItem: CharacterSheet.#addNewItem
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -250,6 +254,19 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
|
||||
}
|
||||
|
||||
static async #openItemBrowser(event, target) {
|
||||
new ItemBrowserDialog(this.document).render(true)
|
||||
}
|
||||
|
||||
static async #addNewItem(event, target) {
|
||||
let item = new EquipmentDocument.Equipment({
|
||||
name: "Neuer Gegenstand",
|
||||
type: "Equipment",
|
||||
})
|
||||
const items = await this.document.createEmbeddedDocuments("Item", [item])
|
||||
items[0].sheet.render(true)
|
||||
}
|
||||
|
||||
_configureRenderOptions(options) {
|
||||
super._configureRenderOptions(options)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
.dsa41.dialog.item-browser {
|
||||
|
||||
.window-content [data-application-part] {
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 240px 1fr;
|
||||
height: 100%;
|
||||
gap: 16px;
|
||||
|
||||
aside {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.scrollable-table {
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: 32px 1fr;
|
||||
overflow: hidden;
|
||||
|
||||
.header {
|
||||
display: grid;
|
||||
grid-template-columns: 64px 1fr 120px 120px 120px;
|
||||
gap: 4px;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
* {
|
||||
font-weight: bold;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-y {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
|
||||
border: 1px inset #ccc;
|
||||
|
||||
.item {
|
||||
display: grid;
|
||||
grid-template-columns: 64px 1fr 120px 120px 120px;
|
||||
gap: 4px;
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -36,3 +36,4 @@
|
|||
@use "organisms/liturgy-sheet";
|
||||
@use "organisms/dialog";
|
||||
@use "organisms/deity-sheet";
|
||||
@use "organisms/item-browser-dialog";
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
|
||||
<h3 class="inventory-header">Inventar </h3>
|
||||
<button data-action="newItem"><i class="fa-solid fa-sack" data-tooltip="Neuer Gegenstand"></i></button>
|
||||
<button data-action="openItemBrowser"><i class="fa-solid fa-store" data-tooltip="Einkaufen"></i></button>
|
||||
<div class="inventory">
|
||||
{{> "systems/DSA_4-1/templates/ui/partial-equipment-button.hbs" equipments}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<div>
|
||||
|
||||
<aside>
|
||||
|
||||
<fieldset>
|
||||
<legend>Name</legend>
|
||||
<input name="filter_name" type="text">
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Kategorie</legend>
|
||||
<select name="filter_category">
|
||||
</select>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Preis</legend>
|
||||
<input name="filter_price" type="range" min="{{minimumPrice}}" max="{{maximumPrice}}"/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Gewicht</legend>
|
||||
<input name="filter_weight" type="range" min="{{minimumWeight}}" max="{{maximumWeight}}"/>
|
||||
</fieldset>
|
||||
|
||||
</aside>
|
||||
|
||||
<div class="scrollable-table">
|
||||
<div class="header">
|
||||
<span></span>
|
||||
<span>Name</span>
|
||||
<span>Kategorie</span>
|
||||
<span>Preis</span>
|
||||
<span>Gewicht</span>
|
||||
</div>
|
||||
<div class="scroll-y items">
|
||||
{{#each items}}
|
||||
<div class="item" data-item-id="{{this.uuid}}" draggable="true">
|
||||
<img class="image" src="{{this.img}}" alt="{{this.name}}"/>
|
||||
<span class="name">{{this.name}}</span>
|
||||
<span class="category">{{this.category}}</span>
|
||||
<span class="price">{{currency this.price}}</span>
|
||||
<span class="weight">{{weight this.weight}}</span>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
Loading…
Reference in New Issue