diff --git a/src/module/sheets/creatureSheet.mjs b/src/module/sheets/creatureSheet.mjs index 2c28134d..93d21402 100644 --- a/src/module/sheets/creatureSheet.mjs +++ b/src/module/sheets/creatureSheet.mjs @@ -1,32 +1,114 @@ -export class CreatureSheet extends foundry.appv1.sheets.ActorSheet { - /**@override */ - static get defaultOptions() { - return foundry.utils.mergeObject(super.defaultOptions, { - classes: ['dsa41', 'sheet', 'actor', 'creature'], - width: 520, - height: 480, +const {HandlebarsApplicationMixin} = foundry.applications.api +const {ActorSheetV2} = foundry.applications.sheets + +export class CreatureSheet extends HandlebarsApplicationMixin(ActorSheetV2) { + + /** @inheritDoc */ + static DEFAULT_OPTIONS = { + position: {width: 520, height: 480}, + classes: ['dsa41', 'sheet', 'actor', 'creature'], + tag: 'form', + form: { + submitOnChange: true, + closeOnSubmit: false, + handler: CreatureSheet.#onSubmitForm + }, + actions: { + removeAttack: CreatureSheet.#removeAttack, + addAttack: CreatureSheet.#addAttack, + roll: CreatureSheet.#dieRoll, + editImage: ActorSheetV2.DEFAULT_OPTIONS.actions.editImage, + + } + } + + static TABS = { + sheet: { tabs: [ - { - navSelector: '.sheet-tabs', - contentSelector: '.sheet-body', - initial: 'meta', - }, + {id: 'meta', group: 'sheet', label: 'Meta'}, + {id: 'attacks', group: 'sheet', label: 'Attacken'}, + {id: 'description', group: 'sheet', label: 'Beschreibung'}, ], + initial: 'meta' + } + } + + /** @inheritDoc */ + static PARTS = { + form: { + template: `systems/DSA_4-1/templates/actor/creature/main-sheet.hbs` + }, + meta: { + template: `systems/DSA_4-1/templates/actor/creature/tab-meta.hbs` + }, + attacks: { + template: `systems/DSA_4-1/templates/actor/creature/tab-attacks.hbs` + }, + description: { + template: `systems/DSA_4-1/templates/actor/creature/tab-description.hbs` + } + } + + /** + * 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 + } + + static async #removeAttack(evt) { + const {index} = evt.srcElement.dataset; + let sans = Array.from(this.document.system.attacks); + sans.splice(index, 1); + await this.document.update({'system.attacks': sans}) + } + + static async #dieRoll(evt) { + const {rollType, rollName, roll} = evt.srcElement.dataset; + let r = new Roll(roll, this.document.getRollData()); + const label = `${rollType} (${rollName})` + await r.toMessage({ + speaker: ChatMessage.getSpeaker({actor: this.document}), + flavor: label, + rollMode: game.settings.get('core', 'rollMode'), }); } - /** @override */ - get template() { - return `systems/DSA_4-1/templates/actor/actor-creature-sheet.hbs`; + static async #addAttack() { + const name = this.element.querySelector('#attack_name').value + const at = this.element.querySelector('#attack_at').value + const pa = this.element.querySelector('#attack_pa').value + const tp = this.element.querySelector('#attack_tp').value + + const newAttack = { + name, + at, + pa, + tp + } + + await this.document.update({'system.attacks': [...this.document.system.attacks, newAttack]}) + + this.element.querySelector('#attack_name').value = "" + this.element.querySelector('#attack_at').value = "" + this.element.querySelector('#attack_pa').value = "" + this.element.querySelector('#attack_tp').value = "" } /** @override */ - getData() { + async _prepareContext(options) { - const context = super.getData(); - const actorData = context.data; + const context = await super._prepareContext(options); + const actorData = context.document; context.attacks = []; + context.actor = actorData; actorData.system.attacks.forEach((attack, index) => { context.attacks.push({ @@ -43,55 +125,7 @@ export class CreatureSheet extends foundry.appv1.sheets.ActorSheet { }) }) - return context; } - activateListeners(html) { - super.activateListeners(html); - - // Everything below here is only needed if the sheet is editable - if (!this.isEditable) return; - - html.on('click', '.remove-attack', async (evt) => { - const {index} = evt.target.dataset; - let sans = Array.from(this.object.system.attacks); - sans.splice(index, 1); - await this.object.update({'system.attacks': sans}) - }) - - html.on('click', '.attacks-die.die', async (evt) => { - const {rollType, rollName, roll} = evt.currentTarget.dataset; - let r = new Roll(roll, this.actor.getRollData()); - const label = `${rollType} (${rollName})` - await r.toMessage({ - speaker: ChatMessage.getSpeaker({actor: this.object}), - flavor: label, - rollMode: game.settings.get('core', 'rollMode'), - }); - }) - - html.on('click', '.editor .add-attack', async (evt) => { - const name = html[0].querySelector('#attack_name').value - const at = html[0].querySelector('#attack_at').value - const pa = html[0].querySelector('#attack_pa').value - const tp = html[0].querySelector('#attack_tp').value - - const newAttack = { - name, - at, - pa, - tp - } - - await this.object.update({'system.attacks': [...this.object.system.attacks, newAttack]}) - - evt.target.parentElement.querySelector('#attack_name').value = "" - evt.target.parentElement.querySelector('#attack_at').value = "" - evt.target.parentElement.querySelector('#attack_pa').value = "" - evt.target.parentElement.querySelector('#attack_tp').value = "" - }) - - } - } diff --git a/src/style/atoms/_svg.scss b/src/style/atoms/_svg.scss new file mode 100644 index 00000000..2092062b --- /dev/null +++ b/src/style/atoms/_svg.scss @@ -0,0 +1,3 @@ +svg { + pointer-events: none; +} \ No newline at end of file diff --git a/src/style/organisms/_creature-sheet.scss b/src/style/organisms/_creature-sheet.scss index 2ea8acd1..707971cd 100644 --- a/src/style/organisms/_creature-sheet.scss +++ b/src/style/organisms/_creature-sheet.scss @@ -6,169 +6,163 @@ .window-content { - form { + .sheet-header { + height: 64px; display: grid; - grid-template-columns: 1fr; - grid-template-rows: 74px 30px 1fr; - - .sheet-header { + grid-template-columns: 64px 1fr; + grid-template-rows: 1fr; + gap: 0 8px; + margin-bottom: 8px; + img { + width: 64px; height: 64px; - display: grid; - grid-template-columns: 64px max-content; - grid-template-rows: 1fr; - gap: 0 8px; - - img { - width: 64px; - height: 64px; - } - - input { - line-height: 64px; - height: 64px; - font-size: 2rem; - - } - } - .sheet-body { - .tab { - margin: 8px; + input { + line-height: 64px; + height: 64px; + font-size: 2rem; - height: 100%; - - div.input { - - height: 32px; - display: grid; - grid-template-columns: 120px 1fr; - - &.compound { - - grid-template-columns: 120px 140px 1fr; - - span { - width: 120px; - } - - - input { - width: 100px; - } - - } - - label { - height: 32px; - width: 100%; - - span { - width: 120px; - text-align: left; - line-height: 32px; - vertical-align: middle; - display: inline-block; - } - - input { - text-align: right; - line-height: 32px; - vertical-align: middle; - padding-left: 120px; - display: inline-block; - } - - } - - } - - table.attacks-table { - - td { - padding: 2px 4px; - } - } - - .rollable.tablecell { - position: relative; - - - .attacks-die { - width: 24px; - height: 24px; - position: absolute; - left: 4px; - top: 4px; - bottom: 2px; - z-index: 1; - - - svg { - stroke-width: 0.5; - - $color: #f30; - - .border { - fill: #0000; - } - - .center { - fill: $color; - stroke: colour.$rollable-die-border-color; - } - - .topleft { - fill: color.adjust($color, $lightness: numbers.$lighter_factor); - stroke: colour.$rollable-die-border-color; - } - - .bottomleft { - fill: color.adjust($color, $lightness: numbers.$lightest_factor); - stroke: colour.$rollable-die-border-color; - } - - .topright { - fill: color.adjust($color, $lightness: numbers.$darken_factor); - stroke: colour.$rollable-die-border-color; - } - - .bottomright, .bottom { - fill: color.adjust($color, $lightness: numbers.$darkest_factor); - stroke: colour.$rollable-die-border-color; - } - } - - - } - - input { - position: absolute; - left: 16px; - top: 4px; - bottom: 2px; - right: 4px; - width: unset; - text-indent: 12px; - } - } - - .button-inline { - border: unset; - background: unset; - } - - .editor { - height: 100%; - } - - } } } - } + div.input { + + height: 32px; + display: grid; + grid-template-columns: 120px 1fr; + + &.compound { + + grid-template-columns: 120px 140px 1fr; + + span { + width: 120px; + } + + + input { + width: 100px; + } + + } + + label { + height: 32px; + width: 100%; + + span { + width: 120px; + text-align: left; + line-height: 32px; + vertical-align: middle; + display: inline-block; + } + + input { + text-align: right; + line-height: 32px; + vertical-align: middle; + padding-left: 120px; + display: inline-block; + } + + } + + } + + table.attacks-table { + + margin: 0; + + td { + padding: 2px 4px; + } + } + + .rollable.tablecell { + position: relative; + + + .attacks-die { + width: 24px; + height: 24px; + position: absolute; + left: 4px; + top: 4px; + bottom: 2px; + z-index: 1; + + + svg { + stroke-width: 0.5; + + $color: #f30; + + .border { + fill: #0000; + } + + .center { + fill: $color; + stroke: colour.$rollable-die-border-color; + } + + .topleft { + fill: color.adjust($color, $lightness: numbers.$lighter_factor); + stroke: colour.$rollable-die-border-color; + } + + .bottomleft { + fill: color.adjust($color, $lightness: numbers.$lightest_factor); + stroke: colour.$rollable-die-border-color; + } + + .topright { + fill: color.adjust($color, $lightness: numbers.$darken_factor); + stroke: colour.$rollable-die-border-color; + } + + .bottomright, .bottom { + fill: color.adjust($color, $lightness: numbers.$darkest_factor); + stroke: colour.$rollable-die-border-color; + } + } + + + } + + input { + position: absolute; + left: 16px; + top: 4px; + bottom: 2px; + right: 4px; + width: unset; + text-indent: 12px; + } + } + + .button-inline { + border: unset; + background: unset; + } + + .editor { + height: 100%; + } + + .tab.active { + padding: 8px; + } + + .tab.attacks.active { + padding: 16px; + } + + } } diff --git a/src/style/styles.scss b/src/style/styles.scss index 8cd4c662..eb843ead 100644 --- a/src/style/styles.scss +++ b/src/style/styles.scss @@ -1,3 +1,4 @@ +@use "atoms/svg"; @use "molecules/rollable"; @use "molecules/lists"; @use "molecules/attributes"; diff --git a/src/templates/actor/actor-creature-sheet.hbs b/src/templates/actor/actor-creature-sheet.hbs deleted file mode 100644 index 221b9a79..00000000 --- a/src/templates/actor/actor-creature-sheet.hbs +++ /dev/null @@ -1,137 +0,0 @@ -
diff --git a/src/templates/actor/creature/main-sheet.hbs b/src/templates/actor/creature/main-sheet.hbs new file mode 100644 index 00000000..a59c040d --- /dev/null +++ b/src/templates/actor/creature/main-sheet.hbs @@ -0,0 +1,22 @@ +| Name | +Attacke | +Parade | +Schaden | ++ |
|---|---|---|---|---|
| + + | +
+
+ {{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
+
+
+ |
+
+
+ {{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
+
+
+ |
+
+
+ {{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
+
+
+ |
+ + + | +
| Attacke hinzufügen | +||||
| + + | + ++ + | ++ + | ++ + + | ++ + | + +