mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-06 04:44:16 +02:00
Fixed so that creating regions without behaviors work for players. Fixed so that creating regions with behaviors works via GmEmit for players
This commit is contained in:
parent
4558fbdcf6
commit
02a489e8f7
4 changed files with 89 additions and 47 deletions
|
|
@ -3220,7 +3220,8 @@
|
|||
"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"
|
||||
"noTokenTargeted": "No token is targeted",
|
||||
"behaviorRegionRequiresGM": "Creating a Region with an attached Behavior requires an online GM"
|
||||
},
|
||||
"Progress": {
|
||||
"migrationLabel": "Performing system migration. Please wait and do not close Foundry."
|
||||
|
|
|
|||
|
|
@ -57,14 +57,14 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer {
|
|||
}
|
||||
|
||||
async placeRegion(data, options = {}) {
|
||||
const preConfirm = ({ _event, document, _create, _options }) => {
|
||||
const shape = document.shapes[0];
|
||||
const preConfirm = data => {
|
||||
const shape = data.document.shapes[0];
|
||||
const isEmanation = shape.type === 'emanation';
|
||||
if (isEmanation) {
|
||||
const token = this.#findTokenInBounds(shape.base.origin);
|
||||
if (!token) return options.preConfirm?.() ?? true;
|
||||
if (!token) return options.preConfirm?.(data) ?? true;
|
||||
const shapeData = shape.toObject();
|
||||
document.updateSource({
|
||||
data.document.updateSource({
|
||||
shapes: [
|
||||
{
|
||||
...shapeData,
|
||||
|
|
@ -80,10 +80,10 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer {
|
|||
});
|
||||
}
|
||||
|
||||
return options?.preConfirm?.() ?? true;
|
||||
return options?.preConfirm?.(data) ?? true;
|
||||
};
|
||||
|
||||
super.placeRegion(data, { ...options, preConfirm });
|
||||
return await super.placeRegion(data, { ...options, preConfirm });
|
||||
}
|
||||
|
||||
/** Searches for token at origin point, returning null if there are no tokens or multiple overlapping tokens */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
||||
import { emitAsGM, emitGMCreate, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
||||
|
||||
export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||
targetHook = null;
|
||||
|
|
@ -259,27 +259,50 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
|||
const { shape: type, size: range } = selectedArea;
|
||||
const shapeData = CONFIG.Canvas.layers.regions.layerClass.getTemplateShape({ type, range });
|
||||
|
||||
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
|
||||
}
|
||||
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
|
||||
},
|
||||
{ create: true }
|
||||
);
|
||||
}] : [],
|
||||
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 }
|
||||
);
|
||||
};
|
||||
|
||||
const needsGMExecution = effects.length > 0;
|
||||
|
||||
if (needsGMExecution && !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);
|
||||
}
|
||||
};
|
||||
|
||||
if (this.system.action.areas.length === 1) createArea(this.system.action.areas[0]);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ 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;
|
||||
|
|
@ -25,6 +28,7 @@ export function handleSocketEvent({ action = null, data = {} } = {}) {
|
|||
|
||||
export const socketEvent = {
|
||||
GMUpdate: 'DhGMUpdate',
|
||||
GMCreate: 'DhGMCreate',
|
||||
Refresh: 'DhRefresh',
|
||||
DhpFearUpdate: 'DhFearUpdate',
|
||||
DowntimeTrigger: 'DowntimeTrigger',
|
||||
|
|
@ -38,7 +42,7 @@ export const GMUpdateEvent = {
|
|||
UpdateSetting: 'DhGMUpdateSetting',
|
||||
UpdateFear: 'DhGMUpdateFear',
|
||||
UpdateCountdowns: 'DhGMUpdateCountdowns',
|
||||
UpdateSaveMessage: 'DhGMUpdateSaveMessage'
|
||||
UpdateSaveMessage: 'DhGMUpdateSaveMessage',
|
||||
};
|
||||
|
||||
export const RefreshType = {
|
||||
|
|
@ -56,14 +60,14 @@ export const registerSocketHooks = () => {
|
|||
const document = data.uuid ? await fromUuid(data.uuid) : null;
|
||||
switch (data.action) {
|
||||
case GMUpdateEvent.UpdateDocument:
|
||||
if (document && data.update) await document.update(data.update);
|
||||
if (document && data.data) await document.update(data.data);
|
||||
break;
|
||||
case GMUpdateEvent.UpdateEffect:
|
||||
if (document && data.update)
|
||||
await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.update);
|
||||
if (document && data.data)
|
||||
await game.system.api.fields.ActionFields.EffectsField.applyEffects.call(document, data.data);
|
||||
break;
|
||||
case GMUpdateEvent.UpdateSetting:
|
||||
await game.settings.set(CONFIG.DH.id, data.uuid, data.update);
|
||||
await game.settings.set(CONFIG.DH.id, data.uuid, data.data);
|
||||
break;
|
||||
case GMUpdateEvent.UpdateFear:
|
||||
await game.settings.set(
|
||||
|
|
@ -73,22 +77,22 @@ export const registerSocketHooks = () => {
|
|||
0,
|
||||
Math.min(
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
|
||||
data.update
|
||||
data.data
|
||||
)
|
||||
)
|
||||
);
|
||||
break;
|
||||
case GMUpdateEvent.UpdateCountdowns:
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data.update);
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data.data);
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||
break;
|
||||
case GMUpdateEvent.UpdateSaveMessage:
|
||||
const message = game.messages.get(data.update.message);
|
||||
const message = game.messages.get(data.data.message);
|
||||
if (!message) return;
|
||||
game.system.api.fields.ActionFields.SaveField.updateSaveMessage(
|
||||
data.update.result,
|
||||
data.data.result,
|
||||
message,
|
||||
data.update.token
|
||||
data.data.token
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
|
@ -102,6 +106,17 @@ 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 = () => {
|
||||
|
|
@ -109,18 +124,21 @@ export const registerUserQueries = () => {
|
|||
CONFIG.queries.reactionRoll = game.system.api.fields.ActionFields.SaveField.rollSaveQuery;
|
||||
};
|
||||
|
||||
export const emitAsGM = async (eventName, callback, update, uuid = null, refresh = null) => {
|
||||
export const emitGMUpdate = async (eventName, callback, update, uuid = null, refresh = null) => {
|
||||
return await emitAsGM(socketEvent.GMUpdate, { 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: {} }) => {
|
||||
if (!game.user.isGM) {
|
||||
return await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.GMUpdate,
|
||||
data: {
|
||||
action: eventName,
|
||||
uuid,
|
||||
update,
|
||||
refresh
|
||||
}
|
||||
action: event,
|
||||
data: data
|
||||
});
|
||||
} else return callback(update);
|
||||
} else return data.callback(data.data);
|
||||
};
|
||||
|
||||
export const emitAsOwner = (eventName, userId, args) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue