From 1f50e9533a6dbfc51595305c70bb7b0e2ab54157 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Sun, 8 Jun 2025 01:57:06 +0200 Subject: [PATCH] Preliminary cleanup in the class sheet --- lang/en.json | 10 +- module/applications/sheets/character.mjs | 241 +---------------------- module/data/item/domainCard.mjs | 39 +++- module/documents/actor.mjs | 5 - templates/sheets/parts/experience.hbs | 4 +- templates/sheets/pc/pc.hbs | 2 +- 6 files changed, 47 insertions(+), 254 deletions(-) diff --git a/lang/en.json b/lang/en.json index 0b2cd154..f64689f9 100755 --- a/lang/en.json +++ b/lang/en.json @@ -138,10 +138,6 @@ "AttackTargetDoesNotExist": "The target token no longer exists" }, "Error": { - "NoClassSelected": "Your character has no class selected!", - "LacksDomain": "Your character doesn't have the domain of the card!", - "MaxLoadoutReached": "You can't have any more domain cards at this level!", - "DuplicateDomainCard": "You already have a domain card with that name!", "ActionRequiresTarget": "The action requires at least one target", "NoAssignedPlayerCharacter": "You have no assigned character.", "NoSelectedToken": "You have no selected token", @@ -1189,7 +1185,11 @@ "MissingClass": "The character is missing a class", "SubclassNotInClass": "The subclass does not belong to the character's class", "ClassAlreadySelected": "The character already has a class", - "SubclassAlreadySelected": "The character already has a subclass for that class." + "SubclassAlreadySelected": "The character already has a subclass for that class.", + "NoClassSelected": "Your character has no class selected!", + "LacksDomain": "Your character doesn't have the domain of the card!", + "MaxLoadoutReached": "You can't have any more domain cards at this level!", + "DuplicateDomainCard": "You already have a domain card with that name!" } }, "Effects": { diff --git a/module/applications/sheets/character.mjs b/module/applications/sheets/character.mjs index 194f134a..3350631d 100644 --- a/module/applications/sheets/character.mjs +++ b/module/applications/sheets/character.mjs @@ -11,14 +11,6 @@ const { TextEditor } = foundry.applications.ux; export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { constructor(options = {}) { super(options); - - this.editAttributes = false; - this.onVaultTab = false; - this.currentInventoryPage = 0; - this.selectedScar = null; - this.storyEditor = null; - this.dropItemBlock = false; - this.multiclassFeatureSetSelected = false; } static DEFAULT_OPTIONS = { @@ -26,19 +18,13 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { classes: ['daggerheart', 'sheet', 'pc'], position: { width: 810, height: 1080 }, actions: { - toggleEditAttributes: this.toggleEditAttributes, attributeRoll: this.rollAttribute, toggleMarks: this.toggleMarks, - toggleAttributeMark: this.toggleAttributeMark, toggleHP: this.toggleHP, toggleStress: this.toggleStress, toggleHope: this.toggleHope, toggleGold: this.toggleGold, attackRoll: this.attackRoll, - tabToLoadout: () => this.domainCardsTab(false), - tabToVault: () => this.domainCardsTab(true), - sendToVault: this.moveDomainCard, - sendToLoadout: this.moveDomainCard, useDomainCard: this.useDomainCard, removeCard: this.removeDomainCard, selectClass: this.selectClass, @@ -49,20 +35,17 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { useFeature: this.useFeature, takeShortRest: this.takeShortRest, takeLongRest: this.takeLongRest, - addMiscItem: this.addMiscItem, deleteItem: this.deleteItem, addScar: this.addScar, - selectScar: this.selectScar, deleteScar: this.deleteScar, makeDeathMove: this.makeDeathMove, - setStoryEditor: this.setStoryEditor, itemQuantityDecrease: (_, button) => this.setItemQuantity(button, -1), itemQuantityIncrease: (_, button) => this.setItemQuantity(button, 1), useAbility: this.useAbility, useAdvancementCard: this.useAdvancementCard, useAdvancementAbility: this.useAdvancementAbility, - selectFeatureSet: this.selectFeatureSet, - toggleEquipItem: this.toggleEquipItem + toggleEquipItem: this.toggleEquipItem, + levelup: this.openLevelUp }, window: { minimizable: false, @@ -76,8 +59,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { dragDrop: [ { dragSelector: null, dropSelector: '.weapon-section' }, { dragSelector: null, dropSelector: '.armor-section' }, - { dragSelector: null, dropSelector: '.inventory-weapon-section-first' }, - { dragSelector: null, dropSelector: '.inventory-weapon-section-second' }, { dragSelector: '.item-list .item', dropSelector: null } ] }; @@ -166,22 +147,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); - htmlElement - .querySelectorAll('.attribute-value') - .forEach(element => element.addEventListener('change', this.attributeChange.bind(this))); - htmlElement - .querySelectorAll('.tab-selector') - .forEach(element => element.addEventListener('click', this.tabSwitch.bind(this))); - htmlElement.querySelector('.level-title.levelup')?.addEventListener('click', this.openLevelUp.bind(this)); - htmlElement - .querySelectorAll('.feature-input') - .forEach(element => element.addEventListener('change', this.onFeatureInputBlur.bind(this))); - htmlElement - .querySelectorAll('.experience-description') - .forEach(element => element.addEventListener('change', this.experienceDescriptionChange.bind(this))); - htmlElement - .querySelectorAll('.experience-value') - .forEach(element => element.addEventListener('change', this.experienceValueChange.bind(this))); + htmlElement.querySelector('.level-value').addEventListener('change', this.onLevelChange.bind(this)); } @@ -191,11 +157,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { context.tabs = this._getTabs(); context.config = SYSTEM; - context.editAttributes = this.editAttributes; - context.onVaultTab = this.onVaultTab; - context.selectedScar = this.selectedScar; - context.storyEditor = this.storyEditor; - context.multiclassFeatureSetSelected = this.multiclassFeatureSetSelected; const selectedAttributes = Object.values(this.document.system.traits).map(x => x.base); context.abilityScoreArray = JSON.parse( @@ -213,18 +174,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { if (!context.abilityScoreArray.includes(0)) context.abilityScoreArray.push({ name: 0, value: 0 }); context.abilityScoresFinished = context.abilityScoreArray.every(x => x.value === 0); - //FIXME: - context.domains = this.document.system.class.value - ? { - first: this.document.system.class.value.system.domains[0] - ? SYSTEM.DOMAIN.domains[this.document.system.class.value.system.domains[0]].src - : null, - second: this.document.system.class.value.system.domains[1] - ? SYSTEM.DOMAIN.domains[this.document.system.class.value.system.domains[1]].src - : null - } - : {}; - context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => { acc[key] = { ...this.document.system.traits[key], @@ -329,16 +278,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { ); } - async attributeChange(event) { - const path = `system.traits.${event.currentTarget.dataset.attribute}.base`; - await this.document.update({ [path]: event.currentTarget.value }); - } - - static toggleEditAttributes() { - this.editAttributes = !this.editAttributes; - this.render(); - } - static async rollAttribute(event, button) { const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll( { title: game.i18n.localize(abilities[button.dataset.attribute].label), value: button.dataset.value }, @@ -381,18 +320,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { await this.document.system.armor.update({ 'system.marks.value': newValue }); } - static async toggleAttributeMark(_, button) { - const attribute = this.document.system.traits[button.dataset.attribute]; - const newMark = this.document.system.availableAttributeMarks - .filter(x => x > Math.max.apply(null, this.document.system.traits[button.dataset.attribute].levelMarks)) - .sort((a, b) => (a > b ? 1 : -1))[0]; - - if (attribute.levelMark || !newMark) return; - - const path = `system.traits.${button.dataset.attribute}.levelMarks`; - await this.document.update({ [path]: [...attribute.levelMarks, newMark] }); - } - static async toggleHP(_, button) { const healthValue = Number.parseInt(button.dataset.value); const newValue = this.document.system.resources.hitPoints.value >= healthValue ? healthValue - 1 : healthValue; @@ -469,16 +396,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { await cls.create(msg.toObject()); } - tabSwitch(event) { - const tab = event.currentTarget.dataset.tab; - if (tab !== 'loadout') { - this.onVaultTab = false; - } - - this.render(); - } - - openLevelUp() { + static openLevelUp() { if (!this.document.system.class.value || !this.document.system.class.subclass) { ui.notifications.error(game.i18n.localize('DAGGERHEART.Sheets.PC.Errors.missingClassOrSubclass')); return; @@ -487,21 +405,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { new DhlevelUp(this.document).render(true); } - static domainCardsTab(toVault) { - this.onVaultTab = toVault; - this.render(); - } - - static async moveDomainCard(_, button) { - const toVault = button.dataset.action === 'sendToVault'; - if (!toVault && this.document.system.domainCards.loadout.length >= 5) { - return; - } - - const card = this.document.items.find(x => x.uuid === button.dataset.domain); - await card.update({ 'system.inVault': toVault }); - } - static async useDomainCard(_, button) { const card = this.document.items.find(x => x.uuid === button.dataset.key); @@ -548,7 +451,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { }); const result = await dialogClosed; - // await this.emulateItemDrop({ type: 'item', data: result }); for (var ancestry of this.document.items.filter(x => x => x.type === 'ancestry')) { await ancestry.delete(); } @@ -560,13 +462,9 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { await feature.delete(); } - // createdItems.push(...result.data.system.abilities); createdItems.push(result.data); await this.document.createEmbeddedDocuments('Item', createdItems); - - // await this.document.createEmbeddedDocuments("Item", [result.toObject()]); - // (await game.packs.get('daggerheart.playtest-ancestries'))?.render(true); } static async selectCommunity() { @@ -595,17 +493,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { await this.minimize(); } - static async addMiscItem() { - const result = await this.document.createEmbeddedDocuments('Item', [ - { - name: game.i18n.localize('DAGGERHEART.Sheets.PC.NewItem'), - type: 'miscellaneous' - } - ]); - - await result[0].sheet.render(true); - } - static async addScar() { if (this.document.system.story.scars.length === 5) return; @@ -617,11 +504,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { }); } - static async selectScar(_, button) { - this.selectedScar = Number.parseInt(button.dataset.value); - this.render(); - } - static async deleteScar(event, button) { event.stopPropagation(); await this.document.update({ @@ -638,21 +520,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { } } - async experienceDescriptionChange(event) { - const path = `system.experiences.${event.currentTarget.dataset.experience}.description`; - await this.document.update({ [path]: event.currentTarget.value }); - } - - async experienceValueChange(event) { - const path = `system.experiences.${event.currentTarget.dataset.index}.value`; - await this.document.update({ [path]: event.currentTarget.value }); - } - - static setStoryEditor(_, button) { - this.storyEditor = this.storyEditor === button.dataset.value ? null : button.dataset.value; - this.render(); - } - async itemUpdate(event) { const name = event.currentTarget.dataset.item; const item = await fromUuid($(event.currentTarget).closest('[data-item-id]')[0].dataset.itemId); @@ -760,7 +627,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { } static async useAdvancementAbility(_, button) { - // const item = await fromUuid(button.dataset.id); const item = this.document.items.find(x => x.uuid === button.dataset.id); const cls = getDocumentClass('ChatMessage'); @@ -783,12 +649,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { cls.create(msg.toObject()); } - static async selectFeatureSet(_, button) { - const multiclass = button.dataset.multiclass === 'true'; - this.multiclassFeatureSetSelected = multiclass; - this.render(); - } - static async toggleEquipItem(_, button) { const item = this.document.items.get(button.id); if (item.system.equipped) { @@ -814,11 +674,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { this.render(); } - static async close(options) { - this.onVaultTab = false; - super.close(options); - } - async _onDragStart(_, event) { if (event.currentTarget.classList.contains('inventory-item')) { if (!['weapon', 'armor'].includes(event.currentTarget.dataset.type)) { @@ -844,70 +699,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { } async _onDrop(event) { - const itemData = event.dataTransfer?.getData('text/plain'); - const item = itemData ? JSON.parse(itemData) : null; - if (item?.internal) { - let target = null; - event.currentTarget.classList.forEach(x => { - if (item.targets.some(target => target === x)) { - target = x; - } - }); - if (target) { - const itemObject = await fromUuid(item.uuid); - switch (target) { - case 'weapon-section': - if (itemObject.system.secondary && this.document.system.getWeaponBurden === 'twoHanded') { - ui.notifications.info( - game.i18n.localize('DAGGERHEART.Notification.Info.SecondaryEquipWhileTwohanded') - ); - return; - } else if (itemObject.system.burden === 'twoHanded' && this.document.system.secondaryWeapon) { - ui.notifications.info( - game.i18n.localize('DAGGERHEART.Notification.Info.TwohandedEquipWhileSecondary') - ); - return; - } - - const existingWeapon = this.document.items.find( - x => x.system.active && x.system.secondary === itemObject.system.secondary - ); - await existingWeapon?.update({ 'system.active': false }); - await itemObject.update({ 'system.active': true }); - break; - case 'armor-section': - const existingArmor = this.document.items.find(x => x.type === 'armor' && x.system.active); - await existingArmor?.update({ 'system.active': false }); - await itemObject.update({ 'system.active': true }); - break; - case 'inventory-weapon-section': - /* FIXME inventoryWeapon is no longer a field - const existingInventoryWeapon = this.document.items.find(x => x.system.inventoryWeapon); - await existingInventoryWeapon?.update({ 'system.inventoryWeapon': false }); - await itemObject.update({ 'system.inventoryWeapon': true }); - break; - */ - case 'inventory-armor-section': - const existingInventoryArmor = this.document.items.find(x => x.system.inventoryArmor); - await existingInventoryArmor?.update({ 'system.inventoryArmor': false }); - await itemObject.update({ 'system.inventoryArmor': true }); - break; - } - } - } else { - super._onDrop(event); - this._onDropItem(event, TextEditor.getDragEventData(event)); - } + super._onDrop(event); + this._onDropItem(event, TextEditor.getDragEventData(event)); } async _onDropItem(event, data) { - if (this.dropItemBlock) { - return; - } else { - this.dropItemBlock = true; - setTimeout(() => (this.dropItemBlock = false), 500); - } - const element = event.currentTarget; const item = await Item.implementation.fromDropData(data); const itemData = item.toObject(); @@ -915,26 +711,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { const createdItems = []; if (item.type === 'domainCard') { - if (!this.document.system.class.value) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.NoClassSelected')); - return; - } - - if (!this.document.system.domains.find(x => x === item.system.domain)) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.LacksDomain')); - return; - } - - if (this.document.system.domainCards.total.length === 5) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.MaxLoadoutReached')); - return; - } - - if (this.document.system.domainCards.total.find(x => x.name === item.name)) { - ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.DuplicateDomainCard')); - return; - } - if (this.document.system.domainCards.loadout.length >= 5) { itemData.system.inVault = true; } @@ -1004,9 +780,4 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { itemData = itemData instanceof Array ? itemData : [itemData]; return this.document.createEmbeddedDocuments('Item', itemData); } - - async emulateItemDrop(data) { - const event = new DragEvent('drop', { altKey: game.keyboard.isModifierActive('Alt') }); - return this._onDropItem(event, data); - } } diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs index 6986708f..75f0b8b9 100644 --- a/module/data/item/domainCard.mjs +++ b/module/data/item/domainCard.mjs @@ -1,13 +1,13 @@ -import DaggerheartAction from "../action.mjs"; -import BaseDataItem from "./base.mjs"; +import DaggerheartAction from '../action.mjs'; +import BaseDataItem from './base.mjs'; export default class DHDomainCard extends BaseDataItem { /** @inheritDoc */ static get metadata() { return foundry.utils.mergeObject(super.metadata, { - label: "TYPES.Item.domainCard", - type: "domainCard", - hasDescription: true, + label: 'TYPES.Item.domainCard', + type: 'domainCard', + hasDescription: true }); } @@ -19,10 +19,37 @@ export default class DHDomainCard extends BaseDataItem { domain: new fields.StringField({ choices: SYSTEM.DOMAIN.domains, required: true, blank: true }), level: new fields.NumberField({ initial: 1, integer: true }), recallCost: new fields.NumberField({ initial: 0, integer: true }), - type: new fields.StringField({ choices: SYSTEM.DOMAIN.cardTypes, required: true, blank: true}), + type: new fields.StringField({ choices: SYSTEM.DOMAIN.cardTypes, required: true, blank: true }), foundation: new fields.BooleanField({ initial: false }), inVault: new fields.BooleanField({ initial: false }), actions: new fields.ArrayField(new fields.EmbeddedDataField(DaggerheartAction)) }; } + + async _preCreate(data, options, user) { + const allowed = await super._preCreate(data, options, user); + if (allowed === false) return; + + if (this.actor?.type === 'pc') { + if (!this.actor.system.class.value) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.Item.Errors.NoClassSelected')); + return false; + } + + if (!this.actor.system.domains.find(x => x === item.system.domain)) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.Item.Errors.LacksDomain')); + return false; + } + + if (this.actor.system.domainCards.total.length === 5) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.Item.Errors.MaxLoadoutReached')); + return false; + } + + if (this.actor.system.domainCards.total.find(x => x.name === item.name)) { + ui.notifications.error(game.i18n.localize('DAGGERHEART.Item.Errors.DuplicateDomainCard')); + return false; + } + } + } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 0d5ae423..9eb20454 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -395,11 +395,6 @@ export default class DhpActor extends Actor { } } - async emulateItemDrop(data) { - const event = new DragEvent('drop', { altKey: game.keyboard.isModifierActive('Alt') }); - return this.sheet._onDropItem(event, { data: data }); - } - //Move to action-scope? async useAction(action) { const userTargets = Array.from(game.user.targets); diff --git a/templates/sheets/parts/experience.hbs b/templates/sheets/parts/experience.hbs index e6de5a4d..ace6970e 100644 --- a/templates/sheets/parts/experience.hbs +++ b/templates/sheets/parts/experience.hbs @@ -2,8 +2,8 @@ {{localize "DAGGERHEART.Sheets.PC.Experience.Title"}} {{#each document.system.experiences as |experience id|}}
- -
{{experience.value}}
+ +
{{experience.value}}
{{/each}} {{#times (subtract 5 (length document.system.experiences))}} diff --git a/templates/sheets/pc/pc.hbs b/templates/sheets/pc/pc.hbs index abeeb76a..5f2f5ad9 100644 --- a/templates/sheets/pc/pc.hbs +++ b/templates/sheets/pc/pc.hbs @@ -47,7 +47,7 @@ {{#if document.system.levelData.canLevelUp}}
*
{{/if}} -
{{localize "DAGGERHEART.Sheets.PC.Level"}}
+
{{localize "DAGGERHEART.Sheets.PC.Level"}}