diff --git a/lang/en.json b/lang/en.json index 684fa06f..ff507b05 100755 --- a/lang/en.json +++ b/lang/en.json @@ -954,7 +954,8 @@ "Features": "Features", "Guide": "Character Guide", "Items": "Items", - "Appearance": "Appearance" + "Appearance": "Appearance", + "settings": "Settings" }, "Domains": "Domains", "DamageThresholds": { @@ -968,14 +969,14 @@ "Subclasses": "Subclasses", "Guide": { "Suggestions": { - "Title": "Suggested", + "Title": "Suggested Equipments", "Traits": { "Title": "Traits" } }, - "SuggestedPrimaryWeaponTitle": "Suggested Primary Weapon", - "SuggestedSecondaryWeaponTitle": "Suggested Secondary Weapon", - "SuggestedArmorTitle": "Suggested Armor", + "SuggestedPrimaryWeaponTitle": "Primary Weapon", + "SuggestedSecondaryWeaponTitle": "Secondary Weapon", + "SuggestedArmorTitle": "Armor", "Inventory": { "Title": "Inventory", "Take": "Take", diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index 21af5efb..5c031db0 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -1,7 +1,7 @@ export { default as DhpPCSheet } from './sheets/pc.mjs'; export { default as DhpAdversarySheet } from './sheets/adversary.mjs'; -export { default as DhpClassSheet } from './sheets/class.mjs'; -export { default as DhpSubclass } from './sheets/subclass.mjs'; +export { default as DhpClassSheet } from './sheets/items/class.mjs'; +export { default as DhpSubclass } from './sheets/items/subclass.mjs'; export { default as DhpFeatureSheet } from './sheets/items/feature.mjs'; export { default as DhpDomainCardSheet } from './sheets/items/domainCard.mjs'; export { default as DhpAncestry } from './sheets/items/ancestry.mjs'; diff --git a/module/applications/sheets/class.mjs b/module/applications/sheets/class.mjs deleted file mode 100644 index e9ec1305..00000000 --- a/module/applications/sheets/class.mjs +++ /dev/null @@ -1,483 +0,0 @@ -// import DhpApplicationMixin from '../daggerheart-sheet.mjs'; -// import Tagify from '@yaireo/tagify'; - -// export default class ClassSheet extends DhpApplicationMixin(ItemSheet) { -// static documentType = "class"; - -// /** @override */ -// static get defaultOptions() { -// return foundry.utils.mergeObject(super.defaultOptions, { -// classes: ["daggerheart", "sheet", "class"], -// width: 600, -// height: 'auto', -// resizable: false, -// tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "features" }], -// dragDrop: [ -// { dragSelector: '.suggested-item', dropSelector: null }, -// { dragSelector: null, dropSelector: '.take-section' }, -// { dragSelector: null, dropSelector: '.choice-a-section' }, -// { dragSelector: null, dropSelector: '.choice-b-section' }, -// { dragSelector: null, dropSelector: '.primary-weapon-section' }, -// { dragSelector: null, dropSelector: '.secondary-weapon-section' }, -// { dragSelector: null, dropSelector: '.armor-section' }, -// { dragSelector: null, dropSelector: null }, -// ] -// }); -// } - -// /** @override */ -// async getData() { -// const context = super.getData(); -// context.domains = this.object.system.domains.map(x => SYSTEM.DOMAIN.domains[x].name) - -// return context; -// } - -// activateListeners(html){ -// super.activateListeners(html); - -// const domainInput = $(html).find('.domain-input')[0]; -// const domainTagify = new Tagify(domainInput, { -// tagTextProp: "name", -// enforceWhitelist: true, -// whitelist : Object.keys(SYSTEM.DOMAIN.domains).map(key => { -// const domain = SYSTEM.DOMAIN.domains[key]; -// return { value: key, name: game.i18n.localize(domain.name), src: domain.src, background: domain.background }; -// }), -// maxTags: 2, -// callbacks : { invalid: this.onAddTag }, -// dropdown : { -// mapValueTo: 'name', -// searchKeys: ['name'], -// enabled: 0, -// maxItems: 20, -// closeOnSelect : true, -// highlightFirst: false, -// }, -// templates: { -// tag(tagData){ //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips? -// return ` -// -//
-// ${tagData[this.settings.tagTextProp] || tagData.value} -// -//
-//
`; -// }} -// }); - -// domainTagify.on('change', this.onDomainSelect.bind(this)); -// } - -// onAddTag(e){ -// if( e.detail.index ===2 ){ -// ui.notifications.info(game.i18n.localize("DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains")); -// } -// } - -// async onDomainSelect(event) { -// const domains = event.detail?.value ? JSON.parse(event.detail.value) : []; -// await this.object.update({ "system.domains": domains.map(x => x.value) }); -// this.render(true); -// } - -// async _handleAction(action, event, button) { -// switch(action){ -// case 'removeSubclass': -// await this.removeSubclass(button); -// break; -// case 'viewSubclass': -// await this.viewSubclass(button); -// break; -// case 'removeFeature': -// await this.removeFeature(button); -// break; -// case 'viewFeature': -// await this.viewFeature(button); -// break; -// case 'removeItem': -// await this.removeItem(event); -// break; -// case 'viewItem': -// await this.viewItem(button); -// break; -// case 'removePrimaryWeapon': -// await this.removePrimaryWeapon(event); -// break; -// case 'removeSecondaryWeapon': -// await this.removeSecondaryWeapon(event); -// break; -// case 'removeArmor': -// await this.removeArmor(event); -// break; -// } -// } - -// async removeSubclass(button){ -// await this.object.update({ "system.subclasses": this.object.system.subclasses.filter(x => x.uuid !== button.dataset.subclass)}); -// } - -// async viewSubclass(button){ -// const subclass = await fromUuid(button.dataset.subclass); -// subclass.sheet.render(true); -// } - -// async removeFeature(button){ -// await this.object.update({ "system.features": this.object.system.features.filter(x => x.uuid !== button.dataset.feature)}); -// } - -// async viewFeature(button){ -// const feature = await fromUuid(button.dataset.feature); -// feature.sheet.render(true); -// } - -// async removeItem(event){ -// event.stopPropagation(); -// const type = event.currentTarget.dataset.type; -// const path = `system.inventory.${type}`; -// await this.object.update({ [path]: this.object.system.inventory[type].filter(x => x.uuid !== event.currentTarget.dataset.item)}); -// } - -// async viewItem(button){ -// const item = await fromUuid(button.dataset.item); -// item.sheet.render(true); -// } - -// async removePrimaryWeapon(event){ -// event.stopPropagation(); -// await this.object.update({ "system.characterGuide.suggestedPrimaryWeapon": null }, { diff: false }); -// } - -// async removeSecondaryWeapon(event){ -// event.stopPropagation(); -// await this.object.update({ "system.characterGuide.suggestedSecondaryWeapon": null }, { diff: false }); -// } - -// async removeArmor(event){ -// event.stopPropagation(); -// await this.object.update({ "system.characterGuide.suggestedArmor": null }, { diff: false }); -// } - -// async _onDragStart(event){ -// if(event.currentTarget.classList.contains('suggested-item')){ -// event.dataTransfer.setData("text/plain", JSON.stringify({ type: 'Item', uuid: event.currentTarget.dataset.item })); -// } - -// super._onDragStart(event); -// } - -// async _onDrop(event) { -// const data = TextEditor.getDragEventData(event); -// const item = await fromUuid(data.uuid); -// if(item.type === 'subclass') { -// await this.object.update({ "system.subclasses": [...this.object.system.subclasses, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// else if(item.type === 'feature') { - -// await this.object.update({ "system.features": [...this.object.system.features, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// else if(item.type === 'weapon'){ -// if(event.currentTarget.classList.contains('primary-weapon-section')){ -// if(!this.object.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary) await this.object.update({ "system.characterGuide.suggestedPrimaryWeapon": { img: item.img, name: item.name, uuid: item.uuid } }); -// } else if(event.currentTarget.classList.contains('secondary-weapon-section')){ -// if(!this.object.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary) await this.object.update({ "system.characterGuide.suggestedSecondaryWeapon": { img: item.img, name: item.name, uuid: item.uuid } }); -// } -// } -// else if(item.type === 'armor'){ -// if(event.currentTarget.classList.contains('armor-section')){ -// if(!this.object.system.characterGuide.suggestedArmor) await this.object.update({ "system.characterGuide.suggestedArmor": { img: item.img, name: item.name, uuid: item.uuid } }); -// } -// } -// else if(event.currentTarget.classList.contains('choice-a-section')){ -// if(item.type === 'miscellaneous' || item.type === 'consumable'){ -// if(this.object.system.inventory.choiceA.length < 2) await this.object.update({ "system.inventory.choiceA": [...this.object.system.inventory.choiceA, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// } -// else if(item.type === 'miscellaneous'){ -// if(event.currentTarget.classList.contains('take-section')){ -// if(this.object.system.inventory.take.length < 3) await this.object.update({ "system.inventory.take": [...this.object.system.inventory.take, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// else if(event.currentTarget.classList.contains('choice-b-section')){ -// if(this.object.system.inventory.choiceB.length < 2) await this.object.update({ "system.inventory.choiceB": [...this.object.system.inventory.choiceB, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// } -// } -// } - -import DaggerheartSheet from './daggerheart-sheet.mjs'; -import Tagify from '@yaireo/tagify'; - -const { ItemSheetV2 } = foundry.applications.sheets; -const { TextEditor } = foundry.applications.ux; -export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'sheet', 'class'], - position: { width: 600 }, - actions: { - removeSubclass: this.removeSubclass, - viewSubclass: this.viewSubclass, - removeFeature: this.removeFeature, - viewFeature: this.viewFeature, - removeItem: this.removeItem, - viewItem: this.viewItem, - removePrimaryWeapon: this.removePrimaryWeapon, - removeSecondaryWeapon: this.removeSecondaryWeapon, - removeArmor: this.removeArmor - }, - form: { - handler: this.updateForm, - submitOnChange: true, - closeOnSubmit: false - }, - dragDrop: [ - { dragSelector: '.suggested-item', dropSelector: null }, - { dragSelector: null, dropSelector: '.take-section' }, - { dragSelector: null, dropSelector: '.choice-a-section' }, - { dragSelector: null, dropSelector: '.choice-b-section' }, - { dragSelector: null, dropSelector: '.primary-weapon-section' }, - { dragSelector: null, dropSelector: '.secondary-weapon-section' }, - { dragSelector: null, dropSelector: '.armor-section' }, - { dragSelector: null, dropSelector: null } - ] - }; - - static PARTS = { - form: { - id: 'feature', - template: 'systems/daggerheart/templates/sheets/class.hbs' - } - }; - - _getTabs() { - const tabs = { - features: { - active: true, - cssClass: '', - group: 'primary', - id: 'features', - icon: null, - label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Features') - }, - guide: { - active: false, - cssClass: '', - group: 'primary', - id: 'guide', - icon: null, - label: game.i18n.localize('DAGGERHEART.Sheets.Class.Tabs.Guide') - } - }; - for (const v of Object.values(tabs)) { - v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active; - v.cssClass = v.active ? 'active' : ''; - } - - return tabs; - } - - _attachPartListeners(partId, htmlElement, options) { - super._attachPartListeners(partId, htmlElement, options); - - const domainInput = htmlElement.querySelector('.domain-input'); - const domainTagify = new Tagify(domainInput, { - tagTextProp: 'name', - enforceWhitelist: true, - whitelist: Object.keys(SYSTEM.DOMAIN.domains).map(key => { - const domain = SYSTEM.DOMAIN.domains[key]; - return { - value: key, - name: game.i18n.localize(domain.label), - src: domain.src, - background: domain.background - }; - }), - maxTags: 2, - callbacks: { invalid: this.onAddTag }, - dropdown: { - mapValueTo: 'name', - searchKeys: ['name'], - enabled: 0, - maxItems: 20, - closeOnSelect: true, - highlightFirst: false - }, - templates: { - tag(tagData) { - //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips? - return ` - -
- ${tagData[this.settings.tagTextProp] || tagData.value} - -
-
`; - } - } - }); - - domainTagify.on('change', this.onDomainSelect.bind(this)); - } - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.document = this.document; - context.tabs = this._getTabs(); - context.domains = this.document.system.domains.map(x => SYSTEM.DOMAIN.domains[x].label); - - return context; - } - - static async updateForm(event, _, formData) { - await this.document.update(formData.object); - this.render(); - } - - onAddTag(e) { - if (e.detail.index === 2) { - ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains')); - } - } - - async onDomainSelect(event) { - const domains = event.detail?.value ? JSON.parse(event.detail.value) : []; - await this.document.update({ 'system.domains': domains.map(x => x.value) }); - this.render(true); - } - - static async removeSubclass(_, button) { - await this.document.update({ - 'system.subclasses': this.document.system.subclasses.filter(x => x.uuid !== button.dataset.subclass) - }); - } - - static async viewSubclass(_, button) { - const subclass = await fromUuid(button.dataset.subclass); - subclass.sheet.render(true); - } - - static async removeFeature(_, button) { - await this.document.update({ - 'system.features': this.document.system.features.filter(x => x.uuid !== button.dataset.feature) - }); - } - - static async viewFeature(_, button) { - const feature = await fromUuid(button.dataset.feature); - feature.sheet.render(true); - } - - static async removeItem(event, button) { - event.stopPropagation(); - const type = button.dataset.type; - const path = `system.inventory.${type}`; - await this.document.update({ - [path]: this.document.system.inventory[type].filter(x => x.uuid !== button.dataset.item) - }); - } - - static async viewItem(_, button) { - const item = await fromUuid(button.dataset.item); - item.sheet.render(true); - } - - static async removePrimaryWeapon(event) { - event.stopPropagation(); - await this.document.update({ 'system.characterGuide.suggestedPrimaryWeapon': null }, { diff: false }); - } - - static async removeSecondaryWeapon(event) { - event.stopPropagation(); - await this.document.update({ 'system.characterGuide.suggestedSecondaryWeapon': null }, { diff: false }); - } - - static async removeArmor(event) { - event.stopPropagation(); - await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false }); - } - - async _onDrop(event) { - const data = TextEditor.getDragEventData(event); - const item = await fromUuid(data.uuid); - if (item.type === 'subclass') { - await this.document.update({ - 'system.subclasses': [ - ...this.document.system.subclasses, - { img: item.img, name: item.name, uuid: item.uuid } - ] - }); - } else if (item.type === 'feature') { - await this.document.update({ - 'system.features': [ - ...this.document.system.features, - { img: item.img, name: item.name, uuid: item.uuid } - ] - }); - } else if (item.type === 'weapon') { - if (event.currentTarget.classList.contains('primary-weapon-section')) { - if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary) - await this.document.update({ - 'system.characterGuide.suggestedPrimaryWeapon': { - img: item.img, - name: item.name, - uuid: item.uuid - } - }); - } else if (event.currentTarget.classList.contains('secondary-weapon-section')) { - if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary) - await this.document.update({ - 'system.characterGuide.suggestedSecondaryWeapon': { - img: item.img, - name: item.name, - uuid: item.uuid - } - }); - } - } else if (item.type === 'armor') { - if (event.currentTarget.classList.contains('armor-section')) { - if (!this.document.system.characterGuide.suggestedArmor) - await this.document.update({ - 'system.characterGuide.suggestedArmor': { img: item.img, name: item.name, uuid: item.uuid } - }); - } - } else if (event.currentTarget.classList.contains('choice-a-section')) { - if (item.type === 'miscellaneous' || item.type === 'consumable') { - if (this.document.system.inventory.choiceA.length < 2) - await this.document.update({ - 'system.inventory.choiceA': [ - ...this.document.system.inventory.choiceA, - { img: item.img, name: item.name, uuid: item.uuid } - ] - }); - } - } else if (item.type === 'miscellaneous') { - if (event.currentTarget.classList.contains('take-section')) { - if (this.document.system.inventory.take.length < 3) - await this.document.update({ - 'system.inventory.take': [ - ...this.document.system.inventory.take, - { img: item.img, name: item.name, uuid: item.uuid } - ] - }); - } else if (event.currentTarget.classList.contains('choice-b-section')) { - if (this.document.system.inventory.choiceB.length < 2) - await this.document.update({ - 'system.inventory.choiceB': [ - ...this.document.system.inventory.choiceB, - { img: item.img, name: item.name, uuid: item.uuid } - ] - }); - } - } - } -} diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs new file mode 100644 index 00000000..2241a715 --- /dev/null +++ b/module/applications/sheets/items/class.mjs @@ -0,0 +1,270 @@ +import DaggerheartSheet from '../daggerheart-sheet.mjs'; +import Tagify from '@yaireo/tagify'; + +const { ItemSheetV2 } = foundry.applications.sheets; +const { TextEditor } = foundry.applications.ux; +export default class ClassSheet extends DaggerheartSheet(ItemSheetV2) { + static DEFAULT_OPTIONS = { + tag: 'form', + classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'class'], + position: { width: 700 }, + actions: { + removeSubclass: this.removeSubclass, + viewSubclass: this.viewSubclass, + removeFeature: this.removeFeature, + viewFeature: this.viewFeature, + removeItem: this.removeItem, + viewItem: this.viewItem, + removePrimaryWeapon: this.removePrimaryWeapon, + removeSecondaryWeapon: this.removeSecondaryWeapon, + removeArmor: this.removeArmor + }, + form: { + handler: this.updateForm, + submitOnChange: true, + closeOnSubmit: false + }, + dragDrop: [ + { dragSelector: '.suggested-item', dropSelector: null }, + { dragSelector: null, dropSelector: '.take-section' }, + { dragSelector: null, dropSelector: '.choice-a-section' }, + { dragSelector: null, dropSelector: '.choice-b-section' }, + { dragSelector: null, dropSelector: '.primary-weapon-section' }, + { dragSelector: null, dropSelector: '.secondary-weapon-section' }, + { dragSelector: null, dropSelector: '.armor-section' }, + { dragSelector: null, dropSelector: null } + ] + }; + + static PARTS = { + header: { template: 'systems/daggerheart/templates/sheets/items/class/header.hbs' }, + tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, + features: { + template: 'systems/daggerheart/templates/sheets/items/class/features.hbs', + scrollable: ['.features'] + }, + settings: { + template: 'systems/daggerheart/templates/sheets/items/class/settings.hbs', + scrollable: ['.settings'] + } + }; + + static TABS = { + features: { + active: true, + cssClass: '', + group: 'primary', + id: 'features', + icon: null, + label: 'DAGGERHEART.Sheets.Class.Tabs.Features' + }, + settings: { + active: false, + cssClass: '', + group: 'primary', + id: 'settings', + icon: null, + label: 'DAGGERHEART.Sheets.Class.Tabs.settings' + } + }; + + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + + const domainInput = htmlElement.querySelector('.domain-input'); + const domainTagify = new Tagify(domainInput, { + tagTextProp: 'name', + enforceWhitelist: true, + whitelist: Object.keys(SYSTEM.DOMAIN.domains).map(key => { + const domain = SYSTEM.DOMAIN.domains[key]; + return { + value: key, + name: game.i18n.localize(domain.label), + src: domain.src, + background: domain.background + }; + }), + maxTags: 2, + callbacks: { invalid: this.onAddTag }, + dropdown: { + mapValueTo: 'name', + searchKeys: ['name'], + enabled: 0, + maxItems: 20, + closeOnSelect: true, + highlightFirst: false + }, + templates: { + tag(tagData) { + //z-index: unset; background-image: ${tagData.background}; Maybe a domain specific background for the chips? + return ` + +
+ ${tagData[this.settings.tagTextProp] || tagData.value} + +
+
`; + } + } + }); + + domainTagify.on('change', this.onDomainSelect.bind(this)); + } + + async _prepareContext(_options) { + const context = await super._prepareContext(_options); + context.document = this.document; + context.tabs = super._getTabs(this.constructor.TABS); + context.domains = this.document.system.domains.map(x => SYSTEM.DOMAIN.domains[x].label); + + return context; + } + + static async updateForm(event, _, formData) { + await this.document.update(formData.object); + this.render(); + } + + onAddTag(e) { + if (e.detail.index === 2) { + ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ClassCanOnlyHaveTwoDomains')); + } + } + + async onDomainSelect(event) { + const domains = event.detail?.value ? JSON.parse(event.detail.value) : []; + await this.document.update({ 'system.domains': domains.map(x => x.value) }); + this.render(true); + } + + static async removeSubclass(_, button) { + await this.document.update({ + 'system.subclasses': this.document.system.subclasses.filter(x => x.uuid !== button.dataset.subclass) + }); + } + + static async viewSubclass(_, button) { + const subclass = await fromUuid(button.dataset.subclass); + subclass.sheet.render(true); + } + + static async removeFeature(_, button) { + await this.document.update({ + 'system.features': this.document.system.features.filter(x => x.uuid !== button.dataset.feature) + }); + } + + static async viewFeature(_, button) { + const feature = await fromUuid(button.dataset.feature); + feature.sheet.render(true); + } + + static async removeItem(event, button) { + event.stopPropagation(); + const type = button.dataset.type; + const path = `system.inventory.${type}`; + await this.document.update({ + [path]: this.document.system.inventory[type].filter(x => x.uuid !== button.dataset.item) + }); + } + + static async viewItem(_, button) { + const item = await fromUuid(button.dataset.item); + item.sheet.render(true); + } + + static async removePrimaryWeapon(event) { + event.stopPropagation(); + await this.document.update({ 'system.characterGuide.suggestedPrimaryWeapon': null }, { diff: false }); + } + + static async removeSecondaryWeapon(event) { + event.stopPropagation(); + await this.document.update({ 'system.characterGuide.suggestedSecondaryWeapon': null }, { diff: false }); + } + + static async removeArmor(event) { + event.stopPropagation(); + await this.document.update({ 'system.characterGuide.suggestedArmor': null }, { diff: false }); + } + + async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + const item = await fromUuid(data.uuid); + if (item.type === 'subclass') { + await this.document.update({ + 'system.subclasses': [ + ...this.document.system.subclasses, + { img: item.img, name: item.name, uuid: item.uuid } + ] + }); + } else if (item.type === 'feature') { + await this.document.update({ + 'system.features': [ + ...this.document.system.features, + { img: item.img, name: item.name, uuid: item.uuid } + ] + }); + } else if (item.type === 'weapon') { + if (event.currentTarget.classList.contains('primary-weapon-section')) { + if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary) + await this.document.update({ + 'system.characterGuide.suggestedPrimaryWeapon': { + img: item.img, + name: item.name, + uuid: item.uuid + } + }); + } else if (event.currentTarget.classList.contains('secondary-weapon-section')) { + if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary) + await this.document.update({ + 'system.characterGuide.suggestedSecondaryWeapon': { + img: item.img, + name: item.name, + uuid: item.uuid + } + }); + } + } else if (item.type === 'armor') { + if (event.currentTarget.classList.contains('armor-section')) { + if (!this.document.system.characterGuide.suggestedArmor) + await this.document.update({ + 'system.characterGuide.suggestedArmor': { img: item.img, name: item.name, uuid: item.uuid } + }); + } + } else if (event.currentTarget.classList.contains('choice-a-section')) { + if (item.type === 'miscellaneous' || item.type === 'consumable') { + if (this.document.system.inventory.choiceA.length < 2) + await this.document.update({ + 'system.inventory.choiceA': [ + ...this.document.system.inventory.choiceA, + { img: item.img, name: item.name, uuid: item.uuid } + ] + }); + } + } else if (item.type === 'miscellaneous') { + if (event.currentTarget.classList.contains('take-section')) { + if (this.document.system.inventory.take.length < 3) + await this.document.update({ + 'system.inventory.take': [ + ...this.document.system.inventory.take, + { img: item.img, name: item.name, uuid: item.uuid } + ] + }); + } else if (event.currentTarget.classList.contains('choice-b-section')) { + if (this.document.system.inventory.choiceB.length < 2) + await this.document.update({ + 'system.inventory.choiceB': [ + ...this.document.system.inventory.choiceB, + { img: item.img, name: item.name, uuid: item.uuid } + ] + }); + } + } + } +} diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs new file mode 100644 index 00000000..d34b8a3f --- /dev/null +++ b/module/applications/sheets/items/subclass.mjs @@ -0,0 +1,121 @@ +import DaggerheartSheet from '../daggerheart-sheet.mjs'; +import DaggerheartFeature from '../../../data/feature.mjs'; + +const { ItemSheetV2 } = foundry.applications.sheets; +const { TextEditor } = foundry.applications.ux; +const { duplicate, getProperty } = foundry.utils; +export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) { + static DEFAULT_OPTIONS = { + tag: 'form', + classes: ['daggerheart', 'sheet', 'item', 'dh-style', 'subclass'], + position: { width: 600 }, + window: { resizable: false }, + actions: { + editAbility: this.editAbility, + deleteFeatureAbility: this.deleteFeatureAbility + }, + form: { + handler: this.updateForm, + submitOnChange: true, + closeOnSubmit: false + }, + dragDrop: [ + { dragSelector: null, dropSelector: '.foundation-tab' }, + { dragSelector: null, dropSelector: '.specialization-tab' }, + { dragSelector: null, dropSelector: '.mastery-tab' } + ] + }; + + static PARTS = { + header: { template: 'systems/daggerheart/templates/sheets/items/subclass/header.hbs' }, + tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, + description: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-description.hbs' }, + features: { + template: 'systems/daggerheart/templates/sheets/items/subclass/features.hbs', + scrollable: ['.features'] + }, + settings: { + template: 'systems/daggerheart/templates/sheets/items/subclass/settings.hbs', + scrollable: ['.settings'] + } + }; + + static TABS = { + description: { + active: true, + cssClass: '', + group: 'primary', + id: 'description', + icon: null, + label: 'DAGGERHEART.Sheets.Feature.Tabs.Description' + }, + features: { + active: false, + cssClass: '', + group: 'primary', + id: 'features', + icon: null, + label: 'DAGGERHEART.Sheets.Feature.Tabs.Features' + }, + settings: { + active: false, + cssClass: '', + group: 'primary', + id: 'settings', + icon: null, + label: 'DAGGERHEART.Sheets.Feature.Tabs.Settings' + } + }; + + async _prepareContext(_options) { + const context = await super._prepareContext(_options); + context.document = this.document; + context.config = CONFIG.daggerheart; + context.tabs = super._getTabs(this.constructor.TABS); + + return context; + } + + static async updateForm(event, _, formData) { + await this.document.update(formData.object); + this.render(); + } + + static async editAbility(_, button) { + const feature = await fromUuid(button.dataset.ability); + feature.sheet.render(true); + } + + static async deleteFeatureAbility(event, button) { + event.preventDefault(); + event.stopPropagation(); + + const feature = button.dataset.feature; + const newAbilities = this.document.system[`${feature}Feature`].abilities.filter( + x => x.uuid !== button.dataset.ability + ); + const path = `system.${feature}Feature.abilities`; + + await this.document.update({ [path]: newAbilities }); + } + + async _onDrop(event) { + event.preventDefault(); + const data = TextEditor.getDragEventData(event); + const item = await fromUuid(data.uuid); + if (!(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id)) return; + + let featureField; + if (event.currentTarget.classList.contains('foundation-tab')) featureField = 'foundation'; + else if (event.currentTarget.classList.contains('specialization-tab')) featureField = 'specialization'; + else if (event.currentTarget.classList.contains('mastery-tab')) featureField = 'mastery'; + else return; + + const path = `system.${featureField}Feature.abilities`; + const abilities = duplicate(getProperty(this.document, path)) || []; + const featureData = { name: item.name, img: item.img, uuid: item.uuid }; + abilities.push(featureData); + + await this.document.update({ [path]: abilities }); + } +} diff --git a/module/applications/sheets/subclass.mjs b/module/applications/sheets/subclass.mjs deleted file mode 100644 index 40128ab0..00000000 --- a/module/applications/sheets/subclass.mjs +++ /dev/null @@ -1,204 +0,0 @@ -// import DhpApplicationMixin from '../daggerheart-sheet.mjs'; - -// export default class SubclassSheet extends DhpApplicationMixin(ItemSheet) { -// static documentType = "subclass"; - -// constructor(options){ -// super(options); -// } - -// static get defaultOptions() { -// return foundry.utils.mergeObject(super.defaultOptions, { -// classes: ["daggerheart", "sheet", "subclass"], -// width: 600, -// height: 720, -// tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "general" }], -// dragDrop: [ -// { dragSelector: null, dropSelector: '.foundation-tab' }, -// { dragSelector: null, dropSelector: '.specialization-tab' }, -// { dragSelector: null, dropSelector: '.mastery-tab' } -// ], -// }); -// } - -// getData() { -// const context = super.getData(); -// context.config = CONFIG.daggerheart; - -// return context; -// } - -// async _handleAction(action, event, button) { -// switch(action){ -// case "editAbility": -// this.editAbility(button); -// break; -// case "deleteFeatureAbility": -// this.deleteFeatureAbility(event); -// break; -// } -// } - -// async editAbility(button){ -// const feature = await fromUuid(button.dataset.ability); -// feature.sheet.render(true); -// } - -// async deleteFeatureAbility(event){ -// event.preventDefault(); -// event.stopPropagation(); - -// const feature = event.currentTarget.dataset.feature; -// const newAbilities = this.item.system[`${feature}Feature`].abilities.filter(x => x.uuid !== event.currentTarget.dataset.ability); -// const path = `system.${feature}Feature.abilities`; - -// await this.item.update({ [path]: newAbilities }); -// } - -// async _onDrop(event) { -// const data = TextEditor.getDragEventData(event); -// const item = await fromUuid(data.uuid); -// if(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id) { -// if(event.currentTarget.classList.contains('foundation-tab')){ -// await this.object.update({ "system.foundationFeature.abilities": [...this.item.system.foundationFeature.abilities, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// else if(event.currentTarget.classList.contains('specialization-tab')){ -// await this.object.update({ "system.specializationFeature.abilities": [...this.item.system.specializationFeature.abilities, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// else if(event.currentTarget.classList.contains('mastery-tab')){ -// await this.object.update({ "system.masteryFeature.abilities": [...this.item.system.masteryFeature.abilities, { img: item.img, name: item.name, uuid: item.uuid }] }); -// } -// } -// } -// } - -import DaggerheartSheet from './daggerheart-sheet.mjs'; -import DaggerheartFeature from '../../data/feature.mjs'; - -const { ItemSheetV2 } = foundry.applications.sheets; -const { TextEditor } = foundry.applications.ux; -const { duplicate, getProperty } = foundry.utils; -export default class SubclassSheet extends DaggerheartSheet(ItemSheetV2) { - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'sheet', 'subclass'], - position: { width: 600, height: 600 }, - window: { resizable: true }, - actions: { - editAbility: this.editAbility, - deleteFeatureAbility: this.deleteFeatureAbility - }, - form: { - handler: this.updateForm, - submitOnChange: true, - closeOnSubmit: false - }, - dragDrop: [ - { dragSelector: null, dropSelector: '.foundation-tab' }, - { dragSelector: null, dropSelector: '.specialization-tab' }, - { dragSelector: null, dropSelector: '.mastery-tab' } - ] - }; - - _getTabs() { - const tabs = { - general: { - active: true, - cssClass: '', - group: 'primary', - id: 'general', - icon: null, - label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.General') - }, - foundation: { - active: false, - cssClass: '', - group: 'primary', - id: 'foundation', - icon: null, - label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Foundation') - }, - specialization: { - active: false, - cssClass: '', - group: 'primary', - id: 'specialization', - icon: null, - label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Specialization') - }, - mastery: { - active: false, - cssClass: '', - group: 'primary', - id: 'mastery', - icon: null, - label: game.i18n.localize('DAGGERHEART.Sheets.Subclass.Tabs.Mastery') - } - }; - for (const v of Object.values(tabs)) { - v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active; - v.cssClass = v.active ? 'active' : ''; - } - - return tabs; - } - - static PARTS = { - form: { - id: 'feature', - template: 'systems/daggerheart/templates/sheets/subclass.hbs' - } - }; - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.document = this.document; - context.config = CONFIG.daggerheart; - context.tabs = this._getTabs(); - - return context; - } - - static async updateForm(event, _, formData) { - await this.document.update(formData.object); - this.render(); - } - - static async editAbility(_, button) { - const feature = await fromUuid(button.dataset.ability); - feature.sheet.render(true); - } - - static async deleteFeatureAbility(event, button) { - event.preventDefault(); - event.stopPropagation(); - - const feature = button.dataset.feature; - const newAbilities = this.document.system[`${feature}Feature`].abilities.filter( - x => x.uuid !== button.dataset.ability - ); - const path = `system.${feature}Feature.abilities`; - - await this.document.update({ [path]: newAbilities }); - } - - async _onDrop(event) { - event.preventDefault(); - const data = TextEditor.getDragEventData(event); - const item = await fromUuid(data.uuid); - if (!(item.type === 'feature' && item.system.type === SYSTEM.ITEM.featureTypes.subclass.id)) return; - - let featureField; - if (event.currentTarget.classList.contains('foundation-tab')) featureField = 'foundation'; - else if (event.currentTarget.classList.contains('specialization-tab')) featureField = 'specialization'; - else if (event.currentTarget.classList.contains('mastery-tab')) featureField = 'mastery'; - else return; - - const path = `system.${featureField}Feature.abilities`; - const abilities = duplicate(getProperty(this.document, path)) || []; - const featureData = { name: item.name, img: item.img, uuid: item.uuid }; - abilities.push(featureData); - - await this.document.update({ [path]: abilities }); - } -} diff --git a/styles/daggerheart.css b/styles/daggerheart.css index 4353bacb..2c1ae691 100755 --- a/styles/daggerheart.css +++ b/styles/daggerheart.css @@ -2268,9 +2268,6 @@ div.daggerheart.views.multiclass { .daggerheart.sheet.heritage .editor { height: 200px; } -.daggerheart.sheet.class .guide .guide-section { - gap: 8px; -} .daggerheart.sheet.class .guide .drop-section { width: 100%; } @@ -2290,18 +2287,12 @@ div.daggerheart.views.multiclass { min-width: 24px; } .daggerheart.sheet.class .guide .suggested-item { - padding: 2px 4px; border-radius: 6px; - border: 1px solid black; - background: #778899; display: flex; justify-content: space-between; align-items: center; width: 100%; } -.daggerheart.sheet.class .guide .suggested-item:not(:last-child) { - margin: 4px; -} .daggerheart.sheet.class .guide .suggested-item img { width: 30px; } @@ -2322,9 +2313,6 @@ div.daggerheart.views.multiclass { font-size: 14px; font-weight: bold; } -.daggerheart.sheet.class .guide .extra-section .extra-input { - margin-bottom: 4px; -} .daggerheart.sheet.class .guide-section-title-centered { font-weight: bold; font-size: 18px; @@ -2340,27 +2328,10 @@ div.daggerheart.views.multiclass { font-size: 14px; text-align: center; } -.daggerheart.sheet.class .tagify { - background: var(--color-light-1); - border: 1px solid var(--color-border); - height: 34px; - width: 100%; - border-radius: 3px; - margin-right: 1px; -} -.daggerheart.sheet.class .tagify tag div { +.daggerheart.sheet.class .domain-section { display: flex; - justify-content: space-between; align-items: center; - height: 22px; -} -.daggerheart.sheet.class .tagify tag div span { - font-weight: 400; -} -.daggerheart.sheet.class .tagify tag div img { - margin-left: 8px; - height: 20px; - width: 20px; + gap: 5px; } .daggerheart.sheet.adversary .adversary-header-container { position: relative; @@ -2802,6 +2773,65 @@ div.daggerheart.views.multiclass { scrollbar-width: thin; scrollbar-color: light-dark(#18162e, #f3c267) transparent; } +.application.sheet.daggerheart.dh-style.class .tagify { + background: light-dark(transparent, transparent); + border: 1px solid light-dark(#222, #efe6d8); + height: 34px; + border-radius: 3px; + margin-right: 1px; +} +.application.sheet.daggerheart.dh-style.class .tagify tag div { + display: flex; + justify-content: space-between; + align-items: center; + height: 22px; +} +.application.sheet.daggerheart.dh-style.class .tagify tag div span { + font-weight: 400; +} +.application.sheet.daggerheart.dh-style.class .tagify tag div img { + margin-left: 8px; + height: 20px; + width: 20px; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section { + display: grid; + gap: 10px; + grid-template-columns: 1fr 1.5fr 1.5fr; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items { + margin-bottom: 10px; + width: 100%; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items:last-child { + margin-bottom: 0px; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line { + display: grid; + align-items: center; + gap: 10px; + grid-template-columns: 1fr 3fr 1fr; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line h4 { + font-family: 'Montserrat', sans-serif; + font-weight: lighter; + color: light-dark(#222, #efe6d8); +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .image { + height: 40px; + width: 40px; + object-fit: cover; + border-radius: 6px; + border: none; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls { + display: flex; + justify-content: center; + gap: 10px; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls a { + text-shadow: none; +} @font-face { font-family: 'Cinzel'; font-style: normal; @@ -2828,14 +2858,14 @@ div.daggerheart.views.multiclass { font-style: normal; font-weight: 400; font-display: swap; - src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); } @font-face { font-family: 'Montserrat'; font-style: normal; font-weight: 600; font-display: swap; - src: url(https://fonts.gstatic.com/s/montserrat/v29/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); } .application.sheet.daggerheart.dh-style h1 { font-family: 'Cinzel Decorative', serif; @@ -3014,6 +3044,7 @@ div.daggerheart.views.multiclass { align-items: start; gap: 10px; min-height: 64px; + width: 100%; } .application.sheet.dh-style fieldset.two-columns { display: grid; diff --git a/styles/daggerheart.less b/styles/daggerheart.less index a47780d8..0d99ac6a 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -14,6 +14,7 @@ // new styles imports @import './less/items/feature.less'; @import './less/items/domainCard.less'; +@import './less/items/class.less'; @import './less/utils/colors.less'; @import './less/utils/fonts.less'; diff --git a/styles/less/global/elements.css b/styles/less/global/elements.css new file mode 100644 index 00000000..2b7cd90a --- /dev/null +++ b/styles/less/global/elements.css @@ -0,0 +1,248 @@ +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel Decorative'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzeldecorative/v17/daaHSScvJGqLYhG8nNt8KPPswUAPniZoaelD.ttf) format('truetype'); +} +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); +} +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); +} +.application.sheet.daggerheart.dh-style h1 { + font-family: 'Cinzel Decorative', serif; + margin: 0; + border: none; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h2, +.application.sheet.daggerheart.dh-style h3 { + font-family: 'Cinzel', serif; + margin: 0; + border: none; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h4 { + font-family: 'Montserrat', sans-serif; + font-size: 14px; + border: none; + font-weight: 700; + margin: 0; + text-shadow: none; + color: #f3c267; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h5 { + font-size: 14px; + color: #f3c267; + margin: 0; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style p, +.application.sheet.daggerheart.dh-style span { + font-family: 'Montserrat', sans-serif; +} +.application.sheet.daggerheart.dh-style small { + font-family: 'Montserrat', sans-serif; + opacity: 0.8; +} +.application.sheet.dh-style { + border: 1px solid light-dark(#18162e, #f3c267); +} +.application.sheet.dh-style input[type='text'], +.application.sheet.dh-style input[type='number'] { + background: light-dark(transparent, transparent); + border-radius: 6px; + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.05); + backdrop-filter: blur(9.5px); + -webkit-backdrop-filter: blur(9.5px); + outline: none; + color: light-dark(#18162e, #f3c267); + border: 1px solid light-dark(#222, #efe6d8); +} +.application.sheet.dh-style input[type='text']:hover[type='text'], +.application.sheet.dh-style input[type='number']:hover[type='text'], +.application.sheet.dh-style input[type='text']:hover[type='number'], +.application.sheet.dh-style input[type='number']:hover[type='number'], +.application.sheet.dh-style input[type='text']:focus[type='text'], +.application.sheet.dh-style input[type='number']:focus[type='text'], +.application.sheet.dh-style input[type='text']:focus[type='number'], +.application.sheet.dh-style input[type='number']:focus[type='number'] { + background: light-dark(rgba(0, 0, 0, 0.05), rgba(24, 22, 46, 0.33)); + box-shadow: none; + outline: 2px solid light-dark(#222, #efe6d8); +} +.application.sheet.dh-style input[type='checkbox']:checked::after { + color: light-dark(#222, #f3c267); +} +.application.sheet.dh-style input[type='checkbox']:checked::before { + color: light-dark(transparent, #18162e); +} +.application.sheet.dh-style input[type='checkbox']::before { + color: light-dark(#222, #efe6d8); +} +.application.sheet.dh-style button { + background: light-dark(transparent, #f3c267); + border: 1px solid light-dark(#18162e, #18162e); + color: light-dark(#18162e, #18162e); + outline: none; + box-shadow: none; +} +.application.sheet.dh-style button:hover { + background: light-dark(rgba(0, 0, 0, 0.3), #18162e); + color: light-dark(#18162e, #f3c267); +} +.application.sheet.dh-style select { + background: light-dark(transparent, transparent); + color: light-dark(#222, #efe6d8); + font-family: 'Montserrat', sans-serif; + outline: 2px solid transparent; + border: 1px solid light-dark(#222, #efe6d8); +} +.application.sheet.dh-style select:focus, +.application.sheet.dh-style select:hover { + outline: 2px solid light-dark(#222, #efe6d8); + box-shadow: none; +} +.application.sheet.dh-style select option { + color: #efe6d8; + background-color: #18162e; + border-radius: 6px; +} +.application.sheet.dh-style p { + margin: 0; +} +.application.sheet.dh-style ul { + margin: 0; + padding: 0; + list-style: none; +} +.application.sheet.dh-style li { + margin: 0; +} +.application.sheet.dh-style fieldset { + align-items: center; + margin-top: 5px; + border-radius: 6px; + border-color: light-dark(#18162e, #f3c267); +} +.application.sheet.dh-style fieldset.one-column { + display: flex; + flex-direction: column; + align-items: start; + gap: 10px; + min-height: 64px; + width: 100%; +} +.application.sheet.dh-style fieldset.two-columns { + display: grid; + grid-template-columns: 1fr 2fr; + gap: 10px; +} +.application.sheet.dh-style fieldset legend { + font-family: 'Montserrat', sans-serif; + font-weight: bold; + color: light-dark(#18162e, #f3c267); +} +.application.sheet.dh-style fieldset legend a { + text-shadow: none; +} +.application.sheet.dh-style fieldset input[type='text'], +.application.sheet.dh-style fieldset input[type='number'] { + color: light-dark(#222, #efe6d8); + font-family: 'Montserrat', sans-serif; + transition: all 0.3s ease; + outline: 2px solid transparent; +} +.application.sheet.dh-style fieldset input[type='text']:focus, +.application.sheet.dh-style fieldset input[type='number']:focus, +.application.sheet.dh-style fieldset input[type='text']:hover, +.application.sheet.dh-style fieldset input[type='number']:hover { + outline: 2px solid light-dark(#222, #efe6d8); +} +.application.sheet.dh-style fieldset .nest-inputs { + display: flex; + align-items: center; + gap: 5px; +} +.application.sheet.dh-style fieldset .form-group label { + font-family: 'Montserrat', sans-serif; + font-weight: bold; + font-size: smaller; +} +.application.sheet.dh-style line-div { + display: block; + height: 1px; + width: 100%; + border-bottom: 1px solid light-dark(#18162e, #f3c267); + mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%); +} +.application.sheet.dh-style .item-description { + opacity: 1; + transform: translateY(0); + transition: opacity 0.3s ease-out, transform 0.3s ease-out; +} +.application.sheet.dh-style .item-description.invisible { + height: 0; + opacity: 0; + overflow: hidden; + transform: translateY(-20px); + transform-origin: top; +} +.application.setting.dh-style fieldset h2, +.application.setting.dh-style fieldset h3, +.application.setting.dh-style fieldset h4 { + margin: 8px 0 4px; + text-align: center; +} +.application.setting.dh-style fieldset .title-hint { + font-size: 12px; + font-variant: small-caps; + text-align: center; +} +.application.setting.dh-style fieldset .field-section .split-section { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} +.application.setting.dh-style fieldset .label-container { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} +.application.setting.dh-style fieldset .label-container label { + align-self: center; + text-align: center; +} +.application.setting.dh-style footer { + margin-top: 8px; + display: flex; + gap: 8px; +} +.application.setting.dh-style footer button { + flex: 1; +} diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 9001e65e..fca23dc1 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -96,6 +96,7 @@ align-items: start; gap: 10px; min-height: 64px; + width: 100%; } &.two-columns { diff --git a/styles/less/items/class.css b/styles/less/items/class.css new file mode 100644 index 00000000..36c3afda --- /dev/null +++ b/styles/less/items/class.css @@ -0,0 +1,131 @@ +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-tbnTYo.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzel/v23/8vIU7ww63mVu7gtR-kwKxNvkNOjw-jHgTYo.ttf) format('truetype'); +} +@font-face { + font-family: 'Cinzel Decorative'; + font-style: normal; + font-weight: 700; + font-display: swap; + src: url(https://fonts.gstatic.com/s/cinzeldecorative/v17/daaHSScvJGqLYhG8nNt8KPPswUAPniZoaelD.ttf) format('truetype'); +} +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 400; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Ew-.ttf) format('truetype'); +} +@font-face { + font-family: 'Montserrat'; + font-style: normal; + font-weight: 600; + font-display: swap; + src: url(https://fonts.gstatic.com/s/montserrat/v30/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu170w-.ttf) format('truetype'); +} +.application.sheet.daggerheart.dh-style h1 { + font-family: 'Cinzel Decorative', serif; + margin: 0; + border: none; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h2, +.application.sheet.daggerheart.dh-style h3 { + font-family: 'Cinzel', serif; + margin: 0; + border: none; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h4 { + font-family: 'Montserrat', sans-serif; + font-size: 14px; + border: none; + font-weight: 700; + margin: 0; + text-shadow: none; + color: #f3c267; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style h5 { + font-size: 14px; + color: #f3c267; + margin: 0; + font-weight: normal; +} +.application.sheet.daggerheart.dh-style p, +.application.sheet.daggerheart.dh-style span { + font-family: 'Montserrat', sans-serif; +} +.application.sheet.daggerheart.dh-style small { + font-family: 'Montserrat', sans-serif; + opacity: 0.8; +} +.application.sheet.daggerheart.dh-style.class .tagify { + background: light-dark(transparent, transparent); + border: 1px solid light-dark(#222, #efe6d8); + height: 34px; + border-radius: 3px; + margin-right: 1px; +} +.application.sheet.daggerheart.dh-style.class .tagify tag div { + display: flex; + justify-content: space-between; + align-items: center; + height: 22px; +} +.application.sheet.daggerheart.dh-style.class .tagify tag div span { + font-weight: 400; +} +.application.sheet.daggerheart.dh-style.class .tagify tag div img { + margin-left: 8px; + height: 20px; + width: 20px; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .fieldsets-section { + display: grid; + gap: 10px; + grid-template-columns: 1fr 1.5fr 1.5fr; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items { + margin-bottom: 10px; + width: 100%; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items:last-child { + margin-bottom: 0px; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line { + display: grid; + align-items: center; + gap: 10px; + grid-template-columns: 1fr 3fr 1fr; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line h4 { + font-family: 'Montserrat', sans-serif; + font-weight: lighter; + color: light-dark(#222, #efe6d8); +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .image { + height: 40px; + width: 40px; + object-fit: cover; + border-radius: 6px; + border: none; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls { + display: flex; + justify-content: center; + gap: 10px; +} +.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls a { + text-shadow: none; +} diff --git a/styles/less/items/class.less b/styles/less/items/class.less new file mode 100644 index 00000000..1b8a0fbc --- /dev/null +++ b/styles/less/items/class.less @@ -0,0 +1,74 @@ +@import '../utils/colors.less'; +@import '../utils/fonts.less'; + +.application.sheet.daggerheart.dh-style.class { + .tagify { + background: light-dark(transparent, transparent); + border: 1px solid light-dark(@dark, @beige); + height: 34px; + + border-radius: 3px; + margin-right: 1px; + + tag { + div { + display: flex; + justify-content: space-between; + align-items: center; + height: 22px; + + span { + font-weight: 400; + } + + img { + margin-left: 8px; + height: 20px; + width: 20px; + } + } + } + } + + .tab.settings { + .fieldsets-section { + display: grid; + gap: 10px; + grid-template-columns: 1fr 1.5fr 1.5fr; + } + + .list-items { + margin-bottom: 10px; + width: 100%; + &:last-child { + margin-bottom: 0px; + } + .item-line { + display: grid; + align-items: center; + gap: 10px; + grid-template-columns: 1fr 3fr 1fr; + h4 { + font-family: @font-body; + font-weight: lighter; + color: light-dark(@dark, @beige); + } + .image { + height: 40px; + width: 40px; + object-fit: cover; + border-radius: 6px; + border: none; + } + .controls { + display: flex; + justify-content: center; + gap: 10px; + a { + text-shadow: none; + } + } + } + } + } +} diff --git a/styles/sheets/class.css b/styles/sheets/class.css new file mode 100644 index 00000000..09ec1def --- /dev/null +++ b/styles/sheets/class.css @@ -0,0 +1,65 @@ +.daggerheart.sheet.class .guide .drop-section { + width: 100%; +} +.daggerheart.sheet.class .guide .drop-section legend { + margin-left: auto; + margin-right: auto; + font-size: 12px; +} +.daggerheart.sheet.class .guide .drop-section .drop-section-body { + min-height: 40px; + display: flex; + flex-direction: column; + align-items: center; +} +.daggerheart.sheet.class .guide .trait-input { + text-align: center; + min-width: 24px; +} +.daggerheart.sheet.class .guide .suggested-item { + border-radius: 6px; + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +} +.daggerheart.sheet.class .guide .suggested-item img { + width: 30px; +} +.daggerheart.sheet.class .guide .suggested-item div { + text-align: center; +} +.daggerheart.sheet.class .guide .suggested-item i { + border-radius: 50%; + margin-right: 4px; + font-size: 11px; +} +.daggerheart.sheet.class .guide .extra-section { + display: flex; + flex-direction: column; + align-items: center; +} +.daggerheart.sheet.class .guide .extra-section .extra-title { + font-size: 14px; + font-weight: bold; +} +.daggerheart.sheet.class .guide-section-title-centered { + font-weight: bold; + font-size: 18px; +} +.daggerheart.sheet.class .inventory-section { + width: 100%; + border: 2px solid black; + border-style: dotted; + min-height: 80px; +} +.daggerheart.sheet.class .inventory-section .inventory-title { + font-weight: bold; + font-size: 14px; + text-align: center; +} +.daggerheart.sheet.class .domain-section { + display: flex; + align-items: center; + gap: 5px; +} diff --git a/styles/sheets/class.less b/styles/sheets/class.less deleted file mode 100644 index 07008699..00000000 --- a/styles/sheets/class.less +++ /dev/null @@ -1,119 +0,0 @@ -.daggerheart.sheet.class { - .guide { - .guide-section { - gap: @fullMargin; - } - - .drop-section { - width: 100%; - - legend { - margin-left: auto; - margin-right: auto; - font-size: 12px; - } - - .drop-section-body { - min-height: 40px; - display: flex; - flex-direction: column; - align-items: center; - } - } - - .trait-input { - text-align: center; - min-width: 24px; - } - - .suggested-item { - padding: @smallPadding @fullPadding; - border-radius: 6px; - border: @thinBorder solid black; - background: @primaryAccent; - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - - &:not(:last-child) { - margin: @halfMargin; - } - - img { - width: 30px; - } - - div { - text-align: center; - } - - i { - border-radius: 50%; - margin-right: 4px; - font-size: 11px; - } - } - - .extra-section { - display: flex; - flex-direction: column; - align-items: center; - - .extra-title { - font-size: 14px; - font-weight: bold; - } - - .extra-input { - margin-bottom: @halfMargin; - } - } - } - - .guide-section-title-centered { - font-weight: bold; - font-size: 18px; - } - - .inventory-section { - width: 100%; - border: 2px solid black; - border-style: dotted; - min-height: 80px; - - .inventory-title { - font-weight: bold; - font-size: 14px; - text-align: center; - } - } - - .tagify { - background: var(--color-light-1); - border: 1px solid var(--color-border); - height: 34px; - width: 100%; - border-radius: 3px; - margin-right: 1px; - - tag { - div { - display: flex; - justify-content: space-between; - align-items: center; - height: 22px; - - span { - font-weight: 400; - } - - img { - margin-left: 8px; - height: 20px; - width: 20px; - } - } - } - } -} diff --git a/templates/sheets/class.hbs b/templates/sheets/class.hbs deleted file mode 100644 index 935b1019..00000000 --- a/templates/sheets/class.hbs +++ /dev/null @@ -1,289 +0,0 @@ -
-
- -
-
-
-
- -
- -
-
- {{formField systemFields.evasion value=source.system.evasion label=(localize "DAGGERHEART.Sheets.Class.Evasion")}} - {{!--
- -
- -
-
--}} -
-

{{localize "DAGGERHEART.Sheets.Class.ClassFeatures"}}

-
- {{#each source.system.features as |feature index|}} -
-
- -
{{feature.name}}
-
-
- - -
-
- {{/each}} -
-
-
-

{{localize "DAGGERHEART.Sheets.Class.Subclasses"}}

-
- {{#each source.system.subclasses as |subclass index|}} -
-
- -
{{subclass.name}}
-
-
- - -
-
- {{/each}} -
-
-
-
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Title"}}
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Traits.Title"}} - - -
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedPrimaryWeaponTitle"}} - - -
- {{#if source.system.characterGuide.suggestedPrimaryWeapon}} -
- -
{{source.system.characterGuide.suggestedPrimaryWeapon.name}}
- -
- {{/if}} -
-
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedSecondaryWeaponTitle"}} - - -
- {{#if source.system.characterGuide.suggestedSecondaryWeapon}} -
- -
{{source.system.characterGuide.suggestedSecondaryWeapon.name}}
- -
- {{/if}} -
-
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedArmorTitle"}} - - -
- {{#if source.system.characterGuide.suggestedArmor}} -
- -
{{source.system.characterGuide.suggestedArmor.name}}
- -
- {{/if}} -
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Title"}}
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Take"}} - - -
- {{#each source.system.inventory.take}} -
- -
{{this.name}}
- -
- {{/each}} -
-
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.ThenChoose"}} - - -
- {{#each source.system.inventory.choiceA}} -
- -
{{this.name}}
- -
- {{/each}} -
-
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.AndEither"}} - - -
- {{#each source.system.inventory.choiceB}} -
- -
{{this.name}}
- -
- {{/each}} -
-
-
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Description.Title"}}
-
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Description.Explanation"}}
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
- - {{localize "DAGGERHEART.Sheets.Class.Guide.Extra.Title"}} - - -
-
{{localize "DAGGERHEART.Sheets.Class.Guide.Extra.Subtitle"}}
- - -
-
-
-
-
-
- {{localize "DAGGERHEART.Sheets.Class.Guide.BackgroundQuestions.Title"}} - -
- {{#times 3}} -
{{localize "DAGGERHEART.Sheets.Class.Guide.BackgroundQuestions.Question"}} {{add this 1}}
- - {{/times}} -
-
- -
- - {{localize "DAGGERHEART.Sheets.Class.Guide.Connections.Title"}} - - -
- {{#times 3}} -
{{localize "DAGGERHEART.Sheets.Class.Guide.Connections.Question"}} {{add this 1}}
- - {{/times}} -
-
-
-
-
-
-
\ No newline at end of file diff --git a/templates/sheets/items/class/features.hbs b/templates/sheets/items/class/features.hbs new file mode 100644 index 00000000..dfa386d1 --- /dev/null +++ b/templates/sheets/items/class/features.hbs @@ -0,0 +1,49 @@ +
+ +
+ {{localize "DAGGERHEART.Sheets.Feature.Tabs.Features"}} +
+ {{#each source.system.features as |feature index|}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}} + {{/each}} +
+
+ +
+ {{localize "TYPES.Item.subclass"}} +
+ {{#each source.system.subclasses as |subclass index|}} +
  • +
    + +

    + {{subclass.name}} +

    + +
    +
  • + {{/each}} +
    +
    + \ No newline at end of file diff --git a/templates/sheets/items/class/header.hbs b/templates/sheets/items/class/header.hbs new file mode 100644 index 00000000..6d601987 --- /dev/null +++ b/templates/sheets/items/class/header.hbs @@ -0,0 +1,13 @@ +
    + +
    +

    +
    +

    {{localize 'TYPES.Item.class'}}

    +

    + {{localize "DAGGERHEART.Sheets.Class.Domains"}} + +

    +
    +
    +
    \ No newline at end of file diff --git a/templates/sheets/items/class/settings.hbs b/templates/sheets/items/class/settings.hbs new file mode 100644 index 00000000..3ae98111 --- /dev/null +++ b/templates/sheets/items/class/settings.hbs @@ -0,0 +1,132 @@ +
    + +
    + {{localize tabs.settings.label}} + {{localize "DAGGERHEART.Sheets.Class.Evasion"}} + {{formField systemFields.evasion value=source.system.evasion}} +
    + +
    +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Traits.Title"}} + + {{localize "DAGGERHEART.Abilities.agility.name"}} + + + {{localize "DAGGERHEART.Abilities.strength.name"}} + + + {{localize "DAGGERHEART.Abilities.finesse.name"}} + + + {{localize "DAGGERHEART.Abilities.instinct.name"}} + + + {{localize "DAGGERHEART.Abilities.presence.name"}} + + + {{localize "DAGGERHEART.Abilities.knowledge.name"}} + +
    + +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.Suggestions.Title"}} +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedPrimaryWeaponTitle"}} +
    + {{#if source.system.characterGuide.suggestedPrimaryWeapon}} +
    + + {{source.system.characterGuide.suggestedPrimaryWeapon.name}} +
    + +
    +
    + {{/if}} +
    +
    + +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedSecondaryWeaponTitle"}} +
    + {{#if source.system.characterGuide.suggestedSecondaryWeapon}} +
    + + {{source.system.characterGuide.suggestedSecondaryWeapon.name}} +
    + +
    +
    + {{/if}} +
    +
    + +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.SuggestedArmorTitle"}} +
    + {{#if source.system.characterGuide.suggestedArmor}} +
    + + {{source.system.characterGuide.suggestedArmor.name}} +
    + +
    +
    + {{/if}} +
    +
    +
    + +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Title"}} +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.Take"}} +
    + {{#each source.system.inventory.take}} +
    + + {{this.name}} +
    + +
    +
    + {{/each}} +
    +
    + +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.ThenChoose"}} +
    + {{#each source.system.inventory.choiceA}} +
    + + {{this.name}} +
    + +
    +
    + {{/each}} +
    +
    + +
    + {{localize "DAGGERHEART.Sheets.Class.Guide.Inventory.AndEither"}} +
    + {{#each source.system.inventory.choiceB}} +
    + + {{this.name}} +
    + +
    +
    + {{/each}} +
    +
    +
    +
    +
    \ No newline at end of file diff --git a/templates/sheets/items/subclass/features.hbs b/templates/sheets/items/subclass/features.hbs new file mode 100644 index 00000000..eb2010c4 --- /dev/null +++ b/templates/sheets/items/subclass/features.hbs @@ -0,0 +1,26 @@ +
    +
    + {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}} + {{#each source.system.foundationFeature.abilities as |feature key|}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}} + {{/each}} +
    + +
    + {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}} + {{#each source.system.specializationFeature.abilities as |feature key|}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}} + {{/each}} +
    + +
    + {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}} + {{#each source.system.masteryFeature.abilities as |feature key|}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}} + {{/each}} +
    +
    \ No newline at end of file diff --git a/templates/sheets/items/subclass/header.hbs b/templates/sheets/items/subclass/header.hbs new file mode 100644 index 00000000..4e6d10e9 --- /dev/null +++ b/templates/sheets/items/subclass/header.hbs @@ -0,0 +1,10 @@ +
    + +
    +

    +
    +

    {{localize 'TYPES.Item.subclass'}}

    +

    {{localize (concat 'DAGGERHEART.Abilities.' source.system.spellcastingTrait '.name')}}

    +
    +
    +
    \ No newline at end of file diff --git a/templates/sheets/items/subclass/settings.hbs b/templates/sheets/items/subclass/settings.hbs new file mode 100644 index 00000000..2d8c3381 --- /dev/null +++ b/templates/sheets/items/subclass/settings.hbs @@ -0,0 +1,12 @@ +
    + +
    + {{localize tabs.settings.label}} + {{localize "DAGGERHEART.Sheets.Subclass.SpellcastingTrait"}} + {{formField systemFields.spellcastingTrait value=source.system.spellcastingTrait localize=true}} +
    +
    \ No newline at end of file diff --git a/templates/sheets/subclass.hbs b/templates/sheets/subclass.hbs deleted file mode 100644 index 6768a719..00000000 --- a/templates/sheets/subclass.hbs +++ /dev/null @@ -1,45 +0,0 @@ -
    -
    -
    - -
    - {{formInput fields.name value=source.name rootId=partId}} -
    -
    - -
    -
    -
    - {{formField systemFields.spellcastingTrait value=source.system.spellcastingTrait label=(localize "DAGGERHEART.Sheets.Subclass.SpellcastingTrait") localize=true}} - {{!--
    - -
    - -
    -
    --}} -
    - - {{formInput systemFields.description value=source.system.description enriched=source.system.description localize=true toggled=true}} - {{!-- {{editor item.system.description target="system.description" button=true}} --}} -
    -
    -
    - {{> "systems/daggerheart/templates/sheets/parts/subclassFeature.hbs" field=systemFields.foundationFeature.fields feature=source.system.foundationFeature featureType="foundation" }} -
    -
    - {{> "systems/daggerheart/templates/sheets/parts/subclassFeature.hbs" field=systemFields.specializationFeature.fields feature=source.system.specializationFeature featureType="specialization" }} -
    -
    - {{> "systems/daggerheart/templates/sheets/parts/subclassFeature.hbs" field=systemFields.masteryFeature.fields feature=source.system.masteryFeature featureType="mastery" }} -
    -
    -
    \ No newline at end of file