Skip to content

Commit

Permalink
Merge branch 'release/0.7.4' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
caewok committed Jan 8, 2024
2 parents 9adc1a9 + 8ec1896 commit 1d06e34
Show file tree
Hide file tree
Showing 11 changed files with 675 additions and 41 deletions.
4 changes: 4 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.7.4
Add option to enable a Token Ruler when dragging tokens.
Add option to use a token speed attribute to highlight in differing colors when using the ruler (from a token) or dragging tokens.

# 0.7.3
Updated lib-geometry to 0.2.12.
Refactor to use Patcher class.
Expand Down
17 changes: 17 additions & 0 deletions languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
"elevationruler.keybindings.incrementElevation.name": "Increment Ruler Elevation",
"elevationruler.keybindings.incrementElevation.hint": "Increase the elevation in grid increments when using the ruler.",

"elevationruler.keybindings.addWaypointTokenRuler.name": "Add Token Ruler Waypoint",
"elevationruler.keybindings.addWaypointTokenRuler.hint": "When token ruler is enabled, add a waypoint while dragging the token.",

"elevationruler.keybindings.removeWaypointTokenRuler.name": "Remove Token Ruler Waypoint",
"elevationruler.keybindings.removeWaypointTokenRuler.hint": "When token ruler is enabled, remove a waypoint while dragging the token.",


"elevationruler.settings.no-modules-message.name": "No elevation-related modules found.",
"elevationruler.settings.no-modules-message.hint": "Additional settings will be available here if Elevated Vision, Enhanced Terrain Layer, or Levels modules are active.",

Expand All @@ -26,5 +33,15 @@
"elevationruler.settings.prefer-token-elevation.name": "Add token elevation control",
"elevationruler.settings.prefer-token-elevation.hint": "Add a control to the token toolbar to prefer the token elevation when measuring. When toggled on, the control will keep the ruler at the elevation of the measuring token unless another token is encountered or the grid space is at a higher elevation than the token. Otherwise, the ruler will assume the elevation of the grid space or the token encountered.",

"elevationruler.settings.enable-token-ruler.name": "Use Token Ruler",
"elevationruler.settings.enable-token-ruler.hint": "Display the ruler when dragging tokens.",

"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-speed-property.name": "Token Speed Property",
"elevationruler.settings.token-speed-property.hint": "For token speed highlighting, this is the property representing token speed.",


"elevationruler.controls.prefer-token-elevation.name": "Prefer Token Elevation"
}
32 changes: 32 additions & 0 deletions scripts/ClientKeybindings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* globals
*/
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */

import { elevationAtWaypoint } from "./segments.js";

// Patches for the ClientKeybindings class
export const PATCHES = {};
PATCHES.TOKEN_RULER = {}; // Assume this patch is only present if the token ruler setting is enabled.

/**
* Mixed wrap of ClientKeybindings._onMeasuredRulerMovement
* Called when spacebar is pressed, for ruler.
* If the Token Ruler is active, call that instead.
* @param {KeyboardEventContext} context The context data of the event
*/
async function _onMeasuredRulerMovement(wrapped, context) {
console.log("_onMeasuredRulerMovement");
// We only care about when tokens are being dragged
const ruler = canvas.controls.ruler;
if ( !ruler.active
|| !canvas.tokens.active
|| ui.controls.tool !== "select" ) return wrapped(context);

// For each controlled token, end the drag.
canvas.tokens.clearPreviewContainer();
await ruler.moveToken();
ruler._endMeasurement();
}

PATCHES.TOKEN_RULER.STATIC_WRAPS = { _onMeasuredRulerMovement }
15 changes: 15 additions & 0 deletions scripts/PlaceableObject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* globals
canvas
*/
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */

// Patches for the Token class
export const PATCHES = {};
PATCHES.TOKEN_RULER = {}; // Assume this patch is only present if the token ruler setting is enabled.


function _onDragLeftStart(wrapped, event) {
console.log("Placeable.prototype._onDragLeftStart");
}

PATCHES.TOKEN_RULER = { _onDragLeftStart };
55 changes: 53 additions & 2 deletions scripts/Token.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,57 @@ import { elevationAtWaypoint } from "./segments.js";
// Patches for the Token class
export const PATCHES = {};
PATCHES.DRAG_RULER = {};
PATCHES.TOKEN_RULER = {}; // Assume this patch is only present if the token ruler setting is enabled.

/**
* Wrap Token.prototype._onDragLeftStart
* Start a ruler measurement.
*/
function _onDragLeftStart(wrapped, event) {
wrapped(event);

// Start a Ruler measurement.
canvas.controls.ruler._onDragStart(event);
}

/**
* Wrap Token.prototype._onDragLeftMove
* Continue the ruler measurement
*/
function _onDragLeftMove(wrapped, event) {
wrapped(event);

// Continue a Ruler measurement.
const ruler = canvas.controls.ruler;
if ( ruler._state > 0 ) ruler._onMouseMove(event);
}

/**
* Mix Token.prototype._onDragLeftDrop
* End the ruler measurement.
*/
async function _onDragLeftDrop(wrapped, event) {
// End the ruler measurement
const ruler = canvas.controls.ruler;
if ( !ruler.active ) return wrapped(event);
const destination = event.interactionData.destination;

// Ensure the cursor destination is within bounds
if ( !canvas.dimensions.rect.contains(destination.x, destination.y) ) {
ruler._onMouseUp(event);
return false;
}
await ruler.moveToken();
ruler._onMouseUp(event);
}


