From 9b2753e85dbbdc6727b7042d9065c8ca063cc6b0 Mon Sep 17 00:00:00 2001 From: caewok Date: Wed, 6 Mar 2024 17:25:00 -0800 Subject: [PATCH 01/13] Ignore .sh files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4897802..28f81db 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ sync_to_module.sh test_sync_to_module.sh sync_module.sh + +*.sh From 121b42e6c24d5e0aa6d081bc4aff66f48778f339 Mon Sep 17 00:00:00 2001 From: caewok Date: Wed, 6 Mar 2024 17:25:15 -0800 Subject: [PATCH 02/13] Fix Point3d import --- scripts/terrain_elevation.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/terrain_elevation.js b/scripts/terrain_elevation.js index 1c3a1e1..acd84cc 100644 --- a/scripts/terrain_elevation.js +++ b/scripts/terrain_elevation.js @@ -43,6 +43,7 @@ Used by ruler to get elevation at waypoints and at the end of the ruler. import { MODULES_ACTIVE } from "./const.js"; import { Settings } from "./settings.js"; +import { Point3d } from "./geometry/3d/Point3d.js"; /** * Calculate the elevation for a given waypoint. From 7103df16f8ede7ae3b771b4e15a9cf40b6851483 Mon Sep 17 00:00:00 2001 From: caewok Date: Wed, 6 Mar 2024 17:25:41 -0800 Subject: [PATCH 03/13] Return 1 if token not present for the terrain move penalty --- scripts/measure_distance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/measure_distance.js b/scripts/measure_distance.js index b4e6551..d1093f9 100644 --- a/scripts/measure_distance.js +++ b/scripts/measure_distance.js @@ -709,7 +709,7 @@ function hasActiveDrawingTerrain(drawing, currElev, prevElev) { * @returns {number} Percent move penalty to apply. Returns 1 if no penalty. */ function griddedTerrainMovePenalty(token, currGridCoords, prevGridCoords, currElev = 0, prevElev = 0) { - if ( !MODULES_ACTIVE.TERRAIN_MAPPER ) return 1; + if ( !MODULES_ACTIVE.TERRAIN_MAPPER || !token ) return 1; const Terrain = MODULES_ACTIVE.API.TERRAIN_MAPPER.Terrain; const speedAttribute = SPEED.ATTRIBUTES[token.movementType] ?? SPEED.ATTRIBUTES.WALK; const GT = Settings.KEYS.GRID_TERRAIN; From 0c0bac5341919e20ebd4ce7ce4595e6ce3ce59fa Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Wed, 6 Mar 2024 17:48:17 -0800 Subject: [PATCH 04/13] Add CONFIG to change the token hud move types --- scripts/const.js | 9 --------- scripts/module.js | 10 +++++++++- scripts/token_hud.js | 7 ++++--- scripts/util.js | 7 +++++++ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/scripts/const.js b/scripts/const.js index ae99663..9bfcb76 100644 --- a/scripts/const.js +++ b/scripts/const.js @@ -46,9 +46,6 @@ export const MOVEMENT_TYPES = { FLY: 2 }; -// Store the flipped key/values. -Object.entries(MOVEMENT_TYPES).forEach(([key, value]) => MOVEMENT_TYPES[value] = key); - export const MOVEMENT_BUTTONS = { [MOVEMENT_TYPES.AUTO]: "road-lock", [MOVEMENT_TYPES.BURROW]: "person-digging", @@ -56,12 +53,6 @@ export const MOVEMENT_BUTTONS = { [MOVEMENT_TYPES.FLY]: "dove" }; -export const SPEED_ATTRIBUTES = { - [MOVEMENT_TYPES.BURROW]: "", - [MOVEMENT_TYPES.WALK]: "", - [MOVEMENT_TYPES.FLY]: "" -}; - /** * Below Taken from Drag Ruler */ diff --git a/scripts/module.js b/scripts/module.js index 36c002c..4548156 100644 --- a/scripts/module.js +++ b/scripts/module.js @@ -41,9 +41,18 @@ Hooks.once("init", function() { // Font awesome identifiers for the Token HUD speed selection. MOVEMENT_BUTTONS, + // Types of movement. + MOVEMENT_TYPES, + debug: false }; + /* To add a movement to the api: + CONFIG.elevationruler.MOVEMENT_TYPES.SWIM = 3; // Increment by 1 from the highest-valued movement type + CONFIG.elevationruler.MOVEMENT_BUTTONS[CONFIG.elevationruler.MOVEMENT_TYPES.SWIM] = "person-swimming"; // From Font Awesome + CONFIG.elevationruler.SPEED.ATTRIBUTES.SWIM = "actor.system.attributes.movement.swim"; // dnd5e + */ + game.modules.get(MODULE_ID).api = { iterateGridUnderLine, @@ -52,7 +61,6 @@ Hooks.once("init", function() { sumGridMoves, gridShapeFromGridCoords, PATCHER, - MOVEMENT_TYPES, // Pathfinding pathfinding: { diff --git a/scripts/token_hud.js b/scripts/token_hud.js index 9b056a8..291c399 100644 --- a/scripts/token_hud.js +++ b/scripts/token_hud.js @@ -31,6 +31,7 @@ SOFTWARE. import { MODULE_ID, FLAGS, MOVEMENT_TYPES, MOVEMENT_BUTTONS, MODULES_ACTIVE } from "./const.js"; import { LevelsElevationAtPoint } from "./terrain_elevation.js"; +import { keyForValue } from "./util.js"; export const PATCHES = {}; PATCHES.MOVEMENT_SELECTION = {}; @@ -56,7 +57,7 @@ PATCHES.MOVEMENT_SELECTION.HOOKS = { renderTokenHUD }; function movementType() { let selectedMovement = this.document.getFlag(MODULE_ID, FLAGS.MOVEMENT_SELECTION); if ( selectedMovement === MOVEMENT_TYPES.AUTO ) return determineMovementType(this); - return MOVEMENT_TYPES[selectedMovement]; + return keyForValue(MOVEMENT_TYPES, selectedMovement); } PATCHES.MOVEMENT_SELECTION.GETTERS = { movementType }; @@ -74,7 +75,7 @@ function determineMovementType(token) { groundElevation = LevelsElevationAtPoint(token.center, { startingElevation: token.elevationE }) ?? 0; } else groundElevation = 0; - return MOVEMENT_TYPES[Math.sign(token.elevationE - groundElevation) + 1]; + return keyForValue(MOVEMENT_TYPES, Math.sign(token.elevationE - groundElevation) + 1); } /** @@ -97,7 +98,7 @@ function addMovementSelectionButton(tokenDocument, html) { */ async function onMovementTypeButtonClick(tokenDocument, html) { const currentType = tokenDocument.getFlag(MODULE_ID, FLAGS.MOVEMENT_SELECTION); // May be undefined. - const nextTypeName = MOVEMENT_TYPES[currentType + 1] ?? "AUTO"; + const nextTypeName = keyForValue(MOVEMENT_TYPES, currentType + 1) ?? "AUTO"; await tokenDocument.setFlag(MODULE_ID, FLAGS.MOVEMENT_SELECTION, MOVEMENT_TYPES[nextTypeName]); html.find("#switch-movement-type").remove(); addMovementSelectionButton(tokenDocument, html); diff --git a/scripts/util.js b/scripts/util.js index b4567f5..92738df 100644 --- a/scripts/util.js +++ b/scripts/util.js @@ -243,4 +243,11 @@ export function filterSplice(arr, filterFn) { indices.sort((a, b) => b - a); // So we can splice without changing other indices. indices.forEach(idx => arr.splice(idx, 1)); return filteredElems; +} + +/** + * Get the key for a given object value. Presumes unique values, otherwise returns first. + */ +export function keyForValue(object, value) { + return Object.keys(object).find(key => object[key] === value); } \ No newline at end of file From abb5b951dd67553e40924107c4dd79f257e5e297 Mon Sep 17 00:00:00 2001 From: caewok Date: Thu, 7 Mar 2024 06:53:16 -0800 Subject: [PATCH 05/13] Update changelog --- Changelog.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Changelog.md b/Changelog.md index de12995..32e6a35 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,14 @@ +# 0.8.9 +Fix errors thrown when using the ruler without a movement token with either Terrain Mapper or Elevated Vision modules active. Closes issue #51. +Add CONFIG options to set additional movement types to the token hud. Closes issue #50. +```js +// Example: Add a swim movement to the api. +CONFIG.elevationruler.MOVEMENT_TYPES.SWIM = 3; // Increment by 1 from the highest-valued movement type +CONFIG.elevationruler.MOVEMENT_BUTTONS[CONFIG.elevationruler.MOVEMENT_TYPES.SWIM] = "person-swimming"; // From Font Awesome +CONFIG.elevationruler.SPEED.ATTRIBUTES.SWIM = "actor.system.attributes.movement.swim"; // dnd5e +``` + + # 0.8.8 Improvements to updating the scene graph. Avoid leaving unneeded vertices and split edges when a token or wall is removed. Fixes to handling overlapping edges to correctly reflect what objects make up the edge. From e466eec477f1c0df4824ebf61453e76b34c53aea Mon Sep 17 00:00:00 2001 From: caewok Date: Thu, 7 Mar 2024 06:53:54 -0800 Subject: [PATCH 06/13] Allow other users to see the movement colors Don't limit to the current user --- scripts/segments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/segments.js b/scripts/segments.js index 8c4c42c..d577b3a 100644 --- a/scripts/segments.js +++ b/scripts/segments.js @@ -289,7 +289,7 @@ export function _highlightMeasurementSegment(wrapped, segment) { const priorColor = this.color; const token = this._getMovementToken(); const doSpeedHighlighting = token - && this.user === game.user + // && this.user === game.user && Settings.get(Settings.KEYS.TOKEN_RULER.SPEED_HIGHLIGHTING); // Highlight each split in turn, changing highlight color each time. From d8e7a712949cd7ae8d28c2765edfe854f38a34a9 Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 06:59:10 -0800 Subject: [PATCH 07/13] Update changelog --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 32e6a35..fb66dc8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,6 @@ # 0.8.9 Fix errors thrown when using the ruler without a movement token with either Terrain Mapper or Elevated Vision modules active. Closes issue #51. +Display speed colors to other users who have the speed color setting enabled. Closes issue #53. Add CONFIG options to set additional movement types to the token hud. Closes issue #50. ```js // Example: Add a swim movement to the api. From b4894ca9043d4daff05332318f8345d99cf29899 Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 07:23:12 -0800 Subject: [PATCH 08/13] Sum combat moves for a single round --- scripts/Token.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/Token.js b/scripts/Token.js index 1282c28..f1dc5f4 100644 --- a/scripts/Token.js +++ b/scripts/Token.js @@ -80,9 +80,12 @@ async function _onDragLeftDrop(wrapped, event) { * @param {boolean} [sinceCombatTurn=true] Should the combat turn zero out the movement distance. * @returns {number} */ -function lastMoveDistance() { - if ( game.combat?.active && this._lastCombatRoundMove < game.combat.round ) return 0; - return this._lastMoveDistance ?? 0; +function lastMoveDistance(sinceCombatTurn=true) { + if ( game.combat?.active && sinceCombatTurn ) { + if ( this._lastCombatRoundMove < game.combat.round ) return 0; + return this._lastCombatRoundMoveDistance || 0; + } + return this._lastMoveDistance || 0; } /** @@ -97,10 +100,15 @@ function updateToken(document, changes, _options, _userId) { if ( token.isPreview || !(Object.hasOwn(changes, "x")|| Object.hasOwn(changes, "y") || Object.hasOwn(changes, "elevation")) ) return; - if ( game.combat?.active ) token._lastCombatRoundMove = game.combat.round; const ruler = canvas.controls.ruler; if ( ruler.active && ruler._getMovementToken() === token ) token._lastMoveDistance = ruler.totalMoveDistance; else token._lastMoveDistance = Ruler.measureMoveDistance(token.position, token.document, token).moveDistance; + if ( game.combat?.active ) { + token._lastCombatRoundMoveDistance ||= 0; + if ( this._lastCombatRoundMove < game.combat.round ) token._lastCombatRoundMoveDistance = token._lastMoveDistance; + else token._lastCombatRoundMoveDistance += token._lastMoveDistance + token._lastCombatRoundMove = game.combat.round; + } } /** From 08fdb2f0e60c1dc987ae5b69424d8ea1cd7bcbd7 Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 07:51:16 -0800 Subject: [PATCH 09/13] Track combat moves for each combat id --- scripts/Token.js | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/scripts/Token.js b/scripts/Token.js index f1dc5f4..05e113f 100644 --- a/scripts/Token.js +++ b/scripts/Token.js @@ -77,13 +77,14 @@ async function _onDragLeftDrop(wrapped, event) { * Token.prototype.lastMoveDistance * Return the last move distance. If combat is active, return the last move since this token * started its turn. - * @param {boolean} [sinceCombatTurn=true] Should the combat turn zero out the movement distance. * @returns {number} */ -function lastMoveDistance(sinceCombatTurn=true) { - if ( game.combat?.active && sinceCombatTurn ) { - if ( this._lastCombatRoundMove < game.combat.round ) return 0; - return this._lastCombatRoundMoveDistance || 0; +function lastMoveDistance() { + if ( game.combat?.started ) { + if ( !this._combatMoveData ) return 0; + const combatData = this._combatMoveData.get(game.combat.id); + if ( !combatData || combatData.lastRound < game.combat.round ) return 0; + return combatData.lastMoveDistance; } return this._lastMoveDistance || 0; } @@ -103,11 +104,16 @@ function updateToken(document, changes, _options, _userId) { const ruler = canvas.controls.ruler; if ( ruler.active && ruler._getMovementToken() === token ) token._lastMoveDistance = ruler.totalMoveDistance; else token._lastMoveDistance = Ruler.measureMoveDistance(token.position, token.document, token).moveDistance; - if ( game.combat?.active ) { - token._lastCombatRoundMoveDistance ||= 0; - if ( this._lastCombatRoundMove < game.combat.round ) token._lastCombatRoundMoveDistance = token._lastMoveDistance; - else token._lastCombatRoundMoveDistance += token._lastMoveDistance - token._lastCombatRoundMove = game.combat.round; + if ( game.combat?.started ) { + // Store the combat move distance and the last round for which the combat move occurred. + // Map to each unique combat. + const combatId = game.combat.id; + token._combatMoveData ??= new Map(); + if ( !token._combatMoveData.has(combatId) ) token._combatMoveData.set(combatId, { lastMoveDistance: 0, lastRound: -1 }); + const combatData = token._combatMoveData.get(combatId); + if ( combatData.lastRound < game.combat.round ) combatData.lastMoveDistance = token._lastMoveDistance; + else combatData.lastMoveDistance += token._lastMoveDistance + combatData.lastRound = game.combat.round; } } From 2d51c3b35c596df9b62a3ca39a24ad9bef4c68ec Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 07:58:20 -0800 Subject: [PATCH 10/13] Add setting to toggle combat move tracking --- languages/en.json | 3 +++ scripts/settings.js | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/languages/en.json b/languages/en.json index b7ada02..05fe1f7 100644 --- a/languages/en.json +++ b/languages/en.json @@ -27,6 +27,9 @@ "elevationruler.settings.token-ruler-highlighting.name": "Use Token Speed Highlighting", "elevationruler.settings.token-ruler-highlighting.hint": "When using the ruler, use different colors for token walk/dash/max distance.", + "elevationruler.settings.token-ruler-combat-history.name": "Track Combat Move", + "elevationruler.settings.token-ruler-combat-history.hint": "For token speed highlighting, sum all the token moves within the round when displaying the highlight.", + "elevationruler.settings.token-speed-property.name": "Token Walk Property", "elevationruler.settings.token-speed-property.hint": "For token speed highlighting, this is the actor property representing token walking speed.", diff --git a/scripts/settings.js b/scripts/settings.js index 0272c53..9c58ac2 100644 --- a/scripts/settings.js +++ b/scripts/settings.js @@ -42,7 +42,8 @@ const SETTINGS = { ENABLED: "enable-token-ruler", ROUND_TO_MULTIPLE: "round-to-multiple", SPEED_HIGHLIGHTING: "token-ruler-highlighting", - TOKEN_MULTIPLIER: "token-terrain-multiplier" + TOKEN_MULTIPLIER: "token-terrain-multiplier", + COMBAT_HISTORY: "token-ruler-combat-history" }, GRID_TERRAIN: { @@ -54,7 +55,6 @@ const SETTINGS = { }, AREA_THRESHOLD: "grid-terrain-area-threshold" } - }; const KEYBINDINGS = { @@ -170,6 +170,16 @@ export class Settings extends ModuleSettingsAbstract { requiresReload: false }); + register(KEYS.TOKEN_RULER.COMBAT_HISTORY, { + name: localize(`${KEYS.TOKEN_RULER.COMBAT_HISTORY}.name`), + hint: localize(`${KEYS.TOKEN_RULER.COMBAT_HISTORY}.hint`), + scope: "user", + config: true, + default: false, + type: Boolean, + requiresReload: false + }); + register(KEYS.TOKEN_RULER.ROUND_TO_MULTIPLE, { name: localize(`${KEYS.TOKEN_RULER.ROUND_TO_MULTIPLE}.name`), hint: localize(`${KEYS.TOKEN_RULER.ROUND_TO_MULTIPLE}.hint`), From e51343391eeb5454b6de67b14bc3d9e86c211800 Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 08:33:49 -0800 Subject: [PATCH 11/13] Add combat move speed tracking --- scripts/Ruler.js | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/scripts/Ruler.js b/scripts/Ruler.js index 485f2a6..506a9ab 100644 --- a/scripts/Ruler.js +++ b/scripts/Ruler.js @@ -342,15 +342,28 @@ function _computeTokenSpeed(gridSpaces) { const walkDistance = tokenSpeed; const dashDistance = tokenSpeed * SPEED.MULTIPLIER; - // For each segment, determine the type of movement: walk, dash, max. - // If a segment has 2+ types, split the segment; recalculating distances. + // Variables changed in the loop let totalDistance = 0; let totalMoveDistance = 0; + let totalCombatMoveDistance = 0; + let prevCombatMoveDistance = 0; let dashing = false; let atMaximum = false; let nSegments = this.segments.length; - const maxIter = nSegments * 3; // Debugging + + // Add in already moved combat distance. + if ( game.combat?.started && Settings.get(Settings.KEYS.TOKEN_RULER.COMBAT_HISTORY) ) { + prevCombatMoveDistance = totalCombatMoveDistance = token.lastMoveDistance; + dashing = totalCombatMoveDistance > walkDistance && !totalCombatMoveDistance.almostEqual(walkDistance, .01); + atMaximum = totalCombatMoveDistance > dashDistance && !totalCombatMoveDistance.almostEqual(dashDistance, .01); + } + + // Debugging, to avoid infinite loops. + const maxIter = nSegments * 3; let iter = 0; + + // For each segment, determine the type of movement: walk, dash, max. + // If a segment has 2+ types, split the segment; recalculating distances. for ( let i = 0; i < nSegments; i += 1 ) { let segment = this.segments[i]; @@ -365,9 +378,9 @@ function _computeTokenSpeed(gridSpaces) { // Check if segment must be split. // Do dash first so the split can later be checked for maximum. - const newMoveDistance = totalMoveDistance + segment.moveDistance; - const targetDistance = (!dashing && newMoveDistance > walkDistance) ? walkDistance - : (!atMaximum && newMoveDistance > dashDistance) ? dashDistance + const newMoveDistance = totalCombatMoveDistance + segment.moveDistance; + const targetDistance = (!dashing && newMoveDistance > walkDistance) ? (walkDistance - prevCombatMoveDistance) + : (!atMaximum && newMoveDistance > dashDistance) ? (dashDistance - prevCombatMoveDistance) : undefined; if ( targetDistance ) { // Force dash and maximum, to avoid loops on error in measurement. @@ -387,13 +400,14 @@ function _computeTokenSpeed(gridSpaces) { totalDistance += segment.distance; totalMoveDistance += segment.moveDistance; + totalCombatMoveDistance += segment.moveDistance; // Mark segment speed and flag when past the dash and maximum points. - if ( totalMoveDistance > dashDistance && !totalMoveDistance.almostEqual(dashDistance, .01) ) { + if ( totalCombatMoveDistance > dashDistance && !totalCombatMoveDistance.almostEqual(dashDistance, .01) ) { segment.speed = SPEED.TYPES.MAXIMUM; dashing ||= true; atMaximum ||= true; - } else if ( totalMoveDistance > walkDistance && !totalMoveDistance.almostEqual(walkDistance, .01) ) { + } else if ( totalCombatMoveDistance > walkDistance && !totalCombatMoveDistance.almostEqual(walkDistance, .01) ) { segment.speed = SPEED.TYPES.DASH; dashing ||= true; } else segment.speed = SPEED.TYPES.WALK; From fb0433e43ceafbf4d08d7e97440aea7907932aab Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 08:37:30 -0800 Subject: [PATCH 12/13] Fix for max color overriding dash if prior move was at walk limit --- scripts/Ruler.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/Ruler.js b/scripts/Ruler.js index 506a9ab..5dc6a11 100644 --- a/scripts/Ruler.js +++ b/scripts/Ruler.js @@ -354,8 +354,8 @@ function _computeTokenSpeed(gridSpaces) { // Add in already moved combat distance. if ( game.combat?.started && Settings.get(Settings.KEYS.TOKEN_RULER.COMBAT_HISTORY) ) { prevCombatMoveDistance = totalCombatMoveDistance = token.lastMoveDistance; - dashing = totalCombatMoveDistance > walkDistance && !totalCombatMoveDistance.almostEqual(walkDistance, .01); - atMaximum = totalCombatMoveDistance > dashDistance && !totalCombatMoveDistance.almostEqual(dashDistance, .01); + dashing = totalCombatMoveDistance >= walkDistance || totalCombatMoveDistance.almostEqual(walkDistance, .01); + atMaximum = totalCombatMoveDistance >= dashDistance || totalCombatMoveDistance.almostEqual(dashDistance, .01); } // Debugging, to avoid infinite loops. From 6e26b1604d883210349bd6922c96366cc7eac742 Mon Sep 17 00:00:00 2001 From: Michael Enion Date: Thu, 7 Mar 2024 08:40:05 -0800 Subject: [PATCH 13/13] Update changelog --- Changelog.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index fb66dc8..64e401c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,8 @@ # 0.8.9 +### New features +Track combat moves on a per-combat basis. Add settings toggle to have movement speed highlighting reflect sum of moves for that combat round. + +### Bug fixes Fix errors thrown when using the ruler without a movement token with either Terrain Mapper or Elevated Vision modules active. Closes issue #51. Display speed colors to other users who have the speed color setting enabled. Closes issue #53. Add CONFIG options to set additional movement types to the token hud. Closes issue #50. @@ -9,7 +13,6 @@ CONFIG.elevationruler.MOVEMENT_BUTTONS[CONFIG.elevationruler.MOVEMENT_TYPES.SWIM CONFIG.elevationruler.SPEED.ATTRIBUTES.SWIM = "actor.system.attributes.movement.swim"; // dnd5e ``` - # 0.8.8 Improvements to updating the scene graph. Avoid leaving unneeded vertices and split edges when a token or wall is removed. Fixes to handling overlapping edges to correctly reflect what objects make up the edge.