diff --git a/daggerheart.mjs b/daggerheart.mjs index 4e88c148..d8ebb713 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -16,10 +16,9 @@ import { settingsRegistration, socketRegistration } from './module/systemRegistration/_module.mjs'; -import { placeables, DhTokenLayer } from './module/canvas/_module.mjs'; +import { placeables } from './module/canvas/_module.mjs'; import './node_modules/@yaireo/tagify/dist/tagify.css'; import TemplateManager from './module/documents/templateManager.mjs'; -import TokenManager from './module/documents/tokenManager.mjs'; CONFIG.DH = SYSTEM; CONFIG.TextEditor.enrichers.push(...enricherConfig); @@ -52,8 +51,6 @@ CONFIG.ChatMessage.template = 'systems/daggerheart/templates/ui/chat/chat-messag CONFIG.Canvas.rulerClass = placeables.DhRuler; CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer; -CONFIG.Canvas.layers.tokens.layerClass = DhTokenLayer; - CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate; CONFIG.Scene.documentClass = documents.DhScene; @@ -65,7 +62,6 @@ CONFIG.Token.rulerClass = placeables.DhTokenRuler; CONFIG.Token.hudClass = applications.hud.DHTokenHUD; CONFIG.ui.combat = applications.ui.DhCombatTracker; -CONFIG.ui.nav = applications.ui.DhSceneNavigation; CONFIG.ui.chat = applications.ui.DhChatLog; CONFIG.ui.effectsDisplay = applications.ui.DhEffectsDisplay; CONFIG.ui.hotbar = applications.ui.DhHotbar; @@ -77,7 +73,6 @@ CONFIG.ui.countdowns = applications.ui.DhCountdowns; CONFIG.ux.ContextMenu = applications.ux.DHContextMenu; CONFIG.ux.TooltipManager = documents.DhTooltipManager; CONFIG.ux.TemplateManager = new TemplateManager(); -CONFIG.ux.TokenManager = new TokenManager(); Hooks.once('init', () => { game.system.api = { @@ -89,8 +84,6 @@ Hooks.once('init', () => { fields }; - game.system.registeredTriggers = new RegisteredTriggers(); - const { DocumentSheetConfig } = foundry.applications.apps; DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig); DocumentSheetConfig.registerSheet(TokenDocument, SYSTEM.id, applications.sheetConfigs.DhTokenConfig, { @@ -309,7 +302,7 @@ Hooks.on('chatMessage', (_, message) => { target, difficulty, title, - label: game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll'), + label: 'test', actionType: null, advantage }); @@ -323,7 +316,7 @@ const updateActorsRangeDependentEffects = async token => { CONFIG.DH.SETTINGS.gameSettings.variantRules ).rangeMeasurement; - for (let effect of token.actor?.allApplicableEffects() ?? []) { + for (let effect of token.actor.allApplicableEffects()) { if (!effect.system.rangeDependence?.enabled) continue; const { target, range, type } = effect.system.rangeDependence; @@ -358,9 +351,7 @@ const updateAllRangeDependentEffects = async () => { const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects; if (!effectsAutomation.rangeDependent) return; - const tokens = canvas.scene?.tokens; - if (!tokens) return; - + const tokens = canvas.scene.tokens; if (game.user.character) { // The character updates their character's token. There can be only one token. const characterToken = tokens.find(x => x.actor === game.user.character); @@ -388,50 +379,3 @@ Hooks.on('refreshToken', (_, options) => { Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html)); Hooks.on('renderDocumentDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html)); - -class RegisteredTriggers extends Map { - constructor() { - super(); - } - - async registerTriggers(trigger, actor, triggeringActorType, uuid, commands) { - const existingTrigger = this.get(trigger); - if (!existingTrigger) this.set(trigger, new Map()); - - this.get(trigger).set(uuid, { actor, triggeringActorType, commands }); - } - - async runTrigger(trigger, currentActor, ...args) { - const updates = []; - const triggerSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).triggers; - if (!triggerSettings.enabled) return updates; - - const dualityTrigger = this.get(trigger); - if (dualityTrigger) { - for (let { actor, triggeringActorType, commands } of dualityTrigger.values()) { - const triggerData = CONFIG.DH.TRIGGER.triggers[trigger]; - if (triggerData.usesActor && triggeringActorType !== 'any') { - if (triggeringActorType === 'self' && currentActor?.uuid !== actor) continue; - else if (triggeringActorType === 'other' && currentActor?.uuid === actor) continue; - } - - for (let command of commands) { - try { - const result = await command(...args); - if (result?.updates?.length) updates.push(...result.updates); - } catch (_) { - const triggerName = game.i18n.localize(triggerData.label); - ui.notifications.error( - game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', { - trigger: triggerName, - actor: currentActor?.name - }) - ); - } - } - } - } - - return updates; - } -} diff --git a/lang/en.json b/lang/en.json index 14915a81..4f1007c4 100755 --- a/lang/en.json +++ b/lang/en.json @@ -69,11 +69,7 @@ }, "summon": { "name": "Summon", - "tooltip": "Create tokens in the scene.", - "error": "You do not have permission to summon tokens or there is no active scene.", - "invalidDrop": "You can only drop Actor entities to summon.", - "chatMessageTitle": "Test2", - "chatMessageHeaderTitle": "Summoning" + "tooltip": "Create tokens in the scene." } }, "Config": { @@ -94,9 +90,7 @@ "customFormula": "Custom Formula", "formula": "Formula" }, - "displayInChat": "Display in chat", - "deleteTriggerTitle": "Delete Trigger", - "deleteTriggerContent": "Are you sure you want to delete the {trigger} trigger?" + "displayInChat": "Display in chat" }, "RollField": { "diceRolling": { @@ -126,9 +120,6 @@ }, "cost": { "stepTooltip": "+{step} per step" - }, - "summon": { - "dropSummonsHere": "Drop Summons Here" } } }, @@ -203,8 +194,6 @@ "unequip": "Unequip", "useItem": "Use Item" }, - "defaultHopeDice": "Default Hope Dice", - "defaultFearDice": "Default Fear Dice", "disadvantageSources": { "label": "Disadvantage Sources", "hint": "Add single words or short text as reminders and hints of what a character has disadvantage on." @@ -1155,8 +1144,7 @@ "any": "Any", "friendly": "Friendly", "hostile": "Hostile", - "self": "Self", - "other": "Other" + "self": "Self" }, "TemplateTypes": { "circle": "Circle", @@ -1230,29 +1218,6 @@ } } }, - "Triggers": { - "postDamageReduction": { - "label": "After Damage Reduction" - }, - "preDamageReduction": { - "label": "Before Damage Reduction" - }, - "dualityRoll": { - "label": "Duality Roll" - }, - "fearRoll": { - "label": "Fear Roll" - }, - "triggerTexts": { - "strangePatternsContentTitle": "Matched {nr} times.", - "strangePatternsContentSubTitle": "Increase hope and stress to a total of {nr}.", - "ferocityContent": "Spend 2 Hope to gain {bonus} bonus Evasion until after the next attack against you?", - "ferocityEffectDescription": "Your evasion is increased by {bonus}. This bonus lasts until after the next attack made against you." - }, - "triggerType": "Trigger Type", - "triggeringActorType": "Triggering Actor Type", - "triggerError": "{trigger} trigger failed for {actor}. It's probably configured wrong." - }, "WeaponFeature": { "barrier": { "name": "Barrier", @@ -2090,10 +2055,10 @@ "partyMembers": "Party Members", "projects": "Projects", "types": "Types", + "itemFeatures": "Item Features", "questions": "Questions", "configuration": "Configuration", - "base": "Base", - "triggers": "Triggers" + "base": "Base" }, "Tiers": { "singular": "Tier", @@ -2214,10 +2179,6 @@ "stress": "Stress", "subclasses": "Subclasses", "success": "Success", - "summon": { - "single": "Summon", - "plural": "Summons" - }, "take": "Take", "Target": { "single": "Target", @@ -2284,8 +2245,7 @@ "placeholder": "Using character dimensions", "disabledPlaceholder": "Set by character size", "height": { "label": "Height" }, - "width": { "label": "Width" }, - "scale": { "label": "Token Scale" } + "width": { "label": "Width" } }, "evolved": { "maximumTier": { "label": "Maximum Tier" }, @@ -2334,9 +2294,6 @@ "DomainCard": { "type": "Type", "recallCost": "Recall Cost", - "vaultActive": "Active In Vault", - "loadoutIgnore": "Ignores Loadout Limits", - "domainTouched": "Domain Touched", "foundationTitle": "Foundation", "specializationTitle": "Specialization", "masteryTitle": "Mastery" @@ -2475,12 +2432,6 @@ "hint": "Automatically apply effects. Targets must be selected before the action is made and Reaction Roll Automation must be different than Never. Bypass users permissions." } }, - "triggers": { - "enabled": { - "label": "Enabled", - "hint": "Advanced automation such as triggering a popup for a wizard's Strange Patterns" - } - }, "summaryMessages": { "label": "Summary Messages" } @@ -2490,9 +2441,6 @@ }, "roll": { "title": "Actions" - }, - "trigger": { - "title": "Triggers" } }, "Homebrew": { @@ -2620,9 +2568,7 @@ } }, "disabledText": "Daggerheart Measurements are disabled in System Settings - Variant Rules", - "rangeMeasurement": "Range Measurement", - "sceneEnvironments": "Scene Environments", - "dragEnvironmentHere": "Drag environments here" + "rangeMeasurement": "Range Measurement" } }, "UI": { @@ -2835,10 +2781,7 @@ "gmRequired": "This action requires an online GM", "gmOnly": "This can only be accessed by the GM", "noActorOwnership": "You do not have permissions for this character", - "documentIsMissing": "The {documentType} is missing from the world.", - "tokenActorMissing": "{name} is missing an Actor", - "tokenActorsMissing": "[{names}] missing Actors", - "domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used" + "documentIsMissing": "The {documentType} is missing from the world." }, "Sidebar": { "actorDirectory": { @@ -2883,8 +2826,7 @@ "deleteItem": "Delete Item", "immune": "Immune", "middleClick": "[Middle Click] Keep tooltip view", - "tokenSize": "The token size used on the canvas", - "previewTokenHelp": "Left-click to place, right-click to cancel" + "tokenSize": "The token size used on the canvas" } } } diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index d8306923..34ca02cd 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -10,7 +10,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio this.config = config; this.config.experiences = []; this.reactionOverride = config.actionType === 'reaction'; - this.selectedEffects = this.config.bonusEffects; if (config.source?.action) { this.item = config.data.parent.items.get(config.source.item) ?? config.data.parent; @@ -36,7 +35,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio selectExperience: this.selectExperience, toggleReaction: this.toggleReaction, toggleTagTeamRoll: this.toggleTagTeamRoll, - toggleSelectedEffect: this.toggleSelectedEffect, submitRoll: this.submitRoll }, form: { @@ -78,9 +76,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio icon })); - context.hasSelectedEffects = Boolean(this.selectedEffects && Object.keys(this.selectedEffects).length); - context.selectedEffects = this.selectedEffects; - this.config.costs ??= []; if (this.config.costs?.length) { const updatedCosts = game.system.api.fields.ActionFields.CostField.calcCosts.call( @@ -213,11 +208,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio this.render(); } - static toggleSelectedEffect(_event, button) { - this.selectedEffects[button.dataset.key].selected = !this.selectedEffects[button.dataset.key].selected; - this.render(); - } - static async submitRoll() { await this.close({ submitted: true }); } diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index b24570cc..fbc584e4 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -6,7 +6,6 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application this.roll = roll; this.config = config; - this.selectedEffects = this.config.bonusEffects; } static DEFAULT_OPTIONS = { @@ -21,7 +20,6 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application icon: 'fa-solid fa-dice' }, actions: { - toggleSelectedEffect: this.toggleSelectedEffect, submitRoll: this.submitRoll }, form: { @@ -59,9 +57,6 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application icon })); context.modifiers = this.config.modifiers; - context.hasSelectedEffects = Boolean(Object.keys(this.selectedEffects).length); - context.selectedEffects = this.selectedEffects; - return context; } @@ -74,11 +69,6 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application this.render(); } - static toggleSelectedEffect(_event, button) { - this.selectedEffects[button.dataset.key].selected = !this.selectedEffects[button.dataset.key].selected; - this.render(); - } - static async submitRoll() { await this.close({ submitted: true }); } diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 9a9a9ddb..f03524f0 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -93,29 +93,27 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV } getRefreshables() { - const actionItems = this.actor.items - .filter(x => this.actor.system.isItemAvailable(x)) - .reduce((acc, x) => { - if (x.system.actions) { - const recoverable = x.system.actions.reduce((acc, action) => { - if (refreshIsAllowed([this.shortrest ? 'shortRest' : 'longRest'], action.uses.recovery)) { - acc.push({ - title: x.name, - name: action.name, - uuid: action.uuid - }); - } - - return acc; - }, []); - - if (recoverable) { - acc.push(...recoverable); + const actionItems = this.actor.items.filter(x => this.actor.system.isItemAvailable(x)).reduce((acc, x) => { + if (x.system.actions) { + const recoverable = x.system.actions.reduce((acc, action) => { + if (refreshIsAllowed([this.shortrest ? 'shortRest' : 'longRest'], action.uses.recovery)) { + acc.push({ + title: x.name, + name: action.name, + uuid: action.uuid + }); } - } - return acc; - }, []); + return acc; + }, []); + + if (recoverable) { + acc.push(...recoverable); + } + } + + return acc; + }, []); const resourceItems = this.actor.items.reduce((acc, x) => { if ( x.system.resource && @@ -191,8 +189,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV })); }); }); - const characters = game.actors - .filter(x => x.type === 'character') + const characters = game.actors.filter(x => x.type === 'character') .filter(x => x.testUserPermission(game.user, 'LIMITED')) .filter(x => x.uuid !== this.actor.uuid); diff --git a/module/applications/hud/tokenHUD.mjs b/module/applications/hud/tokenHUD.mjs index 87c3e88e..b1136995 100644 --- a/module/applications/hud/tokenHUD.mjs +++ b/module/applications/hud/tokenHUD.mjs @@ -21,8 +21,6 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { async _prepareContext(options) { const context = await super._prepareContext(options); - if (!this.actor) return context; - context.partyOnCanvas = this.actor.type === 'party' && this.actor.system.partyMembers.some(member => member.getActiveTokens().length > 0); @@ -60,33 +58,14 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { } static async #onToggleCombat() { - const tokensWithoutActors = canvas.tokens.controlled.filter(t => !t.actor); - const warning = - tokensWithoutActors.length === 1 - ? game.i18n.format('DAGGERHEART.UI.Notifications.tokenActorMissing', { - name: tokensWithoutActors[0].name - }) - : game.i18n.format('DAGGERHEART.UI.Notifications.tokenActorsMissing', { - names: tokensWithoutActors.map(x => x.name).join(', ') - }); - const tokens = canvas.tokens.controlled - .filter(t => t.actor && !DHTokenHUD.#nonCombatTypes.includes(t.actor.type)) + .filter(t => !t.actor || !DHTokenHUD.#nonCombatTypes.includes(t.actor.type)) .map(t => t.document); - if (!this.object.controlled && this.document.actor) tokens.push(this.document); + if (!this.object.controlled) tokens.push(this.document); try { - if (this.document.inCombat) { - const tokensInCombat = tokens.filter(t => t.inCombat); - await TokenDocument.implementation.deleteCombatants([...tokensInCombat, ...tokensWithoutActors]); - } else { - if (tokensWithoutActors.length) { - ui.notifications.warn(warning); - } - - const tokensOutOfCombat = tokens.filter(t => !t.inCombat); - await TokenDocument.implementation.createCombatants(tokensOutOfCombat); - } + if (this.document.inCombat) await TokenDocument.implementation.deleteCombatants(tokens); + else await TokenDocument.implementation.createCombatants(tokens); } catch (err) { ui.notifications.warn(err.message); } diff --git a/module/applications/scene/sceneConfigSettings.mjs b/module/applications/scene/sceneConfigSettings.mjs index 8a58db5c..be8f7b71 100644 --- a/module/applications/scene/sceneConfigSettings.mjs +++ b/module/applications/scene/sceneConfigSettings.mjs @@ -1,25 +1,16 @@ -import { RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; - export default class DhSceneConfigSettings extends foundry.applications.sheets.SceneConfig { - constructor(options) { - super(options); - - Hooks.on(socketEvent.Refresh, ({ refreshType }) => { - if (refreshType === RefreshType.Scene) this.render(); - }); - } - - static DEFAULT_OPTIONS = { - ...super.DEFAULT_OPTIONS, - actions: { - ...super.DEFAULT_OPTIONS.actions, - removeSceneEnvironment: DhSceneConfigSettings.#removeSceneEnvironment - } - }; + // static DEFAULT_OPTIONS = { + // ...super.DEFAULT_OPTIONS, + // form: { + // handler: this.updateData, + // closeOnSubmit: true + // } + // }; static buildParts() { const { footer, tabs, ...parts } = super.PARTS; const tmpParts = { + // tabs, tabs: { template: 'systems/daggerheart/templates/scene/tabs.hbs' }, ...parts, dh: { template: 'systems/daggerheart/templates/scene/dh-config.hbs' }, @@ -37,47 +28,27 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S static TABS = DhSceneConfigSettings.buildTabs(); - async _preRender(context, options) { - await super._preFirstRender(context, options); - - if (!options.internalRefresh) - this.daggerheartFlag = new game.system.api.data.scenes.DHScene(this.document.flags.daggerheart); - } - _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); - switch (partId) { case 'dh': htmlElement.querySelector('#rangeMeasurementSetting')?.addEventListener('change', async event => { - this.daggerheartFlag.updateSource({ rangeMeasurement: { setting: event.target.value } }); - this.render({ internalRefresh: true }); + const flagData = foundry.utils.mergeObject(this.document.flags.daggerheart, { + rangeMeasurement: { setting: event.target.value } + }); + this.document.flags.daggerheart = flagData; + this.render(); }); - - const dragArea = htmlElement.querySelector('.scene-environments'); - if (dragArea) dragArea.ondrop = this._onDrop.bind(this); - break; } } - async _onDrop(event) { - const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); - const item = await foundry.utils.fromUuid(data.uuid); - if (item instanceof game.system.api.documents.DhpActor && item.type === 'environment') { - await this.daggerheartFlag.updateSource({ - sceneEnvironments: [...this.daggerheartFlag.sceneEnvironments, data.uuid] - }); - this.render({ internalRefresh: true }); - } - } - /** @inheritDoc */ async _preparePartContext(partId, context, options) { context = await super._preparePartContext(partId, context, options); switch (partId) { case 'dh': - context.data = this.daggerheartFlag; + context.data = new game.system.api.data.scenes.DHScene(canvas.scene.flags.daggerheart); context.variantRules = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules); break; } @@ -85,24 +56,8 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S return context; } - static async #removeSceneEnvironment(_event, button) { - await this.daggerheartFlag.updateSource({ - sceneEnvironments: this.daggerheartFlag.sceneEnvironments.filter( - (_, index) => index !== Number.parseInt(button.dataset.index) - ) - }); - this.render({ internalRefresh: true }); - } - - /** @override */ - async _processSubmitData(event, form, submitData, options) { - submitData.flags.daggerheart = this.daggerheartFlag.toObject(); - for (const key of Object.keys(this.document._source.flags.daggerheart?.sceneEnvironments ?? {})) { - if (!submitData.flags.daggerheart.sceneEnvironments[key]) { - submitData.flags.daggerheart.sceneEnvironments[`-=${key}`] = null; - } - } - - super._processSubmitData(event, form, submitData, options); - } + // static async updateData(event, _, formData) { + // const data = foundry.utils.expandObject(formData.object); + // this.close(data); + // } } diff --git a/module/applications/sheets-configs/action-base-config.mjs b/module/applications/sheets-configs/action-base-config.mjs index 7051ad2b..96790a5b 100644 --- a/module/applications/sheets-configs/action-base-config.mjs +++ b/module/applications/sheets-configs/action-base-config.mjs @@ -7,7 +7,6 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) this.action = action; this.openSection = null; - this.openTrigger = this.action.triggers.length > 0 ? 0 : null; } get title() { @@ -16,7 +15,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) static DEFAULT_OPTIONS = { tag: 'form', - classes: ['daggerheart', 'dh-style', 'action-config', 'dialog', 'max-800'], + classes: ['daggerheart', 'dh-style', 'dialog', 'max-800'], window: { icon: 'fa-solid fa-wrench', resizable: false @@ -30,18 +29,13 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) removeElement: this.removeElement, editEffect: this.editEffect, addDamage: this.addDamage, - removeDamage: this.removeDamage, - editDoc: this.editDoc, - addTrigger: this.addTrigger, - removeTrigger: this.removeTrigger, - expandTrigger: this.expandTrigger + removeDamage: this.removeDamage }, form: { handler: this.updateForm, submitOnChange: true, closeOnSubmit: false - }, - dragDrop: [{ dragSelector: null, dropSelector: '#summon-drop-zone', handlers: ['_onDrop'] }] + } }; static PARTS = { @@ -61,10 +55,6 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) effect: { id: 'effect', template: 'systems/daggerheart/templates/sheets-settings/action-settings/effect.hbs' - }, - trigger: { - id: 'trigger', - template: 'systems/daggerheart/templates/sheets-settings/action-settings/trigger.hbs' } }; @@ -92,18 +82,10 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) id: 'effect', icon: null, label: 'DAGGERHEART.GENERAL.Tabs.effects' - }, - trigger: { - active: false, - cssClass: '', - group: 'primary', - id: 'trigger', - icon: null, - label: 'DAGGERHEART.GENERAL.Tabs.triggers' } }; - static CLEAN_ARRAYS = ['damage.parts', 'cost', 'effects', 'summon']; + static CLEAN_ARRAYS = ['damage.parts', 'cost', 'effects']; _getTabs(tabs) { for (const v of Object.values(tabs)) { @@ -114,24 +96,9 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) return tabs; } - _attachPartListeners(partId, htmlElement, options) { - super._attachPartListeners(partId, htmlElement, options); - - htmlElement.querySelectorAll('.summon-count-wrapper input').forEach(element => { - element.addEventListener('change', this.updateSummonCount.bind(this)); - }); - } - async _prepareContext(_options) { const context = await super._prepareContext(_options, 'action'); context.source = this.action.toObject(true); - - context.summons = []; - for (const summon of context.source.summon ?? []) { - const actor = await foundry.utils.fromUuid(summon.actorUUID); - context.summons.push({ actor, count: summon.count }); - } - context.openSection = this.openSection; context.tabs = this._getTabs(this.constructor.TABS); context.config = CONFIG.DH; @@ -144,16 +111,6 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) context.baseSaveDifficulty = this.action.actor?.baseSaveDifficulty; context.baseAttackBonus = this.action.actor?.system.attack?.roll.bonus; context.hasRoll = this.action.hasRoll; - context.triggers = context.source.triggers.map((trigger, index) => { - const { hint, returns, usesActor } = CONFIG.DH.TRIGGER.triggers[trigger.trigger]; - return { - ...trigger, - hint, - returns, - usesActor, - revealed: this.openTrigger === index - }; - }); const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers; context.tierOptions = [ @@ -224,9 +181,8 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) } static async updateForm(event, _, formData) { - const submitData = this._prepareSubmitData(event, formData); - - const data = foundry.utils.mergeObject(this.action.toObject(), submitData); + const submitData = this._prepareSubmitData(event, formData), + data = foundry.utils.mergeObject(this.action.toObject(), submitData); this.action = await this.action.update(data); this.sheetUpdate?.(this.action); @@ -245,26 +201,12 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) static removeElement(event, button) { event.stopPropagation(); const data = this.action.toObject(), - key = event.target.closest('[data-key]').dataset.key; - - // Prefer explicit index, otherwise find by uuid - let index = button?.dataset.index; - if (index === undefined || index === null || index === '') { - const uuid = button?.dataset.uuid ?? button?.dataset.itemUuid; - index = data[key].findIndex(e => (e?.actorUUID ?? e?.uuid) === uuid); - if (index === -1) return; - } else index = Number(index); - + key = event.target.closest('[data-key]').dataset.key, + index = button.dataset.index; data[key].splice(index, 1); this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); } - static async editDoc(_event, target) { - const element = target.closest('[data-item-uuid]'); - const doc = (await foundry.utils.fromUuid(element.dataset.itemUuid)) ?? null; - if (doc) return doc.sheet.render({ force: true }); - } - static addDamage(_event) { if (!this.action.damage.parts) return; const data = this.action.toObject(), @@ -282,69 +224,6 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); } - static addTrigger() { - const data = this.action.toObject(); - data.triggers.push({ - trigger: CONFIG.DH.TRIGGER.triggers.dualityRoll.id, - triggeringActor: CONFIG.DH.TRIGGER.triggerActorTargetType.any.id - }); - this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); - } - - static async removeTrigger(_event, button) { - const trigger = CONFIG.DH.TRIGGER.triggers[this.action.triggers[button.dataset.index].trigger]; - const confirmed = await foundry.applications.api.DialogV2.confirm({ - window: { - title: game.i18n.localize('DAGGERHEART.ACTIONS.Config.deleteTriggerTitle') - }, - content: game.i18n.format('DAGGERHEART.ACTIONS.Config.deleteTriggerContent', { - trigger: game.i18n.localize(trigger.label) - }) - }); - - if (!confirmed) return; - - const data = this.action.toObject(); - data.triggers = data.triggers.filter((_, index) => index !== Number.parseInt(button.dataset.index)); - this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); - } - - static async expandTrigger(_event, button) { - const index = Number.parseInt(button.dataset.index); - const toggle = (element, codeMirror) => { - codeMirror.classList.toggle('revealed'); - const button = element.querySelector('a > i'); - button.classList.toggle('fa-angle-up'); - button.classList.toggle('fa-angle-down'); - }; - - const fieldset = button.closest('fieldset'); - const codeMirror = fieldset.querySelector('.code-mirror-wrapper'); - toggle(fieldset, codeMirror); - - if (this.openTrigger !== null && this.openTrigger !== index) { - const previouslyExpanded = fieldset - .closest(`section`) - .querySelector(`fieldset[data-index="${this.openTrigger}"]`); - const codeMirror = previouslyExpanded.querySelector('.code-mirror-wrapper'); - toggle(previouslyExpanded, codeMirror); - this.openTrigger = index; - } else if (this.openTrigger === index) { - this.openTrigger = null; - } else { - this.openTrigger = index; - } - } - - updateSummonCount(event) { - event.stopPropagation(); - const wrapper = event.target.closest('.summon-count-wrapper'); - const index = wrapper.dataset.index; - const data = this.action.toObject(); - data.summon[index].count = event.target.value; - this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); - } - /** Specific implementation in extending classes **/ static async addEffect(_event) {} static removeEffect(_event, _button) {} @@ -354,29 +233,4 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) this.tabGroups.primary = 'base'; await super.close(options); } - - async _onDrop(event) { - const data = foundry.applications.ux.TextEditor.getDragEventData(event); - const item = await foundry.utils.fromUuid(data.uuid); - if (!(item instanceof game.system.api.documents.DhpActor)) { - ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.summon.invalidDrop')); - return; - } - - const actionData = this.action.toObject(); - let countvalue = 1; - for (const entry of actionData.summon) { - if (entry.actorUUID === data.uuid) { - entry.count += 1; - countvalue = entry.count; - await this.constructor.updateForm.bind(this)(null, null, { - object: foundry.utils.flattenObject(actionData) - }); - return; - } - } - - actionData.summon.push({ actorUUID: data.uuid, count: countvalue }); - await this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(actionData) }); - } } diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index d8a3df29..98282d9f 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -31,7 +31,7 @@ export default class AdversarySheet extends DHBaseActorSheet { dragSelector: '[data-item-id][draggable="true"], [data-item-id] [draggable="true"]', dropSelector: null } - ] + ], }; static PARTS = { @@ -185,6 +185,7 @@ export default class AdversarySheet extends DHBaseActorSheet { super._onDragStart(event); } + /* -------------------------------------------- */ /* Application Clicks Actions */ /* -------------------------------------------- */ diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index dd5f35fc..594269be 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -33,7 +33,7 @@ export default class CharacterSheet extends DHBaseActorSheet { advanceResourceDie: CharacterSheet.#advanceResourceDie, cancelBeastform: CharacterSheet.#cancelBeastform, useDowntime: this.useDowntime, - viewParty: CharacterSheet.#viewParty + viewParty: CharacterSheet.#viewParty, }, window: { resizable: true, @@ -338,20 +338,15 @@ export default class CharacterSheet extends DHBaseActorSheet { } const type = 'effect'; const cls = game.system.api.models.actions.actionsTypes[type]; - const action = new cls( - { - ...cls.getSourceConfig(doc.system), - type: type, - chatDisplay: false, - cost: [ - { - key: 'stress', - value: doc.system.recallCost - } - ] - }, - { parent: doc.system } - ); + const action = new cls({ + ...cls.getSourceConfig(doc.system), + type: type, + chatDisplay: false, + cost: [{ + key: 'stress', + value: doc.system.recallCost + }] + }, { parent: doc.system }); const config = await action.use(event); if (config) { return doc.update({ 'system.inVault': false }); @@ -712,10 +707,8 @@ export default class CharacterSheet extends DHBaseActorSheet { headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: abilityLabel }), - effects: Array.from(await this.document.allApplicableEffects()), roll: { - trait: button.dataset.attribute, - type: 'trait' + trait: button.dataset.attribute }, hasRoll: true, actionType: 'action', @@ -725,7 +718,6 @@ export default class CharacterSheet extends DHBaseActorSheet { }) }; const result = await this.document.diceRoll(config); - if (!result) return; /* This could be avoided by baking config.costs into config.resourceUpdates. Didn't feel like messing with it at the time */ const costResources = result.costs @@ -830,7 +822,7 @@ export default class CharacterSheet extends DHBaseActorSheet { static async #toggleVault(_event, button) { const doc = await getDocFromElement(button); const { available } = this.document.system.loadoutSlot; - if (doc.system.inVault && !available && !doc.system.loadoutIgnore) { + if (doc.system.inVault && !available) { return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.loadoutMaxReached')); } @@ -908,32 +900,32 @@ export default class CharacterSheet extends DHBaseActorSheet { return; } - const buttons = parties.map(p => { - const button = document.createElement('button'); - button.type = 'button'; - button.classList.add('plain'); - const img = document.createElement('img'); + const buttons = parties.map((p) => { + const button = document.createElement("button"); + button.type = "button"; + button.classList.add("plain"); + const img = document.createElement("img"); img.src = p.img; button.append(img); - const name = document.createElement('span'); + const name = document.createElement("span"); name.textContent = p.name; button.append(name); - button.addEventListener('click', () => { + button.addEventListener("click", () => { p.sheet?.render({ force: true }); game.tooltip.dismissLockedTooltips(); }); return button; }); - const html = document.createElement('div'); - html.classList.add('party-list'); + const html = document.createElement("div"); + html.classList.add("party-list"); html.append(...buttons); - + game.tooltip.dismissLockedTooltips(); game.tooltip.activate(target, { html, - locked: true - }); + locked: true, + }) } /** diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 7276316f..d25a1a4e 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -211,7 +211,7 @@ export default function DHApplicationMixin(Base) { const step = event.key === 'ArrowUp' ? 1 : event.key === 'ArrowDown' ? -1 : 0; if (step !== 0) { handleUpdate(step); - deltaInput.dispatchEvent(new Event('change', { bubbles: true })); + deltaInput.dispatchEvent(new Event("change", { bubbles: true })); } }); @@ -222,7 +222,7 @@ export default function DHApplicationMixin(Base) { if (deltaInput === document.activeElement) { event.preventDefault(); handleUpdate(Math.sign(-1 * event.deltaY)); - deltaInput.dispatchEvent(new Event('change', { bubbles: true })); + deltaInput.dispatchEvent(new Event("change", { bubbles: true })); } }, { passive: false } @@ -236,7 +236,7 @@ export default function DHApplicationMixin(Base) { // Handle contenteditable for (const input of htmlElement.querySelectorAll('[contenteditable][data-property]')) { const property = input.dataset.property; - input.addEventListener('blur', () => { + input.addEventListener("blur", () => { const selection = document.getSelection(); if (input.contains(selection.anchorNode)) { selection.empty(); @@ -244,12 +244,12 @@ export default function DHApplicationMixin(Base) { this.document.update({ [property]: input.textContent }); }); - input.addEventListener('keydown', event => { - if (event.key === 'Enter') input.blur(); + input.addEventListener("keydown", event => { + if (event.key === "Enter") input.blur(); }); // Chrome sometimes add
, which aren't a problem for the value but are for the placeholder - input.addEventListener('input', () => input.querySelectorAll('br').forEach(i => i.remove())); + input.addEventListener("input", () => input.querySelectorAll("br").forEach((i) => i.remove())); } } @@ -505,7 +505,6 @@ export default function DHApplicationMixin(Base) { const doc = await getDocFromElement(target), action = doc?.system?.attack ?? doc; const config = action.prepareConfig(event); - config.effects = Array.from(await this.document.allApplicableEffects()); config.hasRoll = false; return action && action.workflow.get('damage').execute(config, null, true); } @@ -586,9 +585,7 @@ export default function DHApplicationMixin(Base) { if (!doc || !descriptionElement) continue; // localize the description (idk if it's still necessary) - const description = doc.system?.getEnrichedDescription - ? await doc.system.getEnrichedDescription() - : game.i18n.localize(doc.system?.description ?? doc.description); + const description = game.i18n.localize(doc.system?.description ?? doc.description); // Enrich the description and attach it; const isAction = doc.documentName === 'Action'; @@ -739,7 +736,7 @@ export default function DHApplicationMixin(Base) { }; if (inVault) data['system.inVault'] = true; if (disabled) data.disabled = true; - if (type === 'domainCard' && parent?.system.domains?.length) { + if (type === "domainCard" && parent?.system.domains?.length) { data.system.domain = parent.system.domains[0]; } diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index e3568b23..42ed9426 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -76,10 +76,16 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { /**@inheritdoc */ async _preparePartContext(partId, context, options) { await super._preparePartContext(partId, context, options); + const { TextEditor } = foundry.applications.ux; switch (partId) { case 'description': - context.enrichedDescription = await this.document.system.getEnrichedDescription(); + const value = foundry.utils.getProperty(this.document, 'system.description') ?? ''; + context.enrichedDescription = await TextEditor.enrichHTML(value, { + relativeTo: this.item, + rollData: this.item.getRollData(), + secrets: this.item.isOwner + }); break; case 'effects': await this._prepareEffectsContext(context, options); diff --git a/module/applications/ui/_module.mjs b/module/applications/ui/_module.mjs index 8c5c020e..d5f31906 100644 --- a/module/applications/ui/_module.mjs +++ b/module/applications/ui/_module.mjs @@ -5,5 +5,4 @@ export { default as DhCombatTracker } from './combatTracker.mjs'; export { default as DhEffectsDisplay } from './effectsDisplay.mjs'; export { default as DhFearTracker } from './fearTracker.mjs'; export { default as DhHotbar } from './hotbar.mjs'; -export { default as DhSceneNavigation } from './sceneNavigation.mjs'; export { ItemBrowser } from './itemBrowser.mjs'; diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 20dfea8d..cc42df2f 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -135,7 +135,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo async actionUseButton(event, message) { const { moveIndex, actionIndex, movePath } = event.currentTarget.dataset; const targetUuid = event.currentTarget.closest('.action-use-button-parent').querySelector('select')?.value; - const parent = await foundry.utils.fromUuid(targetUuid || message.system.actor); + const parent = await foundry.utils.fromUuid(targetUuid || message.system.actor) const actionType = message.system.moves[moveIndex].actions[actionIndex]; const cls = game.system.api.models.actions.actionsTypes[actionType.type]; diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs index 288ba8ad..babc4a65 100644 --- a/module/applications/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -127,7 +127,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C resource, active: index === combat.turn, canPing: combatant.sceneId === canvas.scene?.id && game.user.hasPermission('PING_CANVAS'), - type: combatant.actor?.system?.type, + type: combatant.actor.system.type, img: await this._getCombatantThumbnail(combatant) }; @@ -165,7 +165,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C if (this.viewed.turn !== toggleTurn) { const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; - if (combatant.actor?.type === 'character') { + if (combatant.actor.type === 'character') { await updateCountdowns( CONFIG.DH.GENERAL.countdownProgressionTypes.spotlight.id, CONFIG.DH.GENERAL.countdownProgressionTypes.characterSpotlight.id diff --git a/module/applications/ui/itemBrowser.mjs b/module/applications/ui/itemBrowser.mjs index b35573f7..794c3fb6 100644 --- a/module/applications/ui/itemBrowser.mjs +++ b/module/applications/ui/itemBrowser.mjs @@ -230,14 +230,6 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) { result.flatMap(r => r), 'name' ); - - /* If any noticeable slowdown occurs, consider replacing with enriching description on clicking to expand descriptions */ - for (const item of this.items) { - item.system.enrichedDescription = - (await item.system.getEnrichedDescription?.()) ?? - (await foundry.applications.ux.TextEditor.implementation.enrichHTML(item.description)); - } - this.fieldFilter = this._createFieldFilter(); if (this.presets?.filter) { diff --git a/module/applications/ui/sceneNavigation.mjs b/module/applications/ui/sceneNavigation.mjs deleted file mode 100644 index 0a3e08a5..00000000 --- a/module/applications/ui/sceneNavigation.mjs +++ /dev/null @@ -1,89 +0,0 @@ -import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs'; - -export default class DhSceneNavigation extends foundry.applications.ui.SceneNavigation { - /** @inheritdoc */ - static DEFAULT_OPTIONS = { - ...super.DEFAULT_OPTIONS, - classes: ['faded-ui', 'flexcol', 'scene-navigation'], - actions: { - openSceneEnvironment: DhSceneNavigation.#openSceneEnvironment - } - }; - - /** @inheritdoc */ - static PARTS = { - scenes: { - root: true, - template: 'systems/daggerheart/templates/ui/sceneNavigation/scene-navigation.hbs' - } - }; - - /** @inheritdoc */ - async _prepareContext(options) { - const context = await super._prepareContext(options); - - const extendScenes = scenes => - scenes.map(x => { - const scene = game.scenes.get(x.id); - if (!scene.flags.daggerheart) return x; - - const daggerheartInfo = new game.system.api.data.scenes.DHScene(scene.flags.daggerheart); - const environments = daggerheartInfo.sceneEnvironments.filter( - x => x && x.testUserPermission(game.user, 'LIMITED') - ); - const hasEnvironments = environments.length > 0 && x.isView; - return { - ...x, - hasEnvironments, - environmentImage: hasEnvironments ? environments[0].img : null, - environments: environments - }; - }); - context.scenes.active = extendScenes(context.scenes.active); - context.scenes.inactive = extendScenes(context.scenes.inactive); - - return context; - } - - static async #openSceneEnvironment(event, button) { - const scene = game.scenes.get(button.dataset.sceneId); - const sceneEnvironments = new game.system.api.data.scenes.DHScene( - scene.flags.daggerheart - ).sceneEnvironments.filter(x => x.testUserPermission(game.user, 'LIMITED')); - - if (sceneEnvironments.length === 1 || event.shiftKey) { - sceneEnvironments[0].sheet.render(true); - } else { - new foundry.applications.ux.ContextMenu.implementation( - button, - '.scene-environment', - sceneEnvironments.map(environment => ({ - name: environment.name, - callback: () => { - if (scene.flags.daggerheart.sceneEnvironments[0] !== environment.uuid) { - const newEnvironments = scene.flags.daggerheart.sceneEnvironments; - const newFirst = newEnvironments.splice( - newEnvironments.findIndex(x => x === environment.uuid) - )[0]; - newEnvironments.unshift(newFirst); - emitAsGM( - GMUpdateEvent.UpdateDocument, - scene.update.bind(scene), - { 'flags.daggerheart.sceneEnvironments': newEnvironments }, - scene.uuid - ); - } - - environment.sheet.render({ force: true }); - } - })), - { - jQuery: false, - fixed: true - } - ); - - CONFIG.ux.ContextMenu.triggerContextMenu(event, '.scene-environment'); - } - } -} diff --git a/module/applications/ux/contextMenu.mjs b/module/applications/ux/contextMenu.mjs index 081e6ba0..09454848 100644 --- a/module/applications/ux/contextMenu.mjs +++ b/module/applications/ux/contextMenu.mjs @@ -96,11 +96,11 @@ export default class DHContextMenu extends foundry.applications.ux.ContextMenu { * Trigger a context menu event in response to a normal click on a additional options button. * @param {PointerEvent} event */ - static triggerContextMenu(event, altSelector) { + static triggerContextMenu(event) { event.preventDefault(); event.stopPropagation(); const { clientX, clientY } = event; - const selector = altSelector ?? '[data-item-uuid]'; + const selector = '[data-item-uuid]'; const target = event.target.closest(selector) ?? event.currentTarget.closest(selector); target?.dispatchEvent( new PointerEvent('contextmenu', { diff --git a/module/canvas/_module.mjs b/module/canvas/_module.mjs index c211b549..6b8885f4 100644 --- a/module/canvas/_module.mjs +++ b/module/canvas/_module.mjs @@ -1,2 +1 @@ export * as placeables from './placeables/_module.mjs'; -export { default as DhTokenLayer } from './tokens.mjs'; diff --git a/module/canvas/placeables/token.mjs b/module/canvas/placeables/token.mjs index 2266d0da..e8b85938 100644 --- a/module/canvas/placeables/token.mjs +++ b/module/canvas/placeables/token.mjs @@ -1,12 +1,4 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { - /** @inheritdoc */ - async _draw(options) { - await super._draw(options); - - if (this.document.flags.daggerheart?.createPlacement) - this.previewHelp ||= this.addChild(this.#drawPreviewHelp()); - } - /** @inheritDoc */ async _drawEffects() { this.effects.renderable = false; @@ -42,7 +34,7 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { this.renderFlags.set({ refreshEffects: true }); } - /** + /** * Returns the distance from this token to another token object. * This value is corrected to handle alternate token sizes and other grid types * according to the diagonal rules. @@ -55,11 +47,11 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { const destinationPoint = target.center; // Compute for gridless. This version returns circular edge to edge + grid distance, - // so that tokens that are touching return 5. + // so that tokens that are touching return 5. if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) { const boundsCorrection = canvas.grid.distance / canvas.grid.size; - const originRadius = (this.bounds.width * boundsCorrection) / 2; - const targetRadius = (target.bounds.width * boundsCorrection) / 2; + const originRadius = this.bounds.width * boundsCorrection / 2; + const targetRadius = target.bounds.width * boundsCorrection / 2; const distance = canvas.grid.measurePath([originPoint, destinationPoint]).distance; return distance - originRadius - targetRadius + canvas.grid.distance; } @@ -69,11 +61,11 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { const targetEdge = this.#getEdgeBoundary(target.bounds, originPoint, destinationPoint); const adjustedOriginPoint = canvas.grid.getTopLeftPoint({ x: originEdge.x + Math.sign(originPoint.x - originEdge.x), - y: originEdge.y + Math.sign(originPoint.y - originEdge.y) + y: originEdge.y + Math.sign(originPoint.y - originEdge.y) }); const adjustDestinationPoint = canvas.grid.getTopLeftPoint({ x: targetEdge.x + Math.sign(destinationPoint.x - targetEdge.x), - y: targetEdge.y + Math.sign(destinationPoint.y - targetEdge.y) + y: targetEdge.y + Math.sign(destinationPoint.y - targetEdge.y) }); return canvas.grid.measurePath([adjustedOriginPoint, adjustDestinationPoint]).distance; } @@ -102,7 +94,7 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { /** Tests if the token is at least adjacent with another, with some leeway for diagonals */ isAdjacentWith(token) { - return this.distanceTo(token) <= canvas.grid.distance * 1.5; + return this.distanceTo(token) <= (canvas.grid.distance * 1.5); } /** @inheritDoc */ @@ -140,25 +132,4 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { bar.position.set(0, posY); return true; } - - /** - * Draw a helptext for previews as a text object - * @returns {PreciseText} The Text object for the preview helper - */ - #drawPreviewHelp() { - const { uiScale } = canvas.dimensions; - - const textStyle = CONFIG.canvasTextStyle.clone(); - textStyle.fontSize = 18; - textStyle.wordWrapWidth = this.w * 2.5; - textStyle.fontStyle = 'italic'; - - const helpText = new foundry.canvas.containers.PreciseText( - `(${game.i18n.localize('DAGGERHEART.UI.Tooltip.previewTokenHelp')})`, - textStyle - ); - helpText.anchor.set(helpText.width / 900, 1); - helpText.scale.set(uiScale, uiScale); - return helpText; - } } diff --git a/module/canvas/tokens.mjs b/module/canvas/tokens.mjs deleted file mode 100644 index 9813cd48..00000000 --- a/module/canvas/tokens.mjs +++ /dev/null @@ -1,16 +0,0 @@ -export default class DhTokenLayer extends foundry.canvas.layers.TokenLayer { - async _createPreview(createData, options) { - if (options.actor) { - const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; - if (options.actor?.system.metadata.usesSize) { - const tokenSize = tokenSizes[options.actor.system.size]; - if (tokenSize && options.actor.system.size !== CONFIG.DH.ACTOR.tokenSize.custom.id) { - createData.width = tokenSize; - createData.height = tokenSize; - } - } - } - - return super._createPreview(createData, options); - } -} diff --git a/module/config/_module.mjs b/module/config/_module.mjs index 560f3fec..ef26b958 100644 --- a/module/config/_module.mjs +++ b/module/config/_module.mjs @@ -10,4 +10,3 @@ export * as itemConfig from './itemConfig.mjs'; export * as settingsConfig from './settingsConfig.mjs'; export * as systemConfig from './system.mjs'; export * as itemBrowserConfig from './itemBrowserConfig.mjs'; -export * as triggerConfig from './triggerConfig.mjs'; diff --git a/module/config/encounterConfig.mjs b/module/config/encounterConfig.mjs index 4e0f8a6e..7565652f 100644 --- a/module/config/encounterConfig.mjs +++ b/module/config/encounterConfig.mjs @@ -9,7 +9,7 @@ export const AdversaryBPPerEncounter = (adversaries, characters) => { ); if (existingEntry) { existingEntry.nr += 1; - } else if (adversary.type) { + } else { acc.push({ adversary, nr: 1 }); } return acc; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 37894644..3f49f7aa 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -496,8 +496,6 @@ export const diceTypes = { d20: 'd20' }; -export const dieFaces = [4, 6, 8, 10, 12, 20]; - export const multiplierTypes = { prof: 'Proficiency', cast: 'Spellcast', diff --git a/module/config/hooksConfig.mjs b/module/config/hooksConfig.mjs index 9140ea0a..d316c4d4 100644 --- a/module/config/hooksConfig.mjs +++ b/module/config/hooksConfig.mjs @@ -1,3 +1,5 @@ -export const hooksConfig = { +const hooksConfig = { effectDisplayToggle: 'DHEffectDisplayToggle' }; + +export default hooksConfig; diff --git a/module/config/system.mjs b/module/config/system.mjs index 47a41e8d..ac15b1d9 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -7,8 +7,7 @@ import * as SETTINGS from './settingsConfig.mjs'; import * as EFFECTS from './effectConfig.mjs'; import * as ACTIONS from './actionConfig.mjs'; import * as FLAGS from './flagsConfig.mjs'; -import * as HOOKS from './hooksConfig.mjs'; -import * as TRIGGER from './triggerConfig.mjs'; +import HOOKS from './hooksConfig.mjs'; import * as ITEMBROWSER from './itemBrowserConfig.mjs'; export const SYSTEM_ID = 'daggerheart'; @@ -25,6 +24,5 @@ export const SYSTEM = { ACTIONS, FLAGS, HOOKS, - TRIGGER, ITEMBROWSER }; diff --git a/module/config/triggerConfig.mjs b/module/config/triggerConfig.mjs deleted file mode 100644 index 35609bd1..00000000 --- a/module/config/triggerConfig.mjs +++ /dev/null @@ -1,42 +0,0 @@ -/* hints and returns are intentionally not translated. They are programatical terms and best understood in english */ -export const triggers = { - dualityRoll: { - id: 'dualityRoll', - usesActor: true, - args: ['roll', 'actor'], - label: 'DAGGERHEART.CONFIG.Triggers.dualityRoll.label', - hint: 'this: Action, roll: DhRoll, actor: DhActor', - returns: '{ updates: [{ key, value, total }] }' - }, - fearRoll: { - id: 'fearRoll', - usesActor: true, - args: ['roll', 'actor'], - label: 'DAGGERHEART.CONFIG.Triggers.fearRoll.label', - hint: 'this: Action, roll: DhRoll, actor: DhActor', - returns: '{ updates: [{ key, value, total }] }' - }, - postDamageReduction: { - id: 'postDamageReduction', - usesActor: true, - args: ['damageUpdates', 'actor'], - label: 'DAGGERHEART.CONFIG.Triggers.postDamageReduction.label', - hint: 'damageUpdates: ResourceUpdates, actor: DhActor', - returns: '{ updates: [{ originActor: this.actor, updates: [{ key, value, total }] }] }' - } -}; - -export const triggerActorTargetType = { - any: { - id: 'any', - label: 'DAGGERHEART.CONFIG.TargetTypes.any' - }, - self: { - id: 'self', - label: 'DAGGERHEART.CONFIG.TargetTypes.self' - }, - other: { - id: 'other', - label: 'DAGGERHEART.CONFIG.TargetTypes.other' - } -}; diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index 7be7461d..ed97072f 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -36,7 +36,6 @@ export default class DHAttackAction extends DHDamageAction { async use(event, options) { const result = await super.use(event, options); - if (!result.message) return; if (result.message.system.action.roll?.type === 'attack') { const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index dac4cf68..18a09904 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -2,7 +2,6 @@ import DhpActor from '../../documents/actor.mjs'; import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs'; import { ActionMixin } from '../fields/actionField.mjs'; import { originItemField } from '../chat-message/actorRoll.mjs'; -import TriggerField from '../fields/triggerField.mjs'; const fields = foundry.data.fields; @@ -35,8 +34,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel nullable: false, required: true }), - targetUuid: new fields.StringField({ initial: undefined }), - triggers: new fields.ArrayField(new TriggerField()) + targetUuid: new fields.StringField({ initial: undefined }) }; this.extraSchemas.forEach(s => { @@ -166,6 +164,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel */ getRollData(data = {}) { const actorData = this.actor ? this.actor.getRollData(false) : {}; + actorData.result = data.roll?.total ?? 1; actorData.scale = data.costs?.length // Right now only return the first scalable cost. ? (data.costs.find(c => c.scalable)?.total ?? 1) @@ -198,8 +197,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel let config = this.prepareConfig(event); if (!config) return; - await this.addEffects(config); - if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; // Display configuration window if necessary @@ -266,16 +263,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel return config; } - /** */ - async addEffects(config) { - let effects = []; - if (this.actor) { - effects = Array.from(await this.actor.allApplicableEffects()); - } - - config.effects = effects; - } - /** * Method used to know if a configuration dialog must be shown or not when there is no roll. * @param {*} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods. @@ -356,10 +343,6 @@ export class ResourceUpdateMap extends Map { } addResources(resources) { - if (!resources?.length) return; - const invalidResources = resources.some(resource => !resource.key); - if (invalidResources) return; - for (const resource of resources) { if (!resource.key) continue; diff --git a/module/data/action/summonAction.mjs b/module/data/action/summonAction.mjs index 1505ce2d..b06f1d38 100644 --- a/module/data/action/summonAction.mjs +++ b/module/data/action/summonAction.mjs @@ -1,5 +1,19 @@ import DHBaseAction from './baseAction.mjs'; export default class DHSummonAction extends DHBaseAction { - static extraSchemas = [...super.extraSchemas, 'summon']; + 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; + } + + get canSummon() { + return game.user.can('TOKEN_CREATE'); + } } diff --git a/module/data/activeEffect/beastformEffect.mjs b/module/data/activeEffect/beastformEffect.mjs index 65e36606..5311b827 100644 --- a/module/data/activeEffect/beastformEffect.mjs +++ b/module/data/activeEffect/beastformEffect.mjs @@ -19,7 +19,6 @@ export default class BeastformEffect extends BaseEffect { base64: false }), tokenSize: new fields.SchemaField({ - scale: new fields.NumberField({ nullable: false, initial: 1 }), height: new fields.NumberField({ integer: false, nullable: true }), width: new fields.NumberField({ integer: false, nullable: true }) }) @@ -56,9 +55,7 @@ export default class BeastformEffect extends BaseEffect { const update = { ...baseUpdate, texture: { - src: this.characterTokenData.tokenImg, - scaleX: this.characterTokenData.tokenSize.scale, - scaleY: this.characterTokenData.tokenSize.scale + src: this.characterTokenData.tokenImg }, ring: { enabled: this.characterTokenData.usesDynamicToken, @@ -89,9 +86,7 @@ export default class BeastformEffect extends BaseEffect { y, 'texture': { enabled: this.characterTokenData.usesDynamicToken, - src: token.flags.daggerheart?.beastformTokenImg ?? this.characterTokenData.tokenImg, - scaleX: this.characterTokenData.tokenSize.scale, - scaleY: this.characterTokenData.tokenSize.scale + src: token.flags.daggerheart?.beastformTokenImg ?? this.characterTokenData.tokenImg }, 'ring': { subject: { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index f6ab7e3a..eba46f10 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -280,24 +280,6 @@ export default class DhCharacter extends BaseDataActor { }) }) }), - dualityRoll: new fields.SchemaField({ - defaultHopeDice: new fields.NumberField({ - nullable: false, - required: true, - integer: true, - choices: CONFIG.DH.GENERAL.dieFaces, - initial: 12, - label: 'DAGGERHEART.ACTORS.Character.defaultHopeDice' - }), - defaultFearDice: new fields.NumberField({ - nullable: false, - required: true, - integer: true, - choices: CONFIG.DH.GENERAL.dieFaces, - initial: 12, - label: 'DAGGERHEART.ACTORS.Character.defaultFearDice' - }) - }), runeWard: new fields.BooleanField({ initial: false }), burden: new fields.SchemaField({ ignore: new fields.BooleanField() diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs index 0aaf8eb0..4ed3819e 100644 --- a/module/data/actor/environment.mjs +++ b/module/data/actor/environment.mjs @@ -1,11 +1,8 @@ import BaseDataActor from './base.mjs'; import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; import DHEnvironmentSettings from '../../applications/sheets-configs/environment-settings.mjs'; -import { RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; export default class DhEnvironment extends BaseDataActor { - scenes = new Set(); - /**@override */ static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Environment']; @@ -56,31 +53,6 @@ export default class DhEnvironment extends BaseDataActor { } isItemValid(source) { - return source.type === 'feature'; - } - - _onUpdate(changes, options, userId) { - super._onUpdate(changes, options, userId); - for (const scene of this.scenes) { - scene.render(); - } - } - - _onDelete(options, userId) { - super._onDelete(options, userId); - for (const scene of this.scenes) { - if (game.user.isActiveGM) { - const newSceneEnvironments = scene.flags.daggerheart.sceneEnvironments.filter( - x => x !== this.parent.uuid - ); - scene.update({ 'flags.daggerheart.sceneEnvironments': newSceneEnvironments }).then(() => { - Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Scene }); - game.socket.emit(`system.${CONFIG.DH.id}`, { - action: socketEvent.Refresh, - data: { refreshType: RefreshType.TagTeamRoll } - }); - }); - } - } + return source.type === "feature"; } } diff --git a/module/data/combat.mjs b/module/data/combat.mjs index 3671a2cd..565afffc 100644 --- a/module/data/combat.mjs +++ b/module/data/combat.mjs @@ -15,9 +15,8 @@ export default class DhCombat extends foundry.abstract.TypeDataModel { get extendedBattleToggles() { const modifiers = CONFIG.DH.ENCOUNTER.BPModifiers; const adversaries = - this.parent.turns?.filter(x => x.actor && x.isNPC)?.map(x => ({ ...x.actor, type: x.actor.system.type })) ?? - []; - const characters = this.parent.turns?.filter(x => x.actor && !x.isNPC) ?? []; + this.parent.turns?.filter(x => x.isNPC)?.map(x => ({ ...x.actor, type: x.actor.system.type })) ?? []; + const characters = this.parent.turns?.filter(x => !x.isNPC) ?? []; const activeAutomatic = Object.keys(modifiers).reduce((acc, categoryKey) => { const category = modifiers[categoryKey]; diff --git a/module/data/fields/_module.mjs b/module/data/fields/_module.mjs index 2a8ba454..8d36b76d 100644 --- a/module/data/fields/_module.mjs +++ b/module/data/fields/_module.mjs @@ -2,6 +2,5 @@ export { ActionCollection } from './actionField.mjs'; export { default as FormulaField } from './formulaField.mjs'; export { default as ForeignDocumentUUIDField } from './foreignDocumentUUIDField.mjs'; export { default as ForeignDocumentUUIDArrayField } from './foreignDocumentUUIDArrayField.mjs'; -export { default as TriggerField } from './triggerField.mjs'; export { default as MappingField } from './mappingField.mjs'; export * as ActionFields from './action/_module.mjs'; diff --git a/module/data/fields/action/_module.mjs b/module/data/fields/action/_module.mjs index 0bdffca2..ef69394a 100644 --- a/module/data/fields/action/_module.mjs +++ b/module/data/fields/action/_module.mjs @@ -9,4 +9,3 @@ export { default as BeastformField } from './beastformField.mjs'; export { default as DamageField } from './damageField.mjs'; export { default as RollField } from './rollField.mjs'; export { default as MacroField } from './macroField.mjs'; -export { default as SummonField } from './summonField.mjs'; diff --git a/module/data/fields/action/rollField.mjs b/module/data/fields/action/rollField.mjs index 63d48990..e2196c1c 100644 --- a/module/data/fields/action/rollField.mjs +++ b/module/data/fields/action/rollField.mjs @@ -87,7 +87,7 @@ export class DHActionRollData extends foundry.abstract.DataModel { if (this.type === CONFIG.DH.GENERAL.rollTypes.attack.id) modifiers.push({ label: 'Bonus to Hit', - value: this.bonus ?? this.parent.actor.system.attack.roll.bonus ?? 0 + value: this.bonus ?? this.parent.actor.system.attack.roll.bonus }); break; default: diff --git a/module/data/fields/action/summonField.mjs b/module/data/fields/action/summonField.mjs deleted file mode 100644 index dce6414c..00000000 --- a/module/data/fields/action/summonField.mjs +++ /dev/null @@ -1,89 +0,0 @@ -import FormulaField from '../formulaField.mjs'; - -const fields = foundry.data.fields; - -export default class DHSummonField extends fields.ArrayField { - /** - * Action Workflow order - */ - static order = 120; - - constructor(options = {}, context = {}) { - const summonFields = new fields.SchemaField({ - actorUUID: new fields.DocumentUUIDField({ - type: 'Actor', - required: true - }), - count: new FormulaField({ - required: true, - default: '1' - }) - }); - super(summonFields, options, context); - } - - static async execute() { - if (!canvas.scene) { - ui.notifications.warn(game.i18n.localize('DAGGERHEART.ACTIONS.TYPES.summon.error')); - return; - } - - if (this.summon.length === 0) { - ui.notifications.warn('No actors configured for this Summon action.'); - return; - } - - const rolls = []; - const summonData = []; - for (const summon of this.summon) { - let count = summon.count; - const roll = new Roll(summon.count); - if (!roll.isDeterministic) { - await roll.evaluate(); - if (game.modules.get('dice-so-nice')?.active) rolls.push(roll); - count = roll.total; - } - - const actor = DHSummonField.getWorldActor(await foundry.utils.fromUuid(summon.actorUUID)); - /* Extending summon data in memory so it's available in actionField.toChat. Think it's harmless, but ugly. Could maybe find a better way. */ - summon.rolledCount = count; - summon.actor = actor.toObject(); - - summonData.push({ actor, count: count }); - } - - if (rolls.length) await Promise.all(rolls.map(roll => game.dice3d.showForRoll(roll, game.user, true))); - - this.actor.sheet?.minimize(); - DHSummonField.handleSummon(summonData, this.actor); - } - - /* Check for any available instances of the actor present in the world if we're missing artwork in the compendium */ - static getWorldActor(baseActor) { - const dataType = game.system.api.data.actors[`Dh${baseActor.type.capitalize()}`]; - if (baseActor.inCompendium && dataType && baseActor.img === dataType.DEFAULT_ICON) { - const worldActorCopy = game.actors.find(x => x.name === baseActor.name); - return worldActorCopy ?? baseActor; - } - - return baseActor; - } - - static async handleSummon(summonData, actionActor, summonIndex = 0) { - const summon = summonData[summonIndex]; - const result = await CONFIG.ux.TokenManager.createPreviewAsync(summon.actor, { - name: `${summon.actor.prototypeToken.name}${summon.count > 1 ? ` (${summon.count}x)` : ''}` - }); - - if (!result) return actionActor.sheet?.maximize(); - summon.actor = result.actor; - - summon.count--; - if (summon.count <= 0) { - summonIndex++; - if (summonIndex === summonData.length) return actionActor.sheet?.maximize(); - } - - DHSummonField.handleSummon(summonData, actionActor, summonIndex); - } -} diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 0d71ab86..d0d04721 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -267,8 +267,7 @@ export function ActionMixin(Base) { action: { name: this.name, img: this.baseAction ? this.parent.parent.img : this.img, - tags: this.tags ? this.tags : ['Spell', 'Arcana', 'Lv 10'], - summon: this.summon + tags: this.tags ? this.tags : ['Spell', 'Arcana', 'Lv 10'] }, itemOrigin: this.item, description: this.description || (this.item instanceof Item ? this.item.system.description : '') diff --git a/module/data/fields/triggerField.mjs b/module/data/fields/triggerField.mjs deleted file mode 100644 index 8378ea19..00000000 --- a/module/data/fields/triggerField.mjs +++ /dev/null @@ -1,24 +0,0 @@ -export default class TriggerField extends foundry.data.fields.SchemaField { - constructor(context) { - super( - { - trigger: new foundry.data.fields.StringField({ - nullable: false, - blank: false, - initial: CONFIG.DH.TRIGGER.triggers.dualityRoll.id, - choices: CONFIG.DH.TRIGGER.triggers, - label: 'DAGGERHEART.CONFIG.Triggers.triggerType' - }), - triggeringActorType: new foundry.data.fields.StringField({ - nullable: false, - blank: false, - initial: CONFIG.DH.TRIGGER.triggerActorTargetType.any.id, - choices: CONFIG.DH.TRIGGER.triggerActorTargetType, - label: 'DAGGERHEART.CONFIG.Triggers.triggeringActorType' - }), - command: new foundry.data.fields.JavaScriptField({ async: true }) - }, - context - ); - } -} diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 3d4a62fa..e35fae46 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -54,21 +54,6 @@ export default class DHArmor extends AttachableItem { ); } - /**@inheritdoc */ - async getDescriptionData() { - const baseDescription = this.description; - const allFeatures = CONFIG.DH.ITEM.allArmorFeatures(); - const features = this.armorFeatures.map(x => allFeatures[x.value]); - if (!features.length) return { prefix: null, value: baseDescription, suffix: null }; - - const prefix = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/sheets/items/armor/description.hbs', - { features } - ); - - return { prefix, value: baseDescription, suffix: null }; - } - /**@inheritdoc */ async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 415fc8d4..11be0a52 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -8,7 +8,7 @@ * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ -import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; +import { addLinkedItemsDiff, createScrollText, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; import FormulaField from '../fields/formulaField.mjs'; @@ -124,33 +124,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { return [source, page ? `pg ${page}.` : null].filter(x => x).join('. '); } - /** - * Augments the description for the item with type specific info to display. Implemented in applicable item subtypes. - * @param {object} [options] - Options that modify the styling of the rendered template. { headerStyle: undefined|'none'|'large' } - * @returns {string} - */ - async getDescriptionData(_options) { - return { prefix: null, value: this.description, suffix: null }; - } - - /** - * Gets the enriched and augmented description for the item. - * @param {object} [options] - Options that modify the styling of the rendered template. { headerStyle: undefined|'none'|'large' } - * @returns {string} - */ - async getEnrichedDescription() { - if (!this.metadata.hasDescription) return ''; - - const { prefix, value, suffix } = await this.getDescriptionData(); - const fullDescription = [prefix, value, suffix].filter(p => !!p).join('\n
\n'); - - return await foundry.applications.ux.TextEditor.implementation.enrichHTML(fullDescription, { - relativeTo: this, - rollData: this.getRollData(), - secrets: this.isOwner - }); - } - /** * Obtain a data object used to evaluate any dice rolls associated with this Item Type * @param {object} [options] - Options which modify the getRollData method. @@ -162,30 +135,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { return data; } - prepareBaseData() { - super.prepareBaseData(); - - for (const action of this.actions ?? []) { - if (!action.actor) continue; - - const actionsToRegister = []; - for (let i = 0; i < action.triggers.length; i++) { - const trigger = action.triggers[i]; - const { args } = CONFIG.DH.TRIGGER.triggers[trigger.trigger]; - const fn = new foundry.utils.AsyncFunction(...args, `{${trigger.command}\n}`); - actionsToRegister.push(fn.bind(action)); - if (i === action.triggers.length - 1) - game.system.registeredTriggers.registerTriggers( - trigger.trigger, - action.actor?.uuid, - trigger.triggeringActorType, - this.parent.uuid, - actionsToRegister - ); - } - } - } - async _preCreate(data, options, user) { // Skip if no initial action is required or actions already exist if (this.metadata.hasInitialAction && foundry.utils.isEmpty(this.actions)) { diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index dd491169..1840e26a 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -49,7 +49,6 @@ export default class DHBeastform extends BaseDataItem { choices: CONFIG.DH.ACTOR.tokenSize, initial: CONFIG.DH.ACTOR.tokenSize.custom.id }), - scale: new fields.NumberField({ nullable: false, min: 0.2, max: 3, step: 0.05, initial: 1 }), height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }), width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }) }), @@ -185,7 +184,6 @@ export default class DHBeastform extends BaseDataItem { tokenImg: this.parent.parent.prototypeToken.texture.src, tokenRingImg: this.parent.parent.prototypeToken.ring.subject.texture, tokenSize: { - scale: this.parent.parent.prototypeToken.texture.scaleX, height: this.parent.parent.prototypeToken.height, width: this.parent.parent.prototypeToken.width } @@ -211,9 +209,7 @@ export default class DHBeastform extends BaseDataItem { height, width, texture: { - src: this.tokenImg, - scaleX: this.tokenSize.scale, - scaleY: this.tokenSize.scale + src: this.tokenImg }, ring: { subject: { diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs index 327dafce..92d8828c 100644 --- a/module/data/item/domainCard.mjs +++ b/module/data/item/domainCard.mjs @@ -29,21 +29,7 @@ export default class DHDomainCard extends BaseDataItem { required: true, initial: CONFIG.DH.DOMAIN.cardTypes.ability.id }), - inVault: new fields.BooleanField({ initial: false }), - vaultActive: new fields.BooleanField({ - required: true, - nullable: false, - initial: false - }), - loadoutIgnore: new fields.BooleanField({ - required: true, - nullable: false, - initial: false - }), - domainTouched: new fields.NumberField({ - nullable: true, - initial: null - }) + inVault: new fields.BooleanField({ initial: false }) }; } @@ -52,19 +38,6 @@ export default class DHDomainCard extends BaseDataItem { return game.i18n.localize(allDomainData[this.domain].label); } - get isVaultSupressed() { - return this.inVault && !this.vaultActive; - } - - get isDomainTouchedSuppressed() { - if (!this.parent.system.domainTouched || this.parent.parent?.type !== 'character') return false; - - const matchingDomainCards = this.parent.parent.items.filter( - item => !item.system.inVault && item.system.domain === this.parent.system.domain - ).length; - return matchingDomainCards < this.parent.system.domainTouched; - } - /* -------------------------------------------- */ /**@override */ diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index f333e5f3..295cc0c5 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -110,21 +110,6 @@ export default class DHWeapon extends AttachableItem { ); } - /**@inheritdoc */ - async getDescriptionData() { - const baseDescription = this.description; - const allFeatures = CONFIG.DH.ITEM.allWeaponFeatures(); - const features = this.weaponFeatures.map(x => allFeatures[x.value]); - if (!features.length) return { prefix: null, value: baseDescription, suffix: null }; - - const prefix = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/sheets/items/weapon/description.hbs', - { features } - ); - - return { prefix, value: baseDescription, suffix: null }; - } - prepareDerivedData() { this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait; } diff --git a/module/data/scene/scene.mjs b/module/data/scene/scene.mjs index f2a24308..7cf74ade 100644 --- a/module/data/scene/scene.mjs +++ b/module/data/scene/scene.mjs @@ -1,8 +1,3 @@ -import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; - -/* Foundry does not add any system data for subtyped Scenes. The data model is therefore used by instantiating a new instance of it for sceneConfigSettings.mjs. - Needed dataprep and lifetime hooks are handled in documents/scene. -*/ export default class DHScene extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; @@ -18,8 +13,7 @@ export default class DHScene extends foundry.abstract.DataModel { veryClose: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.veryClose.name' }), close: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.close.name' }), far: new fields.NumberField({ integer: true, label: 'DAGGERHEART.CONFIG.Range.far.name' }) - }), - sceneEnvironments: new ForeignDocumentUUIDArrayField({ type: 'Actor', prune: true }) + }) }; } } diff --git a/module/data/settings/Automation.mjs b/module/data/settings/Automation.mjs index 3376b153..2aec990f 100644 --- a/module/data/settings/Automation.mjs +++ b/module/data/settings/Automation.mjs @@ -173,13 +173,6 @@ export default class DhAutomation extends foundry.abstract.DataModel { label: 'DAGGERHEART.GENERAL.player.plurial' }) }) - }), - triggers: new fields.SchemaField({ - enabled: new fields.BooleanField({ - nullable: false, - initial: true, - label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.triggers.enabled.label' - }) }) }; } diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 3ddd8027..0256f281 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -35,9 +35,7 @@ export default class D20Roll extends DHRoll { get isCritical() { if (!this.d20._evaluated) return; - - const criticalThreshold = this.options.actionType === 'reaction' ? 20 : this.data.system.criticalThreshold; - return this.d20.total >= criticalThreshold; + return this.d20.total >= this.data.system.criticalThreshold; } get hasAdvantage() { @@ -129,55 +127,15 @@ export default class D20Roll extends DHRoll { const modifiers = foundry.utils.deepClone(this.options.roll.baseModifiers) ?? []; modifiers.push( - ...this.getBonus( - `system.bonuses.roll.${this.options.actionType}`, - `${this.options.actionType?.capitalize()} Bonus` - ) + ...this.getBonus(`roll.${this.options.actionType}`, `${this.options.actionType?.capitalize()} Bonus`) + ); + modifiers.push( + ...this.getBonus(`roll.${this.options.roll.type}`, `${this.options.roll.type?.capitalize()} Bonus`) ); - if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.attack.id) { - modifiers.push( - ...this.getBonus( - `system.bonuses.roll.${this.options.roll.type}`, - `${this.options.roll.type?.capitalize()} Bonus` - ) - ); - } - - if ( - this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.attack.id || - (this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id && this.options.hasDamage) - ) { - modifiers.push( - ...this.getBonus(`system.bonuses.roll.attack`, `${this.options.roll.type?.capitalize()} Bonus`) - ); - } - return modifiers; } - getActionChangeKeys() { - const changeKeys = new Set([`system.bonuses.roll.${this.options.actionType}`]); - - if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.attack.id) { - changeKeys.add(`system.bonuses.roll.${this.options.roll.type}`); - } - - if ( - this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.attack.id || - (this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id && this.options.hasDamage) - ) { - changeKeys.add(`system.bonuses.roll.attack`); - } - - if (this.options.roll.trait && this.data.traits?.[this.options.roll.trait]) { - if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.spellcast.id) - changeKeys.add('system.bonuses.roll.trait'); - } - - return changeKeys; - } - static postEvaluate(roll, config = {}) { const data = super.postEvaluate(roll, config); data.type = config.actionType; diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index cd26eb21..c10ee6ff 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -93,6 +93,7 @@ export default class DamageRoll extends DHRoll { type = this.options.messageType ?? (this.options.hasHealing ? 'healing' : 'damage'), options = part ?? this.options; + modifiers.push(...this.getBonus(`${type}`, `${type.capitalize()} Bonus`)); if (!this.options.hasHealing) { options.damageTypes?.forEach(t => { modifiers.push(...this.getBonus(`${type}.${t}`, `${t.capitalize()} ${type.capitalize()} Bonus`)); @@ -107,31 +108,6 @@ export default class DamageRoll extends DHRoll { return modifiers; } - getActionChangeKeys() { - const type = this.options.messageType ?? (this.options.hasHealing ? 'healing' : 'damage'); - const changeKeys = []; - - for (const roll of this.options.roll) { - for (const damageType of roll.damageTypes?.values?.() ?? []) { - changeKeys.push(`system.bonuses.${type}.${damageType}`); - } - } - - const item = this.data.parent?.items?.get(this.options.source.item); - if (item) { - switch (item.type) { - case 'weapon': - if (!this.options.hasHealing) - ['primaryWeapon', 'secondaryWeapon'].forEach(w => - changeKeys.push(`system.bonuses.damage.${w}`) - ); - break; - } - } - - return changeKeys; - } - constructFormula(config) { this.options.roll.forEach((part, index) => { part.roll = new Roll(Roll.replaceFormulaData(part.formula, config.data)); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index a5ac5091..ea24f238 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -4,7 +4,6 @@ export default class DHRoll extends Roll { baseTerms = []; constructor(formula, data = {}, options = {}) { super(formula, data, options); - options.bonusEffects = this.bonusEffectBuilder(); if (!this.data || !Object.keys(this.data).length) this.data = options.data; } @@ -165,17 +164,11 @@ export default class DHRoll extends Roll { new foundry.dice.terms.OperatorTerm({ operator: '+' }), ...this.constructor.parse(modifier.join(' + '), this.options.data) ]; - } else if (Number.isNumeric(modifier)) { - const numTerm = modifier < 0 ? '-' : '+'; - return [ - new foundry.dice.terms.OperatorTerm({ operator: numTerm }), - new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) }) - ]; } else { const numTerm = modifier < 0 ? '-' : '+'; return [ new foundry.dice.terms.OperatorTerm({ operator: numTerm }), - ...this.constructor.parse(modifier, this.options.data) + new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) }) ]; } } @@ -192,20 +185,18 @@ export default class DHRoll extends Roll { } getBonus(path, label) { - const modifiers = []; - for (const effect of Object.values(this.options.bonusEffects)) { - if (!effect.selected) continue; - for (const change of effect.changes) { - if (!change.key.includes(path)) continue; - const changeValue = game.system.api.documents.DhActiveEffect.getChangeValue( - this.data, - change, - effect.origEffect - ); - modifiers.push({ label: label, value: changeValue }); - } - } - + const bonus = foundry.utils.getProperty(this.data.bonuses, path), + modifiers = []; + if (bonus?.bonus) + modifiers.push({ + label: label, + value: bonus?.bonus + }); + if (bonus?.dice?.length) + modifiers.push({ + label: label, + value: bonus?.dice + }); return modifiers; } @@ -244,28 +235,4 @@ export default class DHRoll extends Roll { static temporaryModifierBuilder(config) { return {}; } - - bonusEffectBuilder() { - const changeKeys = this.getActionChangeKeys(); - return ( - this.options.effects?.reduce((acc, effect) => { - if (effect.changes.some(x => changeKeys.some(key => x.key.includes(key)))) { - acc[effect.id] = { - id: effect.id, - name: effect.name, - description: effect.description, - changes: effect.changes, - origEffect: effect, - selected: !effect.disabled - }; - } - - return acc; - }, {}) ?? [] - ); - } - - getActionChangeKeys() { - return []; - } } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index aaca7400..d2e20213 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -130,14 +130,9 @@ export default class DualityRoll extends D20Roll { this.terms = [this.terms[0], this.terms[1], this.terms[2]]; return; } - - this.terms[0] = new foundry.dice.terms.Die({ - faces: this.data.rules.dualityRoll?.defaultHopeDice ?? 12 - }); + this.terms[0] = new foundry.dice.terms.Die({ faces: 12 }); this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' }); - this.terms[2] = new foundry.dice.terms.Die({ - faces: this.data.rules.dualityRoll?.defaultFearDice ?? 12 - }); + this.terms[2] = new foundry.dice.terms.Die({ faces: 12 }); } applyAdvantage() { @@ -178,34 +173,6 @@ export default class DualityRoll extends D20Roll { return modifiers; } - getActionChangeKeys() { - const changeKeys = new Set([`system.bonuses.roll.${this.options.actionType}`]); - - if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.attack.id) { - changeKeys.add(`system.bonuses.roll.${this.options.roll.type}`); - } - - if ( - this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.attack.id || - (this.options.roll.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id && this.options.hasDamage) - ) { - changeKeys.add(`system.bonuses.roll.attack`); - } - - if (this.options.roll.trait && this.data.traits?.[this.options.roll.trait]) { - if (this.options.roll.type !== CONFIG.DH.GENERAL.rollTypes.spellcast.id) - changeKeys.add('system.bonuses.roll.trait'); - } - - const weapons = ['primaryWeapon', 'secondaryWeapon']; - weapons.forEach(w => { - if (this.options.source.item && this.options.source.item === this.data[w]?.id) - changeKeys.add(`system.bonuses.roll.${w}`); - }); - - return changeKeys; - } - static async buildEvaluate(roll, config = {}, message = {}) { await super.buildEvaluate(roll, config, message); @@ -257,32 +224,6 @@ export default class DualityRoll extends D20Roll { await super.buildPost(roll, config, message); await DualityRoll.dualityUpdate(config); - await DualityRoll.handleTriggers(roll, config); - } - - static async handleTriggers(roll, config) { - if (!config.source?.actor) return; - - const updates = []; - const dualityUpdates = await game.system.registeredTriggers.runTrigger( - CONFIG.DH.TRIGGER.triggers.dualityRoll.id, - roll.data?.parent, - roll, - roll.data?.parent - ); - if (dualityUpdates?.length) updates.push(...dualityUpdates); - - if (config.roll.result.duality === -1) { - const fearUpdates = await game.system.registeredTriggers.runTrigger( - CONFIG.DH.TRIGGER.triggers.fearRoll.id, - roll.data?.parent, - roll, - roll.data?.parent - ); - if (fearUpdates?.length) updates.push(...fearUpdates); - } - - config.resourceUpdates.addResources(updates); } static async addDualityResourceUpdates(config) { diff --git a/module/documents/_module.mjs b/module/documents/_module.mjs index 8073cfe1..22718bea 100644 --- a/module/documents/_module.mjs +++ b/module/documents/_module.mjs @@ -8,4 +8,3 @@ export { default as DhScene } from './scene.mjs'; export { default as DhToken } from './token.mjs'; export { default as DhTooltipManager } from './tooltipManager.mjs'; export { default as DhTemplateManager } from './templateManager.mjs'; -export { default as DhTokenManager } from './tokenManager.mjs'; diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 5e9b0c3b..2297ea27 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -20,10 +20,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { } if (this.parent?.type === 'domainCard') { - const isVaultSupressed = this.parent.system.isVaultSupressed; - const domainTouchedSupressed = this.parent.system.isDomainTouchedSuppressed; - - return isVaultSupressed || domainTouchedSupressed; + return this.parent.system.inVault; } return super.isSuppressed; @@ -109,29 +106,23 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { /**@inheritdoc*/ static applyField(model, change, field) { - change.value = DhActiveEffect.getChangeValue(model, change, change.effect); - super.applyField(model, change, field); - } - - /** */ - static getChangeValue(model, change, effect) { - let value = change.value; - const isOriginTarget = value.toLowerCase().includes('origin.@'); + const isOriginTarget = change.value.toLowerCase().includes('origin.@'); let parseModel = model; - if (isOriginTarget && effect.origin) { - value = change.value.replaceAll(/origin\.@/gi, '@'); + if (isOriginTarget && change.effect.origin) { + change.value = change.value.replaceAll(/origin\.@/gi, '@'); try { - const originEffect = foundry.utils.fromUuidSync(effect.origin); + const effect = foundry.utils.fromUuidSync(change.effect.origin); const doc = - originEffect.parent?.parent instanceof game.system.api.documents.DhpActor - ? originEffect.parent - : originEffect.parent.parent; + effect.parent?.parent instanceof game.system.api.documents.DhpActor + ? effect.parent + : effect.parent.parent; if (doc) parseModel = doc; } catch (_) {} } - const evalValue = this.effectSafeEval(itemAbleRollParse(value, parseModel, effect.parent)); - return evalValue ?? value; + const evalValue = this.effectSafeEval(itemAbleRollParse(change.value, parseModel, change.effect.parent)); + change.value = evalValue ?? change.value; + super.applyField(model, change, field); } /** diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 1a4153ad..f6666a5e 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -646,19 +646,6 @@ export default class DhpActor extends Actor { } } - const results = await game.system.registeredTriggers.runTrigger( - CONFIG.DH.TRIGGER.triggers.postDamageReduction.id, - this, - updates, - this - ); - - if (results?.length) { - const resourceMap = new ResourceUpdateMap(results[0].originActor); - for (var result of results) resourceMap.addResources(result.updates); - resourceMap.updateResources(); - } - updates.forEach( u => (u.value = diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index d85bcb45..7e313891 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -157,10 +157,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { event.stopPropagation(); const config = foundry.utils.deepClone(this.system); config.event = event; - if (this.system.action) { - await this.system.action.addEffects(config); - await this.system.action.workflow.get('damage')?.execute(config, this._id, true); - } + await this.system.action?.workflow.get('damage')?.execute(config, this._id, true); Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.TagTeamRoll }); await game.socket.emit(`system.${CONFIG.DH.id}`, { diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 7607658c..2c6d68b5 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -31,7 +31,7 @@ export default class DHItem extends foundry.documents.Item { static async createDocuments(sources, operation) { // Ensure that items being created are valid to the actor its being added to const actor = operation.parent; - sources = actor?.system?.isItemValid ? sources.filter(s => actor.system.isItemValid(s)) : sources; + sources = actor?.system?.isItemValid ? sources.filter((s) => actor.system.isItemValid(s)) : sources; return super.createDocuments(sources, operation); } @@ -146,16 +146,6 @@ export default class DHItem extends foundry.documents.Item { /* -------------------------------------------- */ async use(event) { - /* DomainCard check. Can be expanded or made neater */ - if (this.system.isDomainTouchedSuppressed) { - return ui.notifications.warn( - game.i18n.format('DAGGERHEART.UI.Notifications.domainTouchRequirement', { - nr: this.domainTouched, - domain: game.i18n.localize(CONFIG.DH.DOMAIN.allDomains()[this.domain].label) - }) - ); - } - const actions = new Set(this.system.actionsList); if (actions?.size) { let action = actions.first(); diff --git a/module/documents/scene.mjs b/module/documents/scene.mjs index 7f880b1d..c6cdd2c2 100644 --- a/module/documents/scene.mjs +++ b/module/documents/scene.mjs @@ -37,30 +37,4 @@ export default class DhScene extends Scene { this.#sizeSyncBatch.clear(); this.updateEmbeddedDocuments('Token', entries, { animation: { movementSpeed: 1.5 } }); }, 0); - - prepareBaseData() { - super.prepareBaseData(); - - if (this instanceof game.system.api.documents.DhScene) { - const system = new game.system.api.data.scenes.DHScene(this.flags.daggerheart); - - // Register this scene to all environements - for (const environment of system.sceneEnvironments) { - environment.system.scenes?.add(this); - } - } - } - - _onDelete(options, userId) { - super._onDelete(options, userId); - - if (this instanceof game.system.api.documents.DhScene) { - const system = new game.system.api.data.scenes.DHScene(this.flags.daggerheart); - - // Clear this scene from all environments that aren't deleted - for (const environment of system.sceneEnvironments) { - environment?.system?.scenes?.delete(this); - } - } - } } diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 4ac29264..c3babaa1 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -83,7 +83,7 @@ export default class DHToken extends CONFIG.Token.documentClass { if (combat?.system?.battleToggles?.length) { await combat.toggleModifierEffects( true, - tokens.filter(x => x.actor).map(x => x.actor) + tokens.map(x => x.actor) ); } super.createCombatants(tokens, combat ?? {}); @@ -95,7 +95,7 @@ export default class DHToken extends CONFIG.Token.documentClass { if (combat?.system?.battleToggles?.length) { await combat.toggleModifierEffects( false, - tokens.filter(x => x.actor).map(x => x.actor) + tokens.map(x => x.actor) ); } super.deleteCombatants(tokens, combat ?? {}); diff --git a/module/documents/tokenManager.mjs b/module/documents/tokenManager.mjs deleted file mode 100644 index be5467da..00000000 --- a/module/documents/tokenManager.mjs +++ /dev/null @@ -1,104 +0,0 @@ -/** - * A singleton class that handles preview tokens. - */ - -export default class DhTokenManager { - #activePreview; - #actor; - #resolve; - - /** - * Create a template preview, deactivating any existing ones. - * @param {object} data - */ - async createPreview(actor, tokenData) { - this.#actor = actor; - const token = await canvas.tokens._createPreview( - { - ...actor.prototypeToken, - displayName: 50, - ...tokenData - }, - { renderSheet: false, actor } - ); - - this.#activePreview = { - document: token.document, - object: token, - origin: { x: token.document.x, y: token.document.y } - }; - - this.#activePreview.events = { - contextmenu: this.#cancelTemplate.bind(this), - mousedown: this.#confirmTemplate.bind(this), - mousemove: this.#onDragMouseMove.bind(this) - }; - - canvas.stage.on('mousemove', this.#activePreview.events.mousemove); - canvas.stage.on('mousedown', this.#activePreview.events.mousedown); - canvas.app.view.addEventListener('contextmenu', this.#activePreview.events.contextmenu); - } - - /* Currently intended for using as a preview of where to create a token. (note the flag) */ - async createPreviewAsync(actor, tokenData = {}) { - return new Promise(resolve => { - this.#resolve = resolve; - this.createPreview(actor, { ...tokenData, flags: { daggerheart: { createPlacement: true } } }); - }); - } - - /** - * Handles the movement of the token preview on mousedrag. - * @param {mousemove Event} event - */ - #onDragMouseMove(event) { - event.stopPropagation(); - const { moveTime, object } = this.#activePreview; - const update = {}; - - const now = Date.now(); - if (now - (moveTime || 0) <= 16) return; - this.#activePreview.moveTime = now; - - let cursor = event.getLocalPosition(canvas.templates); - - Object.assign(update, canvas.grid.getTopLeftPoint(cursor)); - - object.document.updateSource(update); - object.renderFlags.set({ refresh: true }); - } - - /** - * Cancels the preview token on right-click. - * @param {contextmenu Event} event - */ - #cancelTemplate(_event, resolved) { - const { mousemove, mousedown, contextmenu } = this.#activePreview.events; - this.#activePreview.object.destroy(); - - canvas.stage.off('mousemove', mousemove); - canvas.stage.off('mousedown', mousedown); - canvas.app.view.removeEventListener('contextmenu', contextmenu); - if (this.#resolve && !resolved) this.#resolve(false); - } - - /** - * Creates a real Actor and token at the preview location and cancels the preview. - * @param {click Event} event - */ - async #confirmTemplate(event) { - event.stopPropagation(); - this.#cancelTemplate(event, true); - - const actor = this.#actor.inCompendium - ? await game.system.api.documents.DhpActor.create(this.#actor.toObject()) - : this.#actor; - const tokenData = await actor.getTokenDocument(); - const result = await canvas.scene.createEmbeddedDocuments('Token', [ - { ...tokenData, x: this.#activePreview.document.x, y: this.#activePreview.document.y } - ]); - - this.#activePreview = undefined; - if (this.#resolve && result.length) this.#resolve(result[0]); - } -} diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index c4b52bb5..b0a107b9 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -67,7 +67,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti if (item) { const isAction = item instanceof game.system.api.models.actions.actionsTypes.base; const isEffect = item instanceof ActiveEffect; - await this.enrichText(item); + await this.enrichText(item, isAction || isEffect); const type = isAction ? 'action' : isEffect ? 'effect' : item.type; html = await foundry.applications.handlebars.renderTemplate( @@ -202,20 +202,10 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti } } - async enrichText(item) { + async enrichText(item, flatStructure) { const { TextEditor } = foundry.applications.ux; - - if (item.system?.metadata?.hasDescription) { - const enrichedValue = - (await item.system?.getEnrichedDescription?.()) ?? - (await TextEditor.enrichHTML(item.system.description)); - foundry.utils.setProperty(item, 'system.enrichedDescription', enrichedValue); - } else if (item.description) { - const enrichedValue = await TextEditor.enrichHTML(item.description); - foundry.utils.setProperty(item, 'enrichedDescription', enrichedValue); - } - const enrichPaths = [ + { path: flatStructure ? '' : 'system', name: 'description' }, { path: 'system', name: 'features' }, { path: 'system', name: 'actions' }, { path: 'system', name: 'customActions' } @@ -230,15 +220,12 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti for (const [index, itemValue] of pathValue.entries()) { const itemIsAction = itemValue instanceof game.system.api.models.actions.actionsTypes.base; const value = itemIsAction || !itemValue?.item ? itemValue : itemValue.item; - const enrichedValue = - (await value.system?.getEnrichedDescription?.()) ?? - (await TextEditor.enrichHTML(value.system?.description ?? value.description)); + const enrichedValue = await TextEditor.enrichHTML(value.system?.description ?? value.description); if (itemIsAction) value.enrichedDescription = enrichedValue; else foundry.utils.setProperty(item, `${basePath}.${index}.enrichedDescription`, enrichedValue); } } else { - const enrichedValue = - (await item.system?.getEnrichedDescription?.()) ?? (await TextEditor.enrichHTML(pathValue)); + const enrichedValue = await TextEditor.enrichHTML(pathValue); foundry.utils.setProperty( item, `${data.path ? `${data.path}.` : ''}enriched${data.name.capitalize()}`, @@ -275,7 +262,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti const combat = game.combats.get(combatId); const adversaries = combat.turns?.filter(x => x.actor?.isNPC)?.map(x => ({ ...x.actor, type: x.actor.system.type })) ?? []; - const characters = combat.turns?.filter(x => !x.isNPC && x.actor) ?? []; + const characters = combat.turns?.filter(x => !x.isNPC) ?? []; const nrCharacters = characters.length; const currentBP = AdversaryBPPerEncounter(adversaries, characters); @@ -285,7 +272,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti ); const categories = combat.combatants.reduce((acc, combatant) => { - if (combatant.actor?.type === 'adversary') { + if (combatant.actor.type === 'adversary') { const keyData = Object.keys(acc).reduce((identifiers, categoryKey) => { if (identifiers) return identifiers; const category = acc[categoryKey]; @@ -365,7 +352,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti await combat.toggleModifierEffects( event.target.checked, - combat.combatants.filter(x => x.actor?.type === 'adversary').map(x => x.actor), + combat.combatants.filter(x => x.actor.type === 'adversary').map(x => x.actor), category, grouping ); diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 536847f7..1d6404ff 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -86,9 +86,9 @@ export const enrichedDualityRoll = async ( const config = { event: event ?? {}, title: title, - headerTitle: label, roll: { trait: traitValue && target ? traitValue : null, + label: label, difficulty: difficulty, advantage, type: reaction ? 'reaction' : null @@ -101,7 +101,7 @@ export const enrichedDualityRoll = async ( await target.diceRoll(config); } else { // For no target, call DualityRoll directly with basic data - config.data = { experiences: {}, traits: {}, rules: {} }; + config.data = { experiences: {}, traits: {} }; config.source = { actor: null }; await CONFIG.Dice.daggerheart.DualityRoll.build(config); } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 97769181..32e047fd 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -32,7 +32,6 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/actionTypes/effect.hbs', 'systems/daggerheart/templates/actionTypes/beastform.hbs', 'systems/daggerheart/templates/actionTypes/countdown.hbs', - 'systems/daggerheart/templates/actionTypes/summon.hbs', 'systems/daggerheart/templates/settings/components/settings-item-line.hbs', 'systems/daggerheart/templates/ui/tooltip/parts/tooltipChips.hbs', 'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs', diff --git a/module/systemRegistration/socket.mjs b/module/systemRegistration/socket.mjs index a9e86917..046f1b68 100644 --- a/module/systemRegistration/socket.mjs +++ b/module/systemRegistration/socket.mjs @@ -37,8 +37,7 @@ export const GMUpdateEvent = { export const RefreshType = { Countdown: 'DhCoundownRefresh', TagTeamRoll: 'DhTagTeamRollRefresh', - EffectsDisplay: 'DhEffectsDisplayRefresh', - Scene: 'DhSceneRefresh' + EffectsDisplay: 'DhEffectsDisplayRefresh' }; export const registerSocketHooks = () => { diff --git a/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json b/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json index d4e506cb..4fc58990 100644 --- a/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json +++ b/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json @@ -533,31 +533,33 @@ "description": "

Spend a Fear to summon a @UUID[Compendium.daggerheart.adversaries.Actor.YhJrP7rTBiRdX5Fp]{Zombie Legion}, which appears at Close range and immediately takes the spotlight.

", "resource": null, "actions": { - "qSuWxC8xQOhnbBx9": { - "type": "summon", - "_id": "qSuWxC8xQOhnbBx9", + "gZg3AkzCYUTExjE6": { + "type": "effect", + "_id": "gZg3AkzCYUTExjE6", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", - "cost": [], + "cost": [ + { + "scalable": false, + "key": "fear", + "value": 1, + "step": null + } + ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "any", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.YhJrP7rTBiRdX5Fp", - "count": "1" - } - ], "name": "Spend Fear", + "img": "icons/magic/death/undead-zombie-grave-green.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json index 188b2687..b1804074 100644 --- a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json +++ b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json @@ -312,14 +312,7 @@ "range": "melee" } }, - "changes": [ - { - "key": "system.rules.dualityRoll.defaultHopeDice", - "mode": 5, - "value": "d8", - "priority": null - } - ], + "changes": [], "disabled": false, "duration": { "startTime": null, @@ -330,7 +323,7 @@ "startRound": null, "startTurn": null }, - "description": "

All targets affected replace their Hope Die with a d8 until they roll a success with Hope or their next rest.

", + "description": "

All targets aff ected replace their Hope Die with a d8 until they roll a success with Hope or their next rest.

", "tint": "#ffffff", "statuses": [], "sort": 0, diff --git a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json index 2341ee8a..9e838d6d 100644 --- a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json +++ b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json @@ -256,45 +256,34 @@ "description": "

Spend a Fear to boil the blood of all PCs within Far range. They use a d20 as their Fear Die until the end of the scene.

@Template[type:emanation|range:f]

", "resource": null, "actions": { - "jKvzbQT0vp66DDOH": { + "V142qYppCGJn8OiN": { "type": "effect", - "_id": "jKvzbQT0vp66DDOH", + "_id": "V142qYppCGJn8OiN", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "fear", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null }, - "effects": [ - { - "_id": "gFeHLGgeRoDdd3VG", - "onSave": false - } - ], + "effects": [], "target": { - "type": "hostile", + "type": "self", "amount": null }, "name": "Spend Fear", - "range": "far" + "img": "icons/skills/melee/maneuver-greatsword-yellow.webp", + "range": "" } }, "originItemType": null, @@ -303,51 +292,7 @@ }, "_id": "a33PW8UkziliowlR", "img": "icons/skills/melee/maneuver-greatsword-yellow.webp", - "effects": [ - { - "name": "Battle Lust", - "img": "icons/skills/melee/maneuver-greatsword-yellow.webp", - "origin": "Compendium.daggerheart.adversaries.Actor.5lphJAgzoqZI3VoG.Item.a33PW8UkziliowlR", - "transfer": false, - "_id": "gFeHLGgeRoDdd3VG", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "changes": [ - { - "key": "system.rules.dualityRoll.defaultFearDice", - "mode": 5, - "value": "d20", - "priority": null - } - ], - "disabled": false, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "

You use a d20 as your Fear Die until the end of the scene.

", - "tint": "#ffffff", - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!actors.items.effects!5lphJAgzoqZI3VoG.a33PW8UkziliowlR.gFeHLGgeRoDdd3VG" - } - ], + "effects": [], "folder": null, "sort": 0, "ownership": { @@ -512,12 +457,11 @@ "img": "icons/creatures/unholy/demon-fire-horned-clawed.webp", "range": "" }, - "FlE6i0tbKEguF9wz": { - "type": "summon", - "_id": "FlE6i0tbKEguF9wz", + "7G6uWlFEeOLsJIWY": { + "type": "effect", + "_id": "7G6uWlFEeOLsJIWY", "systemPath": "actions", - "baseAction": false, - "description": "", + "description": "

Summon [[/r 1d4]]@UUID[Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb]{Minor Demons}, who appear at Close range.

", "chatDisplay": true, "originItem": { "type": "itemCollection" @@ -530,13 +474,13 @@ "recovery": null, "consumeOnSuccess": false }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb", - "count": "1d4" - } - ], + "effects": [], + "target": { + "type": "any", + "amount": null + }, "name": "Summon", + "img": "icons/creatures/unholy/demon-fire-horned-clawed.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json b/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json index ca9ce647..f0a5d81c 100644 --- a/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json +++ b/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json @@ -363,31 +363,33 @@ "description": "

Spend a Fear to grow three @UUID[Compendium.daggerheart.adversaries.Actor.o63nS0k3wHu6EgKP]{Treant Sapling Minions}, who appear at Close range and immediately take the spotlight.

", "resource": null, "actions": { - "R84DdS0OIx2cUt1w": { - "type": "summon", - "_id": "R84DdS0OIx2cUt1w", + "84Q2b0zIY9c7Yhho": { + "type": "effect", + "_id": "84Q2b0zIY9c7Yhho", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", - "cost": [], + "cost": [ + { + "scalable": false, + "key": "fear", + "value": 1, + "step": null + } + ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "self", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.o63nS0k3wHu6EgKP", - "count": "3" - } - ], "name": "Spend Fear", + "img": "icons/magic/unholy/orb-hands-pink.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json b/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json index b03b5495..c7446a11 100644 --- a/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json +++ b/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json @@ -510,41 +510,34 @@ "description": "

When the @Lookup[@name] has 3 or more HP marked, you can spend a Fear to split them into two @UUID[Compendium.daggerheart.adversaries.Actor.aLkLFuVoKz2NLoBK]{Tiny Green Oozes} (with no marked HP or Stress). Immediately spotlight both of them.

", "resource": null, "actions": { - "J8U7dw3cDSsEirr5": { - "type": "summon", - "_id": "J8U7dw3cDSsEirr5", + "s5mLw6DRGd76MLcC": { + "type": "effect", + "_id": "s5mLw6DRGd76MLcC", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "fear", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "self", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.aLkLFuVoKz2NLoBK", - "count": "2" - } - ], "name": "Spend Fear", - "range": "self" + "img": "icons/creatures/slimes/slime-movement-pseudopods-green.webp", + "range": "" } }, "originItemType": null, diff --git a/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json b/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json index d5891359..9e948594 100644 --- a/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json +++ b/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json @@ -474,31 +474,33 @@ "description": "

Spend 2 Fear to summon [[/r 1d4]] @UUID[Compendium.daggerheart.adversaries.Actor.WWyUp6Mxl1S3KYUG]{Vampires}, who appear at Far range and immediately take the spotlight.

", "resource": null, "actions": { - "jGFOnU6PNdWU6iF4": { - "type": "summon", - "_id": "jGFOnU6PNdWU6iF4", + "5Q6RMUTiauKw0tDj": { + "type": "effect", + "_id": "5Q6RMUTiauKw0tDj", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", - "cost": [], + "cost": [ + { + "scalable": false, + "key": "fear", + "value": 2, + "step": null + } + ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.WWyUp6Mxl1S3KYUG", - "count": "1d4" - } - ], - "name": "Spend Fear", + "effects": [], + "target": { + "type": "any", + "amount": null + }, + "name": "Summon Vampires", + "img": "icons/creatures/mammals/bat-giant-tattered-purple.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json b/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json index 3bb8ae96..6f64f883 100644 --- a/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json +++ b/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json @@ -479,31 +479,33 @@ "description": "

When the @Lookup[@name] has 4 or more HP marked, you can spend a Fear to split them into two @UUID[Compendium.daggerheart.adversaries.Actor.SHXedd9zZPVfUgUa]{Green Oozes}(with no marked HP or Stress). Immediately spotlight both of them.

", "resource": null, "actions": { - "aeRdkiRsDNagTKhp": { - "type": "summon", - "_id": "aeRdkiRsDNagTKhp", + "iQsYAqpUFvJslRDr": { + "type": "effect", + "_id": "iQsYAqpUFvJslRDr", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", - "cost": [], + "cost": [ + { + "scalable": false, + "key": "fear", + "value": 1, + "step": null + } + ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "any", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.SHXedd9zZPVfUgUa", - "count": "2" - } - ], "name": "Spend Fear", + "img": "icons/creatures/slimes/slime-movement-pseudopods-green.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json b/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json index c139d76f..165bb160 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json @@ -287,35 +287,7 @@ "system": { "description": "

Summon three @Compendium[daggerheart.adversaries.Actor.C0OMQqV7pN6t7ouR], who appear at Far range.

", "resource": null, - "actions": { - "MCTBsw9lusUdubj0": { - "type": "summon", - "_id": "MCTBsw9lusUdubj0", - "systemPath": "actions", - "baseAction": false, - "description": "", - "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, - "actionType": "action", - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.C0OMQqV7pN6t7ouR", - "count": "3" - } - ], - "name": "Summon", - "range": "" - } - }, + "actions": {}, "originItemType": null, "subType": null, "originId": null, diff --git a/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json b/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json index db284f40..4ac7e746 100644 --- a/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json +++ b/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json @@ -258,40 +258,57 @@ "description": "

Once per scene, mark a Stress to summon 1d4 @UUID[Compendium.daggerheart.adversaries.Actor.B4LZcGuBAHzyVdzy]{Bladed Guards}, who appear at Far range to enforce the @Lookup[@name]’s will.

", "resource": null, "actions": { - "tioTtYfIGFIXRITN": { - "type": "summon", - "_id": "tioTtYfIGFIXRITN", + "cUKwhq1imsTVru8D": { + "type": "attack", + "_id": "cUKwhq1imsTVru8D", "systemPath": "actions", - "baseAction": false, - "description": "", + "description": "

Once per scene, mark a Stress to summon 1d4 @UUID[Compendium.daggerheart.adversaries.Actor.B4LZcGuBAHzyVdzy]{Bladed Guards}, who appear at Far range to enforce the Noble’s will.

", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "stress", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, - "max": "1", - "recovery": "scene", - "consumeOnSuccess": false + "max": "", + "recovery": null + }, + "damage": { + "parts": [], + "includeBase": false + }, + "target": { + "type": "any", + "amount": null + }, + "effects": [], + "roll": { + "type": "diceSet", + "trait": null, + "difficulty": null, + "bonus": null, + "advState": "neutral", + "diceRolling": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d4", + "compare": null, + "treshold": null + }, + "useDefault": false + }, + "save": { + "trait": null, + "difficulty": null, + "damageMod": "none" }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.B4LZcGuBAHzyVdzy", - "count": "1d4" - } - ], "name": "Summon Guards", + "img": "icons/environment/people/infantry-armored.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json b/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json index 5b00ec60..409d7698 100644 --- a/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json +++ b/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json @@ -313,43 +313,36 @@ "_id": "WGEGO0DSOs5cF0EL", "img": "icons/environment/people/charge.webp", "system": { - "description": "

Once per scene, mark a Stress to summon a @UUID[Compendium.daggerheart.adversaries.Actor.5YgEajn0wa4i85kC]{Pirate Raider Horde}, which appears at Far range.

", + "description": "

Once per scene, mark a Stress to summon a Pirate Raiders Horde, which appears at Far range.

", "resource": null, "actions": { - "nuYk5WeLLpIKa69q": { - "type": "summon", - "_id": "nuYk5WeLLpIKa69q", + "NlgIp0KrmZoS27Xy": { + "type": "effect", + "_id": "NlgIp0KrmZoS27Xy", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "stress", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "any", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.5YgEajn0wa4i85kC", - "count": "1" - } - ], "name": "Mark Stress", + "img": "icons/environment/people/charge.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json b/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json index 2c10ae3f..320b71af 100644 --- a/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json +++ b/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json @@ -454,40 +454,33 @@ "description": "

When the @Lookup[@name] has 3 or more HP marked, you can spend a Fear to split them into two @UUID[Compendium.daggerheart.adversaries.Actor.1fkLQXVtmILqfJ44]{Tiny Red Oozes} (with no marked HP or Stress). Immediately spotlight both of them.

", "resource": null, "actions": { - "BMEr77hDxaQyYBna": { - "type": "summon", - "_id": "BMEr77hDxaQyYBna", + "dw6Juw8mriH7sg0e": { + "type": "effect", + "_id": "dw6Juw8mriH7sg0e", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "fear", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "any", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.1fkLQXVtmILqfJ44", - "count": "2" - } - ], "name": "Spend Fear", + "img": "icons/creatures/slimes/slime-movement-splashing-red.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json b/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json index d17c3f86..0c8757c5 100644 --- a/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json +++ b/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json @@ -416,6 +416,28 @@ "description": "

