diff --git a/lang/en.json b/lang/en.json index 817fc355..b4b1410e 100755 --- a/lang/en.json +++ b/lang/en.json @@ -3220,8 +3220,7 @@ "domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used", "knowTheTide": "Know The Tide gained a token", "lackingItemTransferPermission": "User {user} lacks owner permission needed to transfer items to {target}", - "noTokenTargeted": "No token is targeted", - "behaviorRegionRequiresGM": "Creating a Region with an attached Behavior requires an online GM" + "noTokenTargeted": "No token is targeted" }, "Progress": { "migrationLabel": "Performing system migration. Please wait and do not close Foundry." diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 367540bf..989e4625 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -259,9 +259,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV const resetValue = increasing ? 0 : feature.system.resource.max - ? new Roll( - Roll.replaceFormulaData(feature.system.resource.max, this.actor.getRollData()) - ).evaluateSync().total + ? new Roll(Roll.replaceFormulaData(feature.system.resource.max, this.actor)).evaluateSync().total : 0; await feature.update({ 'system.resource.value': resetValue }); diff --git a/module/applications/dialogs/groupRollDialog.mjs b/module/applications/dialogs/groupRollDialog.mjs index bd45fe91..48110e4c 100644 --- a/module/applications/dialogs/groupRollDialog.mjs +++ b/module/applications/dialogs/groupRollDialog.mjs @@ -1,5 +1,5 @@ import { ResourceUpdateMap } from '../../data/action/baseAction.mjs'; -import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; import Party from '../sheets/actors/party.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -242,7 +242,7 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat }); }; - await emitGMUpdate( + await emitAsGM( GMUpdateEvent.UpdateDocument, gmUpdate, update, diff --git a/module/applications/dialogs/tagTeamDialog.mjs b/module/applications/dialogs/tagTeamDialog.mjs index e06cbe48..325cc445 100644 --- a/module/applications/dialogs/tagTeamDialog.mjs +++ b/module/applications/dialogs/tagTeamDialog.mjs @@ -1,6 +1,6 @@ import { MemberData } from '../../data/tagTeamData.mjs'; import { getCritDamageBonus } from '../../helpers/utils.mjs'; -import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; import Party from '../sheets/actors/party.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -259,7 +259,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio }); }; - await emitGMUpdate( + await emitAsGM( GMUpdateEvent.UpdateDocument, gmUpdate, update, diff --git a/module/applications/scene/sceneConfigSettings.mjs b/module/applications/scene/sceneConfigSettings.mjs index 0a999506..ce312a45 100644 --- a/module/applications/scene/sceneConfigSettings.mjs +++ b/module/applications/scene/sceneConfigSettings.mjs @@ -120,6 +120,12 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S foundry.utils.fromUuidSync(x) ); + for (const key of Object.keys(this.document._source.flags.daggerheart?.sceneEnvironments ?? {})) { + if (!submitData.flags.daggerheart.sceneEnvironments[key]) { + submitData.flags.daggerheart.sceneEnvironments[key] = _del; + } + } + super._processSubmitData(event, form, submitData, options); } } diff --git a/module/applications/sheets-configs/adversary-settings.mjs b/module/applications/sheets-configs/adversary-settings.mjs index 57405675..6593f23d 100644 --- a/module/applications/sheets-configs/adversary-settings.mjs +++ b/module/applications/sheets-configs/adversary-settings.mjs @@ -110,7 +110,6 @@ export default class DHAdversarySettings extends DHBaseActorSettings { } async _onDrop(event) { - event.stopPropagation(); const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await fromUuid(data.uuid); diff --git a/module/applications/sheets-configs/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs index 6d74f9c6..bc0efef2 100644 --- a/module/applications/sheets-configs/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -121,7 +121,6 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { } async _onDrop(event) { - event.stopPropagation(); const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await fromUuid(data.uuid); if (data.fromInternal && item?.parent?.uuid === this.actor.uuid) return; @@ -139,4 +138,8 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { this.render(); } } + + async _onDropItem(event, item) { + console.log(item); + } } diff --git a/module/applications/ui/countdownEdit.mjs b/module/applications/ui/countdownEdit.mjs index b418107c..8bb9fc1d 100644 --- a/module/applications/ui/countdownEdit.mjs +++ b/module/applications/ui/countdownEdit.mjs @@ -1,6 +1,6 @@ import { DhCountdown } from '../../data/countdowns.mjs'; import { waitForDiceSoNice } from '../../helpers/utils.mjs'; -import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -114,7 +114,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio } await this.data.updateSource(update); - await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, this.gmSetSetting.bind(this.data), this.data, null, { + await emitAsGM(GMUpdateEvent.UpdateCountdowns, this.gmSetSetting.bind(this.data), this.data, null, { refreshType: RefreshType.Countdown }); diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index 052564cc..79a59a07 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -1,5 +1,5 @@ import { waitForDiceSoNice } from '../../helpers/utils.mjs'; -import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -204,7 +204,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application start: newMax } }); - await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { + await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { refreshType: RefreshType.Countdown }); } @@ -218,7 +218,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application ? Math.min(countdown.progress.current + 1, countdown.progress.start) : Math.max(countdown.progress.current - 1, 0); await settings.updateSource({ [`countdowns.${target.id}.progress.current`]: newCurrent }); - await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { + await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { refreshType: RefreshType.Countdown }); } @@ -277,7 +277,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application return acc; }, {}) }; - await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { + await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { refreshType: RefreshType.Countdown }); } diff --git a/module/applications/ui/fearTracker.mjs b/module/applications/ui/fearTracker.mjs index 8c247f79..4e5e1132 100644 --- a/module/applications/ui/fearTracker.mjs +++ b/module/applications/ui/fearTracker.mjs @@ -1,4 +1,4 @@ -import { emitGMUpdate, GMUpdateEvent } from '../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; @@ -104,7 +104,7 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV } async updateFear(value) { - return emitGMUpdate( + return emitAsGM( GMUpdateEvent.UpdateFear, game.settings.set.bind(game.settings, CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear), value diff --git a/module/applications/ui/sceneNavigation.mjs b/module/applications/ui/sceneNavigation.mjs index 982063e7..a0005fc7 100644 --- a/module/applications/ui/sceneNavigation.mjs +++ b/module/applications/ui/sceneNavigation.mjs @@ -1,4 +1,4 @@ -import { emitGMUpdate, GMUpdateEvent } from '../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent } from '../../systemRegistration/socket.mjs'; export default class DhSceneNavigation extends foundry.applications.ui.SceneNavigation { /** @inheritdoc */ @@ -68,7 +68,7 @@ export default class DhSceneNavigation extends foundry.applications.ui.SceneNavi 1 )[0]; newEnvironments.unshift(newFirst); - emitGMUpdate( + emitAsGM( GMUpdateEvent.UpdateDocument, scene.update.bind(scene), { 'flags.daggerheart.sceneEnvironments': newEnvironments }, diff --git a/module/canvas/placeables/regionLayer.mjs b/module/canvas/placeables/regionLayer.mjs index 684fdd5e..c53cf782 100644 --- a/module/canvas/placeables/regionLayer.mjs +++ b/module/canvas/placeables/regionLayer.mjs @@ -57,14 +57,14 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { } async placeRegion(data, options = {}) { - const preConfirm = data => { - const shape = data.document.shapes[0]; + const preConfirm = ({ _event, document, _create, _options }) => { + const shape = document.shapes[0]; const isEmanation = shape.type === 'emanation'; if (isEmanation) { const token = this.#findTokenInBounds(shape.base.origin); - if (!token) return options.preConfirm?.(data) ?? true; + if (!token) return options.preConfirm?.() ?? true; const shapeData = shape.toObject(); - data.document.updateSource({ + document.updateSource({ shapes: [ { ...shapeData, @@ -80,10 +80,10 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer { }); } - return options?.preConfirm?.(data) ?? true; + return options?.preConfirm?.() ?? true; }; - return await super.placeRegion(data, { ...options, preConfirm }); + super.placeRegion(data, { ...options, preConfirm }); } /** Searches for token at origin point, returning null if there are no tokens or multiple overlapping tokens */ diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index a1cd13e8..d42f2f64 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -836,10 +836,10 @@ export default class DhCharacter extends DhCreature { /* Scars can alter the amount of current hope */ if (changes.system?.scars) { - const diff = this.scars - changes.system.scars; - const newHopeMax = this.resources.hope.max + diff; - const newHopeValue = Math.min(newHopeMax, this.resources.hope.value); - if (newHopeValue != this.resources.hope.value) { + const diff = this.system.scars - changes.system.scars; + const newHopeMax = this.system.resources.hope.max + diff; + const newHopeValue = Math.min(newHopeMax, this.system.resources.hope.value); + if (newHopeValue != this.system.resources.hope.value) { if (!changes.system.resources.hope) changes.system.resources.hope = { value: 0 }; changes.system.resources.hope = { diff --git a/module/data/fields/action/countdownField.mjs b/module/data/fields/action/countdownField.mjs index 990f8ef1..719ca749 100644 --- a/module/data/fields/action/countdownField.mjs +++ b/module/data/fields/action/countdownField.mjs @@ -1,4 +1,4 @@ -import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../../systemRegistration/socket.mjs'; const fields = foundry.data.fields; @@ -78,7 +78,7 @@ export default class CountdownField extends fields.ArrayField { ); } - await emitGMUpdate( + await emitAsGM( GMUpdateEvent.UpdateCountdowns, async () => { const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); diff --git a/module/data/fields/action/effectsField.mjs b/module/data/fields/action/effectsField.mjs index 1053e51d..9a4ffc31 100644 --- a/module/data/fields/action/effectsField.mjs +++ b/module/data/fields/action/effectsField.mjs @@ -1,4 +1,4 @@ -import { emitGMUpdate, GMUpdateEvent } from '../../../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent } from '../../../systemRegistration/socket.mjs'; const fields = foundry.data.fields; @@ -34,7 +34,7 @@ export default class EffectsField extends fields.ArrayField { } if (EffectsField.getAutomation() || force) { targets ??= (message.system?.targets ?? config.targets).filter(t => !config.hasRoll || t.hit); - await emitGMUpdate(GMUpdateEvent.UpdateEffect, EffectsField.applyEffects.bind(this), targets, this.uuid); + await emitAsGM(GMUpdateEvent.UpdateEffect, EffectsField.applyEffects.bind(this), targets, this.uuid); // EffectsField.applyEffects.call(this, config.targets.filter(t => !config.hasRoll || t.hit)); } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 5df87b6c..eb57a186 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -1,4 +1,4 @@ -import { emitGMUpdate, GMUpdateEvent } from '../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs'; import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; import { createScrollText, damageKeyToNumber, getDamageKey, createShallowProxy } from '../helpers/utils.mjs'; @@ -827,7 +827,7 @@ export default class DhpActor extends Actor { const u = updates[key]; if (key === 'items') { Object.values(u).forEach(async item => { - await emitGMUpdate( + await emitAsGM( GMUpdateEvent.UpdateDocument, item.target.update.bind(item.target), item.resources, @@ -836,7 +836,7 @@ export default class DhpActor extends Actor { }); } else { if (Object.keys(u.resources).length > 0) { - await emitGMUpdate( + await emitAsGM( GMUpdateEvent.UpdateDocument, u.target.update.bind(u.target), u.resources, diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 78bab016..2e20fb87 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -1,4 +1,4 @@ -import { emitGMUpdate, emitGMCreate, GMUpdateEvent } from '../systemRegistration/socket.mjs'; +import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs'; export default class DhpChatMessage extends foundry.documents.ChatMessage { targetHook = null; @@ -214,7 +214,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { const action = this.system.action; if (!action || !action?.hasSave) return; game.system.api.fields.ActionFields.SaveField.rollSave.call(action, token.actor, event).then(result => - emitGMUpdate( + emitAsGM( GMUpdateEvent.UpdateSaveMessage, game.system.api.fields.ActionFields.SaveField.updateSaveMessage.bind( action, @@ -259,47 +259,27 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { const { shape: type, size: range } = selectedArea; const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range }); - const scene = game.scenes.get(game.user.viewedScene); - const level = scene.levels.find(x => x.isView); - - const regionData = { - name: selectedArea.name, - levels: level ? [level.id] : [], - shapes: [shapeData], - restriction: { enabled: false, type: 'move', priority: 0 }, - behaviors: - effects.length > 0 - ? [ - { - name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'), - type: 'applyActiveEffect', - system: { - effects: effects - } - } - ] - : [], - displayMeasurements: true, - locked: false, - ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE }, - visibility: CONST.REGION_VISIBILITY.ALWAYS - }; - const placeRegion = data => { - canvas.regions.placeRegion(data, { create: true }); - }; - - // Regions with effects must be placed by the GM - if (effects.length > 0 && !game.user.isGM) { - if (!game.users.activeGM) - return ui.notifications.error( - game.i18n.localize('DAGGERHEART.UI.Notifications.behaviorRegionRequiresGM') - ); - - const region = await canvas.regions.placeRegion(regionData, { create: false }); - emitGMCreate('Region', placeRegion, region, scene.id); - } else { - placeRegion(regionData); - } + await canvas.regions.placeRegion( + { + name: selectedArea.name, + shapes: [shapeData], + restriction: { enabled: false, type: 'move', priority: 0 }, + behaviors: [ + { + name: game.i18n.localize('TYPES.RegionBehavior.applyActiveEffect'), + type: 'applyActiveEffect', + system: { + effects: effects + } + } + ], + displayMeasurements: true, + locked: false, + ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE }, + visibility: CONST.REGION_VISIBILITY.ALWAYS + }, + { create: true } + ); }; if (this.system.action.areas.length === 1) createArea(this.system.action.areas[0]); diff --git a/module/systemRegistration/socket.mjs b/module/systemRegistration/socket.mjs index de9bf00c..8fed346d 100644 --- a/module/systemRegistration/socket.mjs +++ b/module/systemRegistration/socket.mjs @@ -6,9 +6,6 @@ export function handleSocketEvent({ action = null, data = {} } = {}) { case socketEvent.GMUpdate: Hooks.callAll(socketEvent.GMUpdate, data); break; - case socketEvent.GMCreate: - Hooks.callAll(socketEvent.GMCreate, data); - break; case socketEvent.DhpFearUpdate: Hooks.callAll(socketEvent.DhpFearUpdate); break; @@ -28,7 +25,6 @@ export function handleSocketEvent({ action = null, data = {} } = {}) { export const socketEvent = { GMUpdate: 'DhGMUpdate', - GMCreate: 'DhGMCreate', Refresh: 'DhRefresh', DhpFearUpdate: 'DhFearUpdate', DowntimeTrigger: 'DowntimeTrigger', @@ -60,14 +56,14 @@ export const registerSocketHooks = () => { const document = data.uuid ? await fromUuid(data.uuid) : null; switch (data.action) { case GMUpdateEvent.UpdateDocument: - if (document && data.data) await document.update(data.data); + if (document && data.update) await document.update(data.update); break; case GMUpdateEvent.UpdateEffect: - if (document && data.data) - await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.data); + if (document && data.update) + await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.update); break; case GMUpdateEvent.UpdateSetting: - await game.settings.set(CONFIG.DH.id, data.uuid, data.data); + await game.settings.set(CONFIG.DH.id, data.uuid, data.update); break; case GMUpdateEvent.UpdateFear: await game.settings.set( @@ -77,22 +73,22 @@ export const registerSocketHooks = () => { 0, Math.min( game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear, - data.data + data.update ) ) ); break; case GMUpdateEvent.UpdateCountdowns: - await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data.data); + await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data.update); Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown }); break; case GMUpdateEvent.UpdateSaveMessage: - const message = game.messages.get(data.data.message); + const message = game.messages.get(data.update.message); if (!message) return; game.system.api.fields.ActionFields.SaveField.updateSaveMessage( - data.data.result, + data.update.result, message, - data.data.token + data.update.token ); break; } @@ -106,17 +102,6 @@ export const registerSocketHooks = () => { } } }); - - Hooks.on(socketEvent.GMCreate, async ({ data, documentType, scene }) => { - if (!game.user.isGM) return; - - switch (documentType) { - default: - const cls = getDocumentClass(documentType); - cls.create(data, { parent: game.scenes.get(scene) }); - break; - } - }); }; export const registerUserQueries = () => { @@ -124,21 +109,18 @@ export const registerUserQueries = () => { CONFIG.queries.reactionRoll = game.system.api.fields.ActionFields.SaveField.rollSaveQuery; }; -export const emitGMUpdate = async (eventName, callback, update, uuid = null, refresh = null) => { - return await emitAsGM(socketEvent.GMUpdate, { action: eventName, callback, data: update, uuid, refresh }); -}; - -export const emitGMCreate = async (documentType, callback, data, scene) => { - return await emitAsGM(socketEvent.GMCreate, { documentType, callback, data, scene }); -}; - -export const emitAsGM = async (event, data = { callback: () => {}, data: {} }) => { +export const emitAsGM = async (eventName, callback, update, uuid = null, refresh = null) => { if (!game.user.isGM) { return await game.socket.emit(`system.${CONFIG.DH.id}`, { - action: event, - data: data + action: socketEvent.GMUpdate, + data: { + action: eventName, + uuid, + update, + refresh + } }); - } else return data.callback(data.data); + } else return callback(update); }; export const emitAsOwner = (eventName, userId, args) => { diff --git a/system.json b/system.json index ac581343..deb30b53 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "2.2.3", + "version": "2.2.2", "compatibility": { "minimum": "14.359", "verified": "14.360", @@ -10,7 +10,7 @@ }, "url": "https://github.com/Foundryborne/daggerheart", "manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json", - "download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.3/system.zip", + "download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.2/system.zip", "authors": [ { "name": "WBHarry"