Reformat with prettier

This commit is contained in:
2022-10-15 21:47:59 +02:00
parent 04d85d818b
commit 2ea4eb04cb
10 changed files with 283 additions and 225 deletions

4
.prettierrc Normal file
View File

@@ -0,0 +1,4 @@
printWidth: 100
trailingComma: "all"
bracketSpacing: false
arrowParens: "avoid"

View File

@@ -1,37 +1,66 @@
import { libWrapper } from "../../lib/libwrapper_shim.js"
import {settingsKey} from "../settings.js"
import {libWrapper} from "../../lib/libwrapper_shim.js";
import {settingsKey} from "../settings.js";
// Adjust the repositioning formula for the door controls
export function hookDoorControlReposition() {
libWrapper.register("smart-doors", "DoorControl.prototype.reposition", function () {
let gridSize = this.wall.scene.data.grid
gridSize *= game.settings.get(settingsKey, "doorControlSizeFactor")
const pos = this.wall.midpoint.map(p => p - gridSize * 0.2)
this.position.set(...pos)
}, "OVERRIDE");
libWrapper.register(
"smart-doors",
"DoorControl.prototype.reposition",
function () {
let gridSize = this.wall.scene.data.grid;
gridSize *= game.settings.get(settingsKey, "doorControlSizeFactor");
const pos = this.wall.midpoint.map(p => p - gridSize * 0.2);
this.position.set(...pos);
},
"OVERRIDE",
);
}
// Set the size of all door controls in relation to the grid size so it'll have a constant percieved size
export function onCanvasReady(currentCanvas) {
const doors = currentCanvas.controls.doors.children
doors.forEach(control => fixDoorControlSize(control))
const doors = currentCanvas.controls.doors.children;
doors.forEach(control => fixDoorControlSize(control));
}
// Set the size of the door control in relation to the grid size so it'll have a constant percieved size
export function onDoorControlPostDraw() {
// If the canvas isn't ready we'll do this after the "canvasReady" event is fired instead
if (!canvas.ready)
return
if (!canvas.ready) return;
fixDoorControlSize(this)
fixDoorControlSize(this);
}
// Resizes the door control according to the grid size
function fixDoorControlSize(control) {
let gridSize = control.wall.scene.data.grid
gridSize *= game.settings.get(settingsKey, "doorControlSizeFactor")
control.icon.width = control.icon.height = gridSize * 0.4
control.hitArea = new PIXI.Rectangle(gridSize * -0.02, gridSize * -0.02, gridSize * 0.44, gridSize * 0.44);
control.border.clear().lineStyle(1, 0xFF5500, 0.8).drawRoundedRect(gridSize * -0.02, gridSize * -0.02, gridSize * 0.44, gridSize * 0.44, gridSize * 0.05).endFill();
control.bg.clear().beginFill(0x000000, 1.0).drawRoundedRect(gridSize * -0.02, gridSize * -0.02, gridSize * 0.44, gridSize * 0.44, gridSize * 0.05).endFill();
let gridSize = control.wall.scene.data.grid;
gridSize *= game.settings.get(settingsKey, "doorControlSizeFactor");
control.icon.width = control.icon.height = gridSize * 0.4;
control.hitArea = new PIXI.Rectangle(
gridSize * -0.02,
gridSize * -0.02,
gridSize * 0.44,
gridSize * 0.44,
);
control.border
.clear()
.lineStyle(1, 0xff5500, 0.8)
.drawRoundedRect(
gridSize * -0.02,
gridSize * -0.02,
gridSize * 0.44,
gridSize * 0.44,
gridSize * 0.05,
)
.endFill();
control.bg
.clear()
.beginFill(0x000000, 1.0)
.drawRoundedRect(
gridSize * -0.02,
gridSize * -0.02,
gridSize * 0.44,
gridSize * 0.44,
gridSize * 0.05,
)
.endFill();
}

View File

@@ -1,34 +1,37 @@
import {settingsKey} from "../settings.js"
import {settingsKey} from "../settings.js";
const SECRET_DOOR_TINT = 0x888888
const SECRET_DOOR_TINT = 0x888888;
// Tint all secret doors dark grey
export function onCanvasReady(currentCanvas) {
if (game.settings.get(settingsKey, "highlightSecretDoors")) {
const types = CONST.WALL_DOOR_TYPES
const secretDoors = canvas.controls.doors.children.filter(control => control.wall.data.door == types.SECRET)
secretDoors.forEach(control => control.icon.tint = SECRET_DOOR_TINT)
const types = CONST.WALL_DOOR_TYPES;
const secretDoors = canvas.controls.doors.children.filter(
control => control.wall.data.door == types.SECRET,
);
secretDoors.forEach(control => (control.icon.tint = SECRET_DOOR_TINT));
}
}
// If door type has been changed, tint the door accordingly
export function onUpdateWall(scene, wall, update) {
if (!game.settings.get(settingsKey, "highlightSecretDoors"))
return
const types = CONST.WALL_DOOR_TYPES
if (wall.door === types.NONE)
return
if (!game.settings.get(settingsKey, "highlightSecretDoors")) return;
const types = CONST.WALL_DOOR_TYPES;
if (wall.door === types.NONE) return;
// Find the door control corresponding to the changed door
const changedDoor = canvas.controls.doors.children.find(control => control.wall.data._id === wall._id);
const changedDoor = canvas.controls.doors.children.find(
control => control.wall.data._id === wall._id,
);
// If the changed door doesn't have a control it's not on this scene - ignore it
if (!changedDoor)
return
if (!changedDoor) return;
// The wall object we got passed might be from another scene so we replace it with the door from the current scene
wall = changedDoor.wall.data
if (wall.door === types.DOOR)
changedDoor.icon.tint = 0xFFFFFF
else if (wall.door === types.SECRET)
changedDoor.icon.tint = SECRET_DOOR_TINT
wall = changedDoor.wall.data;
if (wall.door === types.DOOR) changedDoor.icon.tint = 0xffffff;
else if (wall.door === types.SECRET) changedDoor.icon.tint = SECRET_DOOR_TINT;
else
console.warn("Smart Doors | Encountered unknown door type " + wall.door + " while highlighting secret doors.")
console.warn(
"Smart Doors | Encountered unknown door type " +
wall.door +
" while highlighting secret doors.",
);
}