Countdown (6). When the @Lookup[@name] is in the spotlight for the first time, activate the countdown. When they mark HP, tick down this countdown by the number of HP marked. When it triggers, summon a @UUID[Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb]{Minor Demon} who appears at Close range.

", "resource": null, "actions": { + "0rixG6jLRynAYNqA": { + "type": "effect", + "_id": "0rixG6jLRynAYNqA", + "systemPath": "actions", + "description": "

Summon a @UUID[Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb]{Minor Demon} who appears at Close range.

", + "chatDisplay": true, + "actionType": "action", + "cost": [], + "uses": { + "value": null, + "max": "", + "recovery": null + }, + "effects": [], + "target": { + "type": "any", + "amount": null + }, + "name": "Summon", + "img": "icons/magic/unholy/silhouette-light-fire-blue.webp", + "range": "close" + }, "ZVXHY2fpomoKV7jG": { "type": "countdown", "_id": "ZVXHY2fpomoKV7jG", @@ -452,33 +474,6 @@ "name": "Start Countdown", "img": "icons/magic/unholy/silhouette-light-fire-blue.webp", "range": "" - }, - "YReYG6DrWp4QGSij": { - "type": "summon", - "_id": "YReYG6DrWp4QGSij", - "systemPath": "actions", - "baseAction": false, - "description": "", - "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, - "actionType": "action", - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb", - "count": "1" - } - ], - "name": "Summon", - "range": "" } }, "originItemType": null, @@ -507,31 +502,33 @@ "description": "