PATCHES.TOKEN_RULER.WRAPS = {
_onDragLeftStart,
_onDragLeftMove
};

PATCHES.TOKEN_RULER.MIXES = { _onDragLeftDrop };

/**
* Wrap Token.prototype._onDragLeftDrop
Expand All @@ -17,7 +68,7 @@ PATCHES.DRAG_RULER = {};
* @param {PIXI.InteractionEvent} event The triggering canvas interaction event
* @returns {Promise<*>}
*/
async function _onDragLeftDrop(wrapped, event) {
async function _onDragLeftDropDragRuler(wrapped, event) {
// Assume the destination elevation is the desired elevation if dragging multiple tokens.
// (Likely more useful than having a bunch of tokens move down 10'?)
const ruler = canvas.controls.ruler;
Expand All @@ -40,4 +91,4 @@ async function _onDragLeftDrop(wrapped, event) {
return true;
}

PATCHES.DRAG_RULER.WRAPS = { _onDragLeftDrop };
PATCHES.DRAG_RULER.WRAPS = { _onDragLeftDrop: _onDragLeftDropDragRuler };
95 changes: 95 additions & 0 deletions scripts/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,98 @@ Hooks.once("init", function() {
MODULES_ACTIVE.LEVELS = game.modules.get("levels")?.active;
MODULES_ACTIVE.ELEVATED_VISION = game.modules.get("elevatedvision")?.active;
});

/**
* Below Taken from Drag Ruler
*/
/*
MIT License
Copyright (c) 2021 Manuel Vögele
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

export const SPEED = {
ATTRIBUTE: "",
MULTIPLIER: 0
};

// Avoid testing for the system id each time.
Hooks.once("init", function() {
SPEED.ATTRIBUTE = defaultSpeedAttribute();
SPEED.MULTIPLIER = defaultDashMultiplier();
});

function defaultSpeedAttribute() {
switch (game.system.id) {
case "CoC7":
return "actor.system.attribs.mov.value";
case "dcc":
case "sfrpg":
return "actor.system.attributes.speed.value";
case "dnd4e":
return "actor.system.movement.walk.value";
case "dnd5e":
return "actor.system.attributes.movement.walk";
case "lancer":
return "actor.system.derived.speed";
case "pf1":
case "D35E":
return "actor.system.attributes.speed.land.total";
case "shadowrun5e":
return "actor.system.movement.walk.value";
case "swade":
return "actor.system.stats.speed.adjusted";
case "ds4":
return "actor.system.combatValues.movement.total";
case "splittermond":
return "actor.derivedValues.speed.value";
case "wfrp4e":
return "actor.system.details.move.walk";
case "crucible":
return "actor.system.movement.stride";
}
return "";
}

function defaultDashMultiplier() {
switch (game.system.id) {
case "dcc":
case "dnd4e":
case "dnd5e":
case "lancer":
case "pf1":
case "D35E":
case "sfrpg":
case "shadowrun5e":
case "ds4":
return 2;
case "CoC7":
return 5;
case "splittermond":
return 3;
case "wfrp4e":
return 2;
case "crucible":
case "swade":
return 0;
}
return 0;
}
14 changes: 7 additions & 7 deletions scripts/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ ui
import { Settings } from "./settings.js";
import { initializePatching, PATCHER, registerDragRuler } from "./patching.js";
import { MODULE_ID } from "./const.js";
import { iterateGridUnderLine } from "./ruler.js";

import { registerGeometry } from "./geometry/registration.js";

Hooks.once("init", function() {
// Cannot access localization until init.
PREFER_TOKEN_CONTROL.title = game.i18n.localize(PREFER_TOKEN_CONTROL.title);
registerGeometry();
game.modules.get(MODULE_ID).api = {
iterateGridUnderLine,
PATCHER
};
});

// Setup is after init; before ready.
Expand All @@ -38,13 +45,6 @@ const PREFER_TOKEN_CONTROL = {
toggle: true
};

Hooks.once("init", function() {
// Cannot access localization until init.
PREFER_TOKEN_CONTROL.title = game.i18n.localize(PREFER_TOKEN_CONTROL.title);
game.modules.get(MODULE_ID).api = {
PATCHER
};
});

// Render the prefer token control if that setting is enabled
Hooks.on("getSceneControlButtons", controls => {
Expand Down
6 changes: 5 additions & 1 deletion scripts/patching.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ import { MODULES_ACTIVE } from "./const.js";
import { PATCHES as PATCHES_Ruler } from "./Ruler.js";
import { PATCHES as PATCHES_Token } from "./Token.js";
import { PATCHES as PATCHES_GridLayer } from "./GridLayer.js";
import { PATCHES as PATCHES_PlaceableObject } from "./PlaceableObject.js";
import { PATCHES as PATCHES_ClientKeybindings } from "./ClientKeybindings.js";

// Settings
import { PATCHES as PATCHES_Settings } from "./ModuleSettingsAbstract.js";


const PATCHES = {
ClientKeybindings: PATCHES_ClientKeybindings,
GridLayer: PATCHES_GridLayer,
Ruler: PATCHES_Ruler,
PlaceableObject: PATCHES_PlaceableObject,
Token: PATCHES_Token,
Settings: PATCHES_Settings
};
Expand All @@ -30,3 +33,4 @@ export function initializePatching() {
export function registerDragRuler() {
if ( MODULES_ACTIVE.DRAG_RULER ) PATCHER.registerGroup("DRAG_RULER");
}

Loading

0 comments on commit 1d06e34

Please sign in to comment.