diff --git a/src/module/data/group.mjs b/src/module/data/group.mjs index 9786dd34..f6ef784b 100644 --- a/src/module/data/group.mjs +++ b/src/module/data/group.mjs @@ -18,6 +18,7 @@ export class GroupDataModel extends foundry.abstract.TypeDataModel { quantity: new NumberField(), item: new DocumentIdField(Item) }), + groupId: new DocumentIdField(Actor), characters: new ArrayField( new DocumentIdField(Actor) ), @@ -25,4 +26,13 @@ export class GroupDataModel extends foundry.abstract.TypeDataModel { } } + _onCreate(data, options, userId) { + super._onCreate(data, options, userId); + Folder.implementation.createDocuments([{name: data.name, type: "Actor"}]).then(( + folder + ) => { + this.parent.update({"system.groupId": folder[0]._id}); + }) + } + } diff --git a/src/module/data/skill.mjs b/src/module/data/skill.mjs index 14c84a4c..90d2a4f1 100644 --- a/src/module/data/skill.mjs +++ b/src/module/data/skill.mjs @@ -45,10 +45,11 @@ export class SkillDataModel extends BaseItem { /** * Handle clickable rolls. - * @param {Event} event The originating click event + * @param {RollMode} rollMode * @private */ - async roll() { + async roll(rollMode = null) { + rollMode = rollMode ?? game.settings.get('core', 'rollMode'); const owner = this.parent.parent let roll1 = new Roll("3d20", owner.getRollData()); @@ -63,13 +64,13 @@ export class SkillDataModel extends BaseItem { evaluated1.toMessage({ speaker: ChatMessage.getSpeaker({actor: owner}), flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Meisterlich geschafft' : 'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`, - rollMode: game.settings.get('core', 'rollMode'), + rollMode, }) } else { // misserfolg evaluated1.toMessage({ speaker: ChatMessage.getSpeaker({actor: owner}), flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Gepatzt' : ''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`, - rollMode: game.settings.get('core', 'rollMode'), + rollMode, }) } } diff --git a/src/module/sheets/groupSheet.mjs b/src/module/sheets/groupSheet.mjs index 3edff152..7db70ed3 100644 --- a/src/module/sheets/groupSheet.mjs +++ b/src/module/sheets/groupSheet.mjs @@ -1,20 +1,52 @@ -export class GroupSheet extends foundry.appv1.sheets.ActorSheet { - /**@override */ - static get defaultOptions() { - return foundry.utils.mergeObject(super.defaultOptions, { - classes: ['dsa41', 'sheet', 'actor', 'group'], - width: 520, - height: 480, - tabs: [ - { - navSelector: '.sheet-tabs', - contentSelector: '.sheet-body', - initial: 'description', - }, - ], - }); +const {HandlebarsApplicationMixin} = foundry.applications.api +const {ActorSheetV2} = foundry.applications.sheets + +export class GroupSheet extends HandlebarsApplicationMixin(ActorSheetV2) { + + /** @inheritDoc */ + static DEFAULT_OPTIONS = { + position: {width: 520, height: 480}, + classes: ['dsa41', 'sheet', 'actor', 'group'], + tag: 'form', + form: { + submitOnChange: true, + closeOnSubmit: false, + handler: GroupSheet.#onSubmitForm + }, + actions: { + roll: GroupSheet.#dieRoll, + editImage: ActorSheetV2.DEFAULT_OPTIONS.actions.editImage, + openEmbeddedDocument: GroupSheet.#openEmbeddedDocument, + openActorDocument: GroupSheet.#openActorDocument, + removeFromParty: GroupSheet.#removeFromParty, + } } + static TABS = { + sheet: { + tabs: [ + {id: 'members', group: 'sheet', label: 'Gruppenmitglieder'}, + {id: 'inventory', group: 'sheet', label: 'Gruppeninventar'}, + // settings is only added on context + ], + initial: 'members' + } + } + + /** @inheritDoc */ + static PARTS = { + form: { + template: `systems/DSA_4-1/templates/actor/group/main-sheet.hbs` + }, + members: { + template: `systems/DSA_4-1/templates/actor/group/tab-members.hbs` + }, + inventory: { + template: `systems/DSA_4-1/templates/actor/group/tab-inventory.hbs` + }, + } + + static async onDroppedData(group, sheet, data) { if (data.type === "Actor") { const uuid = await foundry.utils.parseUuid(data.uuid); @@ -63,17 +95,52 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet { return s } - /** @override */ - get template() { - return `systems/DSA_4-1/templates/actor/group-sheet.hbs`; + static async #openEmbeddedDocument(evt) { + const {documentId} = evt.srcElement.dataset + this.document.items.get(documentId).sheet.render(true) + } + + static async #openActorDocument(evt) { + const {id} = evt.srcElement.dataset + evt.stopPropagation() + game.actors.get(id).sheet.render(true) + } + + static async #dieRoll(evt) { + console.log(evt) + } + + static async #removeFromParty(evt) { + const dataset = evt.srcElement.dataset; + const group = this.document; + const charactersWithoutMember = group.system.characters.filter(id => id !== dataset.id) + group.update({ + system: { + characters: charactersWithoutMember + } + }) + + } + + /** + * Handle form submission + * @this {AdvantageSheet} + * @param {SubmitEvent} event + * @param {HTMLFormElement} form + * @param {FormDataExtended} formData + */ + static async #onSubmitForm(event, form, formData) { + event.preventDefault() + + await this.document.update(formData.object) // Note: formData.object } /** @override */ - async getData() { - const context = super.getData(); + async _prepareContext(options) { + const context = await super._prepareContext(options) // Use a safe clone of the actor data for further operations. - const groupData = context.data; + const groupData = context.document; // Add the actor's data to context.data for easier access, as well as flags. context.system = groupData.system; @@ -101,8 +168,11 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet { } } - for (const characterId of groupData.system.characters) { - const character = await game.actors.get(characterId) + // TODO hook on changes in the given folder + const characters = await game.folders.get(groupData.system.groupId).contents + console.log(characters) + + for (const character of characters) { character.items.filter((i) => i.type === "Advantage").filter((i) => hiddenFields.includes(this.#stringToKeyFieldName(i.name))).map((advantage) => { const n = this.#stringToKeyFieldName(advantage.name) @@ -154,7 +224,7 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet { } context.equipments = []; - const actorData = context.data; + const actorData = context.document; Object.values(actorData.items).forEach((item, index) => { if (item.type === "Equipment") { context.equipments.push({ @@ -173,110 +243,8 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet { return await context; } - openEmbeddedDocument(documentId) { - this.object.items.get(documentId).sheet.render(true) - } - - - _evaluateRoll(rolledDice, { - taw, - lowerThreshold = 1, - upperThreshold = 20, - countToMeisterlich = 3, - countToPatzer = 3, - werte = [] - }) { - let tap = taw; - let meisterlichCounter = 0; - let patzerCounter = 0; - let failCounter = 0; - - rolledDice.forEach((rolledDie, index) => { - if (tap < 0 && rolledDie.result > werte[index]) { - tap -= rolledDie.result - werte[index]; - if (tap < 0) { // konnte nicht vollständig ausgeglichen werden - failCounter++; - } - } else if (rolledDie.result > werte[index]) { // taw ist bereits aufgebraucht und wert kann nicht ausgeglichen werden - tap -= rolledDie.result - werte[index]; - failCounter++; - } - if (rolledDie.result <= lowerThreshold) meisterlichCounter++; - if (rolledDie.result > upperThreshold) patzerCounter++; - }) - - return { - tap, - meisterlich: meisterlichCounter === countToMeisterlich, - patzer: patzerCounter === countToPatzer, - } - } - - async _onTalentRoll(event) { - event.preventDefault(); - const dataset = event.currentTarget.dataset; - const actor = await game.actors.get(dataset.actorId); - console.log(dataset, actor) - if (dataset.rolleigenschaft1) { - let roll1 = new Roll("3d20", actor.getRollData()); - - let evaluated1 = (await roll1.evaluate()) - - const dsaDieRollEvaluated = this._evaluateRoll(evaluated1.terms[0].results, { - taw: dataset.taw, - werte: [dataset.rolleigenschaft1, dataset.rolleigenschaft2, dataset.rolleigenschaft3], - }) - - if (dsaDieRollEvaluated.tap >= 0) { // erfolg - evaluated1.toMessage({ - speaker: ChatMessage.getSpeaker({actor: actor}), - flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Meisterlich geschafft' : 'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`, - }, {rollMode: "gmroll"}) - } else { // misserfolg - evaluated1.toMessage({ - speaker: ChatMessage.getSpeaker({actor: actor}), - flavor: ` ${dsaDieRollEvaluated.meisterlich ? 'Gepatzt' : ''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`, - }, {rollMode: "gmroll"}) - } - } - } - - activateListeners(html) { - super.activateListeners(html); - - html.on('click', '.owneroption.clickable', async (evt) => { - const dataset = evt.target.dataset; - const group = this.object; - switch (dataset.operation) { - case "removeFromParty": - const charactersWithoutMember = group.system.characters.filter(id => id !== dataset.id) - await group.update({ - system: { - characters: charactersWithoutMember - } - }) - } - }); - html.on('click', '.header.clickable', async (evt) => { - const {id, operation} = evt.currentTarget.dataset; - if (operation === "openActorSheet") { - evt.stopPropagation(); - (await game.actors.get(id)).sheet.render(true); - } - }) - - - html.on('click', '.equipment', (evt) => { - this.openEmbeddedDocument(evt.target.dataset.id); - evt.stopPropagation(); - }) - - html.on('click', ".rollable", (evt) => { - this._onTalentRoll(evt) - evt.stopPropagation() - }) - - new ContextMenu(html, '.equipment', [ + _onRender(context, options) { + new ContextMenu(this.element, ".equipment", [ { name: "Aus dem Gruppeninventar entfernen", icon: '', @@ -285,6 +253,9 @@ export class GroupSheet extends foundry.appv1.sheets.ActorSheet { }, condition: () => true } - ]); + ], { + jQuery: false + }); } + } diff --git a/src/templates/actor/group-sheet.hbs b/src/templates/actor/group-sheet.hbs deleted file mode 100644 index 776e34e7..00000000 --- a/src/templates/actor/group-sheet.hbs +++ /dev/null @@ -1,121 +0,0 @@ -
diff --git a/src/templates/actor/group/main-sheet.hbs b/src/templates/actor/group/main-sheet.hbs new file mode 100644 index 00000000..3ac4260f --- /dev/null +++ b/src/templates/actor/group/main-sheet.hbs @@ -0,0 +1,20 @@ +| + | Anzahl | +Gewicht | + +|
|---|---|---|---|
| {{this.name}} | +{{this.quantity}} | +{{this.weight}} | +|
| + {{#each this.fields.head}} + |
+
+
+
+
+ {{#if this.isLimited}}
+
+ {{#each this.attributes}}
+
+ {{/if}}
+
+ {{this.value}}
+ {{this.name}}
+
+ {{/each}}
+ |
+ {{/each}}
+
|---|---|
| + {{ @key}} + | + + {{#each this}} +
+ {{#if (eq this "-")}}
+
+ {{else}}
+ {{#if this.taw}}
+
+ {{this.taw}} ({{this.eigenschaft1}}, {{this.eigenschaft2}}
+ , {{this.eigenschaft3}})
+
+ {{else}}
+ Ja
+ {{/if}}
+ {{/if}}
+ |
+ {{/each}}
+
+