diff --git a/lang/en.json b/lang/en.json index 66c6f9c..a06e484 100644 --- a/lang/en.json +++ b/lang/en.json @@ -245,6 +245,7 @@ "clearLevels": "Clear Levels", "debugScene": "Debug Scene (Red means issues detected)", "minElevDiff": "Minimum Level Size", + "tokenAttacher": "Place Token Attacher prefabs relative to the current level", "warning": "WARNING! 'Don't disable lights' is enabled in the Scene Settings - Multiple levels will not work correctly. Click to resolve this issue." }, "yesnodialog": { diff --git a/packs/levels-samples/002055.log b/packs/levels-samples/002095.log similarity index 100% rename from packs/levels-samples/002055.log rename to packs/levels-samples/002095.log diff --git a/packs/levels-samples/CURRENT b/packs/levels-samples/CURRENT index 4c0052f..9ba62b9 100644 --- a/packs/levels-samples/CURRENT +++ b/packs/levels-samples/CURRENT @@ -1 +1 @@ -MANIFEST-002054 +MANIFEST-002094 diff --git a/packs/levels-samples/LOG b/packs/levels-samples/LOG index 65ab5c8..6872016 100644 --- a/packs/levels-samples/LOG +++ b/packs/levels-samples/LOG @@ -1,3 +1,3 @@ -2024/03/17-14:22:08.913 9100 Recovering log #2052 -2024/03/17-14:22:08.917 9100 Delete type=0 #2052 -2024/03/17-14:22:08.917 9100 Delete type=3 #2050 +2024/03/23-17:18:29.289 7450 Recovering log #2093 +2024/03/23-17:18:29.293 7450 Delete type=0 #2093 +2024/03/23-17:18:29.293 7450 Delete type=3 #2092 diff --git a/packs/levels-samples/LOG.old b/packs/levels-samples/LOG.old index 1d538dd..8db7b61 100644 --- a/packs/levels-samples/LOG.old +++ b/packs/levels-samples/LOG.old @@ -1,8 +1,3 @@ -2024/03/16-23:28:33.229 156c Recovering log #2048 -2024/03/16-23:28:33.237 156c Delete type=0 #2048 -2024/03/16-23:28:33.237 156c Delete type=3 #2046 -2024/03/16-23:33:04.688 8f84 Level-0 table #2053: started -2024/03/16-23:33:04.688 8f84 Level-0 table #2053: 0 bytes OK -2024/03/16-23:33:04.689 8f84 Delete type=0 #2051 -2024/03/16-23:33:04.689 8f84 Manual compaction at level-0 from '!scenes!fT64AORvwMUdHzwr' @ 72057594037927935 : 1 .. '!scenes.walls!w5eztsez7EhiFrmE.zlashxFbpTyjyOHo' @ 0 : 0; will stop at (end) -2024/03/16-23:33:04.689 8f84 Manual compaction at level-1 from '!scenes!fT64AORvwMUdHzwr' @ 72057594037927935 : 1 .. '!scenes.walls!w5eztsez7EhiFrmE.zlashxFbpTyjyOHo' @ 0 : 0; will stop at (end) +2024/03/22-16:56:02.550 195c Recovering log #2091 +2024/03/22-16:56:02.553 195c Delete type=0 #2091 +2024/03/22-16:56:02.553 195c Delete type=3 #2090 diff --git a/packs/levels-samples/MANIFEST-002054 b/packs/levels-samples/MANIFEST-002094 similarity index 86% rename from packs/levels-samples/MANIFEST-002054 rename to packs/levels-samples/MANIFEST-002094 index 2e2489a..fe70246 100644 Binary files a/packs/levels-samples/MANIFEST-002054 and b/packs/levels-samples/MANIFEST-002094 differ diff --git a/packs/macros/002055.log b/packs/macros/002095.log similarity index 100% rename from packs/macros/002055.log rename to packs/macros/002095.log diff --git a/packs/macros/CURRENT b/packs/macros/CURRENT index 4c0052f..9ba62b9 100644 --- a/packs/macros/CURRENT +++ b/packs/macros/CURRENT @@ -1 +1 @@ -MANIFEST-002054 +MANIFEST-002094 diff --git a/packs/macros/LOG b/packs/macros/LOG index 30d3a15..222e718 100644 --- a/packs/macros/LOG +++ b/packs/macros/LOG @@ -1,3 +1,3 @@ -2024/03/17-14:22:08.900 3084 Recovering log #2052 -2024/03/17-14:22:08.904 3084 Delete type=0 #2052 -2024/03/17-14:22:08.905 3084 Delete type=3 #2050 +2024/03/23-17:18:29.275 12c0 Recovering log #2093 +2024/03/23-17:18:29.280 12c0 Delete type=0 #2093 +2024/03/23-17:18:29.280 12c0 Delete type=3 #2092 diff --git a/packs/macros/LOG.old b/packs/macros/LOG.old index 9ea36fb..e7e4a0e 100644 --- a/packs/macros/LOG.old +++ b/packs/macros/LOG.old @@ -1,8 +1,3 @@ -2024/03/16-23:28:33.209 913c Recovering log #2048 -2024/03/16-23:28:33.218 913c Delete type=0 #2048 -2024/03/16-23:28:33.218 913c Delete type=3 #2046 -2024/03/16-23:33:04.683 8f84 Level-0 table #2053: started -2024/03/16-23:33:04.683 8f84 Level-0 table #2053: 0 bytes OK -2024/03/16-23:33:04.685 8f84 Delete type=0 #2051 -2024/03/16-23:33:04.685 8f84 Manual compaction at level-0 from '!macros!2LfY4Ky5rRDkK7h8' @ 72057594037927935 : 1 .. '!macros!yx7Eb76rfzjh0LEO' @ 0 : 0; will stop at (end) -2024/03/16-23:33:04.685 8f84 Manual compaction at level-1 from '!macros!2LfY4Ky5rRDkK7h8' @ 72057594037927935 : 1 .. '!macros!yx7Eb76rfzjh0LEO' @ 0 : 0; will stop at (end) +2024/03/22-16:56:02.537 6e8c Recovering log #2091 +2024/03/22-16:56:02.541 6e8c Delete type=0 #2091 +2024/03/22-16:56:02.541 6e8c Delete type=3 #2090 diff --git a/packs/macros/MANIFEST-002054 b/packs/macros/MANIFEST-002094 similarity index 52% rename from packs/macros/MANIFEST-002054 rename to packs/macros/MANIFEST-002094 index 1d7aa87..5f18bdb 100644 Binary files a/packs/macros/MANIFEST-002054 and b/packs/macros/MANIFEST-002094 differ diff --git a/scripts/ui.js b/scripts/ui.js index 997537e..9529d1b 100644 --- a/scripts/ui.js +++ b/scripts/ui.js @@ -1,804 +1,694 @@ class LevelsUI extends FormApplication { - constructor() { - super(); - this.range = []; - this.rangeEnabled = false; - this.isEdit = false; - this.definedLevels = []; - this.roofEnabled = false; - this.placeOverhead = false; - this.stairEnabled = true; - } - - static get defaultOptions() { - return { - ...super.defaultOptions, - title: game.i18n.localize("levels.ui.title"), - id: "levelsUI", - template: `modules/levels/templates/layerTool.hbs`, - resizable: true, - dragDrop: [{ dragSelector: null, dropSelector: null }], - }; - } - - get currentRange() { - const bgElev = canvas.primary.background.elevation; - if(!this.rangeEnabled) return { bottom: bgElev, top: bgElev }; - if(!this.range?.length) return { bottom: bgElev, top: bgElev }; - return { - bottom: parseFloat(this.range[0]), - top: parseFloat(this.range[1]), + constructor() { + super(); + this.range = []; + this.rangeEnabled = false; + this.isEdit = false; + this.definedLevels = []; + this.roofEnabled = false; + this.placeOverhead = false; + this.stairEnabled = true; + this.tokenOnly = false; } - } - getRange() { - return { - bottom: parseFloat(this.range[0] ?? -Infinity), - top: parseFloat(this.range[1] ?? Infinity), + static get defaultOptions() { + return { + ...super.defaultOptions, + title: game.i18n.localize("levels.ui.title"), + id: "levelsUI", + template: `modules/levels/templates/layerTool.hbs`, + resizable: true, + dragDrop: [{ dragSelector: null, dropSelector: null }], + }; } - } - getData() { - return { - lightMasking: canvas.scene.getFlag(CONFIG.Levels.MODULE_ID, "lightMasking") ?? true, - }; - } - - async activateListeners(html) { - ui.controls.control.foreground = true; - canvas.tiles._activateSubLayer(true); - this.rangeEnabled = true; - this.loadLevels(); - html.on("click", ".level-item", this._onChangeLevel.bind(this)); - html.on("click", ".level-item .fa-trash", this._onRemoveLevel.bind(this)); - html.on( - "click", - "#levels-ui-controls .fa-trash", - this._onClearLevels.bind(this) - ); - html.on( - "click", - "#levels-ui-controls .fa-plus", - this._onAddLevel.bind(this) - ); - html.on( - "click", - "#levels-ui-controls .fa-edit", - this._onToggleEdit.bind(this) - ); - html.on( - "click", - "#levels-ui-controls .fa-map", - this._onGetFromScene.bind(this) - ); - html.on( - "click", - "#levels-ui-controls .fa-users", - this._onShowPlayerList.bind(this) - ); - html.on( - "click", - "#levels-ui-controls .fa-archway", - () => { - this.roofEnabled = !this.roofEnabled; - this.setButtonStyles(); - this.computeLevelsVisibility(); - } - ); - html.on( - "click", - "#levels-ui-controls .fa-tree", - () => { - this.placeOverhead = !this.placeOverhead; + get currentRange() { + const bgElev = canvas.primary.background.elevation; + if (!this.rangeEnabled) return { bottom: bgElev, top: bgElev }; + if (!this.range?.length) return { bottom: bgElev, top: bgElev }; + return { + bottom: parseFloat(this.range[0]), + top: parseFloat(this.range[1]), + }; + } + + getRange() { + return { + bottom: parseFloat(this.range[0] ?? -Infinity), + top: parseFloat(this.range[1] ?? Infinity), + }; + } + + getData() { + return { + lightMasking: canvas.scene.getFlag(CONFIG.Levels.MODULE_ID, "lightMasking") ?? true, + }; + } + + async activateListeners(html) { + ui.controls.control.foreground = true; + canvas.tiles._activateSubLayer(true); + this.rangeEnabled = true; + this.loadLevels(); + html.on("click", ".level-item", this._onChangeLevel.bind(this)); + html.on("click", ".level-item .fa-trash", this._onRemoveLevel.bind(this)); + html.on("click", "#levels-ui-controls .fa-trash", this._onClearLevels.bind(this)); + html.on("click", "#levels-ui-controls .fa-plus", this._onAddLevel.bind(this)); + html.on("click", "#levels-ui-controls .fa-edit", this._onToggleEdit.bind(this)); + html.on("click", "#levels-ui-controls .fa-map", this._onGetFromScene.bind(this)); + html.on("click", "#levels-ui-controls .fa-users", this._onShowPlayerList.bind(this)); + html.on("click", "#levels-ui-controls .fa-archway", () => { + this.roofEnabled = !this.roofEnabled; + this.setButtonStyles(); + this.computeLevelsVisibility(); + }); + html.on("click", "#levels-ui-controls .fa-tree", () => { + this.placeOverhead = !this.placeOverhead; + this.setButtonStyles(); + }); + html.on("click", "#levels-ui-controls .fa-sort-amount-up-alt", () => { + this.stairEnabled = !this.stairEnabled; + this.setButtonStyles(); + }); + html.on("click", "#levels-ui-controls .fa-circle-exclamation", async () => { + await canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "lightMasking", false); + this.render(true); + }); + + html.on("click", "#levels-ui-controls .fa-link", async () => { + this.tokenOnly = !this.tokenOnly; this.setButtonStyles(); - } - ); - html.on( - "click", - "#levels-ui-controls .fa-sort-amount-up-alt", - () => { - this.stairEnabled = !this.stairEnabled; + }); + + html.on("drop", (event) => { + let data; + try { + data = JSON.parse(event.originalEvent.dataTransfer.getData("text/plain")); + } catch (err) { + return false; + } + if (data.type === "Scene") this._onDropScene(data.uuid); + }); + + html.on("click", ".player-portrait", this._onControlToken.bind(this)); + html.on("change", ".level-inputs input", this.saveData.bind(this)); + //make list sortable + html.find("#levels-list").sortable({ + axis: "y", + handle: ".fa-arrows-alt", + update: this.saveData.bind(this), + }); + const index = this.definedLevels ? this.definedLevels.indexOf(this.definedLevels.find((l) => l[0] == this.range[0] && l[1] == this.range[1] && l[2] == this.range[2])) : undefined; + if (index === undefined || index === -1) { + html.find("#levels-list li:last-child").click(); + } else html.find("#levels-list li")[index].click(); + this.updatePlayerList(); this.setButtonStyles(); - } - ); - html.on( - "click", - "#levels-ui-controls .fa-circle-exclamation", - async () => { - await canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "lightMasking", false); - this.render(true); - } - ) - - html.on("drop", (event) => { - let data; - try { - data = JSON.parse(event.originalEvent.dataTransfer.getData("text/plain")); - } catch (err) { - return false; - } - if(data.type === "Scene") this._onDropScene(data.uuid) - }); - - html.on("click", ".player-portrait", this._onControlToken.bind(this)); - html.on("change", ".level-inputs input", this.saveData.bind(this)); - //make list sortable - html.find("#levels-list").sortable({ - axis: "y", - handle: ".fa-arrows-alt", - update: this.saveData.bind(this), - }); - const index = this.definedLevels - ? this.definedLevels.indexOf( - this.definedLevels.find( - (l) => - l[0] == this.range[0] && - l[1] == this.range[1] && - l[2] == this.range[2] - ) - ) - : undefined; - if (index === undefined || index === -1) { - html.find("#levels-list li:last-child").click(); - } else html.find("#levels-list li")[index].click(); - this.updatePlayerList(); - this.setButtonStyles(); - } - - setButtonStyles() { - this.element.find(".fa-archway").toggleClass("active", this.roofEnabled); - this.element.find(".fa-tree").toggleClass("active", this.placeOverhead); - this.element.find(".fa-sort-amount-up-alt").toggleClass("active", this.stairEnabled); - this.element.find(".fa-users").toggleClass("active", this.element.find(".players-on-level").hasClass("active")); - } - - _onAddLevel(event) { - let $li = this.generateLi([0, 0, ""]); - $("#levels-list").append($li); - } - //toggle readonly property of inputs and toggle visibility of trash icon - _onToggleEdit(event) { - this.isEdit = !this.isEdit; - let $inputs = $(".level-inputs input"); - $inputs.prop("readonly", !$inputs.prop("readonly")); - $(".level-item .fa-trash").toggleClass("hidden"); - $(".level-item .fa-arrows-alt").toggleClass("hidden"); - this.saveData(); - } - - activateForeground(){ - try{ - ui.controls.control.foreground = true; - ui.controls.control.foreground = true; - canvas.tiles._activateSubLayer(true); - canvas.perception.update({refreshLighting: true, refreshTiles: true}, true); - const fgControl = document.querySelector(`[data-tool="foreground"]`) - if(fgControl) fgControl.classList.add("active") - }catch(e){} - } - - _onChangeLevel(event) { - this.activateForeground() - if (!$(event.target).hasClass("player-portrait")) - canvas.tokens.releaseAll(); - let $target = $(event.currentTarget); - let $parent = $target.parent(); - $parent.find(".fa-caret-right").removeClass("active"); - $parent.find("li").removeClass("active"); - $target.find(".fa-caret-right").addClass("active"); - $target.addClass("active"); - const top = $target.find(".level-top").val(); - const bottom = $target.find(".level-bottom").val(); - const name = $target.find(".level-name").val(); - this.definedLevels = canvas.scene.getFlag( - CONFIG.Levels.MODULE_ID, - "sceneLevels" - ); - this.range = this.definedLevels?.find((l) => l[0] == bottom && l[1] == top) ?? [parseFloat(bottom), parseFloat(top)]; - if ($(event.target).hasClass("player-portrait")) return; - WallHeight.currentTokenElevation = parseFloat(bottom); - this.computeLevelsVisibility(this.range); - Hooks.callAll("levelsUiChangeLevel"); - } - - _onRemoveLevel(event) { - Dialog.confirm({ - title: game.i18n.localize("levels.dialog.removeLevel.title"), - content: game.i18n.localize("levels.dialog.removeLevel.content"), - yes: () => { - let $target = $(event.currentTarget); - $target.remove(); + } + + setButtonStyles() { + this.element.find(".fa-archway").toggleClass("active", this.roofEnabled); + this.element.find(".fa-tree").toggleClass("active", this.placeOverhead); + this.element.find(".fa-sort-amount-up-alt").toggleClass("active", this.stairEnabled); + this.element.find(".fa-users").toggleClass("active", this.element.find(".players-on-level").hasClass("active")); + this.element.find(".fa-link").toggleClass("active", this.tokenOnly); + } + + _onAddLevel(event) { + let $li = this.generateLi([0, 0, ""]); + $("#levels-list").append($li); + } + //toggle readonly property of inputs and toggle visibility of trash icon + _onToggleEdit(event) { + this.isEdit = !this.isEdit; + let $inputs = $(".level-inputs input"); + $inputs.prop("readonly", !$inputs.prop("readonly")); + $(".level-item .fa-trash").toggleClass("hidden"); + $(".level-item .fa-arrows-alt").toggleClass("hidden"); this.saveData(); - }, - no: () => {}, - defaultYes: false, - }); - } - - _onGetFromScene(event) { - Dialog.confirm({ - title: game.i18n.localize("levels.dialog.getFromScene.title"), - content: game.i18n.localize("levels.dialog.getFromScene.content"), - yes: (html) => { - const maxRange = parseFloat(html.find("#maxelevationdifference").val()); - this.getFromScene(maxRange); - }, - no: () => {}, - render: (html) => { - const maxRange = ` + } + + activateForeground() { + try { + ui.controls.control.foreground = true; + ui.controls.control.foreground = true; + canvas.tiles._activateSubLayer(true); + canvas.perception.update({ refreshLighting: true, refreshTiles: true }, true); + const fgControl = document.querySelector(`[data-tool="foreground"]`); + if (fgControl) fgControl.classList.add("active"); + } catch (e) {} + } + + _onChangeLevel(event) { + this.activateForeground(); + if (!$(event.target).hasClass("player-portrait")) canvas.tokens.releaseAll(); + let $target = $(event.currentTarget); + let $parent = $target.parent(); + $parent.find(".fa-caret-right").removeClass("active"); + $parent.find("li").removeClass("active"); + $target.find(".fa-caret-right").addClass("active"); + $target.addClass("active"); + const top = $target.find(".level-top").val(); + const bottom = $target.find(".level-bottom").val(); + const name = $target.find(".level-name").val(); + this.definedLevels = canvas.scene.getFlag(CONFIG.Levels.MODULE_ID, "sceneLevels"); + this.range = this.definedLevels?.find((l) => l[0] == bottom && l[1] == top) ?? [parseFloat(bottom), parseFloat(top)]; + if ($(event.target).hasClass("player-portrait")) return; + WallHeight.currentTokenElevation = parseFloat(bottom); + this.computeLevelsVisibility(this.range); + Hooks.callAll("levelsUiChangeLevel"); + } + + _onRemoveLevel(event) { + Dialog.confirm({ + title: game.i18n.localize("levels.dialog.removeLevel.title"), + content: game.i18n.localize("levels.dialog.removeLevel.content"), + yes: () => { + let $target = $(event.currentTarget); + $target.remove(); + this.saveData(); + }, + no: () => {}, + defaultYes: false, + }); + } + + _onGetFromScene(event) { + Dialog.confirm({ + title: game.i18n.localize("levels.dialog.getFromScene.title"), + content: game.i18n.localize("levels.dialog.getFromScene.content"), + yes: (html) => { + const maxRange = parseFloat(html.find("#maxelevationdifference").val()); + this.getFromScene(maxRange); + }, + no: () => {}, + render: (html) => { + const maxRange = `

- ` - $(html[0]).append(maxRange); - }, - defaultYes: false, - }); - } - - _onShowPlayerList(event) { - this.element.find(".players-on-level").toggleClass("active"); - this.setButtonStyles(); - } - - _onControlToken(event) { - canvas.tokens.releaseAll(); - const tokenId = event.currentTarget.dataset.tokenid; - const token = canvas.tokens.get(tokenId); - token.control(); - } - - async _onDropScene(uuid) { - const scene = await fromUuid(uuid); - if (!scene) return; - const dialogResult = await Dialog.confirm({ - title: game.i18n.localize("levels.dialog.sceneDrop.title"), - content: game.i18n.localize("levels.dialog.sceneDrop.content"), - }) - if (!dialogResult) return; - const collections = Object.keys(scene.collections); - for (const collection of collections) { - const documents = Array.from(scene[collection]); - if(!documents.length) continue; - await canvas.scene.createEmbeddedDocuments(documents[0].documentName, documents); + `; + $(html[0]).append(maxRange); + }, + defaultYes: false, + }); } - const sceneBg = scene.background.src; - if(!sceneBg) return; - const {sceneWidth, sceneHeight, sceneX, sceneY} = scene.dimensions; - await canvas.scene.createEmbeddedDocuments("Tile", [{ - "texture.src": sceneBg, - "width": sceneWidth, - "height": sceneHeight, - "x": sceneX, - "y": sceneY, - }]); - } - - saveData() { - let data = []; - $(this.element) - .find("li") - .each((index, element) => { - let $element = $(element); - let name = $element.find(".level-name").val(); - let top = $element.find(".level-top").val(); - let bottom = $element.find(".level-bottom").val(); - data.push([bottom, top, name]); - }); - canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "sceneLevels", data); - } - - async loadLevels() { - $("#levels-list").empty(); - let levelsFlag = - canvas.scene.getFlag(CONFIG.Levels.MODULE_ID, "sceneLevels") || []; - this.definedLevels = levelsFlag; - this.range = this.range ?? this.definedLevels[levelsFlag.length - 1]; - if (levelsFlag) { - for (let level of levelsFlag) { - this.element.find("#levels-list").append(this.generateLi(level)); - } + + _onShowPlayerList(event) { + this.element.find(".players-on-level").toggleClass("active"); + this.setButtonStyles(); + } + + _onControlToken(event) { + canvas.tokens.releaseAll(); + const tokenId = event.currentTarget.dataset.tokenid; + const token = canvas.tokens.get(tokenId); + token.control(); } - } - generateLi(data) { - //data 0 - top 1- bottom 2- name - let $li = $(` + async _onDropScene(uuid) { + const scene = await fromUuid(uuid); + if (!scene) return; + const dialogResult = await Dialog.confirm({ + title: game.i18n.localize("levels.dialog.sceneDrop.title"), + content: game.i18n.localize("levels.dialog.sceneDrop.content"), + }); + if (!dialogResult) return; + const collections = Object.keys(scene.collections); + for (const collection of collections) { + const documents = Array.from(scene[collection]); + if (!documents.length) continue; + await canvas.scene.createEmbeddedDocuments(documents[0].documentName, documents); + } + const sceneBg = scene.background.src; + if (!sceneBg) return; + const { sceneWidth, sceneHeight, sceneX, sceneY } = scene.dimensions; + await canvas.scene.createEmbeddedDocuments("Tile", [ + { + "texture.src": sceneBg, + width: sceneWidth, + height: sceneHeight, + x: sceneX, + y: sceneY, + }, + ]); + } + + saveData() { + let data = []; + $(this.element) + .find("li") + .each((index, element) => { + let $element = $(element); + let name = $element.find(".level-name").val(); + let top = $element.find(".level-top").val(); + let bottom = $element.find(".level-bottom").val(); + data.push([bottom, top, name]); + }); + canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "sceneLevels", data); + } + + async loadLevels() { + $("#levels-list").empty(); + let levelsFlag = canvas.scene.getFlag(CONFIG.Levels.MODULE_ID, "sceneLevels") || []; + this.definedLevels = levelsFlag; + this.range = this.range ?? this.definedLevels[levelsFlag.length - 1]; + if (levelsFlag) { + for (let level of levelsFlag) { + this.element.find("#levels-list").append(this.generateLi(level)); + } + } + } + + generateLi(data) { + //data 0 - top 1- bottom 2- name + let $li = $(`
  • - + - +
  • `); - $li.find("input").prop("readonly", !this.isEdit); - $li.find(".fa-trash").toggleClass("hidden", this.isEdit); - $li.find(".fa-arrows-alt").toggleClass("hidden", this.isEdit); - return $li; - } - - async _onClearLevels() { - Dialog.confirm({ - title: game.i18n.localize("levels.dialog.levelsclear.title"), - content: game.i18n.localize("levels.dialog.levelsclear.content"), - yes: async () => { - await canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "sceneLevels", []); - this.loadLevels(); - }, - no: () => {}, - defaultYes: false, - }); - } - - updatePlayerList() { - const playerActors = Array.from(game.users).map( - (user) => user.character?.id - ); - const players = canvas.tokens.placeables.filter((token) => - playerActors.includes(token.actor?.id) - ); - $(this.element) - .find("li") - .each((index, element) => { - let $element = $(element); - const top = $element.find(".level-top").val(); - const bottom = $element.find(".level-bottom").val(); - const $playerList = $element.find(".players-on-level"); - $playerList.empty(); - players.forEach((player) => { - if ( - player.losHeight >= bottom && - player.losHeight < top && - player.id - ) { - const color = Array.from(game.users).find( - (user) => user.character?.id == player?.actor?.id - )?.border; - $playerList.append( - `` - ); - } + $li.find("input").prop("readonly", !this.isEdit); + $li.find(".fa-trash").toggleClass("hidden", this.isEdit); + $li.find(".fa-arrows-alt").toggleClass("hidden", this.isEdit); + return $li; + } + + async _onClearLevels() { + Dialog.confirm({ + title: game.i18n.localize("levels.dialog.levelsclear.title"), + content: game.i18n.localize("levels.dialog.levelsclear.content"), + yes: async () => { + await canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "sceneLevels", []); + this.loadLevels(); + }, + no: () => {}, + defaultYes: false, }); - }); - this.element.css("height", "auto"); - } - - close(force = false) { - if (!force) this.saveData(); - this.rangeEnabled = false; - if (!force) this.computeLevelsVisibility(); - CONFIG.Levels.handlers.RefreshHandler.restoreVisAll(); - CONFIG.Levels.handlers.RefreshHandler.refreshAll(); - WallHeight.schedulePerceptionUpdate() - super.close(); - } - - async getFromScene(maxRange = 9) { - let autoLevels = {}; - for (let wall of canvas.walls.placeables) { - const { top, bottom } = WallHeight.getWallBounds(wall); - let entityRange = [bottom, top]; - if ( - entityRange[0] != -Infinity && - entityRange[1] != Infinity && - (entityRange[0] || entityRange[0] == 0) && - (entityRange[1] || entityRange[1] == 0) - ) { - autoLevels[`${entityRange[0]}${entityRange[1]}`] = entityRange; - } } - for (let tile of canvas.tiles.placeables.filter( - (t) => t.document.overhead - )) { - let { rangeBottom, rangeTop } = - CONFIG.Levels.helpers.getRangeForDocument(tile); - if ( - (rangeBottom || rangeBottom == 0) && - (rangeTop || rangeTop == 0) && - rangeTop != Infinity && - rangeBottom != -Infinity - ) { - autoLevels[`${rangeBottom}${rangeTop}`] = [rangeBottom, rangeTop]; - } + updatePlayerList() { + const playerActors = Array.from(game.users).map((user) => user.character?.id); + const players = canvas.tokens.placeables.filter((token) => playerActors.includes(token.actor?.id)); + $(this.element) + .find("li") + .each((index, element) => { + let $element = $(element); + const top = $element.find(".level-top").val(); + const bottom = $element.find(".level-bottom").val(); + const $playerList = $element.find(".players-on-level"); + $playerList.empty(); + players.forEach((player) => { + if (player.losHeight >= bottom && player.losHeight < top && player.id) { + const color = Array.from(game.users).find((user) => user.character?.id == player?.actor?.id)?.border; + $playerList.append(``); + } + }); + }); + this.element.css("height", "auto"); } - for (let light of canvas.lighting.placeables) { - let { rangeBottom, rangeTop } = - CONFIG.Levels.helpers.getRangeForDocument(light); - if ( - (rangeBottom || rangeBottom == 0) && - (rangeTop || rangeTop == 0) && - rangeTop != Infinity && - rangeBottom != -Infinity - ) { - autoLevels[`${rangeBottom}${rangeTop}`] = [rangeBottom, rangeTop]; - } + close(force = false) { + if (!force) this.saveData(); + this.rangeEnabled = false; + if (!force) this.computeLevelsVisibility(); + CONFIG.Levels.handlers.RefreshHandler.restoreVisAll(); + CONFIG.Levels.handlers.RefreshHandler.refreshAll(); + WallHeight.schedulePerceptionUpdate(); + super.close(); } - for (let drawing of canvas.drawings.placeables) { - let { rangeBottom, rangeTop } = - CONFIG.Levels.helpers.getRangeForDocument(drawing); - if ( - (rangeBottom || rangeBottom == 0) && - (rangeTop || rangeTop == 0) && - rangeTop != Infinity && - rangeBottom != -Infinity - ) { - autoLevels[`${rangeBottom}${rangeTop}`] = [rangeBottom, rangeTop]; - } + async getFromScene(maxRange = 9) { + let autoLevels = {}; + for (let wall of canvas.walls.placeables) { + const { top, bottom } = WallHeight.getWallBounds(wall); + let entityRange = [bottom, top]; + if (entityRange[0] != -Infinity && entityRange[1] != Infinity && (entityRange[0] || entityRange[0] == 0) && (entityRange[1] || entityRange[1] == 0)) { + autoLevels[`${entityRange[0]}${entityRange[1]}`] = entityRange; + } + } + + for (let tile of canvas.tiles.placeables.filter((t) => t.document.overhead)) { + let { rangeBottom, rangeTop } = CONFIG.Levels.helpers.getRangeForDocument(tile); + if ((rangeBottom || rangeBottom == 0) && (rangeTop || rangeTop == 0) && rangeTop != Infinity && rangeBottom != -Infinity) { + autoLevels[`${rangeBottom}${rangeTop}`] = [rangeBottom, rangeTop]; + } + } + + for (let light of canvas.lighting.placeables) { + let { rangeBottom, rangeTop } = CONFIG.Levels.helpers.getRangeForDocument(light); + if ((rangeBottom || rangeBottom == 0) && (rangeTop || rangeTop == 0) && rangeTop != Infinity && rangeBottom != -Infinity) { + autoLevels[`${rangeBottom}${rangeTop}`] = [rangeBottom, rangeTop]; + } + } + + for (let drawing of canvas.drawings.placeables) { + let { rangeBottom, rangeTop } = CONFIG.Levels.helpers.getRangeForDocument(drawing); + if ((rangeBottom || rangeBottom == 0) && (rangeTop || rangeTop == 0) && rangeTop != Infinity && rangeBottom != -Infinity) { + autoLevels[`${rangeBottom}${rangeTop}`] = [rangeBottom, rangeTop]; + } + } + let autoRange = Object.entries(autoLevels) + .map((x) => x[1]) + .filter((x) => Math.abs(x[1] - x[0]) >= maxRange) + .sort() + .reverse(); + if (autoRange.length) { + await canvas.scene.setFlag(CONFIG.Levels.MODULE_ID, "sceneLevels", autoRange); + this.loadLevels(); + } } - let autoRange = Object.entries(autoLevels) - .map((x) => x[1]) - .filter( x => Math.abs(x[1] - x[0]) >= maxRange) - .sort() - .reverse(); - if (autoRange.length) { - await canvas.scene.setFlag( - CONFIG.Levels.MODULE_ID, - "sceneLevels", - autoRange - ); - this.loadLevels(); + + computeLevelsVisibility() { + WallHeight.currentTokenElevation = parseFloat(this.range[0] ?? 0); + CONFIG.Levels.handlers.RefreshHandler.refreshAll(); + WallHeight.schedulePerceptionUpdate(); } - } - - computeLevelsVisibility() { - WallHeight.currentTokenElevation = parseFloat(this.range[0] ?? 0); - CONFIG.Levels.handlers.RefreshHandler.refreshAll(); - WallHeight.schedulePerceptionUpdate(); - } - - computeRangeForDocument(document, range, isTile = false) { - let { rangeBottom, rangeTop } = - CONFIG.Levels.helpers.getRangeForDocument(document); - rangeBottom = rangeBottom ?? -Infinity; - rangeTop = rangeTop ?? Infinity; - range[0] = parseFloat(range[0]) ?? -Infinity; - range[1] = parseFloat(range[1]) ?? Infinity; - let entityRange = [rangeBottom, rangeTop]; - if (!isTile) { - if ( - (entityRange[0] >= range[0] && entityRange[0] <= range[1]) || - (entityRange[1] >= range[0] && entityRange[1] <= range[1]) - ) { - return true; - } else { - return false; - } - } else { - if (entityRange[0] == range[1] + 1 && entityRange[1] == Infinity) { - return true; - } else { - if (entityRange[0] >= range[0] && entityRange[1] <= range[1]) { - return true; + + computeRangeForDocument(document, range, isTile = false) { + let { rangeBottom, rangeTop } = CONFIG.Levels.helpers.getRangeForDocument(document); + rangeBottom = rangeBottom ?? -Infinity; + rangeTop = rangeTop ?? Infinity; + range[0] = parseFloat(range[0]) ?? -Infinity; + range[1] = parseFloat(range[1]) ?? Infinity; + let entityRange = [rangeBottom, rangeTop]; + if (!isTile) { + if ((entityRange[0] >= range[0] && entityRange[0] <= range[1]) || (entityRange[1] >= range[0] && entityRange[1] <= range[1])) { + return true; + } else { + return false; + } } else { - return false; + if (entityRange[0] == range[1] + 1 && entityRange[1] == Infinity) { + return true; + } else { + if (entityRange[0] >= range[0] && entityRange[1] <= range[1]) { + return true; + } else { + return false; + } + } } - } } - } - - getObjUpdateData(range) { - return { - flags: { - [`${CONFIG.Levels.MODULE_ID}`]: { - rangeBottom: parseFloat(range[0]), - rangeTop: parseFloat(range[1]), - }, - }, - }; - } - async elevationDialog(tool) { - let content = ` + getObjUpdateData(range) { + return { + flags: { + [`${CONFIG.Levels.MODULE_ID}`]: { + rangeBottom: parseFloat(range[0]), + rangeTop: parseFloat(range[1]), + }, + }, + }; + } + + async elevationDialog(tool) { + let content = `
    - +
    - +

    - +

    `; - let ignoreClose = false; - let toolhtml = $("body").find(`li[data-tool="setTemplateElevation"]`); - let dialog = new Dialog({ - title: game.i18n.localize("levels.dialog.elevation.title"), - content: content, - buttons: { - confirm: { - label: game.i18n.localize("levels.yesnodialog.yes"), - callback: (html) => { - CONFIG.Levels.UI.nextTemplateHeight = html.find( - `input[name="templateElevation"]` - )[0].valueAsNumber; - CONFIG.Levels.UI.nextTemplateSpecial = html.find( - `input[name="special"]` - )[0].valueAsNumber; - CONFIG.Levels.UI.templateElevation = true; - ignoreClose = true; - tool.active = true; - if (toolhtml[0]) - $("body") - .find(`li[data-tool="setTemplateElevation"]`) - .addClass("active"); - }, - }, - close: { - label: game.i18n.localize("levels.yesnodialog.no"), - callback: () => { - CONFIG.Levels.UI.nextTemplateHeight = undefined; - CONFIG.Levels.UI.nextTemplateSpecial = undefined; - CONFIG.Levels.UI.templateElevation = false; - tool.active = false; - if (toolhtml[0]) - $("body") - .find(`li[data-tool="setTemplateElevation"]`) - .removeClass("active"); - }, - }, - }, - default: "confirm", - close: () => { - if (ignoreClose == true) { - ignoreClose = false; - return; - } - CONFIG.Levels.nextTemplateHeight = undefined; - CONFIG.Levels.nextTemplateSpecial = undefined; - CONFIG.Levels.templateElevation = false; - tool.active = false; - if (toolhtml[0]) - $("body") - .find(`li[data-tool="setTemplateElevation"]`) - .removeClass("active"); - }, - }); - await dialog._render(true); - } + let ignoreClose = false; + let toolhtml = $("body").find(`li[data-tool="setTemplateElevation"]`); + let dialog = new Dialog({ + title: game.i18n.localize("levels.dialog.elevation.title"), + content: content, + buttons: { + confirm: { + label: game.i18n.localize("levels.yesnodialog.yes"), + callback: (html) => { + CONFIG.Levels.UI.nextTemplateHeight = html.find(`input[name="templateElevation"]`)[0].valueAsNumber; + CONFIG.Levels.UI.nextTemplateSpecial = html.find(`input[name="special"]`)[0].valueAsNumber; + CONFIG.Levels.UI.templateElevation = true; + ignoreClose = true; + tool.active = true; + if (toolhtml[0]) $("body").find(`li[data-tool="setTemplateElevation"]`).addClass("active"); + }, + }, + close: { + label: game.i18n.localize("levels.yesnodialog.no"), + callback: () => { + CONFIG.Levels.UI.nextTemplateHeight = undefined; + CONFIG.Levels.UI.nextTemplateSpecial = undefined; + CONFIG.Levels.UI.templateElevation = false; + tool.active = false; + if (toolhtml[0]) $("body").find(`li[data-tool="setTemplateElevation"]`).removeClass("active"); + }, + }, + }, + default: "confirm", + close: () => { + if (ignoreClose == true) { + ignoreClose = false; + return; + } + CONFIG.Levels.nextTemplateHeight = undefined; + CONFIG.Levels.nextTemplateSpecial = undefined; + CONFIG.Levels.templateElevation = false; + tool.active = false; + if (toolhtml[0]) $("body").find(`li[data-tool="setTemplateElevation"]`).removeClass("active"); + }, + }); + await dialog._render(true); + } } $(document).on("click", `li[data-control="levels"]`, (e) => { - CONFIG.Levels.UI.render(true); -}) + CONFIG.Levels.UI.render(true); +}); Hooks.on("renderSceneControls", (controls, b, c) => { - if(game.user.isGM){ - $(".main-controls").append(` + if (game.user.isGM) { + $(".main-controls").append(`
  • - `) - } + `); + } }); Hooks.on("ready", () => { - if (game.user.isGM) { - - Hooks.on("activateTilesLayer", ()=>{ - if(CONFIG.Levels.UI.rangeEnabled){ - Hooks.once("renderSceneControls", ()=>{ - CONFIG.Levels.UI.activateForeground(); - }) - } - }) - - Hooks.on("canvasInit", () => { - CONFIG.Levels.UI.close(true); - }) - - Hooks.on("updateToken", (token,updates)=>{ - if("elevation" in updates)CONFIG.Levels.UI.updatePlayerList(); - }) - - Hooks.on("createToken", (token,updates)=>{ - CONFIG.Levels.UI.updatePlayerList(); - }) - - Hooks.on("deleteToken", (token,updates)=>{ - CONFIG.Levels.UI.updatePlayerList(); - }) - - Hooks.on("controlToken", (token,controlled)=>{ - if(CONFIG.Levels.UI.rangeEnabled && !canvas.tokens.controlled.length){ - CONFIG.Levels.UI.computeLevelsVisibility(); - }else if(CONFIG.Levels.UI.rangeEnabled){ - CONFIG.Levels.handlers.RefreshHandler.refresh(canvas.tokens); - } - }) - - Hooks.on("renderLevelsUI", (app, html) => { - - if(!app.positionSet){ - console.log((window.innerWidth - $("#sidebar").width() - $("#levelsUI").width())) - app.setPosition({ - top: 2, - left: (window.innerWidth - $("#sidebar").width() - $("#levelsUI").width()) - 10, - width: $("#levelsUI").width(), - height: Math.max(150, $("#levelsUI").height()) + 10, + if (game.user.isGM) { + Hooks.on("activateTilesLayer", () => { + if (CONFIG.Levels.UI.rangeEnabled) { + Hooks.once("renderSceneControls", () => { + CONFIG.Levels.UI.activateForeground(); + }); + } }); - app.positionSet = true - } - }) - - Hooks.on("preCreateTile", (tile, updates) => { - if (CONFIG.Levels.UI.rangeEnabled == true) { - tile.updateSource({ - overhead: true, + + Hooks.on("canvasInit", () => { + CONFIG.Levels.UI.close(true); }); - if(!game.Levels3DPreview?._active){ - tile.updateSource({ - flags: { - "betterroofs": { - brMode: CONFIG.Levels.UI.roofEnabled, - }, - [`${CONFIG.Levels.MODULE_ID}`]: { - rangeBottom: CONFIG.Levels.UI.roofEnabled - ? parseFloat(CONFIG.Levels.UI.range[1]) - : parseFloat(CONFIG.Levels.UI.range[0]), - rangeTop: CONFIG.Levels.UI.roofEnabled ? Infinity : parseFloat(CONFIG.Levels.UI.range[1]), - allWallBlockSight: CONFIG.Levels.UI.roofEnabled - } - }, - roof: CONFIG.Levels.UI.roofEnabled, - }); - }else{ - tile.updateSource({ - flags: { - [`${CONFIG.Levels.MODULE_ID}`]: { - rangeTop: CONFIG.Levels.UI.roofEnabled ? Infinity : CONFIG.Levels.UI.range[1], - } + + Hooks.on("updateToken", (token, updates) => { + if ("elevation" in updates) CONFIG.Levels.UI.updatePlayerList(); + }); + + Hooks.on("createToken", (token, updates) => { + CONFIG.Levels.UI.updatePlayerList(); + }); + + Hooks.on("deleteToken", (token, updates) => { + CONFIG.Levels.UI.updatePlayerList(); + }); + + Hooks.on("controlToken", (token, controlled) => { + if (CONFIG.Levels.UI.rangeEnabled && !canvas.tokens.controlled.length) { + CONFIG.Levels.UI.computeLevelsVisibility(); + } else if (CONFIG.Levels.UI.rangeEnabled) { + CONFIG.Levels.handlers.RefreshHandler.refresh(canvas.tokens); } - }); - } - if(CONFIG.Levels.UI.placeOverhead){ + }); - tile.updateSource({ - roof: false, - flags: { - [`${CONFIG.Levels.MODULE_ID}`]: { - showIfAbove: true, - noCollision: true, - showAboveRange: parseFloat(CONFIG.Levels.UI.range[1]) - parseFloat(CONFIG.Levels.UI.range[0]), - rangeBottom: parseFloat(CONFIG.Levels.UI.range[1]), - rangeTop: parseFloat(CONFIG.Levels.UI.range[1]), - } + Hooks.on("renderLevelsUI", (app, html) => { + if (!app.positionSet) { + console.log(window.innerWidth - $("#sidebar").width() - $("#levelsUI").width()); + app.setPosition({ + top: 2, + left: window.innerWidth - $("#sidebar").width() - $("#levelsUI").width() - 10, + width: $("#levelsUI").width(), + height: Math.max(150, $("#levelsUI").height()) + 10, + }); + app.positionSet = true; } - }); - } - } - }); - - Hooks.on("preCreateAmbientLight", (light, updates) => { - if (CONFIG.Levels.UI.rangeEnabled == true && !game.Levels3DPreview?._active) { - light.updateSource(CONFIG.Levels.UI.getObjUpdateData(CONFIG.Levels.UI.range)); - } - }); - - Hooks.on("preCreateAmbientSound", (sound, updates) => { - if (CONFIG.Levels.UI.rangeEnabled == true) { - sound.updateSource(CONFIG.Levels.UI.getObjUpdateData(CONFIG.Levels.UI.range)); - } - }); - - Hooks.on("preCreateNote", (note, updates) => { - if (CONFIG.Levels.UI.rangeEnabled == true) { - note.updateSource(CONFIG.Levels.UI.getObjUpdateData(CONFIG.Levels.UI.range)); - } - }); - - Hooks.on("preCreateDrawing", (drawing, updates) => { - let sortedLevels = [...CONFIG.Levels.UI.definedLevels].sort((a, b) => { - return parseFloat(b[0]) - parseFloat(a[0]) - }) - let aboverange = sortedLevels.find(l => CONFIG.Levels.UI.range[0] === l[0] && CONFIG.Levels.UI.range[1] === l[1]) - aboverange = sortedLevels.indexOf(aboverange) === 0 ? undefined : sortedLevels[sortedLevels.indexOf(aboverange) - 1] - - if (aboverange) { - let newTop = aboverange[1]; - let newBot = aboverange[0]; - if (CONFIG.Levels.UI.rangeEnabled == true) { - drawing.updateSource({ - hidden: CONFIG.Levels.UI.stairEnabled, - text: CONFIG.Levels.UI.stairEnabled ? `Levels Stair ${CONFIG.Levels.UI.range[0]}-${newBot}` : "", - flags: { - levels: { - drawingMode: CONFIG.Levels.UI.stairEnabled ? 2 : 0, - rangeBottom: parseFloat(CONFIG.Levels.UI.range[0]), - rangeTop: newBot - 1, - }, - }, - }); - } - } else { - if (CONFIG.Levels.UI.rangeEnabled == true) { - drawing.updateSource({ - hidden: CONFIG.Levels.UI.stairEnabled, - text: CONFIG.Levels.UI.stairEnabled ? `Levels Stair ${CONFIG.Levels.UI.range[0]}-${CONFIG.Levels.UI.range[1] + 1}` : "", - flags: { - levels: { - drawingMode: CONFIG.Levels.UI.stairEnabled ? 2 : 0, - rangeBottom: parseFloat(CONFIG.Levels.UI.range[0]), - rangeTop: parseFloat(CONFIG.Levels.UI.range[1]), - }, - }, - }); - } - } - }); - - Hooks.on("preCreateWall", (wall, updates) => { - if (CONFIG.Levels.UI.rangeEnabled == true) { - wall.updateSource({ - flags: { - "wall-height": { - bottom: parseFloat(CONFIG.Levels.UI.range[0]), - top: parseFloat(CONFIG.Levels.UI.range[1]), - }, - }, }); - } - }); - - Hooks.on("preCreateToken", (token, updates) => { - if (CONFIG.Levels.UI.rangeEnabled == true) { - if(updates) updates.elevation = parseFloat(CONFIG.Levels.UI.range[0]); - token.updateSource({ - elevation: updates?.elevation ?? parseFloat(CONFIG.Levels.UI.range[0]), + + Hooks.on("preCreateTile", (tile, updates) => { + if (CONFIG.Levels.UI.tokensOnly) return; + if (CONFIG.Levels.UI.rangeEnabled == true) { + tile.updateSource({ + overhead: true, + }); + if (!game.Levels3DPreview?._active) { + tile.updateSource({ + flags: { + betterroofs: { + brMode: CONFIG.Levels.UI.roofEnabled, + }, + [`${CONFIG.Levels.MODULE_ID}`]: { + rangeBottom: CONFIG.Levels.UI.roofEnabled ? parseFloat(CONFIG.Levels.UI.range[1]) : parseFloat(CONFIG.Levels.UI.range[0]), + rangeTop: CONFIG.Levels.UI.roofEnabled ? Infinity : parseFloat(CONFIG.Levels.UI.range[1]), + allWallBlockSight: CONFIG.Levels.UI.roofEnabled, + }, + }, + roof: CONFIG.Levels.UI.roofEnabled, + }); + } else { + tile.updateSource({ + flags: { + [`${CONFIG.Levels.MODULE_ID}`]: { + rangeTop: CONFIG.Levels.UI.roofEnabled ? Infinity : CONFIG.Levels.UI.range[1], + }, + }, + }); + } + if (CONFIG.Levels.UI.placeOverhead) { + tile.updateSource({ + roof: false, + flags: { + [`${CONFIG.Levels.MODULE_ID}`]: { + showIfAbove: true, + noCollision: true, + showAboveRange: parseFloat(CONFIG.Levels.UI.range[1]) - parseFloat(CONFIG.Levels.UI.range[0]), + rangeBottom: parseFloat(CONFIG.Levels.UI.range[1]), + rangeTop: parseFloat(CONFIG.Levels.UI.range[1]), + }, + }, + }); + } + } }); - } - }); - } + + Hooks.on("preCreateAmbientLight", (light, updates) => { + if (CONFIG.Levels.UI.tokensOnly) return; + if (CONFIG.Levels.UI.rangeEnabled == true && !game.Levels3DPreview?._active) { + light.updateSource(CONFIG.Levels.UI.getObjUpdateData(CONFIG.Levels.UI.range)); + } + }); + + Hooks.on("preCreateAmbientSound", (sound, updates) => { + if (CONFIG.Levels.UI.tokensOnly) return; + + if (CONFIG.Levels.UI.rangeEnabled == true) { + sound.updateSource(CONFIG.Levels.UI.getObjUpdateData(CONFIG.Levels.UI.range)); + } + }); + + Hooks.on("preCreateNote", (note, updates) => { + if (CONFIG.Levels.UI.tokensOnly) return; + if (CONFIG.Levels.UI.rangeEnabled == true) { + note.updateSource(CONFIG.Levels.UI.getObjUpdateData(CONFIG.Levels.UI.range)); + } + }); + + Hooks.on("preCreateDrawing", (drawing, updates) => { + if (CONFIG.Levels.UI.tokensOnly) return; + let sortedLevels = [...CONFIG.Levels.UI.definedLevels].sort((a, b) => { + return parseFloat(b[0]) - parseFloat(a[0]); + }); + let aboverange = sortedLevels.find((l) => CONFIG.Levels.UI.range[0] === l[0] && CONFIG.Levels.UI.range[1] === l[1]); + aboverange = sortedLevels.indexOf(aboverange) === 0 ? undefined : sortedLevels[sortedLevels.indexOf(aboverange) - 1]; + + if (aboverange) { + let newTop = aboverange[1]; + let newBot = aboverange[0]; + if (CONFIG.Levels.UI.rangeEnabled == true) { + drawing.updateSource({ + hidden: CONFIG.Levels.UI.stairEnabled, + text: CONFIG.Levels.UI.stairEnabled ? `Levels Stair ${CONFIG.Levels.UI.range[0]}-${newBot}` : "", + flags: { + levels: { + drawingMode: CONFIG.Levels.UI.stairEnabled ? 2 : 0, + rangeBottom: parseFloat(CONFIG.Levels.UI.range[0]), + rangeTop: newBot - 1, + }, + }, + }); + } + } else { + if (CONFIG.Levels.UI.rangeEnabled == true) { + drawing.updateSource({ + hidden: CONFIG.Levels.UI.stairEnabled, + text: CONFIG.Levels.UI.stairEnabled ? `Levels Stair ${CONFIG.Levels.UI.range[0]}-${CONFIG.Levels.UI.range[1] + 1}` : "", + flags: { + levels: { + drawingMode: CONFIG.Levels.UI.stairEnabled ? 2 : 0, + rangeBottom: parseFloat(CONFIG.Levels.UI.range[0]), + rangeTop: parseFloat(CONFIG.Levels.UI.range[1]), + }, + }, + }); + } + } + }); + + Hooks.on("preCreateWall", (wall, updates) => { + if (CONFIG.Levels.UI.tokensOnly) return; + + if (CONFIG.Levels.UI.rangeEnabled == true) { + wall.updateSource({ + flags: { + "wall-height": { + bottom: parseFloat(CONFIG.Levels.UI.range[0]), + top: parseFloat(CONFIG.Levels.UI.range[1]), + }, + }, + }); + } + }); + + Hooks.on("preCreateToken", (token, updates) => { + if (CONFIG.Levels.UI.rangeEnabled == true) { + if (updates) updates.elevation = parseFloat(CONFIG.Levels.UI.range[0]); + token.updateSource({ + elevation: updates?.elevation ?? parseFloat(CONFIG.Levels.UI.range[0]), + }); + } + }); + } }); Hooks.on("getSceneControlButtons", (controls, b, c) => { - let templateTool = { - name: "setTemplateElevation", - title: game.i18n.localize("levels.controls.setTemplateElevation.name"), - icon: "fas fa-sort", - toggle: true, - active: CONFIG.Levels?.UI.templateElevation || false, - onClick: (toggle) => { - CONFIG.Levels.UI.templateElevation = toggle; - if (toggle) CONFIG.Levels.UI.elevationDialog(templateTool); - else CONFIG.Levels.UI.nextTemplateHeight = undefined; - }, - }; - CONFIG.Levels.UI._levelsTemplateTool = templateTool; - controls.find((c) => c.name == "token").tools.push(templateTool); + let templateTool = { + name: "setTemplateElevation", + title: game.i18n.localize("levels.controls.setTemplateElevation.name"), + icon: "fas fa-sort", + toggle: true, + active: CONFIG.Levels?.UI.templateElevation || false, + onClick: (toggle) => { + CONFIG.Levels.UI.templateElevation = toggle; + if (toggle) CONFIG.Levels.UI.elevationDialog(templateTool); + else CONFIG.Levels.UI.nextTemplateHeight = undefined; + }, + }; + CONFIG.Levels.UI._levelsTemplateTool = templateTool; + controls.find((c) => c.name == "token").tools.push(templateTool); }); Hooks.once("canvasReady", () => { - console.log( - `%cLEVELS\n%cWelcome to the 3rd Dimension`, - "font-weight: bold;text-shadow: 10px 10px 0px rgba(0,0,0,0.8), 20px 20px 0px rgba(0,0,0,0.6), 30px 30px 0px rgba(0,0,0,0.4);font-size:100px;background: #444; color: #d43f3f; padding: 2px 28px 0 2px; display: inline-block;", - "font-weight: bold;text-shadow: 2px 2px 0px rgba(0,0,0,0.8), 4px 4px 0px rgba(0,0,0,0.6), 6px 6px 0px rgba(0,0,0,0.4);font-size:20px;background: #444; color: #d43f3f; padding: 10px 27px; display: inline-block; margin-left: -30px" - ); -}); \ No newline at end of file + console.log(`%cLEVELS\n%cWelcome to the 3rd Dimension`, "font-weight: bold;text-shadow: 10px 10px 0px rgba(0,0,0,0.8), 20px 20px 0px rgba(0,0,0,0.6), 30px 30px 0px rgba(0,0,0,0.4);font-size:100px;background: #444; color: #d43f3f; padding: 2px 28px 0 2px; display: inline-block;", "font-weight: bold;text-shadow: 2px 2px 0px rgba(0,0,0,0.8), 4px 4px 0px rgba(0,0,0,0.6), 6px 6px 0px rgba(0,0,0,0.4);font-size:20px;background: #444; color: #d43f3f; padding: 10px 27px; display: inline-block; margin-left: -30px"); +}); diff --git a/templates/layerTool.hbs b/templates/layerTool.hbs index e0a4571..cb0c67d 100644 --- a/templates/layerTool.hbs +++ b/templates/layerTool.hbs @@ -7,6 +7,7 @@ +