Once per scene, when the @Lookup[@name] marks 2 or more HP, you can mark a Stress to summon a @UUID[Compendium.daggerheart.adversaries.Actor.NoRZ1PqB8N5wcIw0]{Demonic Hound Pack}, which appears at Close range and is immediately spotlighted.

", "resource": null, "actions": { - "tfmY6HYkkY27NBaF": { - "type": "summon", - "_id": "tfmY6HYkkY27NBaF", + "JBuQUJhif2A7IlJd": { + "type": "effect", + "_id": "JBuQUJhif2A7IlJd", "systemPath": "actions", - "baseAction": false, "description": "", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "summon": [ + "cost": [ { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.NoRZ1PqB8N5wcIw0", - "count": "1" + "scalable": false, + "key": "stress", + "value": 1, + "step": null } ], + "uses": { + "value": null, + "max": "1", + "recovery": "scene" + }, + "effects": [], + "target": { + "type": "self", + "amount": null + }, "name": "Mark Stress", + "img": "icons/creatures/unholy/demon-fire-horned-clawed.webp", "range": "" } }, diff --git a/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json b/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json index 0f1ba28f..a6e5ca17 100644 --- a/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json +++ b/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json @@ -340,35 +340,7 @@ "system": { "description": "

When an attack from the @Lookup[@name] causes a target to mark HP and there are three or more @Lookup[@name] Minions within Close range, you can combine the Minions into a @UUID[Compendium.daggerheart.adversaries.Actor.PKSXFuaIHUCoH63A]{Tangle Bramble Swarm Horde}. The Horde’s HP is equal to the number of Minions combined.

", "resource": null, - "actions": { - "g1OQ5xlMHFWsoktd": { - "type": "summon", - "_id": "g1OQ5xlMHFWsoktd", - "systemPath": "actions", - "baseAction": false, - "description": "", - "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, - "actionType": "action", - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.PKSXFuaIHUCoH63A", - "count": "1" - } - ], - "name": "Summon", - "range": "" - } - }, + "actions": {}, "originItemType": null, "subType": null, "originId": null, diff --git a/src/packs/classes/feature_Strange_Patterns_6YsfFjmCGuFYVhT4.json b/src/packs/classes/feature_Strange_Patterns_6YsfFjmCGuFYVhT4.json index 95f42c06..bd364e6f 100644 --- a/src/packs/classes/feature_Strange_Patterns_6YsfFjmCGuFYVhT4.json +++ b/src/packs/classes/feature_Strange_Patterns_6YsfFjmCGuFYVhT4.json @@ -80,14 +80,7 @@ }, "name": "Clear Stress", "img": "icons/magic/symbols/rune-sigil-black-pink.webp", - "range": "", - "triggers": [ - { - "trigger": "dualityRoll", - "triggeringActorType": "self", - "command": "/* Ignore if it's a TagTeam roll */\nconst tagTeam = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);\nif (tagTeam.members[actor.id]) return;\n\n/* Check if there's a Strange Pattern match */\nconst dice = [roll.dFear.total, roll.dHope.total];\nconst resource = this.parent.resource?.diceStates ? Object.values(this.parent.resource.diceStates).map(x => x.value)[0] : null;\nconst nrMatches = dice.filter(x => x === resource).length;\n\nif (!nrMatches) return;\n\n/* Create a dialog to choose Hope or Stress - or to cancel*/\nconst content = `\n
${game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerTexts.strangePatternsContentTitle', { nr: nrMatches })}
\n
${game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerTexts.strangePatternsContentSubTitle', { nr: nrMatches })}
\n
\n \n \n
\n
`;\n\nconst result = await foundry.applications.api.DialogV2.input({\n classes: ['dh-style', 'two-big-buttons'],\n window: { title: this.item.name },\n content: content,\n render: (_, dialog) => {\n const hopeButton = dialog.element.querySelector('#hopeButton');\n const stressButton = dialog.element.querySelector('#stressButton');\ndialog.element.querySelector('button[type=\"submit\"]').disabled = true;\n \n const updateFunc = (event, selector, adding, clamp) => {\n const button = event.target.closest(`#${selector}Button`);\n const parent = event.target.closest('.flexrow');\n const hope = Number.parseInt(parent.querySelector('#hopeButton label').innerHTML);\n const stress = Number.parseInt(parent.querySelector('#stressButton label').innerHTML);\n const currentTotal = (Number.isNumeric(hope) ? hope : 0) + (Number.isNumeric(stress) ? stress : 0);\n if (adding && currentTotal === nrMatches) return;\n \n const current = Number.parseInt(button.querySelector('label').innerHTML);\n if (!adding && current === 0) return;\n \n const value = Number.isNumeric(current) ? adding ? current+1 : current-1 : 1;\n if (!dialog.data) dialog.data = {};\n dialog.data[selector] = clamp(value);\n button.querySelector('label').innerHTML = dialog.data[selector];\n\n event.target.closest('.dialog-form').querySelector('button[type=\"submit\"]').disabled = !adding || currentTotal < (nrMatches-1);\n \n };\n hopeButton.addEventListener('click', event => updateFunc(event, 'hope', true, x => Math.min(x, nrMatches)));\n hopeButton.addEventListener('contextmenu', event => updateFunc(event, 'hope', false, x => Math.max(x, 0)));\n stressButton.addEventListener('click', event => updateFunc(event, 'stress', true, x => Math.min(x, nrMatches)));\n stressButton.addEventListener('contextmenu', event => updateFunc(event, 'stress', false, x => Math.max(x, 0)));\n },\n ok: { callback: (_event, _result, dialog) => {\n const hope = dialog.data.hope ?? 0;\n const stress = dialog.data.stress ?? 0;\n if (!hope && !stress) return;\n\n /* Return resource update according to choices */\n const hopeUpdate = hope ? { key: 'hope', value: hope, total: -hope, enabled: true } : null;\n const stressUpdate = stress ? { key: 'stress', value: -stress, total: stress, enabled: true } : null;\n return { updates: [hopeUpdate, stressUpdate].filter(x => x) };\n }}\n});\n\nreturn result;" - } - ] + "range": "" } }, "originItemType": null, diff --git a/src/packs/domains/domainCard_Arcana_Touched_5PvMQKCjrgSxzstn.json b/src/packs/domains/domainCard_Arcana_Touched_5PvMQKCjrgSxzstn.json index 556d5074..80d9797f 100644 --- a/src/packs/domains/domainCard_Arcana_Touched_5PvMQKCjrgSxzstn.json +++ b/src/packs/domains/domainCard_Arcana_Touched_5PvMQKCjrgSxzstn.json @@ -54,8 +54,7 @@ "source": "Daggerheart SRD", "page": 120, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "5PvMQKCjrgSxzstn", diff --git a/src/packs/domains/domainCard_Blade_Touched_Gb5bqpFSBiuBxUix.json b/src/packs/domains/domainCard_Blade_Touched_Gb5bqpFSBiuBxUix.json index ebb95570..d2d5dafc 100644 --- a/src/packs/domains/domainCard_Blade_Touched_Gb5bqpFSBiuBxUix.json +++ b/src/packs/domains/domainCard_Blade_Touched_Gb5bqpFSBiuBxUix.json @@ -13,8 +13,7 @@ "source": "Daggerheart SRD", "page": 121, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "Gb5bqpFSBiuBxUix", diff --git a/src/packs/domains/domainCard_Bone_Touched_ON5bvnoQBy0SYc9Y.json b/src/packs/domains/domainCard_Bone_Touched_ON5bvnoQBy0SYc9Y.json index 8880bb07..770ddd63 100644 --- a/src/packs/domains/domainCard_Bone_Touched_ON5bvnoQBy0SYc9Y.json +++ b/src/packs/domains/domainCard_Bone_Touched_ON5bvnoQBy0SYc9Y.json @@ -46,8 +46,7 @@ "source": "Daggerheart SRD", "page": 123, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "ON5bvnoQBy0SYc9Y", diff --git a/src/packs/domains/domainCard_Codex_Touched_7Pu83ABdMukTxu3e.json b/src/packs/domains/domainCard_Codex_Touched_7Pu83ABdMukTxu3e.json index 6443ed6a..1e2d5de3 100644 --- a/src/packs/domains/domainCard_Codex_Touched_7Pu83ABdMukTxu3e.json +++ b/src/packs/domains/domainCard_Codex_Touched_7Pu83ABdMukTxu3e.json @@ -71,8 +71,7 @@ "source": "Daggerheart SRD", "page": 125, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "7Pu83ABdMukTxu3e", diff --git a/src/packs/domains/domainCard_Ferocity_jSQsSP61CX4MhSN7.json b/src/packs/domains/domainCard_Ferocity_jSQsSP61CX4MhSN7.json index 78593c62..9e46e6ba 100644 --- a/src/packs/domains/domainCard_Ferocity_jSQsSP61CX4MhSN7.json +++ b/src/packs/domains/domainCard_Ferocity_jSQsSP61CX4MhSN7.json @@ -17,16 +17,7 @@ "description": "

