From 4e629c035037c8e951e29b458f99e2618fe7f7f9 Mon Sep 17 00:00:00 2001 From: ironmonk88 <75920956+ironmonk88@users.noreply.github.com> Date: Tue, 11 Apr 2023 23:42:05 -0700 Subject: [PATCH] 10.7 changes --- CHANGELOG.md | 14 +++++++ classes/terrain.js | 3 +- classes/terraindocument.js | 14 +++---- classes/terrainlayer.js | 56 +++++++-------------------- img/environment/spiderweb.png | Bin 0 -> 16260 bytes img/environment/underdark.png | Bin 16260 -> 9736 bytes lang/en.json | 4 +- module.json | 11 ++++-- terrain-main.js | 71 +++++++++++++++++++++++++++++++++- 9 files changed, 114 insertions(+), 59 deletions(-) create mode 100644 img/environment/spiderweb.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fde79f..516bd8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,17 @@ +# Version 10.7 + +Fixed issue with holding shift to snap to grid + +Fixed issue with negative dpeth. + +Fixed issue getting access to the terrain from the canvas scene + +Added webbing as an obstacle + +Fixed issue with tokens causing difficult terrain. + +Swapped setting up terrain to initialization rather than on draw. + # Version 10.6 Fixed issue refreshing the terrain shape if the shape doesn't exist diff --git a/classes/terrain.js b/classes/terrain.js index 7382ed0..acf59ab 100644 --- a/classes/terrain.js +++ b/classes/terrain.js @@ -762,7 +762,7 @@ export class Terrain extends PlaceableObject { const now = Date.now(); temporary = (now - this._drawTime) < this.constructor.FREEHAND_SAMPLE_RATE; } - const snap = !(isShift || isFreehand); + const snap = isShift && !isFreehand; this._addPoint(position, { snap, temporary }); break; @@ -770,6 +770,7 @@ export class Terrain extends PlaceableObject { default: const shape = this.shape; const minSize = canvas.dimensions.size * 0.5; + if (isShift) position = canvas.grid.getSnappedPosition(position.x, position.y, this.layer.gridPrecision); let dx = position.x - origin.x; let dy = position.y - origin.y; if (Math.abs(dx) < minSize) dx = minSize * Math.sign(shape.width); diff --git a/classes/terraindocument.js b/classes/terraindocument.js index e634720..8db5aaf 100644 --- a/classes/terraindocument.js +++ b/classes/terraindocument.js @@ -185,11 +185,11 @@ export class TerrainDocument extends CanvasDocumentMixin(BaseTerrain) { } get top() { - return this.elevation + this.depth; + return (this.depth < 0 ? this.elevation : this.elevation + this.depth); } get bottom() { - return this.elevation; + return (this.depth < 0 ? this.elevation + this.depth: this.elevation); } /* -------------------------------------------- */ @@ -239,7 +239,7 @@ export class TerrainDocument extends CanvasDocumentMixin(BaseTerrain) { } //add it to the terrain set - canvas["#scene"].terrain.set(document._id, document); + canvas.scene.terrain.set(document._id, document); //if the multiple has changed then update the image if (document._object != undefined) @@ -272,7 +272,7 @@ export class TerrainDocument extends CanvasDocumentMixin(BaseTerrain) { let originals = []; let updated = []; for (let update of updates) { - let document = canvas["#scene"].terrain.get(update._id); + let document = canvas.scene.terrain.get(update._id); if (game.user.isGM) { originals.push(document.toObject(false)); @@ -328,15 +328,15 @@ export class TerrainDocument extends CanvasDocumentMixin(BaseTerrain) { let updates = []; let originals = []; let deleted = []; - const deleteIds = options.deleteAll ? canvas["#scene"].terrain.keys() : ids; + const deleteIds = options.deleteAll ? canvas.scene.terrain.keys() : ids; for (let id of deleteIds) { - let terrain = canvas["#scene"].terrain.find(t => t.id == id); + let terrain = canvas.scene.terrain.find(t => t.id == id); if (terrain == undefined) continue; //remove this object from the terrain list - canvas["#scene"].terrain.delete(id); + canvas.scene.terrain.delete(id); if (game.user.isGM) { let key = `flags.enhanced-terrain-layer.-=terrain${id}`; diff --git a/classes/terrainlayer.js b/classes/terrainlayer.js index 1b3afda..c039698 100644 --- a/classes/terrainlayer.js +++ b/classes/terrainlayer.js @@ -63,11 +63,11 @@ export class TerrainLayer extends PlaceablesLayer { } getDocuments() { - return canvas["#scene"].terrain || null; + return canvas.scene.terrain || null; } get(objectId) { - return canvas["#scene"].terrain?.get(objectId)?.object || undefined; + return canvas.scene.terrain?.get(objectId)?.object || undefined; } get gridPrecision() { @@ -101,7 +101,8 @@ export class TerrainLayer extends PlaceablesLayer { { id: 'furniture', text: 'EnhancedTerrainLayer.obstacle.furniture', icon: 'modules/enhanced-terrain-layer/img/environment/furniture.png', obstacle: true }, { id: 'magic', text: 'EnhancedTerrainLayer.obstacle.magic', icon: 'modules/enhanced-terrain-layer/img/environment/magic.png', obstacle: true }, { id: 'plants', text: 'EnhancedTerrainLayer.obstacle.plants', icon: 'modules/enhanced-terrain-layer/img/environment/plants.png', obstacle: true }, - { id: 'rubble', text: 'EnhancedTerrainLayer.obstacle.rubble', icon: 'modules/enhanced-terrain-layer/img/environment/rubble.png', obstacle: true } + { id: 'rubble', text: 'EnhancedTerrainLayer.obstacle.rubble', icon: 'modules/enhanced-terrain-layer/img/environment/rubble.png', obstacle: true }, + { id: 'webbing', text: 'EnhancedTerrainLayer.obstacle.webbing', icon: 'modules/enhanced-terrain-layer/img/environment/spiderweb.png', obstacle: true } ]; Hooks.call(`getTerrainEnvironments`, this, environments); @@ -210,8 +211,14 @@ export class TerrainLayer extends PlaceablesLayer { if (!terrainFlag) continue; const terraincost = terrainFlag.multiple ?? 1; - const terrainbottom = terrainFlag.elevation ?? Terrain.defaults.elevation; - const terraintop = terrainbottom + (terrainFlag.depth ?? Terrain.defaults.depth); + let terrainbottom = terrainFlag.elevation ?? Terrain.defaults.elevation; + let terraintop = terrainbottom + (terrainFlag.depth ?? Terrain.defaults.depth); + if (terraintop < terrainbottom) { + let temp = terrainbottom; + terrainbottom = terraintop; + terraintop = temp; + } + const environment = terrainFlag.environment || ''; const obstacle = terrainFlag.obstacle || ''; if (elevation < terrainbottom || elevation > terraintop) @@ -247,7 +254,7 @@ export class TerrainLayer extends PlaceablesLayer { continue; if (token.hidden) continue; - if (elevation != undefined && token.elevation != undefined && token.elevation != elevation) + if (elevation != undefined && token.document.elevation != undefined && token.document.elevation != elevation) continue; let dead = isDead(token); let checkValue = dead ? tokenDead : tokenDifficult; @@ -339,43 +346,6 @@ export class TerrainLayer extends PlaceablesLayer { } async draw() { - canvas["#scene"].terrain = new foundry.abstract.EmbeddedCollection(canvas.scene, [], Terrain); - let etl = canvas.scene.flags['enhanced-terrain-layer']; - if (etl) { - for (let [k, v] of Object.entries(etl)) { - if (k.startsWith('terrain')) { - if (k != 'terrainundefined' && v != undefined && v.x != undefined && v.y != undefined && v._id != undefined) { - //lets correct any changes - let change = false; - if (v.environment == '' && v.obstacle != '') { - v.environment = v.obstacle; - v.obstacle = ''; - change = true; - } - if (v.elevation == undefined || v.depth == undefined) { - if (v.terrainheight != undefined && typeof v.terrainheight === 'string') - v.terrainheight = JSON.parse(v.terrainheight); - v.elevation = v.min || (v.terrainheight != undefined ? v.terrainheight.min : (v.terraintype == 'air' ? 5 : 0)) || 0; - let max = v.max || (v.terrainheight != undefined ? v.terrainheight.max : (v.terraintype == 'air' || v.terraintype == 'both' ? 100 : 0)) || 0; - v.depth = max - v.elevation; - change = true; - } - - change = !!TerrainDocument.migrateData(v); - - if (change) - await canvas.scene.setFlag('enhanced-terrain-layer', k, v); - - //add this the the terrain collection - let document = new TerrainDocument(v, { parent: canvas.scene }); - canvas["#scene"].terrain.set(v._id, document); - } - else - await canvas.scene.unsetFlag('enhanced-terrain-layer', k); - } - }; - } - const d = canvas.dimensions; this.width = d.width; this.height = d.height; diff --git a/img/environment/spiderweb.png b/img/environment/spiderweb.png new file mode 100644 index 0000000000000000000000000000000000000000..3c470d1782cfa8c8fdf34692f4751941263ed914 GIT binary patch literal 16260 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 NHWv2gPfXF+{|k7)+nfLZ literal 0 HcmV?d00001 diff --git a/img/environment/underdark.png b/img/environment/underdark.png index 3c470d1782cfa8c8fdf34692f4751941263ed914..bf0099fbfe042a269d0a7a261d5651154544e28e 100644 GIT binary patch delta 8717 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 delta 15292 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 DeTtDN diff --git a/lang/en.json b/lang/en.json index 58c25f3..9bb408e 100644 --- a/lang/en.json +++ b/lang/en.json @@ -82,6 +82,6 @@ "EnhancedTerrainLayer.obstacle.magic": "Magic", "EnhancedTerrainLayer.obstacle.plants": "Plants", "EnhancedTerrainLayer.obstacle.rubble": "Rubble", - "EnhancedTerrainLayer.obstacle.water": "Water" - + "EnhancedTerrainLayer.obstacle.water": "Water", + "EnhancedTerrainLayer.obstacle.webbing": "Webbing" } diff --git a/module.json b/module.json index c5c8453..cf9507a 100644 --- a/module.json +++ b/module.json @@ -1,13 +1,16 @@ { "title": "Enhanced Terrain Layer", "description": "A base module that adds a Terrain Layer to Foundry. Used as a library for Rulers and other modules", - "version": "10.6", + "version": "10.7", "authors": [ { "name": "IronMonk", "discord": "ironmonk88#4075", - "patreon": "https://www.patreon.com/ironmonk", - "ko-fi": "https://ko-fi.com/ironmonk88" + "flags": { + "github": "https://github.com/ironmonk88", + "patreon": "https://www.patreon.com/ironmonk", + "ko-fi": "https://ko-fi.com/ironmonk88" + } } ], "socket": true, @@ -47,7 +50,7 @@ "css/terrainlayer.css" ], "url": "https://github.com/ironmonk88/enhanced-terrain-layer", - "download": "https://github.com/ironmonk88/enhanced-terrain-layer/archive/10.6.zip", + "download": "https://github.com/ironmonk88/enhanced-terrain-layer/archive/10.7.zip", "manifest": "https://github.com/ironmonk88/enhanced-terrain-layer/releases/latest/download/module.json", "bugs": "https://github.com/ironmonk88/enhanced-terrain-layer/issues", "allowBugReporter": true, diff --git a/terrain-main.js b/terrain-main.js index e1c9a0d..a274d23 100644 --- a/terrain-main.js +++ b/terrain-main.js @@ -55,7 +55,7 @@ function registerLayer() { objectClass: Terrain }; - canvas["#scene"] = {}; + //canvas["#scene"] = {}; let createEmbeddedDocuments = async function (wrapped, ...args) { let [embeddedName, updates = [], context = {}] = args; @@ -147,11 +147,13 @@ function registerLayer() { return oldDeleteEmbeddedDocuments.call(this, embeddedName, ids, context); }*/ + /* Object.defineProperty(Scene.prototype, "terrain", { get: function terrain() { return this.data.terrain; } }); + */ } /* @@ -321,6 +323,55 @@ async function addControlsv9(app, dest, { full = false, insert = false } = {}) { $('input[name="flags.enhanced-terrain-layer.drawcolor"]', dest).attr("placeholder", defaults.drawcolor); } +function setupScene(scene) { + scene.terrain = new foundry.abstract.EmbeddedCollection(scene, [], Terrain); + let etl = scene.flags['enhanced-terrain-layer']; + if (etl) { + for (let [k, v] of Object.entries(etl)) { + if (k.startsWith('terrain')) { + if (k != 'terrainundefined' && v != undefined && v.x != undefined && v.y != undefined && v._id != undefined) { + //lets correct any changes + let change = false; + if (v.environment == '' && v.obstacle != '') { + v.environment = v.obstacle; + v.obstacle = ''; + change = true; + } + if (v.elevation == undefined || v.depth == undefined) { + if (v.terrainheight != undefined && typeof v.terrainheight === 'string') + v.terrainheight = JSON.parse(v.terrainheight); + v.elevation = v.min || (v.terrainheight != undefined ? v.terrainheight.min : (v.terraintype == 'air' ? 5 : 0)) || 0; + let max = v.max || (v.terrainheight != undefined ? v.terrainheight.max : (v.terraintype == 'air' || v.terraintype == 'both' ? 100 : 0)) || 0; + v.depth = max - v.elevation; + change = true; + } + + change = !!TerrainDocument.migrateData(v); + + if (change) { + if (game.user.isGM) + scene.setFlag('enhanced-terrain-layer', k, v); + setProperty(scene, `flags.enhanced-terrain-layer.${k}`, v); + } + + //add this the the terrain collection + try { + let document = new TerrainDocument(v, { parent: scene }); + scene.terrain.set(v._id, document); + } catch (err) { + error(err); + } + } + else { + if (game.user.isGM) + scene.unsetFlag('enhanced-terrain-layer', k); + delete scene.flags["enhanced-terrain-layer"][k] + } + } + }; + } +} + Hooks.on('canvasInit', () => { canvas.hud.terrain = new TerrainHUD(); //Scene.constructor.config.embeddedEntities.Terrain = "terrain"; @@ -393,6 +444,22 @@ Hooks.on('init', async () => { registerLayer(); registerKeybindings(); + let initializeDocuments = async function (wrapped, ...args) { + wrapped(...args); + for (let scene of game.scenes) { + setupScene(scene); + } + } + + if (game.modules.get("lib-wrapper")?.active) { + libWrapper.register("enhanced-terrain-layer", "Game.prototype.initializeDocuments", initializeDocuments, "WRAPPER"); + } else { + const oldInitializeDocuments = Game.prototype.initializeDocuments; + Game.prototype.initializeDocuments = function (event) { + return initializeDocuments.call(this, oldInitializeDocuments.bind(this), ...arguments); + } + } + //remove old layer's controls let getControlButtons = function (wrapped, ...args) { let controls = wrapped.call(this, ...args); @@ -623,7 +690,7 @@ Hooks.on("updateScene", (scene, data) => { if (getProperty(data, "flags.enhanced-terrain-layer.opacity") || getProperty(data, "flags.enhanced-terrain-layer.drawcolor")) { canvas.terrain.refresh(true); //refresh the terrain to respond to default terrain color } - if (canvas.terrain.toolbar) + if (canvas.terrain?.toolbar) canvas.terrain.toolbar.render(true); });