Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d5a273e12e | |||
| b397d35fdd | |||
| a926560b2c | |||
| f1574115f9 | |||
| 948a7eb06d |
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## v1.0.1
|
||||
- When adding a door to a synchronization group adjust it's state to bring it in sync with the other doors
|
||||
- Use the players character as speaker for the Locked Door Alert
|
||||
24
README.md
24
README.md
@@ -1,6 +1,30 @@
|
||||
# Smart Doors
|
||||
Makes doors smarter. Allows doors to synchronize across multiple scenes and sends chat messages when players try to open locked doors (and also tells you which of the doors).
|
||||
|
||||
## Feature overview
|
||||
|
||||
### Locked door alerts
|
||||

|
||||
|
||||
Keep everyone informed who tried to open which door. Whenever a player tries to open a door that is locked, a chat message stating that fact will be sent to all players. Additionally the door locked sound will be played for everyone. When the chat message is hovered with the mouse, the door that the player tried to open will be highlighted.
|
||||
|
||||
If the GM tries to open a locked door the sound will only played for him and no chat message will be sent.
|
||||
|
||||
### Synchronized doors
|
||||

|
||||
|
||||
Keep multiple doors in sync - even across different scenes. Example use cases:
|
||||
- A tavern has an outdoor and an indoor scene. If a player opens the entrance door on the outdoor map, the entrance door in the indoor map will be opened as well
|
||||
- An ancient trap that opens the cell of a monster once the door to the treasury is opened.
|
||||
|
||||
#### Usage
|
||||
To set up door synchronization, assign all doors that should be synchronized to the same Synchronization Group. The Synchronization Group can be any text. Doors that have the same Synchronization Group set will be synchronized. This will work across different scenes. At least two doors must be assigned to the same Synchronization Group. If only a single door is assigned to a synchronization group it will behave as any other normal door.
|
||||
|
||||
Once a Synchronization Group is set up for multiple doors, simply open/close/lock/unlock one of the doors to achieve the same effect on other doors as well.
|
||||
|
||||
## Planned features
|
||||
- Attach macros to doors that are being executed when the door is being opened/closed
|
||||
- Give out keys to players, that allow them to lock/unlock associated doors
|
||||
- Doors that can only be seen from one side when closed
|
||||
- Only allow doors to be opened of the character is near
|
||||
- Doors that can only be opened from one side
|
||||
|
||||
38
main.js
38
main.js
@@ -73,22 +73,25 @@ function hookWallConfigUpdate() {
|
||||
|
||||
// Store our custom data from the WallConfig dialog
|
||||
async function onWallConfigUpdate(event, formData) {
|
||||
// TODO Bring newly merged doors in sync
|
||||
const updateData = {flags: {smartdoors: {synchronizationGroup: formData.synchronizationGroup}}}
|
||||
let ids = this.options.editTargets;
|
||||
if (ids.length == 0) {
|
||||
ids = [this.object.data._id];
|
||||
}
|
||||
|
||||
const ids = this.options.editTargets;
|
||||
if (ids.length > 0) {
|
||||
// Multiple walls are edited at once. Update all of them
|
||||
// If a synchronization group is set, get the state of existing doors and assume their state
|
||||
if (formData.synchronizationGroup) {
|
||||
const doorInGroup = findInAllWalls(wall => wall.door && wall.flags.smartdoors?.synchronizationGroup == formData.synchronizationGroup && !ids.includes(wall._id));
|
||||
if (doorInGroup)
|
||||
updateData.ds = doorInGroup.ds;
|
||||
}
|
||||
|
||||
// Update all the edited walls
|
||||
const updateDataset = ids.reduce((dataset, id) => {
|
||||
dataset.push({_id: id, ...updateData})
|
||||
return dataset
|
||||
}, [])
|
||||
return canvas.scene.updateEmbeddedEntity("Wall", updateDataset)
|
||||
}
|
||||
else {
|
||||
// Only one wall is being edited
|
||||
return this.object.update(updateData);
|
||||
}
|
||||
}
|
||||
|
||||
// Hook mouse events on DoorControls to perform our logic.
|
||||
@@ -117,7 +120,18 @@ function hookDoorEvents() {
|
||||
|
||||
// Searches through all scenes for walls and returns those that match the given filter criteria.
|
||||
function filterAllWalls(filterFn) {
|
||||
return game.scenes.map((scene) => {return {scene: scene, walls: scene.data.walls.filter(filterFn)}});
|
||||
// Find all walls that match the filter criteria
|
||||
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)
|
||||
}
|
||||
|
||||
// Searches through all scenes for a wall that matches the given filter criteria
|
||||
function findInAllWalls(filterFn) {
|
||||
// TODO The performance of this could be increased by stopping the search on the first hit
|
||||
const scenes = filterAllWalls(filterFn)
|
||||
// If results were found take the first wall from the first scene.
|
||||
return scenes[0]?.walls[0]
|
||||
}
|
||||
|
||||
// Our custom handler for mousedown events on doors
|
||||
@@ -165,7 +179,9 @@ function lockedDoorAlertLeftClick() {
|
||||
|
||||
// Create and send the chat message
|
||||
const message = {}
|
||||
message.user = game.user;
|
||||
message.user = game.user
|
||||
if (game.user.character)
|
||||
message.speaker = {actor: game.user.character}
|
||||
message.content = "Just tried to open a locked door"
|
||||
message.sound = CONFIG.sounds.lock
|
||||
message.flags = {smartdoors: {sourceId: this.wall.data._id}}
|
||||
|
||||
@@ -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.0.0",
|
||||
"version": "1.0.1",
|
||||
"minimumCoreVersion" : "0.7.7",
|
||||
"compatibleCoreVersion" : "0.7.8",
|
||||
"author": "Manuel Vögele",
|
||||
@@ -18,7 +18,8 @@
|
||||
],
|
||||
"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.0.0.zip",
|
||||
"download": "https://github.com/manuelVo/foundryvtt-smart-doors/archive/v1.0.1.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"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user