When you cause an adversary to mark 1 or more Hit Points, you can spend 2 Hope to increase your Evasion by the number of Hit Points they marked. This bonus lasts until after the next attack made against you.

", "chatDisplay": true, "actionType": "action", - "cost": [ - { - "scalable": false, - "key": "hope", - "value": 2, - "itemId": null, - "step": null, - "consumeOnSuccess": false - } - ], + "cost": [], "uses": { "value": null, "max": "", @@ -39,15 +30,8 @@ "amount": null }, "name": "Spend Hope", - "img": "icons/skills/melee/maneuver-sword-katana-yellow.webp", - "range": "", - "triggers": [ - { - "trigger": "postDamageReduction", - "triggeringActorType": "other", - "command": "/* Check if sufficient hope */\nif (this.actor.system.resources.hope.value < 2) return;\n\n/* Check if hit point damage was dealt */\nconst hpDamage = damageUpdates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id);\nif (hpDamage.value < 0) return;\n\n/* Dialog to give player choice */\nconst confirmed = await foundry.applications.api.DialogV2.confirm({\n window: { title: this.item?.name ?? '' },\n content: game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerTexts.ferocityContent', { bonus: hpDamage.value }),\n});\n\nif (!confirmed) return;\n\n/* Create the effect */\nthis.actor.createEmbeddedDocuments('ActiveEffect', [{\n name: this.item.name,\n img: 'icons/skills/melee/maneuver-sword-katana-yellow.webp',\n description: game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerTexts.ferocityEffectDescription', { bonus: hpDamage.value }),\n changes: [{ key: 'system.evasion', mode: 2, value: hpDamage.value }]\n}]);\n\n/* Update hope */\nreturn { updates: [{ \n originActor: this.actor, \n updates: [{\n key: CONFIG.DH.GENERAL.healingTypes.hope.id,\n value: -2,\n total: 2\n }] \n}]}" - } - ] + "img": "icons/skills/melee/maneuver-daggers-paired-orange.webp", + "range": "" } }, "attribution": { diff --git a/src/packs/domains/domainCard_Get_Back_Up_BFWN2cObMdlk9uVz.json b/src/packs/domains/domainCard_Get_Back_Up_BFWN2cObMdlk9uVz.json index 571a3fb4..ab74e805 100644 --- a/src/packs/domains/domainCard_Get_Back_Up_BFWN2cObMdlk9uVz.json +++ b/src/packs/domains/domainCard_Get_Back_Up_BFWN2cObMdlk9uVz.json @@ -18,7 +18,7 @@ }, "flags": {}, "_id": "BFWN2cObMdlk9uVz", - "sort": 3500000, + "sort": 3400000, "effects": [ { "name": "Get Back Up", diff --git a/src/packs/domains/domainCard_Grace_Touched_KAuNb51AwhD8KEXk.json b/src/packs/domains/domainCard_Grace_Touched_KAuNb51AwhD8KEXk.json index 346a81f2..b87ea24d 100644 --- a/src/packs/domains/domainCard_Grace_Touched_KAuNb51AwhD8KEXk.json +++ b/src/packs/domains/domainCard_Grace_Touched_KAuNb51AwhD8KEXk.json @@ -96,8 +96,7 @@ "source": "Daggerheart SRD", "page": 127, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "KAuNb51AwhD8KEXk", diff --git a/src/packs/domains/domainCard_Midnight_Touched_uSyGKVxOJcnp28po.json b/src/packs/domains/domainCard_Midnight_Touched_uSyGKVxOJcnp28po.json index 10c42418..3370c30e 100644 --- a/src/packs/domains/domainCard_Midnight_Touched_uSyGKVxOJcnp28po.json +++ b/src/packs/domains/domainCard_Midnight_Touched_uSyGKVxOJcnp28po.json @@ -111,8 +111,7 @@ "source": "Daggerheart SRD", "page": 129, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "uSyGKVxOJcnp28po", diff --git a/src/packs/domains/domainCard_Notorious_IqxzvvjZiYbgx21A.json b/src/packs/domains/domainCard_Notorious_IqxzvvjZiYbgx21A.json index 2e5f5ffd..dfb581e7 100644 --- a/src/packs/domains/domainCard_Notorious_IqxzvvjZiYbgx21A.json +++ b/src/packs/domains/domainCard_Notorious_IqxzvvjZiYbgx21A.json @@ -44,8 +44,7 @@ "source": "Daggerheart SRD", "page": 127, "artist": "" - }, - "loadoutIgnore": true + } }, "flags": {}, "_id": "IqxzvvjZiYbgx21A", diff --git a/src/packs/domains/domainCard_Sage_Touched_VOSFaQHZbmhMyXwi.json b/src/packs/domains/domainCard_Sage_Touched_VOSFaQHZbmhMyXwi.json index 432ff638..dc9ac3d3 100644 --- a/src/packs/domains/domainCard_Sage_Touched_VOSFaQHZbmhMyXwi.json +++ b/src/packs/domains/domainCard_Sage_Touched_VOSFaQHZbmhMyXwi.json @@ -94,8 +94,7 @@ "source": "Daggerheart SRD", "page": 131, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "VOSFaQHZbmhMyXwi", diff --git a/src/packs/domains/domainCard_Salvation_Beam_4uAFGp3LxiC07woC.json b/src/packs/domains/domainCard_Salvation_Beam_4uAFGp3LxiC07woC.json index c7aeb02f..d637f611 100644 --- a/src/packs/domains/domainCard_Salvation_Beam_4uAFGp3LxiC07woC.json +++ b/src/packs/domains/domainCard_Salvation_Beam_4uAFGp3LxiC07woC.json @@ -95,7 +95,7 @@ }, "flags": {}, "_id": "4uAFGp3LxiC07woC", - "sort": 3500000, + "sort": 3400000, "effects": [], "ownership": { "default": 0 diff --git a/src/packs/domains/domainCard_Splendor_Touched_JT5dM3gVL6chDBYU.json b/src/packs/domains/domainCard_Splendor_Touched_JT5dM3gVL6chDBYU.json index 6b530289..45d0dc96 100644 --- a/src/packs/domains/domainCard_Splendor_Touched_JT5dM3gVL6chDBYU.json +++ b/src/packs/domains/domainCard_Splendor_Touched_JT5dM3gVL6chDBYU.json @@ -13,8 +13,7 @@ "source": "Daggerheart SRD", "page": 133, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "JT5dM3gVL6chDBYU", diff --git a/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json b/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json index 20fe18ea..99546d6f 100644 --- a/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json +++ b/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json @@ -82,8 +82,7 @@ "source": "Daggerheart SRD", "page": 134, "artist": "" - }, - "domainTouched": 4 + } }, "flags": {}, "_id": "k1AtYd3lSchIymBr", diff --git a/src/packs/domains/domainCard_Vitality_sWUlSPOJEaXyQLCj.json b/src/packs/domains/domainCard_Vitality_sWUlSPOJEaXyQLCj.json index ec47c9f9..729aa251 100644 --- a/src/packs/domains/domainCard_Vitality_sWUlSPOJEaXyQLCj.json +++ b/src/packs/domains/domainCard_Vitality_sWUlSPOJEaXyQLCj.json @@ -51,8 +51,7 @@ "source": "Daggerheart SRD", "page": 121, "artist": "" - }, - "vaultActive": true + } }, "flags": {}, "_id": "sWUlSPOJEaXyQLCj", diff --git a/src/packs/domains/folders_Level_10_7pKKYgRQAKlQAksV.json b/src/packs/domains/folders_Level_10_7pKKYgRQAKlQAksV.json index 126323da..613aa993 100644 --- a/src/packs/domains/folders_Level_10_7pKKYgRQAKlQAksV.json +++ b/src/packs/domains/folders_Level_10_7pKKYgRQAKlQAksV.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "7pKKYgRQAKlQAksV", "description": "", - "sort": 950000, + "sort": 1000000, "flags": {}, "_key": "!folders!7pKKYgRQAKlQAksV" } diff --git a/src/packs/domains/folders_Level_1_9Xc6KzNyjDtTGZkp.json b/src/packs/domains/folders_Level_1_9Xc6KzNyjDtTGZkp.json index 2d9c78f9..095ff6fb 100644 --- a/src/packs/domains/folders_Level_1_9Xc6KzNyjDtTGZkp.json +++ b/src/packs/domains/folders_Level_1_9Xc6KzNyjDtTGZkp.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "9Xc6KzNyjDtTGZkp", "description": "", - "sort": 700000, + "sort": 100000, "flags": {}, "_key": "!folders!9Xc6KzNyjDtTGZkp" } diff --git a/src/packs/domains/folders_Level_2_o7t2fsAmRxKLoHrO.json b/src/packs/domains/folders_Level_2_o7t2fsAmRxKLoHrO.json index 68cc5f04..b242e121 100644 --- a/src/packs/domains/folders_Level_2_o7t2fsAmRxKLoHrO.json +++ b/src/packs/domains/folders_Level_2_o7t2fsAmRxKLoHrO.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "o7t2fsAmRxKLoHrO", "description": "", - "sort": 800000, + "sort": 200000, "flags": {}, "_key": "!folders!o7t2fsAmRxKLoHrO" } diff --git a/src/packs/domains/folders_Level_3_wWL9mV6i2EGX5xHS.json b/src/packs/domains/folders_Level_3_wWL9mV6i2EGX5xHS.json index e04c6f09..3a4b0055 100644 --- a/src/packs/domains/folders_Level_3_wWL9mV6i2EGX5xHS.json +++ b/src/packs/domains/folders_Level_3_wWL9mV6i2EGX5xHS.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "wWL9mV6i2EGX5xHS", "description": "", - "sort": 850000, + "sort": 300000, "flags": {}, "_key": "!folders!wWL9mV6i2EGX5xHS" } diff --git a/src/packs/domains/folders_Level_4_yalAnCU3SndrYImF.json b/src/packs/domains/folders_Level_4_yalAnCU3SndrYImF.json index 2b70a495..ab0ba963 100644 --- a/src/packs/domains/folders_Level_4_yalAnCU3SndrYImF.json +++ b/src/packs/domains/folders_Level_4_yalAnCU3SndrYImF.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "yalAnCU3SndrYImF", "description": "", - "sort": 900000, + "sort": 400000, "flags": {}, "_key": "!folders!yalAnCU3SndrYImF" } diff --git a/src/packs/domains/folders_Level_5_Emnx4o1DWGTVKoAg.json b/src/packs/domains/folders_Level_5_Emnx4o1DWGTVKoAg.json index 5bde56f3..0a821a2d 100644 --- a/src/packs/domains/folders_Level_5_Emnx4o1DWGTVKoAg.json +++ b/src/packs/domains/folders_Level_5_Emnx4o1DWGTVKoAg.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "Emnx4o1DWGTVKoAg", "description": "", - "sort": 901563, + "sort": 500000, "flags": {}, "_key": "!folders!Emnx4o1DWGTVKoAg" } diff --git a/src/packs/domains/folders_Level_6_EiP5dLozOFZKIeWN.json b/src/packs/domains/folders_Level_6_EiP5dLozOFZKIeWN.json index e20ae6b5..5a58c052 100644 --- a/src/packs/domains/folders_Level_6_EiP5dLozOFZKIeWN.json +++ b/src/packs/domains/folders_Level_6_EiP5dLozOFZKIeWN.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "EiP5dLozOFZKIeWN", "description": "", - "sort": 903125, + "sort": 600000, "flags": {}, "_key": "!folders!EiP5dLozOFZKIeWN" } diff --git a/src/packs/domains/folders_Level_7_HAGbPLHwm0UozDeG.json b/src/packs/domains/folders_Level_7_HAGbPLHwm0UozDeG.json index e53c0e2a..233e3756 100644 --- a/src/packs/domains/folders_Level_7_HAGbPLHwm0UozDeG.json +++ b/src/packs/domains/folders_Level_7_HAGbPLHwm0UozDeG.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "HAGbPLHwm0UozDeG", "description": "", - "sort": 906250, + "sort": 700000, "flags": {}, "_key": "!folders!HAGbPLHwm0UozDeG" } diff --git a/src/packs/domains/folders_Level_8_me7ywrVh38j6T8Sm.json b/src/packs/domains/folders_Level_8_me7ywrVh38j6T8Sm.json index 9a0ad8d9..2b125f0d 100644 --- a/src/packs/domains/folders_Level_8_me7ywrVh38j6T8Sm.json +++ b/src/packs/domains/folders_Level_8_me7ywrVh38j6T8Sm.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "me7ywrVh38j6T8Sm", "description": "", - "sort": 912500, + "sort": 800000, "flags": {}, "_key": "!folders!me7ywrVh38j6T8Sm" } diff --git a/src/packs/domains/folders_Level_9_QYdeGsmVYIF34kZR.json b/src/packs/domains/folders_Level_9_QYdeGsmVYIF34kZR.json index 3547b169..c7984fb9 100644 --- a/src/packs/domains/folders_Level_9_QYdeGsmVYIF34kZR.json +++ b/src/packs/domains/folders_Level_9_QYdeGsmVYIF34kZR.json @@ -6,7 +6,7 @@ "sorting": "a", "_id": "QYdeGsmVYIF34kZR", "description": "", - "sort": 925000, + "sort": 900000, "flags": {}, "_key": "!folders!QYdeGsmVYIF34kZR" } diff --git a/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json b/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json index ea4f1951..dc42fb07 100644 --- a/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json +++ b/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json @@ -314,7 +314,7 @@ "name": "Charcoal Constructs", "type": "feature", "system": { - "description": "

