- `
- html.find(".form-group").last().after(synchronizedSettings)
+ `;
+ html.find(".form-group").last().after(synchronizedSettings);
- const smartdoorsData = data.object.flags.smartdoors
+ const smartdoorsData = data.object.flags.smartdoors;
// Fill the injected input fields with values
- const input = (name) => html.find(`input[name="${name}"]`); // input is a helper function to search for a input field by it's name
- input("synchronizationGroup").prop("value", smartdoorsData?.synchronizationGroup)
+ const input = name => html.find(`input[name="${name}"]`); // input is a helper function to search for a input field by it's name
+ input("synchronizationGroup").prop("value", smartdoorsData?.synchronizationGroup);
input("synchronizeSecretStatus").prop("checked", smartdoorsData?.synchronizeSecretStatus);
// Recalculate config window height
- wallConfig.setPosition({height: "auto"})
+ wallConfig.setPosition({height: "auto"});
}
}
@@ -46,16 +50,14 @@ export async function onWallConfigUpdate(event, formData) {
// Search for other doors in the synchronization group that aren't in the list of edited doors
const doorInGroup = Util.findInAllWalls(wall => {
// We only search for doors
- if (!wall.data.door)
- return false
+ if (!wall.data.door) return false;
// We only want doors in the same synchronization group
if (wall.data.flags.smartdoors?.synchronizationGroup !== formData.synchronizationGroup)
- return false
+ return false;
// Doors on this scene that have their id included in `ids` are currently being changed. Ignore them.
- if (wall.parent.id === canvas.scene.id && ids.includes(wall.id))
- return false
- return true
- })
+ if (wall.parent.id === canvas.scene.id && ids.includes(wall.id)) return false;
+ return true;
+ });
if (doorInGroup) {
// ds is the door sate in foundry
updateData.ds = doorInGroup.data.ds;
@@ -68,7 +70,9 @@ export async function onWallConfigUpdate(event, formData) {
}
// Update all the edited walls
- const updateDataset = ids.map(id => {return {_id: id, ...updateData}});
+ const updateDataset = ids.map(id => {
+ return {_id: id, ...updateData};
+ });
const updateResult = await canvas.scene.updateEmbeddedDocuments("Wall", updateDataset);
// If door is synchronized, synchronize secret status among synchronized doors
@@ -80,70 +84,75 @@ export async function onWallConfigUpdate(event, formData) {
// Update the state of all synchronized doors
export function onDoorLeftClick() {
- const state = this.wall.data.ds
- const states = CONST.WALL_DOOR_STATES
+ const state = this.wall.data.ds;
+ const states = CONST.WALL_DOOR_STATES;
// Check if this feature is enabled
- if (!game.settings.get(settingsKey, "synchronizedDoors"))
- return false
+ if (!game.settings.get(settingsKey, "synchronizedDoors")) return false;
- const synchronizationGroup = this.wall.data.flags.smartdoors?.synchronizationGroup
+ const synchronizationGroup = this.wall.data.flags.smartdoors?.synchronizationGroup;
// Does this door have a synchronization group? If not there is nothing to do
- if (!synchronizationGroup)
- return false
+ if (!synchronizationGroup) return false;
// If the door is locked there is nothing to synchronize
- if (state === states.LOCKED)
- return false
+ if (state === states.LOCKED) return false;
// Calculate new door state
- const newstate = state === states.CLOSED ? states.OPEN : states.CLOSED
+ const newstate = state === states.CLOSED ? states.OPEN : states.CLOSED;
// Update all doors belonging to the synchronization group
- const updateData = {ds: newstate}
- updateSynchronizedDoors(updateData, synchronizationGroup)
+ const updateData = {ds: newstate};
+ updateSynchronizedDoors(updateData, synchronizationGroup);
- return true
+ return true;
}
export function onDoorRightClick() {
- const state = this.wall.data.ds
- const states = CONST.WALL_DOOR_STATES
+ const state = this.wall.data.ds;
+ const states = CONST.WALL_DOOR_STATES;
// Check if this feature is enabled
- if (!game.settings.get(settingsKey, "synchronizedDoors"))
- return false
+ if (!game.settings.get(settingsKey, "synchronizedDoors")) return false;
- const synchronizationGroup = this.wall.data.flags.smartdoors?.synchronizationGroup
+ const synchronizationGroup = this.wall.data.flags.smartdoors?.synchronizationGroup;
// Does this door have a synchronization group? If not there is nothing to do
- if (!synchronizationGroup)
- return false
+ if (!synchronizationGroup) return false;
// Only the gm is allowed to lock/unlock doors
- if ( !game.user.isGM )
- return false;
+ if (!game.user.isGM) return false;
// If the door is currently opened we cannot lock the door
- if ( state === states.OPEN )
- return false;
+ if (state === states.OPEN) return false;
// Calculate new door state
const newstate = state === states.LOCKED ? states.CLOSED : states.LOCKED;
// Update all doors belonging to the synchronization group
- const updateData = {ds: newstate}
- updateSynchronizedDoors(updateData, synchronizationGroup)
+ const updateData = {ds: newstate};
+ updateSynchronizedDoors(updateData, synchronizationGroup);
- return true
+ return true;
}
// Updates all doors in the specified synchronization group with the provided data
export function updateSynchronizedDoors(updateData, synchronizationGroup) {
// Search for doors belonging to the synchronization group in all scenes
- let scenes = Util.filterAllWalls(wall => wall.data.door && wall.data.flags.smartdoors?.synchronizationGroup === synchronizationGroup);
+ let scenes = Util.filterAllWalls(
+ wall =>
+ wall.data.door && wall.data.flags.smartdoors?.synchronizationGroup === synchronizationGroup,
+ );
// Update all doors in the synchronization group
- return Promise.all(scenes.map(scene => scene.scene.updateEmbeddedDocuments("Wall", scene.walls.map((wall) => {return {_id: wall.id, ...updateData}}))));
+ return Promise.all(
+ scenes.map(scene =>
+ scene.scene.updateEmbeddedDocuments(
+ "Wall",
+ scene.walls.map(wall => {
+ return {_id: wall.id, ...updateData};
+ }),
+ ),
+ ),
+ );
}
diff --git a/src/features/toggle_secret_door.js b/src/features/toggle_secret_door.js
index f9ed267..f11e938 100644
--- a/src/features/toggle_secret_door.js
+++ b/src/features/toggle_secret_door.js
@@ -1,21 +1,24 @@
import {toggleSecretDoor} from "../keybindings.js";
-import {settingsKey} from "../settings.js"
+import {settingsKey} from "../settings.js";
import {updateSynchronizedDoors} from "./synchronized_doors.js";
// Toggles between normal and secret doors
export function onDoorLeftClick() {
// We don't trust the event to be filled with the expected data for compatibilty with arms reach (which passes a broken event)
if (toggleSecretDoor && game.user.isGM) {
- const types = CONST.WALL_DOOR_TYPES
- const newtype = this.wall.data.door === types.DOOR ? types.SECRET : types.DOOR
- const updateData = {door: newtype}
- const synchronizationGroup = this.wall.data.flags.smartdoors?.synchronizationGroup
- if (game.settings.get(settingsKey, "synchronizedDoors") && synchronizationGroup && this.wall.data.flags.smartdoors?.synchronizeSecretStatus)
- updateSynchronizedDoors(updateData, synchronizationGroup)
- else
- this.wall.document.update(updateData)
+ const types = CONST.WALL_DOOR_TYPES;
+ const newtype = this.wall.data.door === types.DOOR ? types.SECRET : types.DOOR;
+ const updateData = {door: newtype};
+ const synchronizationGroup = this.wall.data.flags.smartdoors?.synchronizationGroup;
+ if (
+ game.settings.get(settingsKey, "synchronizedDoors") &&
+ synchronizationGroup &&
+ this.wall.data.flags.smartdoors?.synchronizeSecretStatus
+ )
+ updateSynchronizedDoors(updateData, synchronizationGroup);
+ else this.wall.document.update(updateData);
- return true
+ return true;
}
- return false
+ return false;
}
diff --git a/src/main.js b/src/main.js
index 938752a..6100e84 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,105 +1,116 @@
"use strict";
import {libWrapper} from "../lib/libwrapper_shim.js";
-import * as DoorControlIconScale from "./features/door_control_icon_scale.js"
-import * as HighlightSecretDoors from "./features/highlight_secret_doors.js"
-import * as LockedDoorAlert from "./features/locked_door_alert.js"
-import * as SynchronizedDoors from "./features/synchronized_doors.js"
-import * as ToggleSecretDoor from "./features/toggle_secret_door.js"
+import * as DoorControlIconScale from "./features/door_control_icon_scale.js";
+import * as HighlightSecretDoors from "./features/highlight_secret_doors.js";
+import * as LockedDoorAlert from "./features/locked_door_alert.js";
+import * as SynchronizedDoors from "./features/synchronized_doors.js";
+import * as ToggleSecretDoor from "./features/toggle_secret_door.js";
-import {performMigrations} from "./migration.js"
-import {registerKeybindings} from "./keybindings.js"
-import {registerSettings, settingsKey} from "./settings.js"
+import {performMigrations} from "./migration.js";
+import {registerKeybindings} from "./keybindings.js";
+import {registerSettings, settingsKey} from "./settings.js";
Hooks.once("init", () => {
- registerSettings()
- registerKeybindings()
+ registerSettings();
+ registerKeybindings();
- hookDoorEvents()
- hookWallConfigUpdate()
- hookDoorControlDraw()
- DoorControlIconScale.hookDoorControlReposition()
-})
+ hookDoorEvents();
+ hookWallConfigUpdate();
+ hookDoorControlDraw();
+ DoorControlIconScale.hookDoorControlReposition();
+});
Hooks.once("ready", () => {
- performMigrations()
-})
+ performMigrations();
+});
-Hooks.on("renderChatMessage", LockedDoorAlert.onRenderChatMessage)
+Hooks.on("renderChatMessage", LockedDoorAlert.onRenderChatMessage);
-Hooks.on("canvasReady", DoorControlIconScale.onCanvasReady)
-Hooks.on("canvasReady", HighlightSecretDoors.onCanvasReady)
+Hooks.on("canvasReady", DoorControlIconScale.onCanvasReady);
+Hooks.on("canvasReady", HighlightSecretDoors.onCanvasReady);
-Hooks.on("updateWall", HighlightSecretDoors.onUpdateWall)
+Hooks.on("updateWall", HighlightSecretDoors.onUpdateWall);
// Inject our custom settings into the WallConfig dialog
-Hooks.on("renderWallConfig", SynchronizedDoors.onRederWallConfig)
+Hooks.on("renderWallConfig", SynchronizedDoors.onRederWallConfig);
// Hook the update function of the WallConfig dialog so we can store our custom data
function hookWallConfigUpdate() {
// Replace the original function with our custom one
- libWrapper.register("smart-doors", "WallConfig.prototype._updateObject", async function (wrapped, event, formData) {
- await wrapped(event, formData);
- return SynchronizedDoors.onWallConfigUpdate.call(this, event, formData)
- }, "WRAPPER");
+ libWrapper.register(
+ "smart-doors",
+ "WallConfig.prototype._updateObject",
+ async function (wrapped, event, formData) {
+ await wrapped(event, formData);
+ return SynchronizedDoors.onWallConfigUpdate.call(this, event, formData);
+ },
+ "WRAPPER",
+ );
}
function hookDoorControlDraw() {
- libWrapper.register("smart-doors", "DoorControl.prototype.draw", async function (wrapped) {
- const result = await wrapped();
- DoorControlIconScale.onDoorControlPostDraw.call(this)
- return result;
- }, "WRAPPER");
+ libWrapper.register(
+ "smart-doors",
+ "DoorControl.prototype.draw",
+ async function (wrapped) {
+ const result = await wrapped();
+ DoorControlIconScale.onDoorControlPostDraw.call(this);
+ return result;
+ },
+ "WRAPPER",
+ );
}
// Hook mouse events on DoorControls to perform our logic.
// If we successfully handled the event block the original handler. Forward the event otherwise.
function hookDoorEvents() {
// Replace the original mousedown handler with our custom one
- libWrapper.register("smart-doors", "DoorControl.prototype._onMouseDown", function (wrapped, event) {
- // Call our handler first. Only allow the original handler to run if our handler returns true
- const eventHandled = onDoorMouseDown.call(this, event)
- if (eventHandled)
- return
- return wrapped(event);
- }, "MIXED");
+ libWrapper.register(
+ "smart-doors",
+ "DoorControl.prototype._onMouseDown",
+ function (wrapped, event) {
+ // Call our handler first. Only allow the original handler to run if our handler returns true
+ const eventHandled = onDoorMouseDown.call(this, event);
+ if (eventHandled) return;
+ return wrapped(event);
+ },
+ "MIXED",
+ );
// Replace the original rightdown handler with our custom one
- libWrapper.register("smart-doors", "DoorControl.prototype._onRightDown", function (wrapped, event) {
- // Call our handler first. Only allow the original handler to run if our handler returns true
- const eventHandled = onDoorRightDown.call(this, event)
- if (eventHandled)
- return
- return wrapped(event);
- }, "MIXED");
+ libWrapper.register(
+ "smart-doors",
+ "DoorControl.prototype._onRightDown",
+ function (wrapped, event) {
+ // Call our handler first. Only allow the original handler to run if our handler returns true
+ const eventHandled = onDoorRightDown.call(this, event);
+ if (eventHandled) return;
+ return wrapped(event);
+ },
+ "MIXED",
+ );
}
// Our custom handler for mousedown events on doors
function onDoorMouseDown(event) {
// If the user doesn't have the "door" permission we don't do anything.
- if (!game.user.can("WALL_DOORS"))
- return false
+ if (!game.user.can("WALL_DOORS")) return false;
// If the game is paused don't do anything if the current player isn't the gm
- if ( game.paused && !game.user.isGM )
- return false
+ if (game.paused && !game.user.isGM) return false;
- if (ToggleSecretDoor.onDoorLeftClick.call(this, event))
- return true
+ if (ToggleSecretDoor.onDoorLeftClick.call(this, event)) return true;
- if (LockedDoorAlert.onDoorLeftClick.call(this))
- return true
+ if (LockedDoorAlert.onDoorLeftClick.call(this)) return true;
- if (SynchronizedDoors.onDoorLeftClick.call(this))
- return true
+ if (SynchronizedDoors.onDoorLeftClick.call(this)) return true;
- return false
+ return false;
}
// Our custom handler for rightdown events on doors
function onDoorRightDown(event) {
+ if (SynchronizedDoors.onDoorRightClick.call(this)) return true;
- if (SynchronizedDoors.onDoorRightClick.call(this))
- return true
-
- return false
+ return false;
}
diff --git a/src/migration.js b/src/migration.js
index c34dd8e..f93e27b 100644
--- a/src/migration.js
+++ b/src/migration.js
@@ -1,57 +1,58 @@
-import {settingsKey} from "./settings.js"
+import {settingsKey} from "./settings.js";
-const currentDataVersion = "1.1.0"
+const currentDataVersion = "1.1.0";
export function performMigrations() {
- if (!game.user.isGM)
- return
+ if (!game.user.isGM) return;
- let dataVersion = game.settings.get(settingsKey, "dataVersion")
- if (dataVersion === "fresh install")
- {
+ let dataVersion = game.settings.get(settingsKey, "dataVersion");
+ if (dataVersion === "fresh install") {
game.settings.set(settingsKey, "dataVersion", currentDataVersion);
return;
}
if (dataVersion === "1.0.0") {
- dataVersion = "1.1.0"
- ui.notifications.info(game.i18n.format("smart-doors.ui.messages.migrating", {version: dataVersion}))
+ dataVersion = "1.1.0";
+ ui.notifications.info(
+ game.i18n.format("smart-doors.ui.messages.migrating", {version: dataVersion}),
+ );
// Make a dictionary that maps all door ids to their scenes
const walls = game.scenes.reduce((dict, scene) => {
scene.data.walls.forEach(wall => {
- if (!wall.data.door)
- return
+ if (!wall.data.door) return;
dict[wall.id] = scene.id;
- })
- return dict
- }, {})
+ });
+ return dict;
+ }, {});
// Migrate all messages that have a (wall) source id
game.messages.forEach(async message => {
- const wallId = message.data.flags.smartdoors?.sourceId
- if (!wallId)
- return
- const flags = message.data.flags
- delete flags.smartdoors.sourceId
- const scene = walls[wallId]
+ const wallId = message.data.flags.smartdoors?.sourceId;
+ if (!wallId) return;
+ const flags = message.data.flags;
+ delete flags.smartdoors.sourceId;
+ const scene = walls[wallId];
// If there is no wall with this id anymore we can drop the value. It has no purpose anymore
if (!scene) {
- if (!message.data.flags.smartdoors)
- delete flags.smartdoors
- }
- else {
+ if (!message.data.flags.smartdoors) delete flags.smartdoors;
+ } else {
// Assign the id and the scene id to the new data structure
- flags.smartdoors.source = {wall: wallId, scene: scene}
+ flags.smartdoors.source = {wall: wallId, scene: scene};
}
// We have to disable recursive here so deleting keys will actually work
- message.update({flags: flags}, {diff: false, recursive: false})
- })
+ message.update({flags: flags}, {diff: false, recursive: false});
+ });
- game.settings.set(settingsKey, "dataVersion", dataVersion)
- ui.notifications.info(game.i18n.format("smart-doors.ui.messages.migrationDone", {version: dataVersion}))
+ game.settings.set(settingsKey, "dataVersion", dataVersion);
+ ui.notifications.info(
+ game.i18n.format("smart-doors.ui.messages.migrationDone", {version: dataVersion}),
+ );
}
if (dataVersion != currentDataVersion)
- ui.notifications.error(game.i18n.format("smart-doors.ui.messages.unknownVersion", {version: dataVersion}), {permanent: true})
+ ui.notifications.error(
+ game.i18n.format("smart-doors.ui.messages.unknownVersion", {version: dataVersion}),
+ {permanent: true},
+ );
}
diff --git a/src/settings.js b/src/settings.js
index 703f940..55736aa 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -1,8 +1,7 @@
export const settingsKey = "smart-doors";
function reloadGM() {
- if (game.user.isGM)
- delayedReload()
+ if (game.user.isGM) delayedReload();
}
function delayedReload() {
@@ -14,8 +13,8 @@ export function registerSettings() {
scope: "world",
config: false,
type: String,
- default: "fresh install"
- })
+ default: "fresh install",
+ });
game.settings.register(settingsKey, "doorControlSizeFactor", {
name: "smart-doors.settings.doorControlSizeFactor.name",
hint: "smart-doors.settings.doorControlSizeFactor.hint",
@@ -24,7 +23,7 @@ export function registerSettings() {
type: Number,
default: 1.5,
onChange: delayedReload,
- })
+ });
game.settings.register(settingsKey, "highlightSecretDoors", {
name: "smart-doors.settings.highlightSecretDoors.name",
hint: "smart-doors.settings.highlightSecretDoors.hint",
@@ -33,7 +32,7 @@ export function registerSettings() {
type: Boolean,
default: false,
onChange: reloadGM,
- })
+ });
game.settings.register(settingsKey, "lockedDoorAlert", {
name: "smart-doors.settings.lockedDoorAlert.name",
hint: "smart-doors.settings.lockedDoorAlert.hint",
@@ -41,7 +40,7 @@ export function registerSettings() {
config: true,
type: Boolean,
default: true,
- })
+ });
game.settings.register(settingsKey, "synchronizedDoors", {
name: "smart-doors.settings.synchronizedDoors.name",
hint: "smart-doors.settings.synchronizedDoors.hint",
@@ -49,5 +48,5 @@ export function registerSettings() {
config: true,
type: Boolean,
default: true,
- })
+ });
}
diff --git a/src/util.js b/src/util.js
index c052f2f..7ddf301 100644
--- a/src/util.js
+++ b/src/util.js
@@ -1,15 +1,17 @@
// Searches through all scenes for walls and returns those that match the given filter criteria.
export function filterAllWalls(filterFn) {
// Find all walls that match the filter criteria
- const scenes = game.scenes.map((scene) => {return {scene: scene, walls: scene.data.walls.filter(filterFn)}})
+ const scenes = game.scenes.map(scene => {
+ return {scene: scene, walls: scene.data.walls.filter(filterFn)};
+ });
// Drop all scenes that don't contain any results
- return scenes.filter(scene => scene.walls.length > 0)
+ return scenes.filter(scene => scene.walls.length > 0);
}
// Searches through all scenes for a wall that matches the given filter criteria
export function findInAllWalls(filterFn) {
// TODO The performance of this could be increased by stopping the search on the first hit
- const scenes = filterAllWalls(filterFn)
+ const scenes = filterAllWalls(filterFn);
// If results were found take the first wall from the first scene.
- return scenes[0]?.walls[0]
+ return scenes[0]?.walls[0];
}