import {settingsKey} from "../settings.js"; import * as Util from "../util.js"; // Inject settings for synchronized doors export function onRederWallConfig(wallConfig, html, data) { if (game.settings.get(settingsKey, "synchronizedDoors") && data.isDoor) { // Inject settings const synchronizedSettings = `

${game.i18n.localize("smart-doors.ui.synchronizedDoors.description")}

`; html.find(".form-group").last().after(synchronizedSettings); 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); input("synchronizeSecretStatus").prop("checked", smartdoorsData?.synchronizeSecretStatus); // Recalculate config window height wallConfig.setPosition({height: "auto"}); } } // Store our custom data from the WallConfig dialog export async function onWallConfigUpdate(event, formData) { const synchronizeSecretStatus = formData.synchronizeSecretStatus; const updateData = {flags: {smartdoors: {synchronizationGroup: formData.synchronizationGroup}}}; let ids = this.editTargets; if (ids.length == 0) { ids = [this.object.id]; } // If a synchronization group is set, get the state of existing doors and assume their state if (formData.synchronizationGroup) { // Update the synchronizeSecretStatus flag updateData.flags.smartdoors.synchronizeSecretStatus = synchronizeSecretStatus; // 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; // We only want doors in the same synchronization group if (wall.data.flags.smartdoors?.synchronizationGroup !== formData.synchronizationGroup) 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 (doorInGroup) { // ds is the door sate in foundry updateData.ds = doorInGroup.data.ds; if (synchronizeSecretStatus) { // door is the door type in foundry updateData.door = doorInGroup.data.door; } } } // Update all the edited walls 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 if (formData.synchronizationGroup) await updateSynchronizedDoors(updateData, formData.synchronizationGroup); return updateResult; } // Update the state of all synchronized doors export function onDoorLeftClick() { 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; 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 the door is locked there is nothing to synchronize if (state === states.LOCKED) return false; // Calculate new door state const newstate = state === states.CLOSED ? states.OPEN : states.CLOSED; // Update all doors belonging to the synchronization group const updateData = {ds: newstate}; updateSynchronizedDoors(updateData, synchronizationGroup); return true; } export function onDoorRightClick() { 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; 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; // Only the gm is allowed to lock/unlock doors if (!game.user.isGM) return false; // If the door is currently opened we cannot lock the door 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); 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, ); // 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}; }), ), ), ); }