Warped animals wreathed in indigo flame trample through a point of your choice. All targets within Close range of that point must make an Agility Reaction Roll. Targets who fail take 3d12+3 physical damage. Targets who succeed take half damage instead.

@Template[type:emanation|range:c]

Are these real animals consumed by the fl ame or merely constructs of the corrupting magic?

", + "description": "

Warped animals wreathed in indigo f l ame trample through a point of your choice. All targets within Close range of that point must make an Agility Reaction Roll. Targets who fail take 3d12+3 physical damage. Targets who succeed take half damage instead.

@Template[type:emanation|range:c]

Are these real animals consumed by the fl ame or merely constructs of the corrupting magic?

", "resource": null, "actions": { "gbXIaKr8em134IZC": { diff --git a/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json b/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json index 361b15bc..77781de0 100644 --- a/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json +++ b/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json @@ -467,48 +467,33 @@ "description": "

Spend a Fear to summon an @UUID[Compendium.daggerheart.adversaries.Actor.A0SeeDzwjvqOsyof]{Outer Realms Abomination}, an@UUID[Compendium.daggerheart.adversaries.Actor.ms6nuOl3NFkhPj1k]{Outer Realms Corrupter}, and [[/r 2d6]] @UUID[Compendium.daggerheart.adversaries.Actor.moJhHgKqTKPS2WYS]{Outer Realms Thrall}, who appear at Close range of a chosen PC in defiance of logic and causality. Immediately spotlight one of these adversaries, and you can spend an additional Fear to automatically succeed on that adversary’s standard attack.

