From c74f92cd80a537e3e27a583eda5bc4d35bee7e3d Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Fri, 5 Apr 2024 12:23:33 -0700 Subject: [PATCH] Redo elevationAtLocation to handle force-to-ground --- scripts/Ruler.js | 1 + scripts/settings.js | 4 ++- scripts/terrain_elevation.js | 57 ++++++++++++++++++++++++++---------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/scripts/Ruler.js b/scripts/Ruler.js index 45229b9..5828aee 100644 --- a/scripts/Ruler.js +++ b/scripts/Ruler.js @@ -544,6 +544,7 @@ function segmentGridHalfIntersection(gridCoords, a, b) { */ function _onDragStart(wrapped, event) { Settings.FORCE_TO_GROUND = false; + this._userElevationIncrements = 0; this._unsnap = event.shiftKey || canvas.scene.grid.type === CONST.GRID_TYPES.GRIDLESS; return wrapped(event); } diff --git a/scripts/settings.js b/scripts/settings.js index d195953..e3ce0f1 100644 --- a/scripts/settings.js +++ b/scripts/settings.js @@ -288,8 +288,10 @@ export class Settings extends ModuleSettingsAbstract { { key: "KeyG" } ], onDown: _context => { - if ( !canvas.controls.ruler.active ) return; + const ruler = canvas.controls.ruler; + if ( !ruler.active ) return; this.FORCE_TO_GROUND = !this.FORCE_TO_GROUND; + ruler.measure(ruler.destination, { force: true }); ui.notifications.info(`Ruler measure to ground ${this.FORCE_TO_GROUND ? "enabled" : "disabled"}.`); }, precedence: CONST.KEYBINDING_PRECEDENCE.NORMAL diff --git a/scripts/terrain_elevation.js b/scripts/terrain_elevation.js index b753583..23cf674 100644 --- a/scripts/terrain_elevation.js +++ b/scripts/terrain_elevation.js @@ -42,7 +42,7 @@ elevationAtLocation -- all ruler types Used by ruler to get elevation at waypoints and at the end of the ruler. */ -import { MODULES_ACTIVE } from "./const.js"; +import { MODULES_ACTIVE, MOVEMENT_TYPES } from "./const.js"; import { Settings } from "./settings.js"; import { Point3d } from "./geometry/3d/Point3d.js"; @@ -114,23 +114,50 @@ export function elevationAtLocation(location, token) { token ??= this._getMovementToken(); const isTokenRuler = Settings.get(Settings.KEYS.TOKEN_RULER.ENABLED) && ui.controls.activeControl === "token" - && ui.controls.activeTool === "select"; + && ui.controls.activeTool === "select" + && token; + + // 1. If forcing to ground, always use the terrain elevation. + + /* If not forcing to ground: + 2. No move token + --> Default: Use origin elevation + --> If hovering over a token, use that token's elevation + 3. Move token, normal ruler + --> Default: Use move token elevation + --> If hovering over a token, use that token's elevation + 4. Token ruler + --> Default: Use move token elevation + --> If token is walking, use terrain elevation + */ + const terrainElevationFn = () => this.constructor.terrainElevationAtLocation(location, { + movementToken: token, + startingElevation: this.originElevation + }); - // If at the token, use the token's elevation. - if ( token && location.almostEqual(token.center) ) return token.elevationE; - - // If normal ruler and not prioritizing the token elevation, use elevation of other tokens at this point. - if ( !isTokenRuler ) { - const maxTokenE = retrieveVisibleTokens() - .filter(t => t.constrainedTokenBorder.contains(location.x, location.y)) - .reduce((e, t) => Math.max(t.elevationE, e), Number.NEGATIVE_INFINITY); - if ( isFinite(maxTokenE) ) return maxTokenE; + // #1 Forcing to ground + if ( Settings.FORCE_TO_GROUND ) return terrainElevationFn(); + + // #4 token ruler + if ( isTokenRuler ) { + if ( token.movementType === MOVEMENT_TYPES.WALK ) return terrainElevationFn(); + return token.elevationE; } - // Use the terrain at this point. - return this.constructor.terrainElevationAtLocation(location, { - movementToken: token, - startingElevation: this.originElevation }); + // If at the token, use the token's elevation. + // if ( token && location.almostEqual(token.center) ) return token.elevationE; + + // Check for other tokens at destination and use that elevation. + const maxTokenE = retrieveVisibleTokens() + .filter(t => t.constrainedTokenBorder.contains(location.x, location.y)) + .reduce((e, t) => Math.max(t.elevationE, e), Number.NEGATIVE_INFINITY); + if ( isFinite(maxTokenE) ) return maxTokenE; // #2 or #3 + + // #3 move token + if ( token ) return token.elevationE; + + // #2 no move token + return this.originElevation; } // ----- NOTE: HELPER FUNCTIONS ----- //