diff --git a/.gitignore b/.gitignore index a5c96aa8..61c6b176 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,5 @@ node_modules /packs Build -/build foundry styles/daggerheart.css \ No newline at end of file diff --git a/daggerheart.mjs b/daggerheart.mjs index 1b7be686..81b404d5 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -3,30 +3,23 @@ import * as applications from './module/applications/_module.mjs'; import * as models from './module/data/_module.mjs'; import * as documents from './module/documents/_module.mjs'; import RegisterHandlebarsHelpers from './module/helpers/handlebarsHelper.mjs'; -import DhCombatTracker from './module/ui/combatTracker.mjs'; -import { handleSocketEvent, registerSocketHooks } from './module/helpers/socket.mjs'; -import { registerDHSettings } from './module/applications/settings.mjs'; -import DhpChatLog from './module/ui/chatLog.mjs'; -import DhpRuler from './module/ui/ruler.mjs'; -import DhpTokenRuler from './module/ui/tokenRuler.mjs'; import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs'; -import { getCommandTarget, rollCommandToJSON, setDiceSoNiceForDualityRoll } from './module/helpers/utils.mjs'; -import { abilities } from './module/config/actorConfig.mjs'; -import Resources from './module/applications/resources.mjs'; -import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/countdowns.mjs'; -import DHDualityRoll from './module/data/chat-message/dualityRoll.mjs'; +import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs'; +import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/ui/countdowns.mjs'; import { DualityRollColor } from './module/data/settings/Appearance.mjs'; -import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/applications/roll.mjs'; -import { DhMeasuredTemplate } from './module/placeables/_module.mjs'; +import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/dice/_module.mjs'; import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs'; import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs'; import { registerCountdownHooks } from './module/data/countdowns.mjs'; - -globalThis.SYSTEM = SYSTEM; +import { + handlebarsRegistration, + settingsRegistration, + socketRegistration +} from './module/systemRegistration/_module.mjs'; +import { placeables } from './module/canvas/_module.mjs'; Hooks.once('init', () => { - CONFIG.daggerheart = SYSTEM; - + CONFIG.DH = SYSTEM; game.system.api = { applications, models, @@ -60,7 +53,7 @@ Hooks.once('init', () => { }; CONFIG.Dice.rolls = [...CONFIG.Dice.rolls, ...[DHRoll, DualityRoll, D20Roll, DamageRoll]]; - CONFIG.MeasuredTemplate.objectClass = DhMeasuredTemplate; + CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate; CONFIG.Item.documentClass = documents.DHItem; @@ -69,26 +62,32 @@ Hooks.once('init', () => { const { Items, Actors } = foundry.documents.collections; Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2); - Items.registerSheet(SYSTEM.id, applications.DhpAncestry, { types: ['ancestry'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpCommunity, { types: ['community'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpClassSheet, { types: ['class'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpSubclass, { types: ['subclass'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpFeatureSheet, { types: ['feature'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpDomainCardSheet, { types: ['domainCard'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpMiscellaneous, { types: ['miscellaneous'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpConsumable, { types: ['consumable'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpWeapon, { types: ['weapon'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhpArmor, { types: ['armor'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.DhBeastform, { types: ['beastform'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Ancestry, { types: ['ancestry'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Community, { types: ['community'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Class, { types: ['class'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Subclass, { types: ['subclass'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Feature, { types: ['feature'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.DomainCard, { types: ['domainCard'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Miscellaneous, { + types: ['miscellaneous'], + makeDefault: true + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Consumable, { types: ['consumable'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Weapon, { types: ['weapon'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Armor, { types: ['armor'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Beastform, { types: ['beastform'], makeDefault: true }); CONFIG.Actor.documentClass = documents.DhpActor; CONFIG.Actor.dataModels = models.actors.config; Actors.unregisterSheet('core', foundry.applications.sheets.ActorSheetV2); - Actors.registerSheet(SYSTEM.id, applications.DhCharacterSheet, { types: ['character'], makeDefault: true }); - Actors.registerSheet(SYSTEM.id, applications.DhCompanionSheet, { types: ['companion'], makeDefault: true }); - Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, { types: ['adversary'], makeDefault: true }); - Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, { types: ['environment'], makeDefault: true }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Character, { types: ['character'], makeDefault: true }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Companion, { types: ['companion'], makeDefault: true }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Adversary, { types: ['adversary'], makeDefault: true }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Environment, { + types: ['environment'], + makeDefault: true + }); CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect; CONFIG.ActiveEffect.dataModels = models.activeEffects.config; @@ -101,7 +100,7 @@ Hooks.once('init', () => { foundry.applications.apps.DocumentSheetConfig.registerSheet( CONFIG.ActiveEffect.documentClass, SYSTEM.id, - applications.DhActiveEffectConfig, + applications.sheetConfigs.ActiveEffectConfig, { makeDefault: true } @@ -115,29 +114,28 @@ Hooks.once('init', () => { base: models.DhCombatant }; - CONFIG.ChatMessage.dataModels = models.messages.config; - CONFIG.ChatMessage.documentClass = applications.DhpChatMessage; + CONFIG.ChatMessage.dataModels = models.chatMessages.config; + CONFIG.ChatMessage.documentClass = documents.DhChatMessage; - CONFIG.Canvas.rulerClass = DhpRuler; + CONFIG.Canvas.rulerClass = placeables.DhRuler; CONFIG.Combat.documentClass = documents.DhpCombat; - CONFIG.ui.combat = DhCombatTracker; - CONFIG.ui.chat = DhpChatLog; - // CONFIG.ui.players = DhpPlayers; - CONFIG.Token.rulerClass = DhpTokenRuler; + CONFIG.ui.combat = applications.ui.DhCombatTracker; + CONFIG.ui.chat = applications.ui.DhChatLog; + CONFIG.Token.rulerClass = placeables.DhTokenRuler; - CONFIG.ui.resources = Resources; - CONFIG.ux.ContextMenu = applications.DhContextMenu; - CONFIG.ux.TooltipManager = applications.DhTooltipManager; + CONFIG.ui.resources = applications.ui.DhFearTracker; + CONFIG.ux.ContextMenu = applications.ux.ContextMenu; + CONFIG.ux.TooltipManager = documents.DhTooltipManager; - game.socket.on(`system.${SYSTEM.id}`, handleSocketEvent); + game.socket.on(`system.${SYSTEM.id}`, socketRegistration.handleSocketEvent); // Make Compendium Dialog resizable foundry.applications.sidebar.apps.Compendium.DEFAULT_OPTIONS.window.resizable = true; - registerDHSettings(); + settingsRegistration.registerDHSettings(); RegisterHandlebarsHelpers.registerHelpers(); - return preloadHandlebarsTemplates(); + return handlebarsRegistration(); }); Hooks.on('ready', () => { @@ -152,7 +150,7 @@ Hooks.on('ready', () => { ); registerCountdownHooks(); - registerSocketHooks(); + socketRegistration.registerSocketHooks(); registerCountdownApplicationHooks(); }); @@ -212,7 +210,7 @@ Hooks.on('chatMessage', (_, message) => { const title = traitValue ? game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', { - ability: game.i18n.localize(abilities[traitValue].label) + ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label) }) : game.i18n.localize('DAGGERHEART.General.Duality'); @@ -266,46 +264,3 @@ Hooks.on('renderJournalDirectory', async (tab, html, _, options) => { }; } }); - -const preloadHandlebarsTemplates = async function () { - return foundry.applications.handlebars.loadTemplates([ - 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs', - 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs', - 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs', - 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs', - 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs', - 'systems/daggerheart/templates/sheets/parts/attributes.hbs', - 'systems/daggerheart/templates/sheets/parts/defense.hbs', - 'systems/daggerheart/templates/sheets/parts/armor.hbs', - 'systems/daggerheart/templates/sheets/parts/experience.hbs', - 'systems/daggerheart/templates/sheets/parts/features.hbs', - 'systems/daggerheart/templates/sheets/parts/gold.hbs', - 'systems/daggerheart/templates/sheets/parts/health.hbs', - 'systems/daggerheart/templates/sheets/parts/hope.hbs', - 'systems/daggerheart/templates/sheets/parts/weapons.hbs', - 'systems/daggerheart/templates/sheets/parts/domainCard.hbs', - 'systems/daggerheart/templates/sheets/parts/heritage.hbs', - 'systems/daggerheart/templates/sheets/parts/subclassFeature.hbs', - 'systems/daggerheart/templates/sheets/parts/effects.hbs', - 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs', - 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs', - 'systems/daggerheart/templates/components/card-preview.hbs', - 'systems/daggerheart/templates/views/levelup/parts/selectable-card-preview.hbs', - 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs', - 'systems/daggerheart/templates/ui/combat/combatTrackerSection.hbs', - 'systems/daggerheart/templates/views/actionTypes/damage.hbs', - 'systems/daggerheart/templates/views/actionTypes/healing.hbs', - 'systems/daggerheart/templates/views/actionTypes/resource.hbs', - 'systems/daggerheart/templates/views/actionTypes/uuid.hbs', - 'systems/daggerheart/templates/views/actionTypes/uses.hbs', - 'systems/daggerheart/templates/views/actionTypes/roll.hbs', - 'systems/daggerheart/templates/views/actionTypes/save.hbs', - 'systems/daggerheart/templates/views/actionTypes/cost.hbs', - 'systems/daggerheart/templates/views/actionTypes/range-target.hbs', - 'systems/daggerheart/templates/views/actionTypes/effect.hbs', - 'systems/daggerheart/templates/views/actionTypes/beastform.hbs', - 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', - 'systems/daggerheart/templates/chat/parts/damage-chat.hbs', - 'systems/daggerheart/templates/chat/parts/target-chat.hbs' - ]); -}; diff --git a/module/_module.mjs b/module/_module.mjs new file mode 100644 index 00000000..2e1d6fb4 --- /dev/null +++ b/module/_module.mjs @@ -0,0 +1,9 @@ +export * as applications from './applications/_module.mjs'; +export * as canvas from './canvas/_module.mjs'; +export * as config from './config/_module.mjs'; +export * as data from './data/_module.mjs'; +export * as dice from './dice/_module.mjs'; +export * as documents from './documents/_module.mjs'; +export * as enrichers from './enrichers/_module.mjs'; +export * as helpers from './helpers/_module.mjs'; +export * as systemRegistration from './systemRegistration/_module.mjs'; diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index a1574a33..82c2866c 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -1,22 +1,8 @@ -export { default as DhCharacterSheet } from './sheets/actors/character.mjs'; -export { default as DhpAdversarySheet } from './sheets/actors/adversary.mjs'; -export { default as DhCompanionSheet } from './sheets/actors/companion.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'; -export { default as DhpCommunity } from './sheets/items/community.mjs'; -export { default as DhpMiscellaneous } from './sheets/items/miscellaneous.mjs'; -export { default as DhpConsumable } from './sheets/items/consumable.mjs'; -export { default as DhpWeapon } from './sheets/items/weapon.mjs'; -export { default as DhpArmor } from './sheets/items/armor.mjs'; -export { default as DhpChatMessage } from './chatMessage.mjs'; -export { default as DhpEnvironment } from './sheets/actors/environment.mjs'; -export { default as DhActiveEffectConfig } from './sheets/activeEffectConfig.mjs'; -export { default as DhContextMenu } from './contextMenu.mjs'; -export { default as DhBeastform } from './sheets/items/beastform.mjs'; -export { default as DhTooltipManager } from './tooltipManager.mjs'; - -export * as api from './sheets/api/_modules.mjs'; +export * as characterCreation from './characterCreation/_module.mjs'; +export * as dialogs from './dialogs/_module.mjs'; +export * as levelup from './levelup/_module.mjs'; +export * as settings from './settings/_module.mjs'; +export * as sheets from './sheets/_module.mjs'; +export * as sheetConfigs from './sheets-configs/_module.mjs'; +export * as ui from './ui/_module.mjs'; export * as ux from './ux/_module.mjs'; diff --git a/module/applications/ancestrySelectionDialog.mjs b/module/applications/ancestrySelectionDialog.mjs deleted file mode 100644 index bc2f6b5e..00000000 --- a/module/applications/ancestrySelectionDialog.mjs +++ /dev/null @@ -1,250 +0,0 @@ -const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; - -export default class AncestrySelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(resolve) { - super({}); - - this.resolve = resolve; - this.data = { - ancestries: [], - features: [], - ancestryInfo: { - name: '', - img: null, - customImg: 'icons/svg/mystery-man.svg', - description: '' - } - }; - } - - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'views', 'ancestry-selection'], - position: { - width: 800, - height: 'auto' - }, - actions: { - selectAncestry: this.selectAncestry, - selectFeature: this.selectFeature, - viewItem: this.viewItem, - selectImage: this.selectImage, - editImage: this._onEditImage, - saveAncestry: this.saveAncestry - }, - form: { - submitOnChange: true, - closeOnSubmit: false - } - }; - - /** @override */ - static PARTS = { - damageSelection: { - id: 'ancestrySelection', - template: 'systems/daggerheart/templates/views/ancestrySelection.hbs' - } - }; - - /* -------------------------------------------- */ - - /** @inheritDoc */ - get title() { - return `Ancestry Selection`; - } - - _attachPartListeners(partId, htmlElement, options) { - super._attachPartListeners(partId, htmlElement, options); - - const ancestryNameInput = $(htmlElement).find('.ancestry-name'); - if (ancestryNameInput.length > 0) { - ancestryNameInput.on('change', this.setName.bind(this)); - $(htmlElement).find('.ancestry-description').on('change', this.setDescription.bind(this)); - } - // $(htmlElement).find(".ancestry-image").on("change", this.selectImage.bind(this)); - } - - async _prepareContext(_options) { - const systemAncestries = Array.from((await game.packs.get('daggerheart.ancestries')).index).map(x => ({ - ...x, - selected: this.data.ancestries.some(selected => selected.uuid === x.uuid) - })); - - const customAncestries = game.items.reduce((acc, x) => { - if (x.type === 'ancestry') { - acc.push({ - ...x, - uuid: x.uuid, - selected: this.data.ancestries.some(selected => selected.uuid === x.uuid) - }); - } - - return acc; - }, []); - - const ancestryFeatures = this.data.ancestries.flatMap(x => - x.system.abilities.map(x => ({ - ...x, - selected: this.data.features.some(selected => selected.uuid === x.uuid) - })) - ); - - return { - systemAncestries, - customAncestries, - ancestryFeatures, - selectedAncestries: this.data.ancestries, - selectedFeatures: this.data.features, - ancestryInfo: this.data.ancestryInfo - }; - } - - static async selectAncestry(_, button) { - const newAncestries = [...this.data.ancestries]; - if (!newAncestries.findSplice(x => x.uuid === button.dataset.uuid) && this.data.ancestries.length < 2) { - const ancestry = await fromUuid(button.dataset.uuid); - newAncestries.push(ancestry); - } - - this.data.ancestries = newAncestries; - this.data.features = newAncestries.length === 1 ? newAncestries[0].system.abilities : []; - - this.render(true); - } - - static async selectFeature(_, button) { - const newFeatures = [...this.data.features]; - if (!newFeatures.findSplice(x => x.uuid === button.dataset.uuid) && this.data.features.length < 2) { - const feature = await fromUuid(button.dataset.uuid); - newFeatures.push(feature); - } - - this.data.features = newFeatures; - this.render(true); - } - - static async viewItem(_, button) { - (await fromUuid(button.dataset.uuid)).sheet.render(true); - } - - setName(event) { - this.data.ancestryInfo.name = event.currentTarget.value; - this.render(true); - } - - setDescription(event) { - this.data.ancestryInfo.description = event.currentTarget.value; - this.render(true); - } - - static selectImage(_, button) { - this.data.ancestryInfo.img = button.dataset.img; - this.render(true); - } - - static _onEditImage() { - const fp = new foundry.applications.apps.FilePicker.implementation({ - current: this.data.ancestryInfo.img, - type: 'image', - redirectToRoot: ['icons/svg/mystery-man.svg'], - callback: async path => this._updateImage.bind(this)(path), - top: this.position.top + 40, - left: this.position.left + 10 - }); - return fp.browse(); - } - - _updateImage(path) { - this.data.ancestryInfo.customImg = path; - this.data.ancestryInfo.img = path; - this.render(true); - } - - static async saveAncestry(_, button) { - if (this.data.ancestries.length === 2) { - const { name, img, description } = this.data.ancestryInfo; - - this.resolve({ - data: { - name: name, - img: img, - type: 'ancestry', - system: { - description: description, - abilities: this.data.features.map(x => ({ - name: x.name, - img: x.img, - uuid: x.uuid, - subclassLevel: '' - })) - } - } - }); - } else { - this.resolve({ data: this.data.ancestries[0].toObject() }); - } - - this.close(); - } -} - -// export default class DamageSelectionDialog extends FormApplication { -// constructor(rollString, bonusDamage, resolve){ -// super({}, {}); - -// this.data = { -// rollString, -// bonusDamage: bonusDamage.map(x => ({ -// ...x, -// hopeUses: 0 -// })), -// } -// this.resolve = resolve; -// } - -// get title (){ -// return 'Damage Options'; -// } - -// static get defaultOptions() { -// const defaults = super.defaultOptions; -// const overrides = { -// height: 'auto', -// width: 400, -// id: 'damage-selection', -// template: 'systems/daggerheart/templates/views/damageSelection.hbs', -// closeOnSubmit: false, -// classes: ["daggerheart", "views", "damage-selection"], -// }; - -// const mergedOptions = foundry.utils.mergeObject(defaults, overrides); - -// return mergedOptions; -// } - -// async getData(){ -// const context = super.getData(); -// context.rollString = this.data.rollString; -// context.bonusDamage = this.data.bonusDamage; - -// return context; -// } - -// activateListeners(html) { -// super.activateListeners(html); - -// html.find('.roll-button').click(this.finish.bind(this)); -// html.find('.').change(); -// } - -// // async _updateObject(_, formData) { -// // const data = foundry.utils.expandObject(formData); -// // this.data = foundry.utils.mergeObject(this.data, data); -// // this.render(true); -// // } - -// finish(){ -// this.resolve(this.data); -// this.close(); -// } -// } diff --git a/module/applications/characterCreation/_module.mjs b/module/applications/characterCreation/_module.mjs new file mode 100644 index 00000000..f5642951 --- /dev/null +++ b/module/applications/characterCreation/_module.mjs @@ -0,0 +1 @@ +export { default as CharacterCreation } from './characterCreation.mjs'; diff --git a/module/applications/characterCreation.mjs b/module/applications/characterCreation/characterCreation.mjs similarity index 96% rename from module/applications/characterCreation.mjs rename to module/applications/characterCreation/characterCreation.mjs index da76d0a9..1dabc8c2 100644 --- a/module/applications/characterCreation.mjs +++ b/module/applications/characterCreation/characterCreation.mjs @@ -1,5 +1,5 @@ -import { abilities } from '../config/actorConfig.mjs'; -import { burden } from '../config/generalConfig.mjs'; +import { abilities } from '../../config/actorConfig.mjs'; +import { burden } from '../../config/generalConfig.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -74,11 +74,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl }; static PARTS = { - tabs: { template: 'systems/daggerheart/templates/views/characterCreation/tabs.hbs' }, - setup: { template: 'systems/daggerheart/templates/views/characterCreation/tabs/setup.hbs' }, - equipment: { template: 'systems/daggerheart/templates/views/characterCreation/tabs/equipment.hbs' }, - // story: { template: 'systems/daggerheart/templates/views/characterCreation/tabs/story.hbs' }, - footer: { template: 'systems/daggerheart/templates/views/characterCreation/footer.hbs' } + tabs: { template: 'systems/daggerheart/templates/characterCreation/tabs.hbs' }, + setup: { template: 'systems/daggerheart/templates/characterCreation/tabs/setup.hbs' }, + equipment: { template: 'systems/daggerheart/templates/characterCreation/tabs/equipment.hbs' }, + // story: { template: 'systems/daggerheart/templates/characterCreation/tabs/story.hbs' }, + footer: { template: 'systems/daggerheart/templates/characterCreation/footer.hbs' } }; static TABS = { @@ -176,7 +176,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl switch (partId) { case 'setup': const availableTraitModifiers = game.settings - .get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew) + .get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew) .traitArray.map(trait => ({ key: trait, name: trait })); for (let trait of Object.values(this.setup.traits).filter(x => x.value !== null)) { const index = availableTraitModifiers.findIndex(x => x.key === trait.value); @@ -396,7 +396,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl } async _onDrop(event) { - const data = TextEditor.getDragEventData(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await foundry.utils.fromUuid(data.uuid); if (item.type === 'ancestry' && event.target.closest('.ancestry-card')) { this.setup.ancestry = { diff --git a/module/applications/dialogs/_module.mjs b/module/applications/dialogs/_module.mjs new file mode 100644 index 00000000..82c6f17d --- /dev/null +++ b/module/applications/dialogs/_module.mjs @@ -0,0 +1,9 @@ +export { default as BeastformDialog } from './beastformDialog.mjs'; +export { default as costSelectionDialog } from './costSelectionDialog.mjs'; +export { default as d20RollDialog } from './d20RollDialog.mjs'; +export { default as DamageDialog } from './damageDialog.mjs'; +export { default as DamageReductionDialog } from './damageReductionDialog.mjs'; +export { default as DamageSelectionDialog } from './damageSelectionDialog.mjs'; +export { default as DeathMove } from './deathMove.mjs'; +export { default as Downtime } from './downtime.mjs'; +export { default as OwnershipSelection } from './ownershipSelection.mjs'; diff --git a/module/dialogs/beastformDialog.mjs b/module/applications/dialogs/beastformDialog.mjs similarity index 92% rename from module/dialogs/beastformDialog.mjs rename to module/applications/dialogs/beastformDialog.mjs index 34b71c24..df0ee584 100644 --- a/module/dialogs/beastformDialog.mjs +++ b/module/applications/dialogs/beastformDialog.mjs @@ -1,5 +1,3 @@ -import { tiers } from '../config/generalConfig.mjs'; - const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; export default class BeastformDialog extends HandlebarsApplicationMixin(ApplicationV2) { @@ -35,7 +33,7 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat /** @override */ static PARTS = { beastform: { - template: 'systems/daggerheart/templates/views/beastformDialog.hbs' + template: 'systems/daggerheart/templates/dialogs/beastformDialog.hbs' } }; @@ -43,7 +41,7 @@ export default class BeastformDialog extends HandlebarsApplicationMixin(Applicat const context = await super._prepareContext(_options); context.beastformTiers = game.items.reduce((acc, x) => { - const tier = tiers[x.system.tier]; + const tier = CONFIG.DH.GENERAL.tiers[x.system.tier]; if (x.type !== 'beastform' || tier.value > this.configData.tierLimit) return acc; if (!acc[tier.value]) acc[tier.value] = { label: game.i18n.localize(tier.label), values: {} }; diff --git a/module/applications/costSelectionDialog.mjs b/module/applications/dialogs/costSelectionDialog.mjs similarity index 95% rename from module/applications/costSelectionDialog.mjs rename to module/applications/dialogs/costSelectionDialog.mjs index 08bfb1d9..cab0d36d 100644 --- a/module/applications/costSelectionDialog.mjs +++ b/module/applications/dialogs/costSelectionDialog.mjs @@ -30,7 +30,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl static PARTS = { costSelection: { id: 'costSelection', - template: 'systems/daggerheart/templates/views/costSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/costSelection.hbs' } }; diff --git a/module/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs similarity index 95% rename from module/dialogs/d20RollDialog.mjs rename to module/applications/dialogs/d20RollDialog.mjs index 26efaf7d..cf620e43 100644 --- a/module/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -41,11 +41,11 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio static PARTS = { costSelection: { id: 'costSelection', - template: 'systems/daggerheart/templates/views/costSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/costSelection.hbs' }, rollSelection: { id: 'rollSelection', - template: 'systems/daggerheart/templates/views/rollSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/rollSelection.hbs' } }; @@ -60,7 +60,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio })); context.selectedExperiences = this.config.experiences; context.advantage = this.config.roll?.advantage; - context.diceOptions = SYSTEM.GENERAL.diceTypes; + context.diceOptions = CONFIG.DH.GENERAL.diceTypes; context.canRoll = true; context.isLite = this.config.roll?.lite; if (this.config.costs?.length) { diff --git a/module/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs similarity index 95% rename from module/dialogs/damageDialog.mjs rename to module/applications/dialogs/damageDialog.mjs index afec593b..84709251 100644 --- a/module/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -30,7 +30,7 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application static PARTS = { damageSelection: { id: 'damageSelection', - template: 'systems/daggerheart/templates/views/damageSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs' } }; diff --git a/module/applications/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs similarity index 98% rename from module/applications/damageReductionDialog.mjs rename to module/applications/dialogs/damageReductionDialog.mjs index 676def9e..c91bf5d3 100644 --- a/module/applications/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -1,4 +1,4 @@ -import { damageKeyToNumber, getDamageLabel } from '../helpers/utils.mjs'; +import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs'; const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; @@ -71,7 +71,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap static PARTS = { damageSelection: { id: 'damageReduction', - template: 'systems/daggerheart/templates/views/damageReduction.hbs' + template: 'systems/daggerheart/templates/dialogs/damageReduction.hbs' } }; diff --git a/module/applications/damageSelectionDialog.mjs b/module/applications/dialogs/damageSelectionDialog.mjs similarity index 95% rename from module/applications/damageSelectionDialog.mjs rename to module/applications/dialogs/damageSelectionDialog.mjs index 8b7071f7..f4f44bc8 100644 --- a/module/applications/damageSelectionDialog.mjs +++ b/module/applications/dialogs/damageSelectionDialog.mjs @@ -7,7 +7,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap this.data = { rollString, bonusDamage: bonusDamage.reduce((acc, x) => { - if (x.appliesOn === SYSTEM.EFFECTS.applyLocations.damageRoll.id) { + if (x.appliesOn === CONFIG.DH.EFFECTS.applyLocations.damageRoll.id) { acc.push({ ...x, hopeUses: 0 @@ -44,7 +44,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap static PARTS = { damageSelection: { id: 'damageSelection', - template: 'systems/daggerheart/templates/views/damageSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs' } }; diff --git a/module/applications/deathMove.mjs b/module/applications/dialogs/deathMove.mjs similarity index 86% rename from module/applications/deathMove.mjs rename to module/applications/dialogs/deathMove.mjs index ea2c86e6..ecb8ed60 100644 --- a/module/applications/deathMove.mjs +++ b/module/applications/dialogs/deathMove.mjs @@ -24,21 +24,21 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application static PARTS = { application: { id: 'death-move', - template: 'systems/daggerheart/templates/views/deathMove.hbs' + template: 'systems/daggerheart/templates/dialogs/deathMove.hbs' } }; async _prepareContext(_options) { const context = await super._prepareContext(_options); context.selectedMove = this.selectedMove; - context.options = SYSTEM.GENERAL.deathMoves; + context.options = CONFIG.DH.GENERAL.deathMoves; return context; } static selectMove(_, button) { const move = button.dataset.move; - this.selectedMove = SYSTEM.GENERAL.deathMoves[move]; + this.selectedMove = CONFIG.DH.GENERAL.deathMoves[move]; this.render(); } @@ -48,7 +48,7 @@ export default class DhpDeathMove extends HandlebarsApplicationMixin(Application const msg = new cls({ user: game.user.id, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/deathMove.hbs', + 'systems/daggerheart/templates/ui/chat/deathMove.hbs', { player: this.actor.name, title: game.i18n.localize(this.selectedMove.name), diff --git a/module/applications/downtime.mjs b/module/applications/dialogs/downtime.mjs similarity index 91% rename from module/applications/downtime.mjs rename to module/applications/dialogs/downtime.mjs index d0fc34b6..fc6da253 100644 --- a/module/applications/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -1,5 +1,3 @@ -import { actionsTypes } from '../data/_module.mjs'; - const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV2) { @@ -9,7 +7,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV this.actor = actor; this.shortrest = shortrest; - const options = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).restMoves; + const options = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves; this.moveData = shortrest ? options.shortRest : options.longRest; } @@ -31,7 +29,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV static PARTS = { application: { id: 'downtime', - template: 'systems/daggerheart/templates/views/downtime.hbs' + template: 'systems/daggerheart/templates/dialogs/downtime.hbs' } }; @@ -88,7 +86,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV actor: this.actor.uuid }, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/downtime.hbs', + 'systems/daggerheart/templates/ui/chat/downtime.hbs', { title: `${this.actor.name} - ${game.i18n.localize(`DAGGERHEART.Downtime.${this.shortRest ? 'ShortRest' : 'LongRest'}.title`)}`, moves: moves diff --git a/module/applications/ownershipSelection.mjs b/module/applications/dialogs/ownershipSelection.mjs similarity index 95% rename from module/applications/ownershipSelection.mjs rename to module/applications/dialogs/ownershipSelection.mjs index 380acfe1..3555b585 100644 --- a/module/applications/ownershipSelection.mjs +++ b/module/applications/dialogs/ownershipSelection.mjs @@ -22,7 +22,7 @@ export default class OwnershipSelection extends HandlebarsApplicationMixin(Appli static PARTS = { selection: { - template: 'systems/daggerheart/templates/views/ownershipSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/ownershipSelection.hbs' } }; diff --git a/module/applications/levelup/_module.mjs b/module/applications/levelup/_module.mjs new file mode 100644 index 00000000..dd4135b4 --- /dev/null +++ b/module/applications/levelup/_module.mjs @@ -0,0 +1,3 @@ +export { default as CharacterLevelup } from './characterLevelup.mjs'; +export { default as CompanionLevelup } from './companionLevelup.mjs'; +export { default as Levelup } from './levelup.mjs'; diff --git a/module/applications/levelup/characterLevelup.mjs b/module/applications/levelup/characterLevelup.mjs index 26a425e1..5c32f929 100644 --- a/module/applications/levelup/characterLevelup.mjs +++ b/module/applications/levelup/characterLevelup.mjs @@ -7,7 +7,9 @@ export default class DhCharacterLevelUp extends LevelUpBase { constructor(actor) { super(actor); - this.levelTiers = this.addBonusChoices(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers)); + this.levelTiers = this.addBonusChoices( + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers) + ); const playerLevelupData = actor.system.levelData; this.levelup = new DhLevelup(DhLevelup.initializeData(this.levelTiers, playerLevelupData)); } diff --git a/module/applications/levelup/levelup.mjs b/module/applications/levelup/levelup.mjs index 02291514..1d9731a2 100644 --- a/module/applications/levelup/levelup.mjs +++ b/module/applications/levelup/levelup.mjs @@ -43,10 +43,10 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2) }; static PARTS = { - tabs: { template: 'systems/daggerheart/templates/views/levelup/tabs/tab-navigation.hbs' }, - advancements: { template: 'systems/daggerheart/templates/views/levelup/tabs/advancements.hbs' }, - selections: { template: 'systems/daggerheart/templates/views/levelup/tabs/selections.hbs' }, - summary: { template: 'systems/daggerheart/templates/views/levelup/tabs/summary.hbs' } + tabs: { template: 'systems/daggerheart/templates/levelup/tabs/tab-navigation.hbs' }, + advancements: { template: 'systems/daggerheart/templates/levelup/tabs/advancements.hbs' }, + selections: { template: 'systems/daggerheart/templates/levelup/tabs/selections.hbs' }, + summary: { template: 'systems/daggerheart/templates/levelup/tabs/summary.hbs' } }; static TABS = { diff --git a/module/applications/npcRollSelectionDialog.mjs b/module/applications/npcRollSelectionDialog.mjs deleted file mode 100644 index 1a56f12a..00000000 --- a/module/applications/npcRollSelectionDialog.mjs +++ /dev/null @@ -1,80 +0,0 @@ -/** NOT USED ANYMORE - TO BE DELETED **/ - -const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; - -export default class NpcRollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(experiences, resolve, reject) { - super({}); - - this.experiences = experiences; - this.resolve = resolve; - this.reject = reject; - this.selectedExperiences = []; - this.data = { - advantage: null - }; - } - - get title() { - return game.i18n.localize('DAGGERHEART.Application.RollSelection.Title'); - } - - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'views', 'npc-roll-selection'], - position: { width: '500', height: 'auto' }, - actions: { - updateIsAdvantage: this.updateIsAdvantage, - selectExperience: this.selectExperience - }, - form: { handler: this.updateData, submitOnChange: false } - }; - - static PARTS = { - main: { - id: 'main', - template: 'systems/daggerheart/templates/views/npcRollSelection.hbs' - } - }; - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.advantage = this.data.advantage; - context.experiences = Object.values(this.experiences).map(x => ({ - ...x, - selected: this.selectedExperiences.find(selected => selected.id === x.id), - value: `${x.value >= 0 ? '+' : '-'}${x.value}` - })); - - return context; - } - - static updateIsAdvantage(_, button) { - const advantage = Boolean(button.dataset.advantage); - this.data.advantage = this.data.advantage === advantage ? null : advantage; - this.render(); - } - - static selectExperience(_, button) { - const experience = Object.values(this.experiences).find(experience => experience.id === button.id); - this.selectedExperiences = this.selectedExperiences.find(x => x.id === experience.id) - ? this.selectedExperiences.filter(x => x.id !== experience.id) - : [...this.selectedExperiences, experience]; - - this.render(); - } - - static async updateData() { - this.resolve({ ...this.data, experiences: this.selectedExperiences }); - this.close({ updateClose: true }); - } - - async close(options = {}) { - const { updateClose, ...baseOptions } = options; - if (!updateClose) { - this.reject(); - } - - await super.close(baseOptions); - } -} diff --git a/module/applications/roll.mjs b/module/applications/roll.mjs deleted file mode 100644 index fa374262..00000000 --- a/module/applications/roll.mjs +++ /dev/null @@ -1,491 +0,0 @@ -import D20RollDialog from '../dialogs/d20RollDialog.mjs'; -import DamageDialog from '../dialogs/damageDialog.mjs'; -import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs'; - -/* - - Damage & other resources roll - - Close dialog => don't roll -*/ - -export class DHRoll extends Roll { - baseTerms = []; - constructor(formula, data, options) { - super(formula, data, options); - } - - static messageType = 'adversaryRoll'; - - static DefaultDialog = D20RollDialog; - - static async build(config = {}, message = {}) { - const roll = await this.buildConfigure(config, message); - if (!roll) return; - await this.buildEvaluate(roll, config, (message = {})); - await this.buildPost(roll, config, (message = {})); - return config; - } - - static async buildConfigure(config = {}, message = {}) { - config.hooks = [...(config.hooks ?? []), '']; - config.dialog ??= {}; - for (const hook of config.hooks) { - if (Hooks.call(`${SYSTEM.id}.preRoll${hook.capitalize()}`, config, message) === false) return null; - } - - this.applyKeybindings(config); - - let roll = new this(config.roll.formula, config.data, config); - if (config.dialog.configure !== false) { - // Open Roll Dialog - const DialogClass = config.dialog?.class ?? this.DefaultDialog; - const configDialog = await DialogClass.configure(roll, config, message); - if (!configDialog) return; - } - - for (const hook of config.hooks) { - if (Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false) - return []; - } - return roll; - } - - static async buildEvaluate(roll, config = {}, message = {}) { - if (config.evaluate !== false) await roll.evaluate(); - this.postEvaluate(roll, config); - } - - static async buildPost(roll, config, message) { - for (const hook of config.hooks) { - if (Hooks.call(`${SYSTEM.id}.postRoll${hook.capitalize()}`, config, message) === false) return null; - } - - // Create Chat Message - if (config.source?.message) { - } else { - const messageData = {}; - config.message = await this.toMessage(roll, config); - } - } - - static postEvaluate(roll, config = {}) { - if (!config.roll) config.roll = {}; - config.roll.total = roll.total; - config.roll.formula = roll.formula; - config.roll.dice = []; - roll.dice.forEach(d => { - config.roll.dice.push({ - dice: d.denomination, - total: d.total, - formula: d.formula, - results: d.results - }); - }); - } - - static async toMessage(roll, config) { - const cls = getDocumentClass('ChatMessage'), - msg = { - type: this.messageType, - user: game.user.id, - sound: config.mute ? null : CONFIG.sounds.dice, - system: config, - rolls: [roll] - }; - return await cls.create(msg); - } - - static applyKeybindings(config) { - if (config.event) - config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey); - } - - formatModifier(modifier) { - const numTerm = modifier < 0 ? '-' : '+'; - return [ - new foundry.dice.terms.OperatorTerm({ operator: numTerm }), - new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) }) - ]; - } - - getFaces(faces) { - return Number(faces.startsWith('d') ? faces.replace('d', '') : faces); - } - - constructFormula(config) { - this.terms = Roll.parse(this.options.roll.formula, config.data); - - if (this.options.extraFormula) { - this.terms.push( - new foundry.dice.terms.OperatorTerm({ operator: '+' }), - ...this.constructor.parse(this.options.extraFormula, this.options.data) - ); - } - return (this._formula = this.constructor.getFormula(this.terms)); - } - - static calculateTotalModifiers(roll) { - let modifierTotal = 0; - for (let i = 0; i < roll.terms.length; i++) { - if ( - roll.terms[i] instanceof foundry.dice.terms.NumericTerm && - !!roll.terms[i - 1] && - roll.terms[i - 1] instanceof foundry.dice.terms.OperatorTerm - ) - modifierTotal += Number(`${roll.terms[i - 1].operator}${roll.terms[i].total}`); - } - return modifierTotal; - } -} - -export class DualityDie extends foundry.dice.terms.Die { - constructor({ number = 1, faces = 12, ...args } = {}) { - super({ number, faces, ...args }); - } -} - -export class D20Roll extends DHRoll { - constructor(formula, data = {}, options = {}) { - super(formula, data, options); - this.constructFormula(); - } - - static ADV_MODE = { - NORMAL: 0, - ADVANTAGE: 1, - DISADVANTAGE: -1 - }; - - static messageType = 'adversaryRoll'; - - static CRITICAL_TRESHOLD = 20; - - static DefaultDialog = D20RollDialog; - - get d20() { - if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); - return this.terms[0]; - } - - set d20(faces) { - if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); - this.terms[0].faces = this.getFaces(faces); - } - - get dAdvantage() { - return this.dice[2]; - } - - get isCritical() { - if (!this.d20._evaluated) return; - return this.d20.total >= this.constructor.CRITICAL_TRESHOLD; - } - - get hasAdvantage() { - return this.options.roll.advantage === this.constructor.ADV_MODE.ADVANTAGE; - } - - get hasDisadvantage() { - return this.options.roll.advantage === this.constructor.ADV_MODE.DISADVANTAGE; - } - - static applyKeybindings(config) { - let keys = { - normal: true, - advantage: false, - disadvantage: false - }; - - if (config.event) { - keys = { - normal: config.event.shiftKey || config.event.altKey || config.event.ctrlKey, - advantage: config.event.altKey, - disadvantage: config.event.ctrlKey - }; - } - - // Should the roll configuration dialog be displayed? - config.dialog.configure ??= !Object.values(keys).some(k => k); - - // Determine advantage mode - const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage || config.advantage; - const disadvantage = - config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage || config.disadvantage; - if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE; - else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE; - else config.roll.advantage = this.ADV_MODE.NORMAL; - } - - constructFormula(config) { - // this.terms = []; - this.createBaseDice(); - this.configureModifiers(); - this.resetFormula(); - return this._formula; - } - - createBaseDice() { - if (this.terms[0] instanceof foundry.dice.terms.Die) { - this.terms = [this.terms[0]]; - return; - } - this.terms[0] = new foundry.dice.terms.Die({ faces: 20 }); - } - - configureModifiers() { - this.applyAdvantage(); - this.applyBaseBonus(); - - this.options.experiences?.forEach(m => { - if (this.options.data.experiences?.[m]) - this.options.roll.modifiers.push({ - label: this.options.data.experiences[m].name, - value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value - }); - }); - - this.options.roll.modifiers?.forEach(m => { - this.terms.push(...this.formatModifier(m.value)); - }); - - this.baseTerms = foundry.utils.deepClone(this.terms); - - if (this.options.extraFormula) { - this.terms.push( - new foundry.dice.terms.OperatorTerm({ operator: '+' }), - ...this.constructor.parse(this.options.extraFormula, this.options.data) - ); - } - } - - applyAdvantage() { - this.d20.modifiers.findSplice(m => ['kh', 'kl'].includes(m)); - if (!this.hasAdvantage && !this.hasDisadvantage) this.number = 1; - else { - this.d20.number = 2; - this.d20.modifiers.push(this.hasAdvantage ? 'kh' : 'kl'); - } - } - - applyBaseBonus() { - this.options.roll.modifiers = []; - if (!this.options.roll.bonus) return; - this.options.roll.modifiers.push({ - label: 'Bonus to Hit', - value: this.options.roll.bonus - // value: Roll.replaceFormulaData('@attackBonus', this.data) - }); - } - - static async buildEvaluate(roll, config = {}, message = {}) { - if (config.evaluate !== false) await roll.evaluate(); - const advantageState = - config.roll.advantage == this.ADV_MODE.ADVANTAGE - ? true - : config.roll.advantage == this.ADV_MODE.DISADVANTAGE - ? false - : null; - setDiceSoNiceForDualityRoll(roll, advantageState); - this.postEvaluate(roll, config); - } - - static postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); - if (config.targets?.length) { - config.targets.forEach(target => { - const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; - target.hit = this.isCritical || roll.total >= difficulty; - }); - } else if (config.roll.difficulty) - config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty; - config.roll.advantage = { - type: config.roll.advantage, - dice: roll.dAdvantage?.denomination, - value: roll.dAdvantage?.total - }; - config.roll.isCritical = roll.isCritical; - config.roll.extra = roll.dice - .filter(d => !roll.baseTerms.includes(d)) - .map(d => { - return { - dice: d.denomination, - value: d.total - }; - }); - config.roll.modifierTotal = this.calculateTotalModifiers(roll); - } - - resetFormula() { - return (this._formula = this.constructor.getFormula(this.terms)); - } -} - -export class DualityRoll extends D20Roll { - _advantageFaces = 6; - - constructor(formula, data = {}, options = {}) { - super(formula, data, options); - } - - static messageType = 'dualityRoll'; - - static DefaultDialog = D20RollDialog; - - get dHope() { - // if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) return; - if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); - return this.dice[0]; - // return this.#hopeDice; - } - - set dHope(faces) { - if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); - this.terms[0].faces = this.getFaces(faces); - // this.#hopeDice = `d${face}`; - } - - get dFear() { - // if ( !(this.terms[1] instanceof foundry.dice.terms.Die) ) return; - if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); - return this.dice[1]; - // return this.#fearDice; - } - - set dFear(faces) { - if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); - this.dice[1].faces = this.getFaces(faces); - // this.#fearDice = `d${face}`; - } - - get dAdvantage() { - return this.dice[2]; - } - - get advantageFaces() { - return this._advantageFaces; - } - - set advantageFaces(faces) { - this._advantageFaces = this.getFaces(faces); - } - - get isCritical() { - if (!this.dHope._evaluated || !this.dFear._evaluated) return; - return this.dHope.total === this.dFear.total; - } - - get withHope() { - if (!this._evaluated) return; - return this.dHope.total > this.dFear.total; - } - - get withFear() { - if (!this._evaluated) return; - return this.dHope.total < this.dFear.total; - } - - get hasBarRally() { - return null; - } - - get totalLabel() { - const label = this.withHope - ? 'DAGGERHEART.General.Hope' - : this.withFear - ? 'DAGGERHEART.General.Fear' - : 'DAGGERHEART.General.CriticalSuccess'; - - return game.i18n.localize(label); - } - - updateFormula() {} - - createBaseDice() { - if ( - this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie && - this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie - ) { - this.terms = [this.terms[0], this.terms[1], this.terms[2]]; - return; - } - this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie(); - this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' }); - this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie(); - } - - applyAdvantage() { - const dieFaces = this.advantageFaces, - bardRallyFaces = this.hasBarRally, - advDie = new foundry.dice.terms.Die({ faces: dieFaces }); - if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) - this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' })); - if (bardRallyFaces) { - const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces }); - if (this.hasAdvantage) { - this.terms.push( - new foundry.dice.terms.PoolTerm({ - terms: [advDie.formula, rallyDie.formula], - modifiers: ['kh'] - }) - ); - } else if (this.hasDisadvantage) { - this.terms.push(advDie, new foundry.dice.terms.OperatorTerm({ operator: '+' }), rallyDie); - } - } else if (this.hasAdvantage || this.hasDisadvantage) this.terms.push(advDie); - } - - applyBaseBonus() { - this.options.roll.modifiers = []; - if (!this.options.roll.trait) return; - this.options.roll.modifiers.push({ - label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`, - value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data) - }); - } - - static postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); - config.roll.hope = { - dice: roll.dHope.denomination, - value: roll.dHope.total - }; - config.roll.fear = { - dice: roll.dFear.denomination, - value: roll.dFear.total - }; - config.roll.result = { - duality: roll.withHope ? 1 : roll.withFear ? -1 : 0, - total: roll.dHope.total + roll.dFear.total, - label: roll.totalLabel - }; - } -} - -export class DamageRoll extends DHRoll { - constructor(formula, data = {}, options = {}) { - super(formula, data, options); - } - - static messageType = 'damageRoll'; - - static DefaultDialog = DamageDialog; - - static async postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); - config.roll.type = config.type; - config.roll.modifierTotal = this.calculateTotalModifiers(roll); - if (config.source?.message) { - const chatMessage = ui.chat.collection.get(config.source.message); - chatMessage.update({ 'system.damage': config }); - } - } - - constructFormula(config) { - super.constructFormula(config); - if(config.isCritical) { - const tmpRoll = new Roll(this._formula)._evaluateSync({maximize: true}), - criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); - this.terms.push(...this.formatModifier(criticalBonus)); - } - return (this._formula = this.constructor.getFormula(this.terms)); - } -} diff --git a/module/applications/rollSelectionDialog.mjs b/module/applications/rollSelectionDialog.mjs deleted file mode 100644 index 543fa6c5..00000000 --- a/module/applications/rollSelectionDialog.mjs +++ /dev/null @@ -1,111 +0,0 @@ -/** NOT USED ANYMORE - TO BE DELETED **/ - -const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; - -export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(experiences, costs, action, resolve) { - super({}, {}); - - this.experiences = experiences; - this.costs = costs; - this.action = action; - this.resolve = resolve; - this.isNpc; - this.selectedExperiences = []; - this.data = { - diceOptions: [ - { name: 'd12', value: 'd12' }, - { name: 'd20', value: 'd20' } - ], - hope: ['d12'], - fear: ['d12'], - advantage: null - }; - } - - static DEFAULT_OPTIONS = { - tag: 'form', - id: 'roll-selection', - classes: ['daggerheart', 'views', 'roll-selection'], - position: { - width: 400, - height: 'auto' - }, - actions: { - updateIsAdvantage: this.updateIsAdvantage, - selectExperience: this.selectExperience, - finish: this.finish - }, - form: { - handler: this.updateSelection, - submitOnChange: true, - submitOnClose: false - } - }; - - /** @override */ - static PARTS = { - costSelection: { - id: 'costSelection', - template: 'systems/daggerheart/templates/views/costSelection.hbs' - }, - damageSelection: { - id: 'damageSelection', - template: 'systems/daggerheart/templates/views/rollSelection.hbs' - } - }; - - get title() { - return game.i18n.localize('DAGGERHEART.Application.RollSelection.Title'); - } - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.isNpc = this.isNpc; - context.diceOptions = this.data.diceOptions; - context.hope = this.data.hope; - context.fear = this.data.fear; - context.advantage = this.data.advantage; - context.experiences = Object.keys(this.experiences).map(id => ({ id, ...this.experiences[id] })); - if (this.costs?.length) { - const updatedCosts = this.action.calcCosts(this.costs); - context.costs = updatedCosts; - context.canRoll = this.action.getRealCosts(updatedCosts)?.hasCost; - } else context.canRoll = true; - - return context; - } - - static updateSelection(event, _, formData) { - const { ...rest } = foundry.utils.expandObject(formData.object); - this.data = foundry.utils.mergeObject(this.data, rest); - this.costs = foundry.utils.mergeObject(this.costs, rest.costs); - this.render(); - } - - static selectExperience(_, button) { - if (this.selectedExperiences.find(x => x.id === button.dataset.key)) { - this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key); - } else { - this.selectedExperiences = [...this.selectedExperiences, button.dataset.key]; - } - - this.render(); - } - - static updateIsAdvantage(_, button) { - const advantage = Boolean(button.dataset.advantage); - this.data.advantage = this.data.advantage === advantage ? null : advantage; - this.render(); - } - - static async finish() { - const { diceOptions, ...rest } = this.data; - this.resolve({ - ...rest, - experiences: this.selectedExperiences.map(x => ({ id: x, ...this.experiences[x] })), - costs: this.action.getRealCosts(this.costs) - }); - this.close(); - } -} diff --git a/module/applications/settings/_module.mjs b/module/applications/settings/_module.mjs index b5b5748d..de11242e 100644 --- a/module/applications/settings/_module.mjs +++ b/module/applications/settings/_module.mjs @@ -1,13 +1,5 @@ -import DhAppearanceSettings from './appearanceSettings.mjs'; -import DhAutomationSettings from './automationSettings.mjs'; -import DhHomebrewSettings from './homebrewSettings.mjs'; -import DhRangeMeasurementSettings from './rangeMeasurementSettings.mjs'; -import DhVariantRuleSettings from './variantRuleSettings.mjs'; - -export { - DhAppearanceSettings, - DhAutomationSettings, - DhHomebrewSettings, - DhRangeMeasurementSettings, - DhVariantRuleSettings -}; +export { default as DhAppearanceSettings } from './appearanceSettings.mjs'; +export { default as DhAutomationSettings } from './automationSettings.mjs'; +export { default as DhHomebrewSettings } from './homebrewSettings.mjs'; +export { default as DhRangeMeasurementSettings } from './rangeMeasurementSettings.mjs'; +export { default as DhVariantRuleSettings } from './variantRuleSettings.mjs'; diff --git a/module/applications/settings/appearanceSettings.mjs b/module/applications/settings/appearanceSettings.mjs index c11efd0f..51185b81 100644 --- a/module/applications/settings/appearanceSettings.mjs +++ b/module/applications/settings/appearanceSettings.mjs @@ -7,7 +7,7 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App super({}); this.settings = new DhAppearance( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).toObject() + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).toObject() ); } @@ -53,10 +53,10 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App } static async save() { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, this.settings.toObject()); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance, this.settings.toObject()); document.body.classList.toggle( 'theme-colorful', - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme === + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).dualityColorScheme === DualityRollColor.colorful.value ); diff --git a/module/applications/settings/automationSettings.mjs b/module/applications/settings/automationSettings.mjs index 6de21efd..a32b0dae 100644 --- a/module/applications/settings/automationSettings.mjs +++ b/module/applications/settings/automationSettings.mjs @@ -7,7 +7,7 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App super({}); this.settings = new DhAutomation( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).toObject() + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).toObject() ); } @@ -53,7 +53,7 @@ export default class DhAutomationSettings extends HandlebarsApplicationMixin(App } static async save() { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation, this.settings.toObject()); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation, this.settings.toObject()); this.close(); } } diff --git a/module/applications/settings/components/settingsActionsView.mjs b/module/applications/settings/components/settingsActionsView.mjs index ff0f0286..a905e824 100644 --- a/module/applications/settings/components/settingsActionsView.mjs +++ b/module/applications/settings/components/settingsActionsView.mjs @@ -1,5 +1,5 @@ -import { actionsTypes } from '../../../data/_module.mjs'; -import DHActionConfig from '../../config/Action.mjs'; +import { actionsTypes } from '../../../data/action/_module.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -96,8 +96,8 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App async selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionType.hbs', - { types: SYSTEM.ACTIONS.actionTypes } + 'systems/daggerheart/templates/actionTypes/actionType.hbs', + { types: CONFIG.DH.ACTIONS.actionTypes } ), title = 'Select Action Type', type = 'form', @@ -123,7 +123,7 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App action = new cls({ _id: foundry.utils.randomID(), type: actionType.type, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name), ...cls.getSourceConfig(this.document) }); diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index e67afb1b..f54f127f 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -7,7 +7,9 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli constructor() { super({}); - this.settings = new DhHomebrew(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).toObject()); + this.settings = new DhHomebrew( + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).toObject() + ); } get title() { @@ -113,7 +115,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli if (!confirmed) return; - const fields = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).schema.fields; + const fields = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).schema.fields; const removeUpdate = Object.keys(this.settings.restMoves[target.dataset.type].moves).reduce((acc, key) => { acc[`-=${key}`] = null; @@ -153,7 +155,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli } static async save() { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, this.settings.toObject()); this.close(); } diff --git a/module/applications/settings/rangeMeasurementSettings.mjs b/module/applications/settings/rangeMeasurementSettings.mjs index 8e90b462..e655d963 100644 --- a/module/applications/settings/rangeMeasurementSettings.mjs +++ b/module/applications/settings/rangeMeasurementSettings.mjs @@ -7,7 +7,7 @@ export default class DhRangeMeasurementSettings extends HandlebarsApplicationMix super({}); this.settings = new DhRangeMeasurement( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement).toObject() + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement).toObject() ); } @@ -53,7 +53,11 @@ export default class DhRangeMeasurementSettings extends HandlebarsApplicationMix } static async save() { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement, this.settings.toObject()); + await game.settings.set( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement, + this.settings.toObject() + ); this.close(); } } diff --git a/module/applications/settings/variantRuleSettings.mjs b/module/applications/settings/variantRuleSettings.mjs index 101d3e42..26a73761 100644 --- a/module/applications/settings/variantRuleSettings.mjs +++ b/module/applications/settings/variantRuleSettings.mjs @@ -7,7 +7,7 @@ export default class DHVariantRuleSettings extends HandlebarsApplicationMixin(Ap super({}); this.settings = new DhVariantRules( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules).toObject() + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).toObject() ); } @@ -53,7 +53,7 @@ export default class DHVariantRuleSettings extends HandlebarsApplicationMixin(Ap } static async save() { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules, this.settings.toObject()); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules, this.settings.toObject()); this.close(); } } diff --git a/module/applications/sheets-configs/_module.mjs b/module/applications/sheets-configs/_module.mjs new file mode 100644 index 00000000..e1ae8fe2 --- /dev/null +++ b/module/applications/sheets-configs/_module.mjs @@ -0,0 +1,5 @@ +export { default as ActionConfig } from './action-config.mjs'; +export { default as AdversarySettings } from './adversary-settings.mjs'; +export { default as CompanionSettings } from './companion-settings.mjs'; +export { default as EnvironmentSettings } from './environment-settings.mjs'; +export { default as ActiveEffectConfig } from './activeEffectConfig.mjs'; diff --git a/module/applications/config/Action.mjs b/module/applications/sheets-configs/action-config.mjs similarity index 97% rename from module/applications/config/Action.mjs rename to module/applications/sheets-configs/action-config.mjs index 803f22fe..61ce3fd7 100644 --- a/module/applications/config/Action.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -34,7 +34,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { static PARTS = { form: { id: 'action', - template: 'systems/daggerheart/templates/views/action.hbs' + template: 'systems/daggerheart/templates/config/action.hbs' } }; @@ -60,7 +60,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { context.source = this.action.toObject(false); context.openSection = this.openSection; context.tabs = this._getTabs(); - context.config = SYSTEM; + context.config = CONFIG.DH; if (!!this.action.effects) context.effects = this.action.effects.map(e => this.action.item.effects.get(e._id)); if (this.action.damage?.hasOwnProperty('includeBase') && this.action.type === 'attack') context.hasBaseDamage = !!this.action.parent.damage; @@ -70,7 +70,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { context.isNPC = this.action.actor && this.action.actor.type !== 'character'; context.hasRoll = this.action.hasRoll; - const settingsTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers; + const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers; context.tierOptions = [ { key: 1, label: game.i18n.localize('DAGGERHEART.Tiers.tier1') }, ...Object.values(settingsTiers).map(x => ({ key: x.tier, label: x.name })) diff --git a/module/applications/sheets/activeEffectConfig.mjs b/module/applications/sheets-configs/activeEffectConfig.mjs similarity index 100% rename from module/applications/sheets/activeEffectConfig.mjs rename to module/applications/sheets-configs/activeEffectConfig.mjs diff --git a/module/applications/sheets/applications/adversary-settings.mjs b/module/applications/sheets-configs/adversary-settings.mjs similarity index 86% rename from module/applications/sheets/applications/adversary-settings.mjs rename to module/applications/sheets-configs/adversary-settings.mjs index 2ecdcb60..22ad4b18 100644 --- a/module/applications/sheets/applications/adversary-settings.mjs +++ b/module/applications/sheets-configs/adversary-settings.mjs @@ -1,6 +1,6 @@ -import DHActionConfig from '../../config/Action.mjs'; -import DHBaseItemSheet from '../api/base-item.mjs'; -import { actionsTypes } from '../../../data/_module.mjs'; +import DHActionConfig from './action-config.mjs'; +import DHBaseItemSheet from '../sheets/api/base-item.mjs'; +import { actionsTypes } from '../../data/action/_module.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -40,24 +40,24 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl static PARTS = { header: { id: 'header', - template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/header.hbs' + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, details: { id: 'details', - template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/details.hbs' + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/details.hbs' }, attack: { id: 'attack', - template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/attack.hbs' + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/attack.hbs' }, experiences: { id: 'experiences', - template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/experiences.hbs' + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/experiences.hbs' }, actions: { id: 'actions', - template: 'systems/daggerheart/templates/sheets/applications/adversary-settings/actions.hbs' + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/actions.hbs' } }; @@ -139,7 +139,7 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl { _id: foundry.utils.randomID(), type: actionType, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), ...cls.getSourceConfig(this.actor) }, { diff --git a/module/applications/sheets/applications/companion-settings.mjs b/module/applications/sheets-configs/companion-settings.mjs similarity index 87% rename from module/applications/sheets/applications/companion-settings.mjs rename to module/applications/sheets-configs/companion-settings.mjs index 89d20a07..7f9d5423 100644 --- a/module/applications/sheets/applications/companion-settings.mjs +++ b/module/applications/sheets-configs/companion-settings.mjs @@ -1,5 +1,5 @@ -import { GMUpdateEvent, socketEvent } from '../../../helpers/socket.mjs'; -import DhCompanionlevelUp from '../../levelup/companionLevelup.mjs'; +import { GMUpdateEvent, socketEvent } from '../../systemRegistration/socket.mjs'; +import DhCompanionlevelUp from '../levelup/companionLevelup.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -35,20 +35,20 @@ export default class DHCompanionSettings extends HandlebarsApplicationMixin(Appl static PARTS = { header: { id: 'header', - template: 'systems/daggerheart/templates/sheets/applications/companion-settings/header.hbs' + template: 'systems/daggerheart/templates/sheets-settings/companion-settings/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, details: { id: 'details', - template: 'systems/daggerheart/templates/sheets/applications/companion-settings/details.hbs' + template: 'systems/daggerheart/templates/sheets-settings/companion-settings/details.hbs' }, experiences: { id: 'experiences', - template: 'systems/daggerheart/templates/sheets/applications/companion-settings/experiences.hbs' + template: 'systems/daggerheart/templates/sheets-settings/companion-settings/experiences.hbs' }, attack: { id: 'attack', - template: 'systems/daggerheart/templates/sheets/applications/companion-settings/attack.hbs' + template: 'systems/daggerheart/templates/sheets-settings/companion-settings/attack.hbs' } }; @@ -120,7 +120,7 @@ export default class DHCompanionSettings extends HandlebarsApplicationMixin(Appl const partnerUpdate = { 'system.companion': event.target.value ? this.actor.uuid : null }; if (!partnerDocument.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) { - await game.socket.emit(`system.${SYSTEM.id}`, { + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.GMUpdate, data: { action: GMUpdateEvent.UpdateDocument, diff --git a/module/applications/sheets/applications/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs similarity index 89% rename from module/applications/sheets/applications/environment-settings.mjs rename to module/applications/sheets-configs/environment-settings.mjs index fa58893b..5e0c5cda 100644 --- a/module/applications/sheets/applications/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -1,6 +1,6 @@ -import DHActionConfig from '../../config/Action.mjs'; -import DHBaseItemSheet from '../api/base-item.mjs'; -import { actionsTypes } from '../../../data/_module.mjs'; +import DHActionConfig from './action-config.mjs'; +import DHBaseItemSheet from '../sheets/api/base-item.mjs'; +import { actionsTypes } from '../../data/action/_module.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -44,20 +44,20 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap static PARTS = { header: { id: 'header', - template: 'systems/daggerheart/templates/sheets/applications/environment-settings/header.hbs' + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/header.hbs' }, tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, details: { id: 'details', - template: 'systems/daggerheart/templates/sheets/applications/environment-settings/details.hbs' + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/details.hbs' }, actions: { id: 'actions', - template: 'systems/daggerheart/templates/sheets/applications/environment-settings/actions.hbs' + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/actions.hbs' }, adversaries: { id: 'adversaries', - template: 'systems/daggerheart/templates/sheets/applications/environment-settings/adversaries.hbs' + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/adversaries.hbs' } }; @@ -131,7 +131,7 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap { _id: foundry.utils.randomID(), type: actionType, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), ...cls.getSourceConfig(this.actor) }, { @@ -200,7 +200,7 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap } async _onDrop(event) { - const data = TextEditor.getDragEventData(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await fromUuid(data.uuid); if (item.type === 'adversary') { const target = event.target.closest('.category-container'); diff --git a/module/applications/sheets/_module.mjs b/module/applications/sheets/_module.mjs new file mode 100644 index 00000000..c503e054 --- /dev/null +++ b/module/applications/sheets/_module.mjs @@ -0,0 +1,3 @@ +export * as actors from './actors/_module.mjs'; +export * as api from './api/_modules.mjs'; +export * as items from './items/_module.mjs'; diff --git a/module/applications/sheets/actors/_module.mjs b/module/applications/sheets/actors/_module.mjs new file mode 100644 index 00000000..9998733c --- /dev/null +++ b/module/applications/sheets/actors/_module.mjs @@ -0,0 +1,4 @@ +export { default as Adversary } from './adversary.mjs'; +export { default as Character } from './character.mjs'; +export { default as Companion } from './companion.mjs'; +export { default as Environment } from './environment.mjs'; diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index e2f5c978..a48c1fa4 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -1,6 +1,6 @@ -import DHActionConfig from '../../config/Action.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; import DaggerheartSheet from '../daggerheart-sheet.mjs'; -import DHAdversarySettings from '../applications/adversary-settings.mjs'; +import DHAdversarySettings from '../../sheets-configs/adversary-settings.mjs'; const { ActorSheetV2 } = foundry.applications.sheets; export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { @@ -92,7 +92,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { }, chatMessage: { type: 'adversaryRoll', - template: 'systems/daggerheart/templates/chat/adversary-roll.hbs', + template: 'systems/daggerheart/templates/ui/chat/adversary-roll.hbs', mute: true } }; @@ -127,7 +127,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 10791435..5a443119 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -1,14 +1,12 @@ import { capitalize } from '../../../helpers/utils.mjs'; -import DhpDeathMove from '../../deathMove.mjs'; -import DhpDowntime from '../../downtime.mjs'; -import AncestrySelectionDialog from '../../ancestrySelectionDialog.mjs'; +import DhpDeathMove from '../../dialogs/deathMove.mjs'; +import DhpDowntime from '../../dialogs/downtime.mjs'; import DaggerheartSheet from '.././daggerheart-sheet.mjs'; import { abilities } from '../../../config/actorConfig.mjs'; import DhCharacterlevelUp from '../../levelup/characterLevelup.mjs'; -import DhCharacterCreation from '../../characterCreation.mjs'; +import DhCharacterCreation from '../../characterCreation/characterCreation.mjs'; import FilterMenu from '../../ux/filter-menu.mjs'; -import { DhBeastformAction } from '../../../data/action/action.mjs'; -import DHActionConfig from '../../config/Action.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; const { ActorSheetV2 } = foundry.applications.sheets; const { TextEditor } = foundry.applications.ux; @@ -33,7 +31,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { useDomainCard: this.useDomainCard, selectClass: this.selectClass, selectSubclass: this.selectSubclass, - selectAncestry: this.selectAncestry, selectCommunity: this.selectCommunity, viewObject: this.viewObject, useItem: this.useItem, @@ -338,13 +335,13 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { const context = await super._prepareContext(_options); context.document = this.document; context.tabs = super._getTabs(this.constructor.TABS); - context.config = SYSTEM; + context.config = CONFIG.DH; context.attributes = Object.keys(this.document.system.traits).reduce((acc, key) => { acc[key] = { ...this.document.system.traits[key], - name: game.i18n.localize(SYSTEM.ACTOR.abilities[key].name), - verbs: SYSTEM.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x)) + name: game.i18n.localize(CONFIG.DH.ACTOR.abilities[key].name), + verbs: CONFIG.DH.ACTOR.abilities[key].verbs.map(x => game.i18n.localize(x)) }; return acc; @@ -360,7 +357,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { } }; - const homebrewCurrency = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).currency; + const homebrewCurrency = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).currency; if (homebrewCurrency.enabled) { context.inventory.currency = homebrewCurrency; } @@ -631,13 +628,13 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { static async toggleLoadoutView(_, button) { const newAbilityView = !(button.dataset.value === 'true'); - await game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS.displayDomainCardsAsList, newAbilityView); + await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.displayDomainCardsAsList, newAbilityView); this.render(); } static async toggleLoadoutView(_, button) { const newAbilityView = !(button.dataset.value === 'true'); - await game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS.displayDomainCardsAsList, newAbilityView); + await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.displayDomainCardsAsList, newAbilityView); this.render(); } @@ -647,7 +644,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { const wasUsed = await weapon.use(event); if (wasUsed) { - Hooks.callAll(SYSTEM.HOOKS.characterAttack, {}); + Hooks.callAll(CONFIG.DH.HOOKS.characterAttack, {}); } } @@ -689,7 +686,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { type: 'abilityUse', user: game.user.id, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ), system: systemData @@ -706,28 +703,6 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { (await game.packs.get('daggerheart.subclasses'))?.render(true); } - static async selectAncestry() { - const dialogClosed = new Promise((resolve, _) => { - new AncestrySelectionDialog(resolve).render(true); - }); - const result = await dialogClosed; - - for (var ancestry of this.document.items.filter(x => x => x.type === 'ancestry')) { - await ancestry.delete(); - } - - const createdItems = []; - for (var feature of this.document.items.filter( - x => x.type === 'feature' && x.system.type === SYSTEM.ITEM.featureTypes.ancestry.id - )) { - await feature.delete(); - } - - createdItems.push(result.data); - - await this.document.createEmbeddedDocuments('Item', createdItems); - } - static async selectCommunity() { (await game.packs.get('daggerheart.communities'))?.render(true); } @@ -744,7 +719,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { } else { const wasUsed = await item.use(event); if (wasUsed && item.type === 'weapon') { - Hooks.callAll(SYSTEM.HOOKS.characterAttack, {}); + Hooks.callAll(CONFIG.DH.HOOKS.characterAttack, {}); } } } @@ -840,7 +815,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { type: 'abilityUse', user: game.user.id, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ), system: systemData @@ -862,7 +837,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); @@ -898,7 +873,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); @@ -921,7 +896,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); diff --git a/module/applications/sheets/actors/companion.mjs b/module/applications/sheets/actors/companion.mjs index 89939e9a..bf8f2ec6 100644 --- a/module/applications/sheets/actors/companion.mjs +++ b/module/applications/sheets/actors/companion.mjs @@ -1,5 +1,5 @@ import DaggerheartSheet from '../daggerheart-sheet.mjs'; -import DHCompanionSettings from '../applications/companion-settings.mjs'; +import DHCompanionSettings from '../../sheets-configs/companion-settings.mjs'; const { ActorSheetV2 } = foundry.applications.sheets; export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) { @@ -90,7 +90,7 @@ export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); diff --git a/module/applications/sheets/actors/environment.mjs b/module/applications/sheets/actors/environment.mjs index dc0da8e9..733e8e10 100644 --- a/module/applications/sheets/actors/environment.mjs +++ b/module/applications/sheets/actors/environment.mjs @@ -1,5 +1,5 @@ import DaggerheartSheet from '../daggerheart-sheet.mjs'; -import DHEnvironmentSettings from '../applications/environment-settings.mjs'; +import DHEnvironmentSettings from '../../sheets-configs/environment-settings.mjs'; const { ActorSheetV2 } = foundry.applications.sheets; export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 2dcfff6e..6f04acb4 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -139,7 +139,7 @@ export default function DHApplicationMixin(Base) { * @param {DragEvent} event * @protected */ - _onDrop(event) { } + _onDrop(event) {} /* -------------------------------------------- */ /* Prepare Context */ @@ -154,7 +154,7 @@ export default function DHApplicationMixin(Base) { */ async _prepareContext(options, objectPath = 'document') { const context = await super._prepareContext(options); - context.config = CONFIG.daggerheart; + context.config = CONFIG.DH; context.source = this[objectPath]; context.fields = this[objectPath].schema.fields; context.systemFields = this[objectPath].system ? this[objectPath].system.schema.fields : {}; diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index 1299b208..47ba5188 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -1,6 +1,6 @@ import DHApplicationMixin from './application-mixin.mjs'; -import { actionsTypes } from '../../../data/_module.mjs'; -import DHActionConfig from '../../config/Action.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; +import { actionsTypes } from '../../../data/action/_module.mjs'; const { ItemSheetV2 } = foundry.applications.sheets; @@ -69,8 +69,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { */ static async selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionType.hbs', - { types: SYSTEM.ACTIONS.actionTypes } + 'systems/daggerheart/templates/actionTypes/actionType.hbs', + { types: CONFIG.DH.ACTIONS.actionTypes } ), title = 'Select Action Type'; @@ -98,7 +98,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { { _id: foundry.utils.randomID(), type: actionType, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), ...cls.getSourceConfig(this.document) }, { diff --git a/module/applications/sheets/items/_module.mjs b/module/applications/sheets/items/_module.mjs new file mode 100644 index 00000000..84332f96 --- /dev/null +++ b/module/applications/sheets/items/_module.mjs @@ -0,0 +1,11 @@ +export { default as Ancestry } from './ancestry.mjs'; +export { default as Armor } from './armor.mjs'; +export { default as Beastform } from './beastform.mjs'; +export { default as Class } from './class.mjs'; +export { default as Community } from './community.mjs'; +export { default as Consumable } from './consumable.mjs'; +export { default as DomainCard } from './domainCard.mjs'; +export { default as Feature } from './feature.mjs'; +export { default as Miscellaneous } from './miscellaneous.mjs'; +export { default as Subclass } from './subclass.mjs'; +export { default as Weapon } from './weapon.mjs'; diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index 4e53d8fa..bb98c8c3 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -8,7 +8,7 @@ export default class ArmorSheet extends DHBaseItemSheet { tagifyConfigs: [ { selector: '.features-input', - options: () => CONFIG.daggerheart.ITEM.armorFeatures, + options: () => CONFIG.DH.ITEM.armorFeatures, callback: ArmorSheet.#onFeatureSelect } ] diff --git a/module/applications/sheets/items/beastform.mjs b/module/applications/sheets/items/beastform.mjs index b04671ec..9ce9b739 100644 --- a/module/applications/sheets/items/beastform.mjs +++ b/module/applications/sheets/items/beastform.mjs @@ -55,7 +55,7 @@ export default class BeastformSheet extends DHBaseItemSheet { } async _onDrop(event) { - const data = TextEditor.getDragEventData(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await fromUuid(data.uuid); if (item.type === 'feature') { const current = this.document.system.features.map(x => x.uuid); diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index efe556fa..2ba17346 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -1,6 +1,6 @@ import DHBaseItemSheet from '../api/base-item.mjs'; -import { actionsTypes } from '../../../data/_module.mjs'; -import DHActionConfig from '../../config/Action.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; +import { actionsTypes } from '../../../data/action/_module.mjs'; const { TextEditor } = foundry.applications.ux; @@ -20,7 +20,7 @@ export default class ClassSheet extends DHBaseItemSheet { tagifyConfigs: [ { selector: '.domain-input', - options: () => CONFIG.daggerheart.DOMAIN.domains, + options: () => CONFIG.DH.DOMAIN.domains, callback: ClassSheet.#onDomainSelect } ], @@ -172,8 +172,8 @@ export default class ClassSheet extends DHBaseItemSheet { //TODO: redo this async selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionType.hbs', - { types: SYSTEM.ACTIONS.actionTypes } + 'systems/daggerheart/templates/actionTypes/actionType.hbs', + { types: CONFIG.DH.ACTIONS.actionTypes } ), title = 'Select Action Type', type = 'form', @@ -209,7 +209,7 @@ export default class ClassSheet extends DHBaseItemSheet { _id: foundry.utils.randomID(), systemPath: actionPath, type: actionType.type, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name), ...cls.getSourceConfig(this.document) }, { diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs index 841c3eb2..3c70d84a 100644 --- a/module/applications/sheets/items/subclass.mjs +++ b/module/applications/sheets/items/subclass.mjs @@ -1,6 +1,6 @@ import DHBaseItemSheet from '../api/base-item.mjs'; -import { actionsTypes } from '../../../data/_module.mjs'; -import DHActionConfig from '../../config/Action.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; +import { actionsTypes } from '../../../data/action/_module.mjs'; export default class SubclassSheet extends DHBaseItemSheet { /**@inheritdoc */ @@ -58,8 +58,8 @@ export default class SubclassSheet extends DHBaseItemSheet { async #selectActionType() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionType.hbs', - { types: SYSTEM.ACTIONS.actionTypes } + 'systems/daggerheart/templates/actionTypes/actionType.hbs', + { types: CONFIG.DH.ACTIONS.actionTypes } ), title = 'Select Action Type', type = 'form', @@ -87,7 +87,7 @@ export default class SubclassSheet extends DHBaseItemSheet { _id: foundry.utils.randomID(), systemPath: `${level}.actions`, type: actionType.type, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType.type].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name), ...cls.getSourceConfig(this.document) }, { diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index 5f2a12d7..fdce55fc 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -7,7 +7,7 @@ export default class WeaponSheet extends DHBaseItemSheet { tagifyConfigs: [ { selector: '.features-input', - options: () => CONFIG.daggerheart.ITEM.weaponFeatures, + options: () => CONFIG.DH.ITEM.weaponFeatures, callback: WeaponSheet.#onFeatureSelect } ] diff --git a/module/applications/ui/_module.mjs b/module/applications/ui/_module.mjs new file mode 100644 index 00000000..f1c32840 --- /dev/null +++ b/module/applications/ui/_module.mjs @@ -0,0 +1,4 @@ +export { default as DhChatLog } from './chatLog.mjs'; +export { default as DhCombatTracker } from './combatTracker.mjs'; +export * as DhCountdowns from './countdowns.mjs'; +export { default as DhFearTracker } from './fearTracker.mjs'; diff --git a/module/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs similarity index 96% rename from module/ui/chatLog.mjs rename to module/applications/ui/chatLog.mjs index 14d99734..182a3539 100644 --- a/module/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -1,5 +1,3 @@ -import { actionsTypes } from '../data/_module.mjs'; - export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog { constructor() { super(); @@ -213,7 +211,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo for (let target of targets) { let damage = message.system.roll.total; if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) - damage = Math.ceil(damage * (SYSTEM.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); + damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); await target.actor.takeDamage(damage, message.system.roll.type); } @@ -260,10 +258,10 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo actionUseButton = async (_, message) => { const parent = await foundry.utils.fromUuid(message.system.actor); - const testAction = Object.values(message.system.moves)[0].actions[0]; - const cls = actionsTypes[testAction.type]; + const actionType = Object.values(message.system.moves)[0].actions[0]; + const cls = CONFIG.DH.ACTIONS.actionTypes[actionType.type]; const action = new cls( - { ...testAction, _id: foundry.utils.randomID(), name: game.i18n.localize(testAction.name) }, + { ...actionType, _id: foundry.utils.randomID(), name: game.i18n.localize(actionType.name) }, { parent: parent } ); diff --git a/module/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs similarity index 83% rename from module/ui/combatTracker.mjs rename to module/applications/ui/combatTracker.mjs index d6d64f98..e5414d47 100644 --- a/module/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -1,4 +1,4 @@ -import { EncounterCountdowns } from '../applications/countdowns.mjs'; +import { EncounterCountdowns } from '../ui/countdowns.mjs'; export default class DhCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker { static DEFAULT_OPTIONS = { @@ -12,13 +12,13 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C static PARTS = { header: { - template: 'systems/daggerheart/templates/ui/combat/combatTrackerHeader.hbs' + template: 'systems/daggerheart/templates/ui/combatTracker/combatTrackerHeader.hbs' }, tracker: { - template: 'systems/daggerheart/templates/ui/combat/combatTracker.hbs' + template: 'systems/daggerheart/templates/ui/combatTracker/combatTracker.hbs' }, footer: { - template: 'systems/daggerheart/templates/ui/combat/combatTrackerFooter.hbs' + template: 'systems/daggerheart/templates/ui/combatTracker/combatTrackerFooter.hbs' } }; @@ -26,7 +26,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C await super._prepareCombatContext(context, options); Object.assign(context, { - fear: game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear) + fear: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear) }); } @@ -37,7 +37,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C const characters = context.turns?.filter(x => !x.isNPC) ?? []; Object.assign(context, { - actionTokens: game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules).actionTokens, + actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens, adversaries, characters }); @@ -86,7 +86,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C .map(x => x.id) .indexOf(combatantId); - if (this.viewed.turn !== toggleTurn) Hooks.callAll(SYSTEM.HOOKS.spotlight, {}); + if (this.viewed.turn !== toggleTurn) Hooks.callAll(CONFIG.DH.HOOKS.spotlight, {}); await this.viewed.update({ turn: this.viewed.turn === toggleTurn ? null : toggleTurn }); await combatant.update({ 'system.spotlight.requesting': false }); diff --git a/module/applications/countdowns.mjs b/module/applications/ui/countdowns.mjs similarity index 75% rename from module/applications/countdowns.mjs rename to module/applications/ui/countdowns.mjs index 54c999a9..627eac75 100644 --- a/module/applications/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -1,7 +1,7 @@ -import { countdownTypes } from '../config/generalConfig.mjs'; -import { GMUpdateEvent, RefreshType, socketEvent } from '../helpers/socket.mjs'; -import constructHTMLButton from '../helpers/utils.mjs'; -import OwnershipSelection from './ownershipSelection.mjs'; +import { countdownTypes } from '../../config/generalConfig.mjs'; +import { GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; +import constructHTMLButton from '../../helpers/utils.mjs'; +import OwnershipSelection from '../dialogs/ownershipSelection.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -41,7 +41,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { static PARTS = { countdowns: { - template: 'systems/daggerheart/templates/views/countdowns.hbs', + template: 'systems/daggerheart/templates/ui/countdowns.hbs', scrollable: ['.expanded-view'] } }; @@ -57,18 +57,18 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { async _preFirstRender(context, options) { options.position = - game.user.getFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].position) ?? + game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].position) ?? Countdowns.DEFAULT_OPTIONS.position; const viewSetting = - game.user.getFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].simple) ?? !game.user.isGM; + game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].simple) ?? !game.user.isGM; this.simpleView = game.user.isGM || !this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER) ? viewSetting : true; context.simple = this.simpleView; } _onPosition(position) { - game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].position, position); + game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].position, position); } async _renderFrame(options) { @@ -90,7 +90,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { if (game.user.isGM) return true; const settings = - altSettings ?? game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath]; + altSettings ?? game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath]; const defaultAllowed = exact ? settings.ownership.default === level : settings.ownership.default >= level; const userAllowed = exact ? settings.playerOwnership[game.user.id]?.value === level @@ -100,7 +100,9 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { async _prepareContext(_options) { const context = await super._prepareContext(_options); - const countdownData = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath]; + const countdownData = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[ + this.basePath + ]; context.isGM = game.user.isGM; context.base = this.basePath; @@ -131,19 +133,19 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { static async updateData(event, _, formData) { const data = foundry.utils.expandObject(formData.object); const newSetting = foundry.utils.mergeObject( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns).toObject(), + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns).toObject(), data ); if (game.user.isGM) { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, newSetting); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, newSetting); this.render(); } else { - await game.socket.emit(`system.${SYSTEM.id}`, { + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.GMUpdate, data: { action: GMUpdateEvent.UpdateSetting, - uuid: SYSTEM.SETTINGS.gameSettings.Countdowns, + uuid: CONFIG.DH.SETTINGS.gameSettings.Countdowns, update: newSetting } }); @@ -152,8 +154,8 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { async updateSetting(update) { if (game.user.isGM) { - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, update); - await game.socket.emit(`system.${SYSTEM.id}`, { + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, update); + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.Refresh, data: { refreshType: RefreshType.Countdown, @@ -163,11 +165,11 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { this.render(); } else { - await game.socket.emit(`system.${SYSTEM.id}`, { + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.GMUpdate, data: { action: GMUpdateEvent.UpdateSetting, - uuid: SYSTEM.SETTINGS.gameSettings.Countdowns, + uuid: CONFIG.DH.SETTINGS.gameSettings.Countdowns, update: update, refresh: { refreshType: RefreshType.Countdown, application: `${this.basePath}-countdowns` } } @@ -176,7 +178,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { } static onEditImage(_, target) { - const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath]; + const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath]; const current = setting.countdowns[target.dataset.countdown].img; const fp = new foundry.applications.apps.FilePicker.implementation({ current, @@ -189,7 +191,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { } async updateImage(path, countdown) { - const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); await setting.updateSource({ [`${this.basePath}.countdowns.${countdown}.img`]: path }); @@ -199,16 +201,16 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { static openOwnership(_, target) { new Promise((resolve, reject) => { - const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath]; + const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath]; const ownership = { default: setting.ownership.default, players: setting.playerOwnership }; new OwnershipSelection(resolve, reject, this.title, ownership).render(true); }).then(async ownership => { - const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); await setting.updateSource({ [`${this.basePath}.ownership`]: ownership }); - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, setting.toObject()); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, setting.toObject()); this.render(); }); } @@ -216,29 +218,29 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { static openCountdownOwnership(_, target) { const countdownId = target.dataset.countdown; new Promise((resolve, reject) => { - const countdown = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath] + const countdown = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath] .countdowns[countdownId]; const ownership = { default: countdown.ownership.default, players: countdown.playerOwnership }; new OwnershipSelection(resolve, reject, countdown.name, ownership).render(true); }).then(async ownership => { - const setting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); await setting.updateSource({ [`${this.basePath}.countdowns.${countdownId}.ownership`]: ownership }); - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, setting); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, setting); this.render(); }); } static async toggleSimpleView() { this.simpleView = !this.simpleView; - await game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS[`${this.basePath}Countdown`].simple, this.simpleView); + await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS[`${this.basePath}Countdown`].simple, this.simpleView); this.render(); } async updateCountdownValue(event, increase) { - const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); const countdown = countdownSetting[this.basePath].countdowns[event.currentTarget.dataset.countdown]; if (!this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) { @@ -260,7 +262,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { } static async addCountdown() { - const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); await countdownSetting.updateSource({ [`${this.basePath}.countdowns.${foundry.utils.randomID()}`]: { name: game.i18n.localize('DAGGERHEART.Countdown.NewCountdown'), @@ -278,7 +280,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { } static async removeCountdown(_, target) { - const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); const countdownName = countdownSetting[this.basePath].countdowns[target.dataset.countdown].name; const confirmed = await foundry.applications.api.DialogV2.confirm({ @@ -297,8 +299,9 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) { async open() { await this.render(true); if ( - Object.keys(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath].countdowns) - .length > 0 + Object.keys( + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns)[this.basePath].countdowns + ).length > 0 ) { this.minimize(); } @@ -327,8 +330,8 @@ export class EncounterCountdowns extends Countdowns { export const registerCountdownApplicationHooks = () => { const updateCountdowns = async shouldProgress => { - if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).countdowns) { - const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns); + if (game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).countdowns) { + const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); for (let countdownCategoryKey in countdownSetting) { const countdownCategory = countdownSetting[countdownCategoryKey]; for (let countdownKey in countdownCategory.countdowns) { @@ -339,7 +342,11 @@ export const registerCountdownApplicationHooks = () => { [`${countdownCategoryKey}.countdowns.${countdownKey}.progress.current`]: countdown.progress.current - 1 }); - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, countdownSetting); + await game.settings.set( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.Countdowns, + countdownSetting + ); foundry.applications.instances.get(`${countdownCategoryKey}-countdowns`)?.render(); } } @@ -347,7 +354,7 @@ export const registerCountdownApplicationHooks = () => { } }; - Hooks.on(SYSTEM.HOOKS.characterAttack, async () => { + Hooks.on(CONFIG.DH.HOOKS.characterAttack, async () => { updateCountdowns(countdown => { return ( countdown.progress.type.value === countdownTypes.characterAttack.id && countdown.progress.current > 0 @@ -355,7 +362,7 @@ export const registerCountdownApplicationHooks = () => { }); }); - Hooks.on(SYSTEM.HOOKS.spotlight, async () => { + Hooks.on(CONFIG.DH.HOOKS.spotlight, async () => { updateCountdowns(countdown => { return countdown.progress.type.value === countdownTypes.spotlight.id && countdown.progress.current > 0; }); diff --git a/module/applications/resources.mjs b/module/applications/ui/fearTracker.mjs similarity index 71% rename from module/applications/resources.mjs rename to module/applications/ui/fearTracker.mjs index 3b8c6ce6..c2f56c4c 100644 --- a/module/applications/resources.mjs +++ b/module/applications/ui/fearTracker.mjs @@ -8,7 +8,7 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; * @mixes HandlebarsApplication */ -export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) { +export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV2) { constructor(options = {}) { super(options); } @@ -26,8 +26,8 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) minimizable: false }, actions: { - setFear: Resources.setFear, - increaseFear: Resources.increaseFear + setFear: FearTracker.setFear, + increaseFear: FearTracker.increaseFear }, position: { width: 222, @@ -41,16 +41,16 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) static PARTS = { resources: { root: true, - template: 'systems/daggerheart/templates/views/resources.hbs' + template: 'systems/daggerheart/templates/ui/fearTracker.hbs' } }; get currentFear() { - return game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear); + return game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear); } get maxFear() { - return game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew).maxFear; + return game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear; } /* -------------------------------------------- */ @@ -59,7 +59,7 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) /** @override */ async _prepareContext(_options) { - const display = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).displayFear, + const display = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).displayFear, current = this.currentFear, max = this.maxFear, percent = (current / max) * 100, @@ -70,17 +70,18 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) /** @override */ async _preFirstRender(context, options) { - options.position = game.user.getFlag(SYSTEM.id, 'app.resources.position') ?? Resources.DEFAULT_OPTIONS.position; + options.position = + game.user.getFlag(CONFIG.DH.id, 'app.resources.position') ?? FearTracker.DEFAULT_OPTIONS.position; } /** @override */ async _preRender(context, options) { if (this.currentFear > this.maxFear) - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, this.maxFear); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, this.maxFear); } _onPosition(position) { - game.user.setFlag(SYSTEM.id, 'app.resources.position', position); + game.user.setFlag(CONFIG.DH.id, 'app.resources.position', position); } async close(options = {}) { @@ -104,6 +105,6 @@ export default class Resources extends HandlebarsApplicationMixin(ApplicationV2) async updateFear(value) { if (!game.user.isGM) return; value = Math.max(0, Math.min(this.maxFear, value)); - await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, value); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, value); } } diff --git a/module/applications/ux/_module.mjs b/module/applications/ux/_module.mjs index a16a4d6f..5ec0eecf 100644 --- a/module/applications/ux/_module.mjs +++ b/module/applications/ux/_module.mjs @@ -1 +1,2 @@ export { default as FilterMenu } from './filter-menu.mjs'; +export { default as ContextMenu } from './contextMenu.mjs'; diff --git a/module/applications/contextMenu.mjs b/module/applications/ux/contextMenu.mjs similarity index 100% rename from module/applications/contextMenu.mjs rename to module/applications/ux/contextMenu.mjs diff --git a/module/applications/ux/filter-menu.mjs b/module/applications/ux/filter-menu.mjs index 0973a358..ff2fb036 100644 --- a/module/applications/ux/filter-menu.mjs +++ b/module/applications/ux/filter-menu.mjs @@ -19,7 +19,8 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { const mergedOptions = { eventName: 'click', fixed: true, - ...options + ...options, + jQuery: false }; super(container, selector, menuItems, mergedOptions); @@ -176,7 +177,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { } })); - const burdenFilter = Object.values(CONFIG.daggerheart.GENERAL.burden).map(({ value, label }) => ({ + const burdenFilter = Object.values(CONFIG.DH.GENERAL.burden).map(({ value, label }) => ({ group: game.i18n.localize('DAGGERHEART.Sheets.Weapon.Burden'), name: game.i18n.localize(label), filter: { @@ -186,7 +187,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { } })); - const damageTypeFilter = Object.values(CONFIG.daggerheart.GENERAL.damageTypes).map(({ id, abbreviation }) => ({ + const damageTypeFilter = Object.values(CONFIG.DH.GENERAL.damageTypes).map(({ id, abbreviation }) => ({ group: 'Damage Type', //TODO localize name: game.i18n.localize(abbreviation), filter: { @@ -210,7 +211,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { static get cardsFilters() { const { OPERATORS } = foundry.applications.ux.SearchFilter; - const typesFilters = Object.values(CONFIG.daggerheart.DOMAIN.cardTypes).map(({ id, label }) => ({ + const typesFilters = Object.values(CONFIG.DH.DOMAIN.cardTypes).map(({ id, label }) => ({ group: game.i18n.localize('Type'), name: game.i18n.localize(label), filter: { @@ -220,7 +221,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { } })); - const domainFilter = Object.values(CONFIG.daggerheart.DOMAIN.domains).map(({ id, label }) => ({ + const domainFilter = Object.values(CONFIG.DH.DOMAIN.domains).map(({ id, label }) => ({ group: game.i18n.localize('DAGGERHEART.Sheets.DomainCard.Domain'), name: game.i18n.localize(label), filter: { diff --git a/module/canvas/_module.mjs b/module/canvas/_module.mjs new file mode 100644 index 00000000..6b8885f4 --- /dev/null +++ b/module/canvas/_module.mjs @@ -0,0 +1 @@ +export * as placeables from './placeables/_module.mjs'; diff --git a/module/canvas/placeables/_module.mjs b/module/canvas/placeables/_module.mjs new file mode 100644 index 00000000..1da3a1e9 --- /dev/null +++ b/module/canvas/placeables/_module.mjs @@ -0,0 +1,3 @@ +export { default as DhMeasuredTemplate } from './measuredTemplate.mjs'; +export { default as DhRuler } from './ruler.mjs'; +export { default as DhTokenRuler } from './tokenRuler.mjs'; diff --git a/module/placeables/measuredTemplate.mjs b/module/canvas/placeables/measuredTemplate.mjs similarity index 88% rename from module/placeables/measuredTemplate.mjs rename to module/canvas/placeables/measuredTemplate.mjs index 385cf81e..6fffa1e5 100644 --- a/module/placeables/measuredTemplate.mjs +++ b/module/canvas/placeables/measuredTemplate.mjs @@ -2,7 +2,10 @@ export default class DhMeasuredTemplate extends foundry.canvas.placeables.Measur _refreshRulerText() { super._refreshRulerText(); - const rangeMeasurementSettings = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement); + const rangeMeasurementSettings = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement + ); if (rangeMeasurementSettings.enabled) { const splitRulerText = this.ruler.text.split(' '); if (splitRulerText.length > 0) { diff --git a/module/ui/ruler.mjs b/module/canvas/placeables/ruler.mjs similarity index 85% rename from module/ui/ruler.mjs rename to module/canvas/placeables/ruler.mjs index 655c9c61..498ee3df 100644 --- a/module/ui/ruler.mjs +++ b/module/canvas/placeables/ruler.mjs @@ -5,7 +5,7 @@ export default class DhpRuler extends foundry.canvas.interaction.Ruler { const context = super._getWaypointLabelContext(waypoint, state); if (!context) return; - const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement); + const range = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement); if (range.enabled) { const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range); diff --git a/module/ui/tokenRuler.mjs b/module/canvas/placeables/tokenRuler.mjs similarity index 85% rename from module/ui/tokenRuler.mjs rename to module/canvas/placeables/tokenRuler.mjs index 5c5a275e..ea30ca95 100644 --- a/module/ui/tokenRuler.mjs +++ b/module/canvas/placeables/tokenRuler.mjs @@ -5,7 +5,7 @@ export default class DhpTokenRuler extends foundry.canvas.placeables.tokens.Toke const context = super._getWaypointLabelContext(waypoint, state); if (!context) return; - const range = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement); + const range = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement); if (range.enabled) { const distance = DhMeasuredTemplate.getDistanceLabel(waypoint.measurement.distance.toNearest(0.01), range); diff --git a/module/config/_module.mjs b/module/config/_module.mjs new file mode 100644 index 00000000..88003595 --- /dev/null +++ b/module/config/_module.mjs @@ -0,0 +1,10 @@ +export * as actionConfig from './actionConfig.mjs'; +export * as actorConfig from './actorConfig.mjs'; +export * as domainConfig from './domainConfig.mjs'; +export * as effectConfig from './effectConfig.mjs'; +export * as flagsConfig from './flagsConfig.mjs'; +export * as generalConfig from './generalConfig.mjs'; +export * as hooksConfig from './hooksConfig.mjs'; +export * as itemConfig from './itemConfig.mjs'; +export * as settingsConfig from './settingsConfig.mjs'; +export * as systemConfig from './system.mjs'; diff --git a/module/config/effectConfig.mjs b/module/config/effectConfig.mjs index 17d5c960..2204b612 100644 --- a/module/config/effectConfig.mjs +++ b/module/config/effectConfig.mjs @@ -1,4 +1,4 @@ -import { range } from './generalConfig.mjs'; +import { range } from '../config/generalConfig.mjs'; export const valueTypes = { numberString: { diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 06c75fce..971ee3fe 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -290,7 +290,7 @@ export const diceSetNumbers = { }; export const getDiceSoNicePresets = () => { - const { diceSoNice } = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance); + const { diceSoNice } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance); return { hope: { diff --git a/module/data/_module.mjs b/module/data/_module.mjs index 45a1d558..cac02a4a 100644 --- a/module/data/_module.mjs +++ b/module/data/_module.mjs @@ -1,9 +1,9 @@ export { default as DhCombat } from './combat.mjs'; export { default as DhCombatant } from './combatant.mjs'; -export * as actors from './actor/_module.mjs'; -export * as items from './item/_module.mjs'; -export { actionsTypes } from './action/_module.mjs'; -export * as messages from './chat-message/_modules.mjs'; -export * as fields from './fields/_module.mjs'; +export * as actions from './action/_module.mjs'; export * as activeEffects from './activeEffect/_module.mjs'; +export * as actors from './actor/_module.mjs'; +export * as chatMessages from './chat-message/_modules.mjs'; +export * as fields from './fields/_module.mjs'; +export * as items from './item/_module.mjs'; diff --git a/module/data/action/_module.mjs b/module/data/action/_module.mjs index 09c027d1..bc2c16fd 100644 --- a/module/data/action/_module.mjs +++ b/module/data/action/_module.mjs @@ -1,25 +1,20 @@ -import { - DHAttackAction, - DHBaseAction, - DhBeastformAction, - DHDamageAction, - DHEffectAction, - DHHealingAction, - DHMacroAction, - // DHResourceAction, - // DHSpellCastAction, - DHSummonAction -} from './action.mjs'; +export * as ActionDice from './actionDice.mjs'; +import AttackAction from './attackAction.mjs'; +import BaseAction from './baseAction.mjs'; +import BeastformAction from './beastformAction.mjs'; +import DamageAction from './damageAction.mjs'; +import EffectAction from './effectAction.mjs'; +import HealingAction from './healingAction.mjs'; +import MacroAction from './macroAction.mjs'; +import SummonAction from './summonAction.mjs'; export const actionsTypes = { - base: DHBaseAction, - attack: DHAttackAction, - // spellcast: DHSpellCastAction, - // resource: DHResourceAction, - damage: DHDamageAction, - healing: DHHealingAction, - summon: DHSummonAction, - effect: DHEffectAction, - macro: DHMacroAction, - beastform: DhBeastformAction + base: BaseAction, + attack: AttackAction, + damage: DamageAction, + healing: HealingAction, + summon: SummonAction, + effect: EffectAction, + macro: MacroAction, + beastform: BeastformAction }; diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index adf00461..38122c1d 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -8,21 +8,25 @@ export class DHActionRollData extends foundry.abstract.DataModel { /** @override */ static defineSchema() { return { - type: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.GENERAL.rollTypes }), - trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }), + type: new fields.StringField({ nullable: true, initial: null, choices: CONFIG.DH.GENERAL.rollTypes }), + trait: new fields.StringField({ nullable: true, initial: null, choices: CONFIG.DH.ACTOR.abilities }), difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }), bonus: new fields.NumberField({ nullable: true, initial: null, integer: true }), - advState: new fields.StringField({ choices: SYSTEM.ACTIONS.advandtageState, initial: 'neutral' }), + advState: new fields.StringField({ choices: CONFIG.DH.ACTIONS.advandtageState, initial: 'neutral' }), diceRolling: new fields.SchemaField({ multiplier: new fields.StringField({ - choices: SYSTEM.GENERAL.diceSetNumbers, + choices: CONFIG.DH.GENERAL.diceSetNumbers, initial: 'prof', label: 'Dice Number' }), flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }), - dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Dice Type' }), + dice: new fields.StringField({ + choices: CONFIG.DH.GENERAL.diceTypes, + initial: 'd6', + label: 'Dice Type' + }), compare: new fields.StringField({ - choices: SYSTEM.ACTIONS.diceCompare, + choices: CONFIG.DH.ACTIONS.diceCompare, initial: 'above', label: 'Should be' }), @@ -40,7 +44,7 @@ export class DHActionRollData extends foundry.abstract.DataModel { this.diceRolling.multiplier === 'flat' ? this.diceRolling.flatMultiplier : `@${this.diceRolling.multiplier}`; - formula = `${multiplier}${this.diceRolling.dice}cs${SYSTEM.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`; + formula = `${multiplier}${this.diceRolling.dice}cs${CONFIG.DH.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`; break; default: // formula = `${(!!this.parent?.actor?.system?.attack ? `@attackBonus` : `@traits.${this.trait}.total`)}`; @@ -58,12 +62,12 @@ export class DHActionDiceData extends foundry.abstract.DataModel { static defineSchema() { return { multiplier: new fields.StringField({ - choices: SYSTEM.GENERAL.multiplierTypes, + choices: CONFIG.DH.GENERAL.multiplierTypes, initial: 'prof', label: 'Multiplier' }), flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }), - dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Dice' }), + dice: new fields.StringField({ choices: CONFIG.DH.GENERAL.diceTypes, initial: 'd6', label: 'Dice' }), bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }), custom: new fields.SchemaField({ enabled: new fields.BooleanField({ label: 'Custom Formula' }), @@ -101,7 +105,7 @@ export class DHDamageData extends foundry.abstract.DataModel { // ...super.defineSchema(), base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }), type: new fields.StringField({ - choices: SYSTEM.GENERAL.damageTypes, + choices: CONFIG.DH.GENERAL.damageTypes, initial: 'physical', label: 'Type', nullable: false, diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs new file mode 100644 index 00000000..c7cc83ca --- /dev/null +++ b/module/data/action/attackAction.mjs @@ -0,0 +1,34 @@ +import { DHDamageData } from './actionDice.mjs'; +import DHDamageAction from './damageAction.mjs'; + +export default class DHAttackAction extends DHDamageAction { + static extraSchemas = [...super.extraSchemas, ...['roll', 'save']]; + + static getRollType(parent) { + return parent.type === 'weapon' ? 'weapon' : 'spellcast'; + } + + get chatTemplate() { + return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs'; + } + + prepareData() { + super.prepareData(); + if (this.damage.includeBase && !!this.item?.system?.damage) { + const baseDamage = this.getParentDamage(); + this.damage.parts.unshift(new DHDamageData(baseDamage)); + } + } + + getParentDamage() { + return { + value: { + multiplier: 'prof', + dice: this.item?.system?.damage.dice, + bonus: this.item?.system?.damage.bonus ?? 0 + }, + type: this.item?.system?.damage.type, + base: true + }; + } +} diff --git a/module/data/action/action.mjs b/module/data/action/baseAction.mjs similarity index 66% rename from module/data/action/action.mjs rename to module/data/action/baseAction.mjs index a8ab2bb2..e752421c 100644 --- a/module/data/action/action.mjs +++ b/module/data/action/baseAction.mjs @@ -1,7 +1,6 @@ import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField } from './actionDice.mjs'; import DhpActor from '../../documents/actor.mjs'; -import D20RollDialog from '../../dialogs/d20RollDialog.mjs'; -import BeastformDialog from '../../dialogs/beastformDialog.mjs'; +import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs'; const fields = foundry.data.fields; @@ -21,7 +20,7 @@ const fields = foundry.data.fields; - Auto use action <= Into Roll */ -export class DHBaseAction extends foundry.abstract.DataModel { +export default class DHBaseAction extends foundry.abstract.DataModel { static extraSchemas = []; static defineSchema() { @@ -33,11 +32,15 @@ export class DHBaseAction extends foundry.abstract.DataModel { description: new fields.HTMLField(), img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }), chatDisplay: new fields.BooleanField({ initial: true, label: 'Display in chat' }), - actionType: new fields.StringField({ choices: SYSTEM.ITEM.actionTypes, initial: 'action', nullable: true }), + actionType: new fields.StringField({ + choices: CONFIG.DH.ITEM.actionTypes, + initial: 'action', + nullable: true + }), cost: new fields.ArrayField( new fields.SchemaField({ type: new fields.StringField({ - choices: SYSTEM.GENERAL.abilityCosts, + choices: CONFIG.DH.GENERAL.abilityCosts, nullable: false, required: true, initial: 'hope' @@ -51,13 +54,13 @@ export class DHBaseAction extends foundry.abstract.DataModel { value: new fields.NumberField({ nullable: true, initial: null }), max: new fields.NumberField({ nullable: true, initial: null }), recovery: new fields.StringField({ - choices: SYSTEM.GENERAL.refreshTypes, + choices: CONFIG.DH.GENERAL.refreshTypes, initial: null, nullable: true }) }), range: new fields.StringField({ - choices: SYSTEM.GENERAL.range, + choices: CONFIG.DH.GENERAL.range, required: false, blank: true // initial: null @@ -71,17 +74,21 @@ export class DHBaseAction extends foundry.abstract.DataModel { damage: new DHDamageField(), roll: new fields.EmbeddedDataField(DHActionRollData), save: new fields.SchemaField({ - trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }), + trait: new fields.StringField({ + nullable: true, + initial: null, + choices: CONFIG.DH.ACTOR.abilities + }), difficulty: new fields.NumberField({ nullable: true, initial: 10, integer: true, min: 0 }), damageMod: new fields.StringField({ - initial: SYSTEM.ACTIONS.damageOnSave.none.id, - choices: SYSTEM.ACTIONS.damageOnSave + initial: CONFIG.DH.ACTIONS.damageOnSave.none.id, + choices: CONFIG.DH.ACTIONS.damageOnSave }) }), target: new fields.SchemaField({ type: new fields.StringField({ - choices: SYSTEM.ACTIONS.targetTypes, - initial: SYSTEM.ACTIONS.targetTypes.any.id, + choices: CONFIG.DH.ACTIONS.targetTypes, + initial: CONFIG.DH.ACTIONS.targetTypes.any.id, nullable: true, initial: null }), @@ -95,10 +102,10 @@ export class DHBaseAction extends foundry.abstract.DataModel { ), healing: new fields.SchemaField({ type: new fields.StringField({ - choices: SYSTEM.GENERAL.healingTypes, + choices: CONFIG.DH.GENERAL.healingTypes, required: true, blank: false, - initial: SYSTEM.GENERAL.healingTypes.hitPoints.id, + initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id, label: 'Healing' }), resultBased: new fields.BooleanField({ @@ -143,7 +150,7 @@ export class DHBaseAction extends foundry.abstract.DataModel { } get chatTemplate() { - return 'systems/daggerheart/templates/chat/duality-roll.hbs'; + return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs'; } static getRollType(parent) { @@ -228,7 +235,7 @@ export class DHBaseAction extends foundry.abstract.DataModel { data: actorData }; - if (Hooks.call(`${SYSTEM.id}.preUseAction`, this, config) === false) return; + if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; // Display configuration window if necessary if (config.dialog?.configure && this.requireConfigurationDialog(config)) { @@ -284,7 +291,7 @@ export class DHBaseAction extends foundry.abstract.DataModel { // Consume resources await this.consume(config); - if (Hooks.call(`${SYSTEM.id}.postUseAction`, this, config) === false) return; + if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return; return config; } @@ -324,11 +331,11 @@ export class DHBaseAction extends foundry.abstract.DataModel { prepareTarget() { let targets; - if (this.target?.type === SYSTEM.ACTIONS.targetTypes.self.id) + if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id) targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken); targets = Array.from(game.user.targets); // foundry.CONST.TOKEN_DISPOSITIONS.FRIENDLY - if (this.target?.type && this.target.type !== SYSTEM.ACTIONS.targetTypes.any.id) { + if (this.target?.type && this.target.type !== CONFIG.DH.ACTIONS.targetTypes.any.id) { targets = targets.filter(t => this.isTargetFriendly(t)); if (this.target.amount && targets.length > this.target.amount) targets = []; } @@ -350,7 +357,7 @@ export class DHBaseAction extends foundry.abstract.DataModel { difficulty: this.roll?.difficulty, formula: this.roll.getFormula(), bonus: this.roll.bonus, - advantage: SYSTEM.ACTIONS.advandtageState[this.roll.advState].value + advantage: CONFIG.DH.ACTIONS.advandtageState[this.roll.advState].value }; if (this.roll?.type === 'diceSet') roll.lite = true; @@ -413,7 +420,7 @@ export class DHBaseAction extends foundry.abstract.DataModel { const fearCost = realCosts.splice(hasFearCost, 1); if ( !game.user.isGM || - fearCost[0].total > game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear) + fearCost[0].total > game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear) ) return false; } @@ -446,8 +453,10 @@ export class DHBaseAction extends foundry.abstract.DataModel { : this.actor.prototypeToken.disposition, targetDisposition = target.document.disposition; return ( - (this.target.type === SYSTEM.ACTIONS.targetTypes.friendly.id && actorDisposition === targetDisposition) || - (this.target.type === SYSTEM.ACTIONS.targetTypes.hostile.id && actorDisposition + targetDisposition === 0) + (this.target.type === CONFIG.DH.ACTIONS.targetTypes.friendly.id && + actorDisposition === targetDisposition) || + (this.target.type === CONFIG.DH.ACTIONS.targetTypes.hostile.id && + actorDisposition + targetDisposition === 0) ); } @@ -567,7 +576,7 @@ export class DHBaseAction extends foundry.abstract.DataModel { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); @@ -575,239 +584,3 @@ export class DHBaseAction extends foundry.abstract.DataModel { cls.create(msg.toObject()); } } - -export class DHDamageAction extends DHBaseAction { - static extraSchemas = ['damage', 'target', 'effects']; - - getFormulaValue(part, data) { - let formulaValue = part.value; - if (this.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt; - return formulaValue; - } - - async rollDamage(event, data) { - let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '); - - if (!formula || formula == '') return; - let roll = { formula: formula, total: formula }, - bonusDamage = []; - - if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data)); - - const config = { - title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }), - roll: { formula }, - targets: data.system?.targets.filter(t => t.hit) ?? data.targets, - hasSave: this.hasSave, - isCritical: data.system?.roll?.isCritical ?? false, - source: data.system?.source, - event - }; - if (this.hasSave) config.onSave = this.save.damageMod; - if (data.system) { - config.source.message = data._id; - config.directDamage = false; - } - - roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); - } -} - -export class DHAttackAction extends DHDamageAction { - static extraSchemas = [...super.extraSchemas, ...['roll', 'save']]; - - static getRollType(parent) { - return parent.type === 'weapon' ? 'weapon' : 'spellcast'; - } - - get chatTemplate() { - return 'systems/daggerheart/templates/chat/duality-roll.hbs'; - } - - prepareData() { - super.prepareData(); - if (this.damage.includeBase && !!this.item?.system?.damage) { - const baseDamage = this.getParentDamage(); - this.damage.parts.unshift(new DHDamageData(baseDamage)); - } - } - - getParentDamage() { - return { - value: { - multiplier: 'prof', - dice: this.item?.system?.damage.dice, - bonus: this.item?.system?.damage.bonus ?? 0 - }, - type: this.item?.system?.damage.type, - base: true - }; - } -} - -export class DHHealingAction extends DHBaseAction { - static extraSchemas = ['target', 'effects', 'healing', 'roll']; - - static getRollType(parent) { - return 'spellcast'; - } - - getFormulaValue(data) { - let formulaValue = this.healing.value; - if (this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1) - return this.healing.valueAlt; - return formulaValue; - } - - async rollHealing(event, data) { - let formulaValue = this.getFormulaValue(data), - formula = formulaValue.getFormula(this.actor); - - if (!formula || formula == '') return; - let roll = { formula: formula, total: formula }, - bonusDamage = []; - - const config = { - title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', { - healing: game.i18n.localize(SYSTEM.GENERAL.healingTypes[this.healing.type].label) - }), - roll: { formula }, - targets: (data.system?.targets ?? data.targets).filter(t => t.hit), - messageType: 'healing', - type: this.healing.type, - event - }; - - roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); - } - - get chatTemplate() { - return 'systems/daggerheart/templates/chat/healing-roll.hbs'; - } -} - -export class DHSummonAction extends DHBaseAction { - static defineSchema() { - return { - ...super.defineSchema(), - documentUUID: new fields.DocumentUUIDField({ type: 'Actor' }) - }; - } - - async trigger(event, ...args) { - if (!this.canSummon || !canvas.scene) return; - // const config = await super.use(event, args); - } - - get canSummon() { - return game.user.can('TOKEN_CREATE'); - } -} - -export class DHEffectAction extends DHBaseAction { - static extraSchemas = ['effects', 'target']; - - async use(event, ...args) { - const config = await super.use(event, args); - if (['error', 'warning'].includes(config.type)) return; - return await this.chatApplyEffects(event, config); - } - - async chatApplyEffects(event, data) { - const cls = getDocumentClass('ChatMessage'), - systemData = { - title: game.i18n.format('DAGGERHEART.Chat.ApplyEffect.Title', { name: this.name }), - origin: this.actor._id, - description: '', - targets: data.targets.map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })), - action: { - itemId: this.item._id, - actionId: this._id - } - }, - msg = new cls({ - type: 'applyEffect', - user: game.user.id, - system: systemData, - content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/apply-effects.hbs', - systemData - ) - }); - - cls.create(msg.toObject()); - } - - get chatTemplate() { - return 'systems/daggerheart/templates/chat/apply-effects.hbs'; - } -} - -export class DHMacroAction extends DHBaseAction { - static defineSchema() { - return { - ...super.defineSchema(), - documentUUID: new fields.DocumentUUIDField({ type: 'Macro' }) - }; - } - - async trigger(event, ...args) { - // const config = await super.use(event, args); - // if (['error', 'warning'].includes(config.type)) return; - const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID, - macro = await fromUuid(fixUUID); - try { - if (!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`); - macro.execute(); - } catch (error) { - ui.notifications.error(error); - } - } -} - -export class DhBeastformAction extends DHBaseAction { - static extraSchemas = ['beastform']; - - async use(event, ...args) { - const beastformConfig = this.prepareBeastformConfig(); - - const abort = await this.handleActiveTransformations(); - if (abort) return; - - const beastformUuid = await BeastformDialog.configure(beastformConfig); - if (!beastformUuid) return; - - await this.transform(beastformUuid); - } - - prepareBeastformConfig(config) { - const settingsTiers = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers; - const actorLevel = this.actor.system.levelData.level.current; - const actorTier = - Object.values(settingsTiers).find( - tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end - ) ?? 1; - - return { - tierLimit: this.beastform.tierAccess.exact ?? actorTier - }; - } - - async transform(beastformUuid) { - const beastform = await foundry.utils.fromUuid(beastformUuid); - this.actor.createEmbeddedDocuments('Item', [beastform.toObject()]); - } - - async handleActiveTransformations() { - const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform'); - if (beastformEffects.length > 0) { - for (let effect of beastformEffects) { - await effect.delete(); - } - - return true; - } - - return false; - } -} diff --git a/module/data/action/beastformAction.mjs b/module/data/action/beastformAction.mjs new file mode 100644 index 00000000..98d8053f --- /dev/null +++ b/module/data/action/beastformAction.mjs @@ -0,0 +1,49 @@ +import BeastformDialog from '../../applications/dialogs/beastformDialog.mjs'; +import DHBaseAction from './baseAction.mjs'; + +export default class DhBeastformAction extends DHBaseAction { + static extraSchemas = ['beastform']; + + async use(event, ...args) { + const beastformConfig = this.prepareBeastformConfig(); + + const abort = await this.handleActiveTransformations(); + if (abort) return; + + const beastformUuid = await BeastformDialog.configure(beastformConfig); + if (!beastformUuid) return; + + await this.transform(beastformUuid); + } + + prepareBeastformConfig(config) { + const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers; + const actorLevel = this.actor.system.levelData.level.current; + const actorTier = + Object.values(settingsTiers).find( + tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end + ) ?? 1; + + return { + tierLimit: this.beastform.tierAccess.exact ?? actorTier + }; + } + + async transform(beastformUuid) { + const beastform = await foundry.utils.fromUuid(beastformUuid); + this.actor.createEmbeddedDocuments('Item', [beastform.toObject()]); + } + + async handleActiveTransformations() { + const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform'); + if (beastformEffects.length > 0) { + for (let effect of beastformEffects) { + await effect.delete(); + } + + return true; + } + + return false; + } +} diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs new file mode 100644 index 00000000..ab34198d --- /dev/null +++ b/module/data/action/damageAction.mjs @@ -0,0 +1,38 @@ +import DHBaseAction from './baseAction.mjs'; + +export default class DHDamageAction extends DHBaseAction { + static extraSchemas = ['damage', 'target', 'effects']; + + getFormulaValue(part, data) { + let formulaValue = part.value; + if (this.hasRoll && part.resultBased && data.system.roll.result.duality === -1) return part.valueAlt; + return formulaValue; + } + + async rollDamage(event, data) { + let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '); + + if (!formula || formula == '') return; + let roll = { formula: formula, total: formula }, + bonusDamage = []; + + if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(data.system ?? data)); + + const config = { + title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }), + roll: { formula }, + targets: data.system?.targets.filter(t => t.hit) ?? data.targets, + hasSave: this.hasSave, + isCritical: data.system?.roll?.isCritical ?? false, + source: data.system?.source, + event + }; + if (this.hasSave) config.onSave = this.save.damageMod; + if (data.system) { + config.source.message = data._id; + config.directDamage = false; + } + + roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); + } +} diff --git a/module/data/action/effectAction.mjs b/module/data/action/effectAction.mjs new file mode 100644 index 00000000..6ef3e93c --- /dev/null +++ b/module/data/action/effectAction.mjs @@ -0,0 +1,40 @@ +import DHBaseAction from './baseAction.mjs'; + +export default class DHEffectAction extends DHBaseAction { + static extraSchemas = ['effects', 'target']; + + async use(event, ...args) { + const config = await super.use(event, args); + if (['error', 'warning'].includes(config.type)) return; + return await this.chatApplyEffects(event, config); + } + + async chatApplyEffects(event, data) { + const cls = getDocumentClass('ChatMessage'), + systemData = { + title: game.i18n.format('DAGGERHEART.Chat.ApplyEffect.Title', { name: this.name }), + origin: this.actor._id, + description: '', + targets: data.targets.map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })), + action: { + itemId: this.item._id, + actionId: this._id + } + }, + msg = new cls({ + type: 'applyEffect', + user: game.user.id, + system: systemData, + content: await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/ui/chat/apply-effects.hbs', + systemData + ) + }); + + cls.create(msg.toObject()); + } + + get chatTemplate() { + return 'systems/daggerheart/templates/ui/chat/apply-effects.hbs'; + } +} diff --git a/module/data/action/healingAction.mjs b/module/data/action/healingAction.mjs new file mode 100644 index 00000000..ed785388 --- /dev/null +++ b/module/data/action/healingAction.mjs @@ -0,0 +1,42 @@ +import DHBaseAction from './baseAction.mjs'; + +export default class DHHealingAction extends DHBaseAction { + static extraSchemas = ['target', 'effects', 'healing', 'roll']; + + static getRollType(parent) { + return 'spellcast'; + } + + getFormulaValue(data) { + let formulaValue = this.healing.value; + if (this.hasRoll && this.healing.resultBased && data.system.roll.result.duality === -1) + return this.healing.valueAlt; + return formulaValue; + } + + async rollHealing(event, data) { + let formulaValue = this.getFormulaValue(data), + formula = formulaValue.getFormula(this.actor); + + if (!formula || formula == '') return; + let roll = { formula: formula, total: formula }, + bonusDamage = []; + + const config = { + title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', { + healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.type].label) + }), + roll: { formula }, + targets: (data.system?.targets ?? data.targets).filter(t => t.hit), + messageType: 'healing', + type: this.healing.type, + event + }; + + roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); + } + + get chatTemplate() { + return 'systems/daggerheart/templates/ui/chat/healing-roll.hbs'; + } +} diff --git a/module/data/action/macroAction.mjs b/module/data/action/macroAction.mjs new file mode 100644 index 00000000..bfdc8f6b --- /dev/null +++ b/module/data/action/macroAction.mjs @@ -0,0 +1,24 @@ +import DHBaseAction from './baseAction.mjs'; + +export default class DHMacroAction extends DHBaseAction { + static defineSchema() { + const fields = foundry.data.fields; + return { + ...super.defineSchema(), + documentUUID: new fields.DocumentUUIDField({ type: 'Macro' }) + }; + } + + async trigger(event, ...args) { + // const config = await super.use(event, args); + // if (['error', 'warning'].includes(config.type)) return; + const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID, + macro = await fromUuid(fixUUID); + try { + if (!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`); + macro.execute(); + } catch (error) { + ui.notifications.error(error); + } + } +} diff --git a/module/data/action/summonAction.mjs b/module/data/action/summonAction.mjs new file mode 100644 index 00000000..13b4ee99 --- /dev/null +++ b/module/data/action/summonAction.mjs @@ -0,0 +1,20 @@ +import DHBaseAction from './baseAction.mjs'; + +export default class DHSummonAction extends DHBaseAction { + static defineSchema() { + const fields = foundry.data.fields; + return { + ...super.defineSchema(), + documentUUID: new fields.DocumentUUIDField({ type: 'Actor' }) + }; + } + + async trigger(event, ...args) { + if (!this.canSummon || !canvas.scene) return; + // const config = await super.use(event, args); + } + + get canSummon() { + return game.user.can('TOKEN_CREATE'); + } +} diff --git a/module/data/activeEffect/_module.mjs b/module/data/activeEffect/_module.mjs index f4627f0c..126aec5e 100644 --- a/module/data/activeEffect/_module.mjs +++ b/module/data/activeEffect/_module.mjs @@ -1,7 +1,7 @@ -import beastformEffect from './beastformEffect.mjs'; +import BeastformEffect from './beastformEffect.mjs'; -export { beastformEffect }; +export { BeastformEffect }; export const config = { - beastform: beastformEffect + beastform: BeastformEffect }; diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index 6e94d38e..ec2b96eb 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -22,13 +22,13 @@ export default class DhpAdversary extends BaseDataActor { return { tier: new fields.StringField({ required: true, - choices: SYSTEM.GENERAL.tiers, - initial: SYSTEM.GENERAL.tiers.tier1.id + choices: CONFIG.DH.GENERAL.tiers, + initial: CONFIG.DH.GENERAL.tiers.tier1.id }), type: new fields.StringField({ required: true, - choices: SYSTEM.ACTOR.adversaryTypes, - initial: SYSTEM.ACTOR.adversaryTypes.standard.id + choices: CONFIG.DH.ACTOR.adversaryTypes, + initial: CONFIG.DH.ACTOR.adversaryTypes.standard.id }), description: new fields.StringField(), motivesAndTactics: new fields.StringField(), @@ -47,6 +47,7 @@ export default class DhpAdversary extends BaseDataActor { attack: new ActionField({ initial: { name: 'Attack', + img: 'icons/skills/melee/blood-slash-foam-red.webp', _id: foundry.utils.randomID(), systemPath: 'attack', type: 'attack', diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 7b1ec939..d9ea6eef 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -144,7 +144,7 @@ export default class DhCharacter extends BaseDataActor { get tier() { return this.levelData.level.current === 1 ? 1 - : Object.values(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers).find( + : Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers).find( tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end ).tier; } @@ -225,7 +225,7 @@ export default class DhCharacter extends BaseDataActor { const primary = this.primaryWeapon, secondary = this.secondaryWeapon; if (itemToEquip.system.secondary) { - if (primary && primary.burden === SYSTEM.GENERAL.burden.twoHanded.value) { + if (primary && primary.burden === CONFIG.DH.GENERAL.burden.twoHanded.value) { await primary.update({ 'system.equipped': false }); } @@ -233,7 +233,7 @@ export default class DhCharacter extends BaseDataActor { await secondary.update({ 'system.equipped': false }); } } else { - if (secondary && itemToEquip.system.burden === SYSTEM.GENERAL.burden.twoHanded.value) { + if (secondary && itemToEquip.system.burden === CONFIG.DH.GENERAL.burden.twoHanded.value) { await secondary.update({ 'system.equipped': false }); } @@ -248,7 +248,7 @@ export default class DhCharacter extends BaseDataActor { const currentTier = currentLevel === 1 ? null - : Object.values(game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers).find( + : Object.values(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers).find( tier => currentLevel >= tier.levels.start && currentLevel <= tier.levels.end ).tier; for (let levelKey in this.levelData.levelups) { diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs index 4b7e0716..db75612b 100644 --- a/module/data/actor/environment.mjs +++ b/module/data/actor/environment.mjs @@ -1,6 +1,4 @@ -import { environmentTypes } from '../../config/actorConfig.mjs'; import BaseDataActor from './base.mjs'; -import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import ActionField from '../fields/actionField.mjs'; import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; @@ -19,10 +17,10 @@ export default class DhEnvironment extends BaseDataActor { return { tier: new fields.StringField({ required: true, - choices: SYSTEM.GENERAL.tiers, - initial: SYSTEM.GENERAL.tiers.tier1.id + choices: CONFIG.DH.GENERAL.tiers, + initial: CONFIG.DH.GENERAL.tiers.tier1.id }), - type: new fields.StringField({ choices: environmentTypes }), + type: new fields.StringField({ choices: CONFIG.DH.ACTOR.environmentTypes }), description: new fields.StringField(), impulses: new fields.StringField(), difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }), diff --git a/module/data/chat-message/adversaryRoll.mjs b/module/data/chat-message/adversaryRoll.mjs index 8a54af48..9210ef99 100644 --- a/module/data/chat-message/adversaryRoll.mjs +++ b/module/data/chat-message/adversaryRoll.mjs @@ -1,4 +1,4 @@ -import { DHBaseAction } from '../action/action.mjs'; +import DHBaseAction from '../../data/action/baseAction.mjs'; const fields = foundry.data.fields; @@ -37,7 +37,7 @@ export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel { } get messageTemplate() { - return 'systems/daggerheart/templates/chat/adversary-roll.hbs'; + return 'systems/daggerheart/templates/ui/chat/adversary-roll.hbs'; } prepareDerivedData() { diff --git a/module/data/chat-message/damageRoll.mjs b/module/data/chat-message/damageRoll.mjs index 5e692d97..6d54b3f7 100644 --- a/module/data/chat-message/damageRoll.mjs +++ b/module/data/chat-message/damageRoll.mjs @@ -33,7 +33,7 @@ export default class DHDamageRoll extends foundry.abstract.TypeDataModel { } get messageTemplate() { - return `systems/daggerheart/templates/chat/${this.messageType}-roll.hbs`; + return `systems/daggerheart/templates/ui/chat/${this.messageType}-roll.hbs`; } prepareDerivedData() { diff --git a/module/data/chat-message/dualityRoll.mjs b/module/data/chat-message/dualityRoll.mjs index a6ffd85b..63fa9fa3 100644 --- a/module/data/chat-message/dualityRoll.mjs +++ b/module/data/chat-message/dualityRoll.mjs @@ -2,6 +2,6 @@ import DHAdversaryRoll from './adversaryRoll.mjs'; export default class DHDualityRoll extends DHAdversaryRoll { get messageTemplate() { - return 'systems/daggerheart/templates/chat/duality-roll.hbs'; + return 'systems/daggerheart/templates/ui/chat/duality-roll.hbs'; } } diff --git a/module/data/chat-message/hitRoll.mjs b/module/data/chat-message/hitRoll.mjs deleted file mode 100644 index e69de29b..00000000 diff --git a/module/data/countdowns.mjs b/module/data/countdowns.mjs index a61a1aab..eaa8d9d9 100644 --- a/module/data/countdowns.mjs +++ b/module/data/countdowns.mjs @@ -1,5 +1,4 @@ -import { countdownTypes } from '../config/generalConfig.mjs'; -import { RefreshType, socketEvent } from '../helpers/socket.mjs'; +import { RefreshType, socketEvent } from '../systemRegistration/socket.mjs'; export default class DhCountdowns extends foundry.abstract.DataModel { static defineSchema() { @@ -102,8 +101,8 @@ class DhCountdown extends foundry.abstract.DataModel { type: new fields.SchemaField({ value: new fields.StringField({ required: true, - choices: countdownTypes, - initial: countdownTypes.spotlight.id, + choices: CONFIG.DH.GENERAL.countdownTypes, + initial: CONFIG.DH.GENERAL.countdownTypes.spotlight.id, label: 'DAGGERHEART.Countdown.FIELDS.countdowns.element.progress.type.value.label' }), label: new fields.StringField({ diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 3628bbae..da520fd1 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -1,9 +1,9 @@ -// import { actionsTypes } from '../action/_module.mjs'; +import { actionsTypes } from '../action/_module.mjs'; // Temporary Solution export default class ActionField extends foundry.data.fields.ObjectField { getModel(value) { - return game.system.api.models.actionsTypes[value.type] ?? game.system.api.models.actionsTypes.attack; + return actionsTypes[value.type] ?? actionsTypes.attack; } /* -------------------------------------------- */ diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 9c19fb80..4e5a26e6 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -24,7 +24,11 @@ export default class DHArmor extends BaseDataItem { baseScore: new fields.NumberField({ integer: true, initial: 0 }), features: new fields.ArrayField( new fields.SchemaField({ - value: new fields.StringField({ required: true, choices: SYSTEM.ITEM.armorFeatures, blank: true }), + value: new fields.StringField({ + required: true, + choices: CONFIG.DH.ITEM.armorFeatures, + blank: true + }), effectIds: new fields.ArrayField(new fields.StringField({ required: true })), actionIds: new fields.ArrayField(new fields.StringField({ required: true })) }) @@ -41,7 +45,7 @@ export default class DHArmor extends BaseDataItem { } get featureInfo() { - return this.feature ? CONFIG.daggerheart.ITEM.armorFeatures[this.feature] : null; + return this.feature ? CONFIG.DH.ITEM.armorFeatures[this.feature] : null; } async _preUpdate(changes, options, user) { diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 4d41d731..c90202fb 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -66,7 +66,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { { _id: foundry.utils.randomID(), type: actionType, - name: game.i18n.localize(SYSTEM.ACTIONS.actionTypes[actionType].name), + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), ...cls.getSourceConfig(this.parent) }, { diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index e90af930..b069f910 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -21,8 +21,8 @@ export default class DHBeastform extends BaseDataItem { ...super.defineSchema(), tier: new fields.StringField({ required: true, - choices: SYSTEM.GENERAL.tiers, - initial: SYSTEM.GENERAL.tiers.tier1.id + choices: CONFIG.DH.GENERAL.tiers, + initial: CONFIG.DH.GENERAL.tiers.tier1.id }), tokenImg: new fields.FilePathField({ initial: 'icons/svg/mystery-man.svg', diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs index f9ecca8a..3f64d74f 100644 --- a/module/data/item/domainCard.mjs +++ b/module/data/item/domainCard.mjs @@ -17,16 +17,16 @@ export default class DHDomainCard extends BaseDataItem { return { ...super.defineSchema(), domain: new fields.StringField({ - choices: SYSTEM.DOMAIN.domains, + choices: CONFIG.DH.DOMAIN.domains, required: true, - initial: SYSTEM.DOMAIN.domains.arcana.id + initial: CONFIG.DH.DOMAIN.domains.arcana.id }), level: new fields.NumberField({ initial: 1, integer: true }), recallCost: new fields.NumberField({ initial: 0, integer: true }), type: new fields.StringField({ - choices: SYSTEM.DOMAIN.cardTypes, + choices: CONFIG.DH.DOMAIN.cardTypes, required: true, - initial: SYSTEM.DOMAIN.cardTypes.ability.id + initial: CONFIG.DH.DOMAIN.cardTypes.ability.id }), foundation: new fields.BooleanField({ initial: false }), inVault: new fields.BooleanField({ initial: false }), diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs index 3c996584..8590468e 100644 --- a/module/data/item/subclass.mjs +++ b/module/data/item/subclass.mjs @@ -26,7 +26,7 @@ export default class DHSubclass extends BaseDataItem { return { ...super.defineSchema(), spellcastingTrait: new fields.StringField({ - choices: SYSTEM.ACTOR.abilities, + choices: CONFIG.DH.ACTOR.abilities, integer: false, nullable: true, initial: null diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index ee59a7f7..30bed1e0 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -1,8 +1,5 @@ import BaseDataItem from './base.mjs'; -import FormulaField from '../fields/formulaField.mjs'; import ActionField from '../fields/actionField.mjs'; -import { weaponFeatures } from '../../config/itemConfig.mjs'; -import { actionsTypes } from '../action/_module.mjs'; export default class DHWeapon extends BaseDataItem { /** @inheritDoc */ @@ -27,22 +24,26 @@ export default class DHWeapon extends BaseDataItem { //SETTINGS secondary: new fields.BooleanField({ initial: false }), - trait: new fields.StringField({ required: true, choices: SYSTEM.ACTOR.abilities, initial: 'agility' }), - range: new fields.StringField({ required: true, choices: SYSTEM.GENERAL.range, initial: 'melee' }), - burden: new fields.StringField({ required: true, choices: SYSTEM.GENERAL.burden, initial: 'oneHanded' }), + trait: new fields.StringField({ required: true, choices: CONFIG.DH.ACTOR.abilities, initial: 'agility' }), + range: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.range, initial: 'melee' }), + burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, initial: 'oneHanded' }), //DAMAGE damage: new fields.SchemaField({ - dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6' }), + dice: new fields.StringField({ choices: CONFIG.DH.GENERAL.diceTypes, initial: 'd6' }), bonus: new fields.NumberField({ nullable: true, initial: null }), type: new fields.StringField({ required: true, - choices: SYSTEM.GENERAL.damageTypes, + choices: CONFIG.DH.GENERAL.damageTypes, initial: 'physical' }) }), features: new fields.ArrayField( new fields.SchemaField({ - value: new fields.StringField({ required: true, choices: SYSTEM.ITEM.weaponFeatures, blank: true }), + value: new fields.StringField({ + required: true, + choices: CONFIG.DH.ITEM.weaponFeatures, + blank: true + }), effectIds: new fields.ArrayField(new fields.StringField({ required: true })), actionIds: new fields.ArrayField(new fields.StringField({ required: true })) }) @@ -68,7 +69,7 @@ export default class DHWeapon extends BaseDataItem { } for (var feature of added) { - const featureData = weaponFeatures[feature.value]; + const featureData = CONFIG.DH.ITEM.weaponFeatures[feature.value]; if (featureData.effects?.length > 0) { const embeddedItems = await this.parent.createEmbeddedDocuments('ActiveEffect', [ { @@ -81,7 +82,7 @@ export default class DHWeapon extends BaseDataItem { } if (featureData.actions?.length > 0) { const newActions = featureData.actions.map(action => { - const cls = actionsTypes[action.type]; + const cls = CONFIG.DH.ACTIONS.actionsTypes[action.type]; return new cls( { ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, { parent: this } diff --git a/module/data/settings/_module.mjs b/module/data/settings/_module.mjs index dc99ed36..032974a9 100644 --- a/module/data/settings/_module.mjs +++ b/module/data/settings/_module.mjs @@ -1,7 +1,5 @@ -import DhAppearance from './Appearance.mjs'; -import DhAutomation from './Automation.mjs'; -import DhHomebrew from './Homebrew.mjs'; -import DhRangeMeasurement from './RangeMeasurement.mjs'; -import DhVariantRules from './VariantRules.mjs'; - -export { DhAppearance, DhAutomation, DhHomebrew, DhRangeMeasurement, DhVariantRules }; +export { default as DhAppearance } from './Appearance.mjs'; +export { default as DhAutomation } from './Automation.mjs'; +export { default as DhHomebrew } from './Homebrew.mjs'; +export { default as DhRangeMeasurement } from './RangeMeasurement.mjs'; +export { default as DhVariantRules } from './VariantRules.mjs'; diff --git a/module/dice/_module.mjs b/module/dice/_module.mjs new file mode 100644 index 00000000..93c8c53a --- /dev/null +++ b/module/dice/_module.mjs @@ -0,0 +1,5 @@ +export { default as D20Roll } from './d20Roll.mjs'; +export { default as DamageRoll } from './damageRoll.mjs'; +export { default as DHRoll } from './dhRoll.mjs'; +export { default as DualityDie } from './dualityDie.mjs'; +export { default as DualityRoll } from './dualityRoll.mjs'; diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs new file mode 100644 index 00000000..b36c0884 --- /dev/null +++ b/module/dice/d20Roll.mjs @@ -0,0 +1,179 @@ +import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; +import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs'; +import DHRoll from './dhRoll.mjs'; + +export default class D20Roll extends DHRoll { + constructor(formula, data = {}, options = {}) { + super(formula, data, options); + this.constructFormula(); + } + + static ADV_MODE = { + NORMAL: 0, + ADVANTAGE: 1, + DISADVANTAGE: -1 + }; + + static messageType = 'adversaryRoll'; + + static CRITICAL_TRESHOLD = 20; + + static DefaultDialog = D20RollDialog; + + get d20() { + if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); + return this.terms[0]; + } + + set d20(faces) { + if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice(); + this.terms[0].faces = this.getFaces(faces); + } + + get dAdvantage() { + return this.dice[2]; + } + + get isCritical() { + if (!this.d20._evaluated) return; + return this.d20.total >= this.constructor.CRITICAL_TRESHOLD; + } + + get hasAdvantage() { + return this.options.roll.advantage === this.constructor.ADV_MODE.ADVANTAGE; + } + + get hasDisadvantage() { + return this.options.roll.advantage === this.constructor.ADV_MODE.DISADVANTAGE; + } + + static applyKeybindings(config) { + let keys = { + normal: true, + advantage: false, + disadvantage: false + }; + + if (config.event) { + keys = { + normal: config.event.shiftKey || config.event.altKey || config.event.ctrlKey, + advantage: config.event.altKey, + disadvantage: config.event.ctrlKey + }; + } + + // Should the roll configuration dialog be displayed? + config.dialog.configure ??= !Object.values(keys).some(k => k); + + // Determine advantage mode + const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage || config.advantage; + const disadvantage = + config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage || config.disadvantage; + if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE; + else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE; + else config.roll.advantage = this.ADV_MODE.NORMAL; + } + + constructFormula(config) { + // this.terms = []; + this.createBaseDice(); + this.configureModifiers(); + this.resetFormula(); + return this._formula; + } + + createBaseDice() { + if (this.terms[0] instanceof foundry.dice.terms.Die) { + this.terms = [this.terms[0]]; + return; + } + this.terms[0] = new foundry.dice.terms.Die({ faces: 20 }); + } + + configureModifiers() { + this.applyAdvantage(); + this.applyBaseBonus(); + + this.options.experiences?.forEach(m => { + if (this.options.data.experiences?.[m]) + this.options.roll.modifiers.push({ + label: this.options.data.experiences[m].name, + value: this.options.data.experiences[m].total ?? this.options.data.experiences[m].value + }); + }); + + this.options.roll.modifiers?.forEach(m => { + this.terms.push(...this.formatModifier(m.value)); + }); + + this.baseTerms = foundry.utils.deepClone(this.terms); + + if (this.options.extraFormula) { + this.terms.push( + new foundry.dice.terms.OperatorTerm({ operator: '+' }), + ...this.constructor.parse(this.options.extraFormula, this.options.data) + ); + } + } + + applyAdvantage() { + this.d20.modifiers.findSplice(m => ['kh', 'kl'].includes(m)); + if (!this.hasAdvantage && !this.hasDisadvantage) this.number = 1; + else { + this.d20.number = 2; + this.d20.modifiers.push(this.hasAdvantage ? 'kh' : 'kl'); + } + } + + applyBaseBonus() { + this.options.roll.modifiers = []; + if (!this.options.roll.bonus) return; + this.options.roll.modifiers.push({ + label: 'Bonus to Hit', + value: this.options.roll.bonus + // value: Roll.replaceFormulaData('@attackBonus', this.data) + }); + } + + static async buildEvaluate(roll, config = {}, message = {}) { + if (config.evaluate !== false) await roll.evaluate(); + const advantageState = + config.roll.advantage == this.ADV_MODE.ADVANTAGE + ? true + : config.roll.advantage == this.ADV_MODE.DISADVANTAGE + ? false + : null; + setDiceSoNiceForDualityRoll(roll, advantageState); + this.postEvaluate(roll, config); + } + + static postEvaluate(roll, config = {}) { + super.postEvaluate(roll, config); + if (config.targets?.length) { + config.targets.forEach(target => { + const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; + target.hit = this.isCritical || roll.total >= difficulty; + }); + } else if (config.roll.difficulty) + config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty; + config.roll.advantage = { + type: config.roll.advantage, + dice: roll.dAdvantage?.denomination, + value: roll.dAdvantage?.total + }; + config.roll.isCritical = roll.isCritical; + config.roll.extra = roll.dice + .filter(d => !roll.baseTerms.includes(d)) + .map(d => { + return { + dice: d.denomination, + value: d.total + }; + }); + config.roll.modifierTotal = this.calculateTotalModifiers(roll); + } + + resetFormula() { + return (this._formula = this.constructor.getFormula(this.terms)); + } +} diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs new file mode 100644 index 00000000..d9c4a61e --- /dev/null +++ b/module/dice/damageRoll.mjs @@ -0,0 +1,32 @@ +import DamageDialog from '../applications/dialogs/damageDialog.mjs'; +import DHRoll from './dhRoll.mjs'; + +export default class DamageRoll extends DHRoll { + constructor(formula, data = {}, options = {}) { + super(formula, data, options); + } + + static messageType = 'damageRoll'; + + static DefaultDialog = DamageDialog; + + static async postEvaluate(roll, config = {}) { + super.postEvaluate(roll, config); + config.roll.type = config.type; + config.roll.modifierTotal = this.calculateTotalModifiers(roll); + if (config.source?.message) { + const chatMessage = ui.chat.collection.get(config.source.message); + chatMessage.update({ 'system.damage': config }); + } + } + + constructFormula(config) { + super.constructFormula(config); + if (config.isCritical) { + const tmpRoll = new Roll(this._formula)._evaluateSync({ maximize: true }), + criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); + this.terms.push(...this.formatModifier(criticalBonus)); + } + return (this._formula = this.constructor.getFormula(this.terms)); + } +} diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs new file mode 100644 index 00000000..c461e14a --- /dev/null +++ b/module/dice/dhRoll.mjs @@ -0,0 +1,133 @@ +import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; + +export default class DHRoll extends Roll { + baseTerms = []; + constructor(formula, data, options) { + super(formula, data, options); + } + + static messageType = 'adversaryRoll'; + + static DefaultDialog = D20RollDialog; + + static async build(config = {}, message = {}) { + const roll = await this.buildConfigure(config, message); + if (!roll) return; + await this.buildEvaluate(roll, config, (message = {})); + await this.buildPost(roll, config, (message = {})); + return config; + } + + static async buildConfigure(config = {}, message = {}) { + config.hooks = [...(config.hooks ?? []), '']; + config.dialog ??= {}; + for (const hook of config.hooks) { + if (Hooks.call(`${CONFIG.DH.id}.preRoll${hook.capitalize()}`, config, message) === false) return null; + } + + this.applyKeybindings(config); + + let roll = new this(config.roll.formula, config.data, config); + if (config.dialog.configure !== false) { + // Open Roll Dialog + const DialogClass = config.dialog?.class ?? this.DefaultDialog; + const configDialog = await DialogClass.configure(roll, config, message); + if (!configDialog) return; + } + + for (const hook of config.hooks) { + if ( + Hooks.call(`${CONFIG.DH.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false + ) + return []; + } + return roll; + } + + static async buildEvaluate(roll, config = {}, message = {}) { + if (config.evaluate !== false) await roll.evaluate(); + this.postEvaluate(roll, config); + } + + static async buildPost(roll, config, message) { + for (const hook of config.hooks) { + if (Hooks.call(`${CONFIG.DH.id}.postRoll${hook.capitalize()}`, config, message) === false) return null; + } + + // Create Chat Message + if (config.source?.message) { + } else { + const messageData = {}; + config.message = await this.toMessage(roll, config); + } + } + + static postEvaluate(roll, config = {}) { + if (!config.roll) config.roll = {}; + config.roll.total = roll.total; + config.roll.formula = roll.formula; + config.roll.dice = []; + roll.dice.forEach(d => { + config.roll.dice.push({ + dice: d.denomination, + total: d.total, + formula: d.formula, + results: d.results + }); + }); + } + + static async toMessage(roll, config) { + const cls = getDocumentClass('ChatMessage'), + msg = { + type: this.messageType, + user: game.user.id, + sound: config.mute ? null : CONFIG.sounds.dice, + system: config, + rolls: [roll] + }; + return await cls.create(msg); + } + + static applyKeybindings(config) { + if (config.event) + config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey); + } + + formatModifier(modifier) { + const numTerm = modifier < 0 ? '-' : '+'; + return [ + new foundry.dice.terms.OperatorTerm({ operator: numTerm }), + new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) }) + ]; + } + + getFaces(faces) { + return Number(faces.startsWith('d') ? faces.replace('d', '') : faces); + } + + constructFormula(config) { + this.terms = Roll.parse(this.options.roll.formula, config.data); + + if (this.options.extraFormula) { + this.terms.push( + new foundry.dice.terms.OperatorTerm({ operator: '+' }), + ...this.constructor.parse(this.options.extraFormula, this.options.data) + ); + } + return (this._formula = this.constructor.getFormula(this.terms)); + } + + static calculateTotalModifiers(roll) { + let modifierTotal = 0; + for (let i = 0; i < roll.terms.length; i++) { + if ( + roll.terms[i] instanceof foundry.dice.terms.NumericTerm && + !!roll.terms[i - 1] && + roll.terms[i - 1] instanceof foundry.dice.terms.OperatorTerm + ) + modifierTotal += Number(`${roll.terms[i - 1].operator}${roll.terms[i].total}`); + } + return modifierTotal; + } +} diff --git a/module/dice/dualityDie.mjs b/module/dice/dualityDie.mjs new file mode 100644 index 00000000..f8fa0410 --- /dev/null +++ b/module/dice/dualityDie.mjs @@ -0,0 +1,5 @@ +export default class DualityDie extends foundry.dice.terms.Die { + constructor({ number = 1, faces = 12, ...args } = {}) { + super({ number, faces, ...args }); + } +} diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs new file mode 100644 index 00000000..0960ba1b --- /dev/null +++ b/module/dice/dualityRoll.mjs @@ -0,0 +1,143 @@ +import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; +import D20Roll from './d20Roll.mjs'; + +export default class DualityRoll extends D20Roll { + _advantageFaces = 6; + + constructor(formula, data = {}, options = {}) { + super(formula, data, options); + } + + static messageType = 'dualityRoll'; + + static DefaultDialog = D20RollDialog; + + get dHope() { + // if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) return; + if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); + return this.dice[0]; + // return this.#hopeDice; + } + + set dHope(faces) { + if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); + this.terms[0].faces = this.getFaces(faces); + // this.#hopeDice = `d${face}`; + } + + get dFear() { + // if ( !(this.terms[1] instanceof foundry.dice.terms.Die) ) return; + if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); + return this.dice[1]; + // return this.#fearDice; + } + + set dFear(faces) { + if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice(); + this.dice[1].faces = this.getFaces(faces); + // this.#fearDice = `d${face}`; + } + + get dAdvantage() { + return this.dice[2]; + } + + get advantageFaces() { + return this._advantageFaces; + } + + set advantageFaces(faces) { + this._advantageFaces = this.getFaces(faces); + } + + get isCritical() { + if (!this.dHope._evaluated || !this.dFear._evaluated) return; + return this.dHope.total === this.dFear.total; + } + + get withHope() { + if (!this._evaluated) return; + return this.dHope.total > this.dFear.total; + } + + get withFear() { + if (!this._evaluated) return; + return this.dHope.total < this.dFear.total; + } + + get hasBarRally() { + return null; + } + + get totalLabel() { + const label = this.withHope + ? 'DAGGERHEART.General.Hope' + : this.withFear + ? 'DAGGERHEART.General.Fear' + : 'DAGGERHEART.General.CriticalSuccess'; + + return game.i18n.localize(label); + } + + updateFormula() {} + + createBaseDice() { + if ( + this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie && + this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie + ) { + this.terms = [this.terms[0], this.terms[1], this.terms[2]]; + return; + } + this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie(); + this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' }); + this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie(); + } + + applyAdvantage() { + const dieFaces = this.advantageFaces, + bardRallyFaces = this.hasBarRally, + advDie = new foundry.dice.terms.Die({ faces: dieFaces }); + if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) + this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' })); + if (bardRallyFaces) { + const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces }); + if (this.hasAdvantage) { + this.terms.push( + new foundry.dice.terms.PoolTerm({ + terms: [advDie.formula, rallyDie.formula], + modifiers: ['kh'] + }) + ); + } else if (this.hasDisadvantage) { + this.terms.push(advDie, new foundry.dice.terms.OperatorTerm({ operator: '+' }), rallyDie); + } + } else if (this.hasAdvantage || this.hasDisadvantage) this.terms.push(advDie); + } + + applyBaseBonus() { + this.options.roll.modifiers = []; + if (!this.options.roll.trait) return; + this.options.roll.modifiers.push({ + label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`, + value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data) + }); + } + + static postEvaluate(roll, config = {}) { + super.postEvaluate(roll, config); + config.roll.hope = { + dice: roll.dHope.denomination, + value: roll.dHope.total + }; + config.roll.fear = { + dice: roll.dFear.denomination, + value: roll.dFear.total + }; + config.roll.result = { + duality: roll.withHope ? 1 : roll.withFear ? -1 : 0, + total: roll.dHope.total + roll.dFear.total, + label: roll.totalLabel + }; + } +} diff --git a/module/documents/_module.mjs b/module/documents/_module.mjs index e6099009..4dfa6264 100644 --- a/module/documents/_module.mjs +++ b/module/documents/_module.mjs @@ -2,3 +2,5 @@ export { default as DhpActor } from './actor.mjs'; export { default as DHItem } from './item.mjs'; export { default as DhpCombat } from './combat.mjs'; export { default as DhActiveEffect } from './activeEffect.mjs'; +export { default as DhChatMessage } from './chatMessage.mjs'; +export { default as DhTooltipManager } from './tooltipManager.mjs'; diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 2a2aa33e..c27baccb 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -44,7 +44,7 @@ export default class DhActiveEffect extends ActiveEffect { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 2bb4084f..a12d4e6a 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -1,6 +1,6 @@ -import DamageSelectionDialog from '../applications/damageSelectionDialog.mjs'; -import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs'; -import DamageReductionDialog from '../applications/damageReductionDialog.mjs'; +import DamageSelectionDialog from '../applications/dialogs/damageSelectionDialog.mjs'; +import { GMUpdateEvent, socketEvent } from '../systemRegistration/socket.mjs'; +import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs'; import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; @@ -24,7 +24,7 @@ export default class DhpActor extends Actor { if (newLevel > this.system.levelData.level.current) { const maxLevel = Object.values( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers).tiers + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers ).reduce((acc, tier) => Math.max(acc, tier.levels.end), 0); if (newLevel > maxLevel) { ui.notifications.warn(game.i18n.localize('DAGGERHEART.Sheets.PC.Errors.tooHighLevel')); @@ -375,7 +375,7 @@ export default class DhpActor extends Actor { bonusDamage = result.bonusDamage; rollString = result.rollString; - const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope); + const automateHope = await game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation.Hope); if (automateHope && result.hopeUsed) { await this.update({ 'system.resources.hope.value': this.system.resources.hope.value - result.hopeUsed @@ -421,7 +421,7 @@ export default class DhpActor extends Actor { sound: CONFIG.sounds.dice, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/damage-roll.hbs', + 'systems/daggerheart/templates/ui/chat/damage-roll.hbs', systemData ), rolls: [roll] @@ -488,7 +488,7 @@ export default class DhpActor extends Actor { switch (r.type) { case 'fear': ui.resources.updateFear( - game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear) + r.value + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear) + r.value ); break; case 'armorStack': @@ -513,7 +513,7 @@ export default class DhpActor extends Actor { if (game.user.isGM) { await u.target.update(u.resources); } else { - await game.socket.emit(`system.${SYSTEM.id}`, { + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.GMUpdate, data: { action: GMUpdateEvent.UpdateDocument, diff --git a/module/applications/chatMessage.mjs b/module/documents/chatMessage.mjs similarity index 100% rename from module/applications/chatMessage.mjs rename to module/documents/chatMessage.mjs diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 79e065fd..a2a8955f 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -79,7 +79,7 @@ export default class DHItem extends foundry.documents.Item { async selectActionDialog() { const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/views/actionSelect.hbs', + 'systems/daggerheart/templates/dialogs/actionSelect.hbs', { actions: this.system.actions } ), title = 'Select Action'; @@ -131,7 +131,7 @@ export default class DHItem extends foundry.documents.Item { user: game.user.id, system: systemData, content: await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/chat/ability-use.hbs', + 'systems/daggerheart/templates/ui/chat/ability-use.hbs', systemData ) }); diff --git a/module/applications/tooltipManager.mjs b/module/documents/tooltipManager.mjs similarity index 72% rename from module/applications/tooltipManager.mjs rename to module/documents/tooltipManager.mjs index d7d3117c..b780dfa9 100644 --- a/module/applications/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -1,11 +1,11 @@ -export default class DhTooltipManager extends TooltipManager { +export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager { async activate(element, options = {}) { let html = options.html; if (element.dataset.tooltip.startsWith('#item#')) { const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6)); if (item) { html = await foundry.applications.handlebars.renderTemplate( - `systems/daggerheart/templates/tooltip/${item.type}.hbs`, + `systems/daggerheart/templates/ui/tooltip/${item.type}.hbs`, item ); } diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 61884acc..54fe2a1a 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -55,7 +55,7 @@ export const renderDualityButton = async event => { type: button.dataset.actionType ?? null // Need check }, chatMessage: { - template: 'systems/daggerheart/templates/chat/duality-roll.hbs' + template: 'systems/daggerheart/templates/ui/chat/duality-roll.hbs' } }; await target.diceRoll(config); diff --git a/module/enrichers/TemplateEnricher.mjs b/module/enrichers/TemplateEnricher.mjs index 50b27068..33061151 100644 --- a/module/enrichers/TemplateEnricher.mjs +++ b/module/enrichers/TemplateEnricher.mjs @@ -45,7 +45,7 @@ export const renderMeasuredTemplate = async event => { if (!type || !range || !game.canvas.scene) return; - const distance = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement)[range]; + const distance = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement)[range]; const { width, height } = game.canvas.scene.dimensions; canvas.scene.createEmbeddedDocuments('MeasuredTemplate', [ { diff --git a/module/enrichers/_module.mjs b/module/enrichers/_module.mjs index 4ba1bdb6..1907f117 100644 --- a/module/enrichers/_module.mjs +++ b/module/enrichers/_module.mjs @@ -1,4 +1,2 @@ -import DhDualityRollEnricher from './DualityRollEnricher.mjs'; -import DhTemplateEnricher from './TemplateEnricher.mjs'; - -export { DhDualityRollEnricher, DhTemplateEnricher }; +export { default as DhDualityRollEnricher } from './DualityRollEnricher.mjs'; +export { default as DhTemplateEnricher } from './TemplateEnricher.mjs'; diff --git a/module/helpers/_module.mjs b/module/helpers/_module.mjs new file mode 100644 index 00000000..d7baca50 --- /dev/null +++ b/module/helpers/_module.mjs @@ -0,0 +1,2 @@ +export { default as HandlebarsHelper } from './handlebarsHelper.mjs'; +export * as utils from './utils.mjs'; diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 3dd4abc2..72a8a95d 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -226,7 +226,7 @@ export const getDeleteKeys = (property, innerProperty, innerPropertyDefaultValue // Fix on Foundry native formula replacement for DH const nativeReplaceFormulaData = Roll.replaceFormulaData; Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false } = {}) { - const terms = Object.keys(SYSTEM.GENERAL.multiplierTypes).map(type => { + const terms = Object.keys(CONFIG.DH.GENERAL.multiplierTypes).map(type => { return { term: type, default: 1 }; }); formula = terms.reduce((a, c) => a.replaceAll(`@${c.term}`, data[c.term] ?? c.default), formula); diff --git a/module/placeables/_module.mjs b/module/placeables/_module.mjs deleted file mode 100644 index 52e3dffe..00000000 --- a/module/placeables/_module.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import DhMeasuredTemplate from './measuredTemplate.mjs'; - -export { DhMeasuredTemplate }; diff --git a/module/systemRegistration/_module.mjs b/module/systemRegistration/_module.mjs new file mode 100644 index 00000000..38dcac4f --- /dev/null +++ b/module/systemRegistration/_module.mjs @@ -0,0 +1,3 @@ +export { preloadHandlebarsTemplates as handlebarsRegistration } from './handlebars.mjs'; +export * as settingsRegistration from './settings.mjs'; +export * as socketRegistration from './socket.mjs'; diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs new file mode 100644 index 00000000..4c2f7f1d --- /dev/null +++ b/module/systemRegistration/handlebars.mjs @@ -0,0 +1,29 @@ +export const preloadHandlebarsTemplates = async function () { + return foundry.applications.handlebars.loadTemplates([ + 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs', + 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs', + 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs', + 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs', + 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs', + 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs', + 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs', + 'systems/daggerheart/templates/components/card-preview.hbs', + 'systems/daggerheart/templates/levelup/parts/selectable-card-preview.hbs', + 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs', + 'systems/daggerheart/templates/ui/combatTracker/combatTrackerSection.hbs', + 'systems/daggerheart/templates/actionTypes/damage.hbs', + 'systems/daggerheart/templates/actionTypes/healing.hbs', + 'systems/daggerheart/templates/actionTypes/resource.hbs', + 'systems/daggerheart/templates/actionTypes/uuid.hbs', + 'systems/daggerheart/templates/actionTypes/uses.hbs', + 'systems/daggerheart/templates/actionTypes/roll.hbs', + 'systems/daggerheart/templates/actionTypes/save.hbs', + 'systems/daggerheart/templates/actionTypes/cost.hbs', + 'systems/daggerheart/templates/actionTypes/range-target.hbs', + 'systems/daggerheart/templates/actionTypes/effect.hbs', + 'systems/daggerheart/templates/actionTypes/beastform.hbs', + 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', + 'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs', + 'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs' + ]); +}; diff --git a/module/applications/settings.mjs b/module/systemRegistration/settings.mjs similarity index 72% rename from module/applications/settings.mjs rename to module/systemRegistration/settings.mjs index 8cfc5161..6da1cce0 100644 --- a/module/applications/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -13,7 +13,7 @@ import { DhHomebrewSettings, DhRangeMeasurementSettings, DhVariantRuleSettings -} from './settings/_module.mjs'; +} from '../applications/settings/_module.mjs'; export const registerDHSettings = () => { registerMenuSettings(); @@ -22,19 +22,19 @@ export const registerDHSettings = () => { }; const registerMenuSettings = () => { - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.variantRules, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules, { scope: 'world', config: false, type: DhVariantRules }); - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation, { scope: 'world', config: false, type: DhAutomation }); - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Homebrew, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew, { scope: 'world', config: false, type: DhHomebrew, @@ -45,7 +45,7 @@ const registerMenuSettings = () => { } }); - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance, { scope: 'client', config: false, type: DhAppearance, @@ -59,7 +59,7 @@ const registerMenuSettings = () => { } }); - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.RangeMeasurement, { scope: 'client', config: false, type: DhRangeMeasurement @@ -67,32 +67,32 @@ const registerMenuSettings = () => { }; const registerMenus = () => { - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Automation.Name, { + game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.menu.Automation.Name, { name: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Name'), label: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Label'), hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Automation.Hint'), - icon: SYSTEM.SETTINGS.menu.Automation.Icon, + icon: CONFIG.DH.SETTINGS.menu.Automation.Icon, type: DhAutomationSettings, restricted: true }); - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Homebrew.Name, { + game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.menu.Homebrew.Name, { name: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Name'), label: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Label'), hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Homebrew.Hint'), - icon: SYSTEM.SETTINGS.menu.Homebrew.Icon, + icon: CONFIG.DH.SETTINGS.menu.Homebrew.Icon, type: DhHomebrewSettings, restricted: true }); - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.Range.Name, { + game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.menu.Range.Name, { name: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Name'), label: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Label'), hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Range.Hint'), - icon: SYSTEM.SETTINGS.menu.Range.Icon, + icon: CONFIG.DH.SETTINGS.menu.Range.Icon, type: DhRangeMeasurementSettings, restricted: true }); - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance, { + game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance, { name: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.title'), label: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.label'), hint: game.i18n.localize('DAGGERHEART.Settings.Menu.Appearance.hint'), @@ -101,25 +101,25 @@ const registerMenus = () => { restricted: false }); - game.settings.registerMenu(SYSTEM.id, SYSTEM.SETTINGS.menu.VariantRules.Name, { + game.settings.registerMenu(CONFIG.DH.id, CONFIG.DH.SETTINGS.menu.VariantRules.Name, { name: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.title'), label: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.label'), hint: game.i18n.localize('DAGGERHEART.Settings.Menu.VariantRules.hint'), - icon: SYSTEM.SETTINGS.menu.VariantRules.Icon, + icon: CONFIG.DH.SETTINGS.menu.VariantRules.Icon, type: DhVariantRuleSettings, restricted: false }); }; const registerNonConfigSettings = () => { - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.LevelTiers, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers, { scope: 'world', config: false, type: DhLevelTiers, default: defaultLevelTiers }); - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, { name: game.i18n.localize('DAGGERHEART.Settings.Resources.Fear.Name'), hint: game.i18n.localize('DAGGERHEART.Settings.Resources.Fear.Hint'), scope: 'world', @@ -132,7 +132,7 @@ const registerNonConfigSettings = () => { } }); - game.settings.register(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, { + game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, { scope: 'world', config: false, type: DhCountdowns diff --git a/module/helpers/socket.mjs b/module/systemRegistration/socket.mjs similarity index 83% rename from module/helpers/socket.mjs rename to module/systemRegistration/socket.mjs index 6cd041aa..0be0a633 100644 --- a/module/helpers/socket.mjs +++ b/module/systemRegistration/socket.mjs @@ -40,24 +40,24 @@ export const registerSocketHooks = () => { break; case GMUpdateEvent.UpdateSetting: if (game.user.isGM) { - await game.settings.set(SYSTEM.id, data.uuid, data.update); + await game.settings.set(CONFIG.DH.id, data.uuid, data.update); } break; case GMUpdateEvent.UpdateFear: if (game.user.isGM) { await game.settings.set( - SYSTEM.id, - SYSTEM.SETTINGS.gameSettings.Resources.Fear, + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, Math.max(Math.min(data.update, 6), 0) ); Hooks.callAll(socketEvent.DhpFearUpdate); - await game.socket.emit(`system.${SYSTEM.id}`, { action: socketEvent.DhpFearUpdate }); + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.DhpFearUpdate }); } break; } if (data.refresh) { - await game.socket.emit(`system.${SYSTEM.id}`, { + await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.Refresh, data: data.refresh }); diff --git a/rollup.config.mjs b/rollup.config.mjs index 9317eb1a..b8868cb6 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -14,10 +14,7 @@ export default { config: { path: './postcss.config.js' }, - use: { - less: { javascriptEnabled: true } - }, - extensions: ['.less'], + extensions: ['.css'], extract: false }), commonjs({ diff --git a/system.json b/system.json index 99bdd747..7bd337f0 100644 --- a/system.json +++ b/system.json @@ -40,7 +40,7 @@ "name": "Po0lp" } ], - "scripts": ["build/daggerheart.js"], + "esmodules": ["build/daggerheart.js"], "styles": ["styles/daggerheart.css"], "packs": [ { diff --git a/templates/views/actionType.hbs b/templates/actionTypes/actionType.hbs similarity index 100% rename from templates/views/actionType.hbs rename to templates/actionTypes/actionType.hbs diff --git a/templates/views/actionTypes/beastform.hbs b/templates/actionTypes/beastform.hbs similarity index 100% rename from templates/views/actionTypes/beastform.hbs rename to templates/actionTypes/beastform.hbs diff --git a/templates/views/actionTypes/cost.hbs b/templates/actionTypes/cost.hbs similarity index 100% rename from templates/views/actionTypes/cost.hbs rename to templates/actionTypes/cost.hbs diff --git a/templates/views/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs similarity index 100% rename from templates/views/actionTypes/damage.hbs rename to templates/actionTypes/damage.hbs diff --git a/templates/views/actionTypes/effect.hbs b/templates/actionTypes/effect.hbs similarity index 100% rename from templates/views/actionTypes/effect.hbs rename to templates/actionTypes/effect.hbs diff --git a/templates/views/actionTypes/healing.hbs b/templates/actionTypes/healing.hbs similarity index 100% rename from templates/views/actionTypes/healing.hbs rename to templates/actionTypes/healing.hbs diff --git a/templates/views/actionTypes/range-target.hbs b/templates/actionTypes/range-target.hbs similarity index 100% rename from templates/views/actionTypes/range-target.hbs rename to templates/actionTypes/range-target.hbs diff --git a/templates/views/actionTypes/resource.hbs b/templates/actionTypes/resource.hbs similarity index 100% rename from templates/views/actionTypes/resource.hbs rename to templates/actionTypes/resource.hbs diff --git a/templates/views/actionTypes/roll.hbs b/templates/actionTypes/roll.hbs similarity index 100% rename from templates/views/actionTypes/roll.hbs rename to templates/actionTypes/roll.hbs diff --git a/templates/views/actionTypes/save.hbs b/templates/actionTypes/save.hbs similarity index 100% rename from templates/views/actionTypes/save.hbs rename to templates/actionTypes/save.hbs diff --git a/templates/views/actionTypes/target.hbs b/templates/actionTypes/target.hbs similarity index 100% rename from templates/views/actionTypes/target.hbs rename to templates/actionTypes/target.hbs diff --git a/templates/views/actionTypes/uses.hbs b/templates/actionTypes/uses.hbs similarity index 100% rename from templates/views/actionTypes/uses.hbs rename to templates/actionTypes/uses.hbs diff --git a/templates/views/actionTypes/uuid.hbs b/templates/actionTypes/uuid.hbs similarity index 100% rename from templates/views/actionTypes/uuid.hbs rename to templates/actionTypes/uuid.hbs diff --git a/templates/views/characterCreation/footer.hbs b/templates/characterCreation/footer.hbs similarity index 100% rename from templates/views/characterCreation/footer.hbs rename to templates/characterCreation/footer.hbs diff --git a/templates/views/characterCreation/tabs.hbs b/templates/characterCreation/tabs.hbs similarity index 100% rename from templates/views/characterCreation/tabs.hbs rename to templates/characterCreation/tabs.hbs diff --git a/templates/views/characterCreation/tabs/equipment.hbs b/templates/characterCreation/tabs/equipment.hbs similarity index 100% rename from templates/views/characterCreation/tabs/equipment.hbs rename to templates/characterCreation/tabs/equipment.hbs diff --git a/templates/views/characterCreation/tabs/setup.hbs b/templates/characterCreation/tabs/setup.hbs similarity index 100% rename from templates/views/characterCreation/tabs/setup.hbs rename to templates/characterCreation/tabs/setup.hbs diff --git a/templates/views/characterCreation/tabs/story.hbs b/templates/characterCreation/tabs/story.hbs similarity index 100% rename from templates/views/characterCreation/tabs/story.hbs rename to templates/characterCreation/tabs/story.hbs diff --git a/templates/views/action.hbs b/templates/config/action.hbs similarity index 65% rename from templates/views/action.hbs rename to templates/config/action.hbs index 711094a5..bc259acd 100644 --- a/templates/views/action.hbs +++ b/templates/config/action.hbs @@ -1,6 +1,5 @@