What halfconsumed remnants of the shattered world do these monstrosities cast aside in pursuit of living flesh? What jagged refl ections of former personhood do you catch between moments of unquestioning malice?

", "resource": null, "actions": { - "KCzdCu2KhAx9KyhT": { - "type": "summon", - "_id": "KCzdCu2KhAx9KyhT", + "5a8ESNroEQHAm7rO": { + "type": "effect", + "_id": "5a8ESNroEQHAm7rO", "systemPath": "actions", - "baseAction": false, - "description": "", + "description": "

Spend a Fear to summon an @UUID[Compendium.daggerheart.adversaries.Actor.A0SeeDzwjvqOsyof]{Outer Realms Abomination}, an@UUID[Compendium.daggerheart.adversaries.Actor.ms6nuOl3NFkhPj1k]{Outer Realms Corrupter}, and [[/r 2d6]] @UUID[Compendium.daggerheart.adversaries.Actor.moJhHgKqTKPS2WYS]{Outer Realms Thrall}, who appear at Close range of a chosen PC in defiance of logic and causality. Immediately spotlight one of these adversaries, and you can spend an additional Fear to automatically succeed on that adversary’s standard attack.

What halfconsumed remnants of the shattered world do these monstrosities cast aside in pursuit of living flesh? What jagged refl ections of former personhood do you catch between moments of unquestioning malice?

", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "fear", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "any", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.A0SeeDzwjvqOsyof", - "count": "1" - }, - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.ms6nuOl3NFkhPj1k", - "count": "1" - }, - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.moJhHgKqTKPS2WYS", - "count": "2d6" - } - ], "name": "Spend Fear", + "img": "icons/creatures/unholy/demons-horned-glowing-pink.webp", "range": "" } }, diff --git a/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json b/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json index 1295db59..705c9585 100644 --- a/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json +++ b/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json @@ -136,89 +136,13 @@ "system": { "description": "

Cultists dedicated this place to the Fallen Gods, and their foul influence seeps into it. Reduce the PCs’ Hope Die to a d10 while in this environment. The desecration can be removed with a Progress Countdown (6).

How do the PCs fist notice that something is wrong about this place? What fears resurface while hope is kept at bay?

", "resource": null, - "actions": { - "7W3sWRLzjG3dKcgq": { - "type": "effect", - "_id": "7W3sWRLzjG3dKcgq", - "systemPath": "actions", - "baseAction": false, - "description": "", - "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, - "actionType": "action", - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "effects": [ - { - "_id": "8yNIw8Y7rfMdOqWC", - "onSave": false - } - ], - "target": { - "type": "any", - "amount": null - }, - "name": "Influence", - "range": "" - } - }, + "actions": {}, "originItemType": null, "originId": null }, "_id": "iiHjguQG2aBn9g8i", "img": "icons/magic/unholy/orb-contained-pink.webp", - "effects": [ - { - "name": "Desecrated Ground", - "img": "icons/magic/unholy/orb-contained-pink.webp", - "origin": "Compendium.daggerheart.environments.Actor.QAXXiOKBDmCTauHD.Item.iiHjguQG2aBn9g8i", - "transfer": false, - "_id": "8yNIw8Y7rfMdOqWC", - "type": "base", - "system": { - "rangeDependence": { - "enabled": false, - "type": "withinRange", - "target": "hostile", - "range": "melee" - } - }, - "changes": [ - { - "key": "system.rules.dualityRoll.defaultHopeDice", - "mode": 5, - "value": "d10", - "priority": null - } - ], - "disabled": false, - "duration": { - "startTime": null, - "combat": null, - "seconds": null, - "rounds": null, - "turns": null, - "startRound": null, - "startTurn": null - }, - "description": "

Your Hope Die is reduced to a d10 while in the Desecrated Grounds.

", - "tint": "#ffffff", - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!actors.items.effects!QAXXiOKBDmCTauHD.iiHjguQG2aBn9g8i.8yNIw8Y7rfMdOqWC" - } - ], + "effects": [], "folder": null, "sort": 0, "ownership": { @@ -419,12 +343,11 @@ "img": "icons/magic/unholy/barrier-fire-pink.webp", "range": "" }, - "HG7tbEdlYl3yLQnR": { - "type": "summon", - "_id": "HG7tbEdlYl3yLQnR", + "suFEnfpOfeVRvnJF": { + "type": "effect", + "_id": "suFEnfpOfeVRvnJF", "systemPath": "actions", - "baseAction": false, - "description": "", + "description": "

Summon a @UUID[Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb]{Minor Demon} within Very Close range of the ritual’s leader.

", "chatDisplay": true, "originItem": { "type": "itemCollection" @@ -437,13 +360,13 @@ "recovery": null, "consumeOnSuccess": false }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.3tqCjDwJAQ7JKqMb", - "count": "1" - } - ], + "effects": [], + "target": { + "type": "any", + "amount": null + }, "name": "Summon Demon", + "img": "icons/magic/unholy/barrier-fire-pink.webp", "range": "" } }, diff --git a/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json b/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json index d8e9cded..aacf87e9 100644 --- a/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json +++ b/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json @@ -248,31 +248,33 @@ "description": "

Spend 2 Fear to summon [[/r 1d4+2]] @UUID[Compendium.daggerheart.adversaries.Actor.OsLG2BjaEdTZUJU9]{Fallen Shock Troop} that appear within Close range of the Usurper to assist their divine siege. Immediately spotlight the Shock Troops to use a “Group Attack” action.

Which High Fallen do these troops serve? Which god’s fl esh do they wish to feast upon?

", "resource": null, "actions": { - "okcqGrI4rdghugUi": { - "type": "summon", - "_id": "okcqGrI4rdghugUi", + "qIQTEO5t72xFtKYI": { + "type": "effect", + "_id": "qIQTEO5t72xFtKYI", "systemPath": "actions", - "baseAction": false, - "description": "", + "description": "

Spend 2 Fear to summon [[/r 1d4+2]] @UUID[Compendium.daggerheart.adversaries.Actor.OsLG2BjaEdTZUJU9]{Fallen Shock Troop} that appear within Close range of the Usurper to assist their divine siege. Immediately spotlight the Shock Troops to use a “Group Attack” action.

Which High Fallen do these troops serve? Which god’s fl esh do they wish to feast upon?

", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", - "cost": [], + "cost": [ + { + "scalable": false, + "key": "fear", + "value": 2, + "step": null + } + ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "self", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.OsLG2BjaEdTZUJU9", - "count": "1d4+2" - } - ], "name": "Spend Fear", + "img": "icons/magic/unholy/orb-hands-pink.webp", "range": "" } }, diff --git a/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json b/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json index 9ba6a918..8e7cf1c8 100644 --- a/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json +++ b/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json @@ -246,35 +246,7 @@ "system": { "description": "

When the PCs enter the raptors’ hunting grounds, two @UUID[Compendium.daggerheart.adversaries.Actor.OMQ0v6PE8s1mSU0K]{Giant Eagles} appear at Very Far range of a chosen PC, identifying the PCs as likely prey.

How long has it been since the eagles last found prey? Do they have eggs in their nest or unfl edged young?

", "resource": null, - "actions": { - "88MyOC3IRcct6VLk": { - "type": "summon", - "_id": "88MyOC3IRcct6VLk", - "systemPath": "actions", - "baseAction": false, - "description": "", - "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, - "actionType": "action", - "cost": [], - "uses": { - "value": null, - "max": "", - "recovery": null, - "consumeOnSuccess": false - }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.OMQ0v6PE8s1mSU0K", - "count": "2" - } - ], - "name": "Summon", - "range": "" - } - }, + "actions": {}, "originItemType": null, "originId": null, "featureForm": "reaction" diff --git a/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json b/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json index 6c34c296..5c973fa6 100644 --- a/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json +++ b/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json @@ -360,40 +360,33 @@ "description": "

Spend a Fear to summon a @UUID[Compendium.daggerheart.adversaries.Actor.8KWVLWXFhlY2kYx0]{Glass Snake} within Close range of a chosen PC. The Snake appears in or near the river and immediately takes the spotlight to use their “Spinning Serpent” action.

What treasures does the beast have in their burrow? What travelers have already fallen victim to this predator?

", "resource": null, "actions": { - "uY9HMKE4Q5g7bRKg": { - "type": "summon", - "_id": "uY9HMKE4Q5g7bRKg", + "Mnp0Yzc7EPVXm8So": { + "type": "effect", + "_id": "Mnp0Yzc7EPVXm8So", "systemPath": "actions", - "baseAction": false, - "description": "", + "description": "

Spend a Fear to summon a @UUID[Compendium.daggerheart.adversaries.Actor.8KWVLWXFhlY2kYx0]{Glass Snake} within Close range of a chosen PC. The Snake appears in or near the river and immediately takes the spotlight to use their “Spinning Serpent” action.

What treasures does the beast have in their burrow? What travelers have already fallen victim to this predator?

", "chatDisplay": true, - "originItem": { - "type": "itemCollection" - }, "actionType": "action", "cost": [ { "scalable": false, "key": "fear", "value": 1, - "itemId": null, - "step": null, - "consumeOnSuccess": false + "step": null } ], "uses": { "value": null, "max": "", - "recovery": null, - "consumeOnSuccess": false + "recovery": null + }, + "effects": [], + "target": { + "type": "self", + "amount": null }, - "summon": [ - { - "actorUUID": "Compendium.daggerheart.adversaries.Actor.8KWVLWXFhlY2kYx0", - "count": "1" - } - ], "name": "Spend Fear", + "img": "icons/creatures/reptiles/snake-fangs-bite-green-yellow.webp", "range": "" } }, diff --git a/styles/less/global/dialog.less b/styles/less/global/dialog.less index a3400700..8c532c2b 100644 --- a/styles/less/global/dialog.less +++ b/styles/less/global/dialog.less @@ -67,35 +67,6 @@ } } - .dialog-selection-container { - display: flex; - gap: 10px; - flex-wrap: wrap; - - .selection-chip { - display: flex; - align-items: center; - border-radius: 5px; - width: fit-content; - gap: 5px; - cursor: pointer; - padding: 5px; - background: light-dark(@dark-blue-10, @golden-10); - color: light-dark(@dark-blue, @golden); - - .label { - font-style: normal; - font-weight: 400; - font-size: var(--font-size-14); - line-height: 17px; - } - - &.selected { - background: light-dark(@dark-blue-40, @golden-40); - } - } - } - .standard-form { font-family: @font-body; } diff --git a/styles/less/global/global.less b/styles/less/global/global.less index 6c63fe7a..6cc63c2a 100644 --- a/styles/less/global/global.less +++ b/styles/less/global/global.less @@ -51,14 +51,3 @@ } } } - -/* TODO: Remove me when this issue is resolved https://github.com/foundryvtt/foundryvtt/issues/13734 */ -body.theme-dark, -.themed.theme-dark { - color-scheme: dark; -} - -body.theme-light, -.themed.theme-light { - color-scheme: light; -} diff --git a/styles/less/global/index.less b/styles/less/global/index.less index 216dc9f4..f51140de 100644 --- a/styles/less/global/index.less +++ b/styles/less/global/index.less @@ -10,6 +10,7 @@ @import './tab-description.less'; @import './tab-features.less'; @import './tab-effects.less'; +@import './tab-settings.less'; @import './item-header.less'; @import './feature-section.less'; @import './inventory-item.less'; diff --git a/styles/less/global/item-header.less b/styles/less/global/item-header.less index f47ca7dc..073762e0 100755 --- a/styles/less/global/item-header.less +++ b/styles/less/global/item-header.less @@ -160,7 +160,7 @@ .item-description { display: flex; flex-direction: column; - gap: 7px; + gap: 10px; } h3 { diff --git a/styles/less/global/tab-settings.less b/styles/less/global/tab-settings.less new file mode 100644 index 00000000..3d5248be --- /dev/null +++ b/styles/less/global/tab-settings.less @@ -0,0 +1,8 @@ +@import '../utils/colors.less'; +@import '../utils/fonts.less'; + +.sheet.daggerheart.dh-style { + .tab.settings { + margin-bottom: 36px; + } +} diff --git a/styles/less/sheets/actions/actions.less b/styles/less/sheets/actions/actions.less deleted file mode 100644 index 07c99491..00000000 --- a/styles/less/sheets/actions/actions.less +++ /dev/null @@ -1,104 +0,0 @@ -.application.daggerheart.dh-style.action-config { - .actor-summon-items { - width: 100%; - display: flex; - flex-direction: column; - gap: 10px; - - .actor-summon-line { - display: flex; - align-items: center; - gap: 5px; - border-radius: 3px; - - .actor-summon-name { - flex: 2; - display: flex; - align-items: center; - gap: 5px; - - img { - height: 40px; - } - } - - .actor-summon-controls { - flex: 1; - display: flex; - align-items: center; - gap: 5px; - - .controls { - display: flex; - gap: 5px; - } - } - } - - .summon-dragger { - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - height: 40px; - margin-top: 10px; - border: 1px dashed light-dark(@dark-blue-50, @beige-50); - border-radius: 3px; - color: light-dark(@dark-blue-50, @beige-50); - } - } - - .trigger-data { - width: 100%; - display: flex; - justify-content: space-between; - gap: 8px; - - .trigger-data-inner { - flex: 1; - display: flex; - flex-direction: column; - - select { - flex: 1; - } - - .select-section { - flex: 1; - display: flex; - gap: 8px; - } - - .programmer-section { - flex: 3; - display: flex; - flex-direction: column; - - .hint-section { - display: flex; - gap: 4px; - - .hint { - flex: 1; - flex-wrap: wrap; - } - } - } - } - - .expand-trigger { - font-size: 18px; - } - } - - .code-mirror-wrapper { - width: 100%; - height: 0; - min-height: 0; - transition: height 0.1s ease-in-out; - - &.revealed { - height: 300px; - } - } -} diff --git a/styles/less/sheets/actors/character/header.less b/styles/less/sheets/actors/character/header.less index 593f1b73..93d6c6be 100644 --- a/styles/less/sheets/actors/character/header.less +++ b/styles/less/sheets/actors/character/header.less @@ -148,7 +148,7 @@ padding: 0 0.375rem; } - button[data-action='viewParty'] { + button[data-action=viewParty] { margin-right: 6px; } } diff --git a/styles/less/sheets/index.less b/styles/less/sheets/index.less index 216cda33..1de1b055 100644 --- a/styles/less/sheets/index.less +++ b/styles/less/sheets/index.less @@ -1,5 +1,3 @@ -@import './actions/actions.less'; - @import './actors/actor-sheet-shared.less'; @import './actors/adversary/actions.less'; @@ -39,5 +37,3 @@ @import './items/feature.less'; @import './items/heritage.less'; @import './items/item-sheet-shared.less'; - -@import './actions/actions.less'; diff --git a/styles/less/ui/chat/action.less b/styles/less/ui/chat/action.less index 8d309cfe..817b0acd 100644 --- a/styles/less/ui/chat/action.less +++ b/styles/less/ui/chat/action.less @@ -98,61 +98,6 @@ .description { padding: 8px; - - .summons-header { - font-size: var(--font-size-14); - text-align: center; - display: flex; - align-items: center; - justify-content: center; - - span { - width: 100%; - } - - &:before, - &:after { - content: ' '; - height: 1px; - width: 100%; - } - - &:before { - background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, light-dark(@dark-blue, @golden) 100%); - } - - &:after { - background: linear-gradient(90deg, light-dark(@dark-blue, @golden) 0%, rgba(0, 0, 0, 0) 100%); - } - } - - .summons-container { - display: flex; - flex-direction: column; - gap: 4px; - - .summon-container { - display: flex; - align-items: center; - justify-content: space-between; - - .summon-label-container { - flex: 1; - display: flex; - align-items: center; - gap: 4px; - - img { - height: 32px; - } - - label { - display: flex; - flex-wrap: wrap; - } - } - } - } } .ability-card-footer { diff --git a/styles/less/ui/chat/downtime.less b/styles/less/ui/chat/downtime.less index 2875ea10..a99bde33 100644 --- a/styles/less/ui/chat/downtime.less +++ b/styles/less/ui/chat/downtime.less @@ -103,7 +103,7 @@ width: 100%; .action-use-target { - display: flex; + display:flex; align-items: center; justify-content: space-between; gap: 4px; @@ -127,6 +127,7 @@ font-weight: 600; height: 40px; } + } } } diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less index 25f51d0f..7f9ada25 100644 --- a/styles/less/ui/index.less +++ b/styles/less/ui/index.less @@ -33,5 +33,3 @@ @import './scene-config/scene-config.less'; @import './effects-display/sheet.less'; - -@import './scene-navigation/scene-navigation.less'; diff --git a/styles/less/ui/scene-config/scene-config.less b/styles/less/ui/scene-config/scene-config.less index 664e7526..fb36dd33 100644 --- a/styles/less/ui/scene-config/scene-config.less +++ b/styles/less/ui/scene-config/scene-config.less @@ -37,63 +37,4 @@ .helper-text { font-style: italic; } - - .scene-environments { - display: flex; - flex-direction: column; - gap: 8px; - - .scene-environment { - display: flex; - align-items: center; - gap: 8px; - - .scene-environment-inner { - display: flex; - align-items: center; - gap: 16px; - flex: 1; - - img { - height: 36px; - } - - h5 { - margin: 0; - } - - .tags { - display: flex; - gap: 4px; - padding-bottom: 0; - - .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: var(--font-size-12); - font: @font-body; - - background: light-dark(@dark-15, @beige-15); - border: 1px solid light-dark(@dark, @beige); - border-radius: 3px; - } - - .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: var(--font-size-12); - } - } - } - - .remove-icon { - font-size: 16px; - } - } - } } diff --git a/styles/less/ui/scene-navigation/scene-navigation.less b/styles/less/ui/scene-navigation/scene-navigation.less deleted file mode 100644 index 6b97ddec..00000000 --- a/styles/less/ui/scene-navigation/scene-navigation.less +++ /dev/null @@ -1,36 +0,0 @@ -#ui-left #ui-left-column-2 { - flex: 0 0 230px; - - .scene-navigation { - .scene-wrapper { - display: flex; - gap: 2px; - height: var(--control-size); - width: 100%; - - .scene-environment { - padding: 0; - - img { - border-radius: 4px; - } - } - } - - .scene { - justify-content: center; - align-content: center; - background: var(--control-bg-color); - border: 1px solid var(--control-border-color); - border-radius: 4px; - color: var(--control-icon-color); - pointer-events: all; - transition: - border 0.25s, - color 0.25s; - text-shadow: none; - width: 200px; - max-width: 200px; - } - } -} diff --git a/styles/less/ui/sidebar/tabs.less b/styles/less/ui/sidebar/tabs.less index c620ff91..e9de2924 100644 --- a/styles/less/ui/sidebar/tabs.less +++ b/styles/less/ui/sidebar/tabs.less @@ -1,4 +1,4 @@ -.theme-light#interface #ui-right #sidebar { +.theme-light #interface #ui-right #sidebar { menu li button img { filter: @grey-filter; } diff --git a/styles/less/ux/tooltip/tooltip.less b/styles/less/ux/tooltip/tooltip.less index 0f632772..bfe0c01f 100644 --- a/styles/less/ux/tooltip/tooltip.less +++ b/styles/less/ux/tooltip/tooltip.less @@ -11,7 +11,7 @@ aside[role='tooltip']:has(div.daggerheart.dh-style.tooltip.card-style) { width: 18rem; background-image: url('../assets/parchments/dh-parchment-dark.png'); outline: 1px solid light-dark(@dark-80, @beige-80); - box-shadow: 0 0 25px rgba(0, 0, 0, 0.8); + box-shadow: 0 0 25px rgba(0, 0, 0, 0.80); .tooltip-title { font-size: var(--font-size-20); @@ -235,6 +235,7 @@ aside[role='tooltip'].locked-tooltip:has(div.daggerheart.dh-style.tooltip.card-s .theme-light aside[role='tooltip'].locked-tooltip:has(div.daggerheart.dh-style.tooltip) { box-shadow: 0 0 25px @dark-blue-90; outline: 1px solid light-dark(@dark-blue, @golden); + } #tooltip, diff --git a/system.json b/system.json index 43f82f06..c5fd61f2 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "1.5.0", + "version": "1.4.5", "compatibility": { "minimum": "13.346", "verified": "13.351", diff --git a/templates/actionTypes/summon.hbs b/templates/actionTypes/summon.hbs deleted file mode 100644 index 429977d9..00000000 --- a/templates/actionTypes/summon.hbs +++ /dev/null @@ -1,50 +0,0 @@ -
- - {{localize "DAGGERHEART.ACTIONS.TYPES.summon.name"}} - - - -
\ No newline at end of file diff --git a/templates/dialogs/dice-roll/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs index c0dbae62..ba542666 100644 --- a/templates/dialogs/dice-roll/damageSelection.hbs +++ b/templates/dialogs/dice-roll/damageSelection.hbs @@ -2,20 +2,6 @@

{{title}}

- - {{#if hasSelectedEffects}} -
- {{localize "DAGGERHEART.GENERAL.Effect.plural"}} - - {{#each selectedEffects as |effect id|}} -
- - {{effect.name}} -
- {{/each}} -
- {{/if}} - {{#each @root.formula}}
{{localize "DAGGERHEART.GENERAL.formula"}}: {{roll.formula}} diff --git a/templates/dialogs/dice-roll/rollSelection.hbs b/templates/dialogs/dice-roll/rollSelection.hbs index e60f4683..c7a9b0f9 100644 --- a/templates/dialogs/dice-roll/rollSelection.hbs +++ b/templates/dialogs/dice-roll/rollSelection.hbs @@ -70,19 +70,6 @@ {{/if}}
- {{#if hasSelectedEffects}} -
- {{localize "DAGGERHEART.GENERAL.Effect.plural"}} - - {{#each selectedEffects as |effect id|}} -
- - {{effect.name}} -
- {{/each}} -
- {{/if}} - {{#if experiences.length}}
{{localize "DAGGERHEART.GENERAL.experience.plural"}} diff --git a/templates/scene/dh-config.hbs b/templates/scene/dh-config.hbs index 017613ee..1f7dcd81 100644 --- a/templates/scene/dh-config.hbs +++ b/templates/scene/dh-config.hbs @@ -21,39 +21,4 @@ {{localize "DAGGERHEART.SETTINGS.Scene.disabledText"}} {{/if}}
- -
- - {{localize "DAGGERHEART.SETTINGS.Scene.sceneEnvironments"}} - - -
- {{#each data.sceneEnvironments as |environment index|}} -
- {{#if environment}} -
- -
{{environment.name}}
-
-
- - {{localize (concat 'DAGGERHEART.GENERAL.Tiers.' environment.system.tier)}} - -
- {{#if environment.system.type}} -
- - {{localize (concat 'DAGGERHEART.CONFIG.EnvironmentType.' environment.system.type '.label')}} - -
- {{/if}} -
-
- {{/if}} - -
- {{/each}} - {{localize "DAGGERHEART.SETTINGS.Scene.dragEnvironmentHere"}} -
-
\ No newline at end of file diff --git a/templates/settings/automation-settings/roll.hbs b/templates/settings/automation-settings/roll.hbs index dc65f8ae..5769bf61 100644 --- a/templates/settings/automation-settings/roll.hbs +++ b/templates/settings/automation-settings/roll.hbs @@ -19,15 +19,4 @@ {{/each}} - -
- - {{localize "DAGGERHEART.SETTINGS.Automation.trigger.title"}} - - -
- {{formGroup settingFields.schema.fields.triggers.fields.enabled value=settingFields.triggers.enabled localize=true}} -

{{localize "DAGGERHEART.SETTINGS.Automation.FIELDS.triggers.enabled.hint"}}

-
-
\ No newline at end of file diff --git a/templates/sheets-settings/action-settings/configuration.hbs b/templates/sheets-settings/action-settings/configuration.hbs index 5bd29e39..51b2a72b 100644 --- a/templates/sheets-settings/action-settings/configuration.hbs +++ b/templates/sheets-settings/action-settings/configuration.hbs @@ -2,7 +2,7 @@ class="tab {{this.tabs.config.cssClass}}" data-group="primary" data-tab="config" -> +> {{> 'systems/daggerheart/templates/actionTypes/uses.hbs' fields=fields.uses.fields source=source.uses}} {{> 'systems/daggerheart/templates/actionTypes/cost.hbs' fields=fields.cost.element.fields source=source.cost costOptions=costOptions}} {{> 'systems/daggerheart/templates/actionTypes/range-target.hbs' fields=(object range=fields.range target=fields.target.fields) source=(object target=source.target range=source.range)}} diff --git a/templates/sheets-settings/action-settings/effect.hbs b/templates/sheets-settings/action-settings/effect.hbs index e94f4328..bf2f3aa1 100644 --- a/templates/sheets-settings/action-settings/effect.hbs +++ b/templates/sheets-settings/action-settings/effect.hbs @@ -9,6 +9,5 @@ {{#if fields.macro}}{{> 'systems/daggerheart/templates/actionTypes/macro.hbs' fields=fields.macro source=source.macro}}{{/if}} {{#if fields.effects}}{{> 'systems/daggerheart/templates/actionTypes/effect.hbs' fields=fields.effects.element.fields source=source.effects}}{{/if}} {{#if fields.beastform}}{{> 'systems/daggerheart/templates/actionTypes/beastform.hbs' fields=fields.beastform.fields source=source.beastform}}{{/if}} - {{#if fields.summon}}{{> 'systems/daggerheart/templates/actionTypes/summon.hbs' fields=fields.summon.element.fields source=source.summon}}{{/if}} {{#if fields.countdown}}{{> 'systems/daggerheart/templates/actionTypes/countdown.hbs' fields=fields.countdown.element.fields source=source.countdown}}{{/if}} \ No newline at end of file diff --git a/templates/sheets-settings/action-settings/trigger.hbs b/templates/sheets-settings/action-settings/trigger.hbs deleted file mode 100644 index b048461e..00000000 --- a/templates/sheets-settings/action-settings/trigger.hbs +++ /dev/null @@ -1,37 +0,0 @@ -
- - - {{#each @root.triggers as |trigger index|}} -
- - -
-
-
- {{formGroup @root.fields.triggers.element.fields.trigger value=trigger.trigger name=(concat "triggers." index ".trigger") blank=false localize=true}} - {{#if trigger.usesActor}}{{formGroup @root.fields.triggers.element.fields.triggeringActorType value=trigger.triggeringActorType name=(concat "triggers." index ".triggeringActorType") blank=false localize=true}}{{/if}} -
-
-
- {{localize "Context: "}} - {{localize trigger.hint}} -
-
- {{localize "Return: "}} - {{localize trigger.returns}} -
-
-
- -
- -
- {{formInput @root.fields.triggers.element.fields.command value=trigger.command elementType="code-mirror" name=(concat "triggers." index ".command") aria=(object label=(localize "Test")) }} -
-
- {{/each}} -
\ No newline at end of file diff --git a/templates/sheets/items/armor/description.hbs b/templates/sheets/items/armor/description.hbs deleted file mode 100644 index c5a9924e..00000000 --- a/templates/sheets/items/armor/description.hbs +++ /dev/null @@ -1,5 +0,0 @@ -
- {{#each features as | feature |}} -
{{localize feature.label}}: {{{localize feature.description}}}
- {{/each}} -
\ No newline at end of file diff --git a/templates/sheets/items/beastform/settings.hbs b/templates/sheets/items/beastform/settings.hbs index 82065ad3..844b9d61 100644 --- a/templates/sheets/items/beastform/settings.hbs +++ b/templates/sheets/items/beastform/settings.hbs @@ -47,9 +47,6 @@ disabled=dimensionsDisabled }} -
- {{formGroup systemFields.tokenSize.fields.scale value=source.system.tokenSize.scale localize=true }} -
{{else}} {{localize "DAGGERHEART.ITEMS.Beastform.evolvedTokenHint"}} {{/unless}} diff --git a/templates/sheets/items/domainCard/settings.hbs b/templates/sheets/items/domainCard/settings.hbs index f5781606..f3d05a2a 100644 --- a/templates/sheets/items/domainCard/settings.hbs +++ b/templates/sheets/items/domainCard/settings.hbs @@ -14,12 +14,6 @@ {{formField systemFields.level value=source.system.level data-dtype="Number"}} {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}} {{formField systemFields.recallCost value=source.system.recallCost data-dtype="Number"}} - {{localize "DAGGERHEART.ITEMS.DomainCard.vaultActive"}} - {{formField systemFields.vaultActive value=source.system.vaultActive}} - {{localize "DAGGERHEART.ITEMS.DomainCard.loadoutIgnore"}} - {{formField systemFields.loadoutIgnore value=source.system.loadoutIgnore}} - {{localize "DAGGERHEART.ITEMS.DomainCard.domainTouched"}} - {{formField systemFields.domainTouched value=source.system.domainTouched placeholder=0 }} {{> "systems/daggerheart/templates/sheets/global/partials/resource-section/resource-section.hbs" }} diff --git a/templates/sheets/items/weapon/description.hbs b/templates/sheets/items/weapon/description.hbs deleted file mode 100644 index c5a9924e..00000000 --- a/templates/sheets/items/weapon/description.hbs +++ /dev/null @@ -1,5 +0,0 @@ -
- {{#each features as | feature |}} -
{{localize feature.label}}: {{{localize feature.description}}}
- {{/each}} -
\ No newline at end of file diff --git a/templates/ui/chat/action.hbs b/templates/ui/chat/action.hbs index 65bb0762..6b505164 100644 --- a/templates/ui/chat/action.hbs +++ b/templates/ui/chat/action.hbs @@ -8,22 +8,6 @@ -
- {{{description}}} - {{#if action.summon}} -
{{localize "DAGGERHEART.GENERAL.summon.plural"}}
-
- {{#each action.summon}} -
-
- - -
- # {{this.rolledCount}} -
- {{/each}} -
- {{/if}} -
+
{{{description}}}
\ No newline at end of file diff --git a/templates/ui/itemBrowser/itemContainer.hbs b/templates/ui/itemBrowser/itemContainer.hbs index 0040a692..f6aefa6b 100644 --- a/templates/ui/itemBrowser/itemContainer.hbs +++ b/templates/ui/itemBrowser/itemContainer.hbs @@ -10,7 +10,7 @@
- {{{system.enrichedDescription}}} + {{{system.description}}}
{{/each}} \ No newline at end of file diff --git a/templates/ui/sceneNavigation/scene-navigation.hbs b/templates/ui/sceneNavigation/scene-navigation.hbs deleted file mode 100644 index 41e9e3e8..00000000 --- a/templates/ui/sceneNavigation/scene-navigation.hbs +++ /dev/null @@ -1,36 +0,0 @@ -