View File

@@ -1,26 +1,27 @@
import {settingsKey} from "../settings.js"
import {settingsKey} from "../settings.js";
// Tint the source door red when a locked alert is hovered
export function onRenderChatMessage(message, html, data) {
// Tint the door that generated this message
const source = message.data.flags.smartdoors?.source
if (!source)
return
const source = message.data.flags.smartdoors?.source;
if (!source) return;
// Tint on mouse enter
const mouseEnter = function () {
const sourceDoor = canvas.controls.doors.children.find(door => door.wall.id === source.wall && door.wall.scene.id === source.scene);
if (sourceDoor)
sourceDoor.icon.tint = 0xff0000;
}
const sourceDoor = canvas.controls.doors.children.find(
door => door.wall.id === source.wall && door.wall.scene.id === source.scene,
);
if (sourceDoor) sourceDoor.icon.tint = 0xff0000;
};
html.on("mouseenter", mouseEnter);
// Remove tint on mouse leave
const mouseLeave = function () {
const sourceDoor = canvas.controls.doors.children.find(door => door.wall.id === source.wall && door.wall.scene.id === source.scene);
if (sourceDoor)
sourceDoor.icon.tint = 0xffffff;
}
const sourceDoor = canvas.controls.doors.children.find(
door => door.wall.id === source.wall && door.wall.scene.id === source.scene,
);
if (sourceDoor) sourceDoor.icon.tint = 0xffffff;
};
html.on("mouseleave", mouseLeave);
// Localize the message
@@ -30,28 +31,24 @@ export function onRenderChatMessage(message, html, data) {
// Creates a chat message stating that a player tried to open a locked door
export function onDoorLeftClick() {
// Check if this feature is enabled
if (!game.settings.get(settingsKey, "lockedDoorAlert"))
return false
if (!game.settings.get(settingsKey, "lockedDoorAlert")) return false;
const state = this.wall.data.ds
const states = CONST.WALL_DOOR_STATES
const state = this.wall.data.ds;
const states = CONST.WALL_DOOR_STATES;
// Only create messages when the door is locked.
if (state !== states.LOCKED)
return false
if (state !== states.LOCKED) return false;
// Generate no message if the gm attempts to open the door
if (game.user.isGM)
return false
if (game.user.isGM) return false;
// Create and send the chat message
const message = {}
const message = {};
message.user = game.user.id;
if (game.user.character)
message.speaker = {actor: game.user.character}
if (game.user.character) message.speaker = {actor: game.user.character};
message.content = game.i18n.localize("smart-doors.ui.lockedDoorAlert");
message.sound = CONFIG.sounds.lock
message.flags = {smartdoors: {source: {wall: this.wall.data._id, scene: this.wall.scene.id}}}
ChatMessage.create(message)
return true
message.sound = CONFIG.sounds.lock;
message.flags = {smartdoors: {source: {wall: this.wall.data._id, scene: this.wall.scene.id}}};
ChatMessage.create(message);
return true;
}

View File

@@ -1,5 +1,5 @@
import {settingsKey} from "../settings.js"
import * as Util from "../util.js"
import {settingsKey} from "../settings.js";
import * as Util from "../util.js";
// Inject settings for synchronized doors
export function onRederWallConfig(wallConfig, html, data) {
@@ -8,24 +8,28 @@ export function onRederWallConfig(wallConfig, html, data) {
const synchronizedSettings = `
<p class="notes">${game.i18n.localize("smart-doors.ui.synchronizedDoors.description")}</p>
<div class="form-group">
<label for="synchronizationGroup">${game.i18n.localize("smart-doors.ui.synchronizedDoors.groupName")}</label>
<label for="synchronizationGroup">${game.i18n.localize(
"smart-doors.ui.synchronizedDoors.groupName",
)}</label>
<input type="text" name="synchronizationGroup"/>
</div>
<div class="form-group">
<label for="synchronizeSecretStatus">${game.i18n.localize("smart-doors.ui.synchronizedDoors.synchronizeSecretStatus")}</label>
<label for="synchronizeSecretStatus">${game.i18n.localize(
"smart-doors.ui.synchronizedDoors.synchronizeSecretStatus",
)}</label>
<input type="checkbox" name="synchronizeSecretStatus" value="true"/>
</div>
`
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};
}),
),
),
);
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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},
);
}

View File

@@ -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,
})
});
}

View File

@@ -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];
}