Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c632a342d | |||
| 82b495f4c3 | |||
| f67899500e |
@@ -1,12 +1,12 @@
|
||||
## v1.1.0
|
||||
## v1.2.0
|
||||
### New features
|
||||
- Draw outlines around Door Control icons to increase their visibility
|
||||
- Execute a macro when someone interacts with a door
|
||||
|
||||
### Other
|
||||
- Secret doors are now tinted black instead of dark grey.
|
||||
- Setting hints will now be shown below the title of the setting (before it was above)
|
||||
|
||||
|
||||
## v1.1.0
|
||||
### New features
|
||||
- Tint secret doors grey for the GM to differentiate them from regular doors
|
||||
- Toggle doors between secret and normal with ctrl+click
|
||||
|
||||
19
lang/en.json
19
lang/en.json
@@ -17,10 +17,6 @@
|
||||
"name": "Locked Door Alert",
|
||||
"hint": "Send a message in chat when a player tried to open a locked door"
|
||||
},
|
||||
"macros": {
|
||||
"name": "Door Interaction Macros",
|
||||
"hint": "Trigger a macro when a door is being interacted with"
|
||||
},
|
||||
"synchronizedDoors": {
|
||||
"name": "Synchronized Doors",
|
||||
"hint": "Synchronize the state of configured doors"
|
||||
@@ -31,22 +27,7 @@
|
||||
}
|
||||
},
|
||||
"ui": {
|
||||
"form": {
|
||||
"macroExecuteEverywhere": {
|
||||
"name": "Execute on all clients",
|
||||
"hint": "If disabled the macro will be executed on the GMs client"
|
||||
},
|
||||
"macroName": {
|
||||
"name": "Macro Name",
|
||||
"hint": "The name of the macro that should be executed when this door is interacted with. No macro is executed if left blank."
|
||||
},
|
||||
"macroArguments": {
|
||||
"name": "Marco Parameters",
|
||||
"hint": "The parameters passed to the macro. Any JSON string is valid."
|
||||
}
|
||||
},
|
||||
"messages": {
|
||||
"argsInvalidJson": "The macro arguments must be valid JSON. See console for details.",
|
||||
"migrating": "Migrating Smart Doors to version {version}. Please don't close the application.",
|
||||
"migrationDone": "Smart Doors successfully migrated to version {version}.",
|
||||
"unknownVersion": "Smart Doors migration failed with the error: Unkown Version {version}. Please report this to the Smart Doors issue tracker. To prevent possible data loss don't use this plugin until this error is fixed."
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "smart-doors",
|
||||
"title": "Smart Doors",
|
||||
"description": "Makes doors smarter. Allows doors to synchronize across multiple scenes and sends chat messages when players try to open locked doors.",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"minimumCoreVersion" : "0.7.7",
|
||||
"compatibleCoreVersion" : "0.7.8",
|
||||
"author": "Manuel Vögele",
|
||||
@@ -18,7 +18,7 @@
|
||||
],
|
||||
"url": "https://github.com/manuelVo/foundryvtt-smart-doors",
|
||||
"manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-smart-doors/master/module.json",
|
||||
"download": "https://github.com/manuelVo/foundryvtt-smart-doors/archive/v1.1.0.zip",
|
||||
"download": "https://github.com/manuelVo/foundryvtt-smart-doors/archive/v1.2.0.zip",
|
||||
"readme": "https://github.com/manuelVo/foundryvtt-smart-doors/blob/master/README.md",
|
||||
"changelog": "https://github.com/manuelVo/foundryvtt-smart-doors/blob/master/CHANGELOG.md",
|
||||
"bugs": "https://github.com/manuelVo/foundryvtt-smart-doors/issues"
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import {settingsKey} from "../settings.js"
|
||||
import {textInput, checkboxInput, injectSettings} from "../form.js"
|
||||
|
||||
// Inject settings for synchronized doors
|
||||
export function onRederWallConfig(wallConfig, html, data) {
|
||||
if (data.isDoor && game.settings.get(settingsKey, "macros")) {
|
||||
|
||||
const settings = [
|
||||
textInput("macroName", data.object.flags.smartdoors?.macro?.name),
|
||||
textInput("macroArguments", JSON.stringify(data.object.flags.smartdoors?.macro?.args ?? undefined)),
|
||||
checkboxInput("macroExecuteEverywhere", data.object.flags.smartdoors?.macro?.executeEverywhere),
|
||||
]
|
||||
|
||||
injectSettings(html, settings)
|
||||
}
|
||||
}
|
||||
|
||||
// Check data input by the user for validity
|
||||
export async function onWallConfigPreUpdate(event, formData) {
|
||||
const args = formData.macroArguments || "null"
|
||||
|
||||
try {
|
||||
// Check if args can be converted to JSON
|
||||
JSON.parse(args)
|
||||
}
|
||||
catch (error) {
|
||||
ui.notifications.error(game.i18n.localize("smart-doors.ui.messages.argsInvalidJson"))
|
||||
// Rethrow the error to stop the update and prevent the dialog from closing
|
||||
throw(error)
|
||||
}
|
||||
|
||||
// The JSON is valid. Assign "null" instead of an empty string if necessary
|
||||
formData.macroArguments = args
|
||||
}
|
||||
|
||||
// Store our custom data from the WallConfig dialog
|
||||
export async function onWallConfigUpdate(event, formData) {
|
||||
let ids = this.options.editTargets;
|
||||
if (ids.length == 0) {
|
||||
ids = [this.object.data._id];
|
||||
}
|
||||
|
||||
const updateData = {flags: {smartdoors: {macro: {
|
||||
name: formData.macroName,
|
||||
args: JSON.parse(formData.macroArguments),
|
||||
executeEverywhere: formData.macroExecuteEverywhere
|
||||
}}}}
|
||||
|
||||
// Update all the edited walls
|
||||
const updateDataset = ids.reduce((dataset, id) => {
|
||||
dataset.push({_id: id, ...updateData})
|
||||
return dataset
|
||||
}, [])
|
||||
return canvas.scene.updateEmbeddedEntity("Wall", updateDataset)
|
||||
}
|
||||
@@ -18,6 +18,9 @@ export function onRederWallConfig(wallConfig, html, data) {
|
||||
// Fill the injected input fields with values
|
||||
const input = (name) => html.find(`input[name="${name}"]`)
|
||||
input("synchronizationGroup").prop("value", smartdoorsData?.synchronizationGroup)
|
||||
|
||||
// Recalculate config window height
|
||||
wallConfig.setPosition({height: "auto"})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
38
src/form.js
38
src/form.js
@@ -1,38 +0,0 @@
|
||||
function formEntry(name, input) {
|
||||
return `
|
||||
<div class="form-group">
|
||||
<label for="${name}">${game.i18n.localize(`smart-doors.ui.form.${name}.name`)}</label>
|
||||
${input}
|
||||
</div>
|
||||
<p class="notes">${game.i18n.localize(`smart-doors.ui.form.${name}.hint`)}</p>
|
||||
`
|
||||
}
|
||||
|
||||
export function injectSettings(html, settings) {
|
||||
html.find(".form-group").last().after(settings.join(""))
|
||||
}
|
||||
|
||||
export function textInput(name, value) {
|
||||
return formEntry(name, `<input type="text" name="${escapeHtml(name)}" value="${escapeHtml(value ?? "")}"/>`)
|
||||
}
|
||||
|
||||
export function selectInput(name, values) {
|
||||
// TODO Set selected option
|
||||
let html = `<select name="${name}">`
|
||||
html += values.reduce((html, value) => html + `<option value="${escapeHtml(value)}">${game.i18n.localize(`smart-doors.ui.form.${name}.options.${value}`)}</option>`, "")
|
||||
html += "</select>"
|
||||
return formEntry(name, html)
|
||||
}
|
||||
|
||||
export function checkboxInput(name, checked) {
|
||||
return formEntry(name, `<input type="checkbox" name="${escapeHtml(name)}" value="true" ${checked ? "checked" : ""}/>`)
|
||||
}
|
||||
|
||||
function escapeHtml(unsafe) {
|
||||
return unsafe
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
18
src/main.js
18
src/main.js
@@ -2,7 +2,6 @@
|
||||
|
||||
import * as DoorControlIconScale from "./features/door_control_icon_scale.js"
|
||||
import * as DoorControlOutline from "./features/door_control_outline.js"
|
||||
import * as ExecuteMacro from "./features/execute_macro.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"
|
||||
@@ -31,28 +30,15 @@ Hooks.on("canvasReady", HighlightSecretDoors.onCanvasReady)
|
||||
Hooks.on("updateWall", HighlightSecretDoors.onUpdateWall)
|
||||
|
||||
// Inject our custom settings into the WallConfig dialog
|
||||
Hooks.on("renderWallConfig", (wallConfig, html, data) => {
|
||||
SynchronizedDoors.onRederWallConfig(wallConfig, html, data)
|
||||
ExecuteMacro.onRederWallConfig(wallConfig, html, data)
|
||||
|
||||
// Recalculate config window position and height
|
||||
wallConfig.element[0].style.top = "" // This forces foundry to re-calculate the top position
|
||||
wallConfig.setPosition({height: "auto"})
|
||||
})
|
||||
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
|
||||
const originalHandler = WallConfig.prototype._updateObject;
|
||||
WallConfig.prototype._updateObject = async function (event, formData) {
|
||||
await ExecuteMacro.onWallConfigPreUpdate.call(this, event, formData)
|
||||
|
||||
await originalHandler.call(this, event, formData)
|
||||
|
||||
return Promise.all([
|
||||
SynchronizedDoors.onWallConfigUpdate.call(this, event, formData),
|
||||
ExecuteMacro.onWallConfigUpdate.call(this, event, formData),
|
||||
])
|
||||
return SynchronizedDoors.onWallConfigUpdate.call(this, event, formData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,12 +63,4 @@ export function registerSettings() {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
})
|
||||
game.settings.register(settingsKey, "macros", {
|
||||
name: "smart-doors.settings.macros.name",
|
||||
hint: "smart-doors.settings.macros.hint",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user