Compare commits

...

15 Commits

Author SHA1 Message Date
Crovaxon 0372b6a3b9 Removed duplicates from merging, fuck VS Code. 2025-05-11 16:43:52 +02:00
Crovaxon 3bd945b6e2 Merge branch 'develop' of https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler into develop 2025-05-11 16:42:37 +02:00
Crovaxon 63b946051a Updated URLs and prepared for test release. 2025-05-11 16:41:13 +02:00
Crovaxon 179cc73fa1 Merge branch 'develop' of https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler into develop 2025-05-11 16:39:19 +02:00
Crovaxon 9eed5d4245 Updated download URL for upcoming test release. 2025-05-11 16:38:27 +02:00
Crovaxon f31c2c0f8a Updated URLs
Updated the download URL
2025-05-11 16:36:44 +02:00
Crovaxon 72a646ab89 Updated URLs 2025-05-11 16:35:28 +02:00
Crovaxon e0c57ce78b Changed socketlib dependency to my own hosted instance and upped version compatibility so Foundry v13 will be able to install this. 2025-05-11 16:22:17 +02:00
Jonas Karlsson a21085ca5b Add dragonbane support (#333) 2024-08-03 21:19:05 +02:00
Joe 21533a0075 Update lancer speed attribute (#301) 2024-08-03 21:18:48 +02:00
Manuel Vögele 8d67ca01c3 Release v1.14.2 2024-07-28 23:26:33 +02:00
Manuel Vögele 80ff8832fd Add a word of warning about bugs to the readme 2024-07-28 23:24:40 +02:00
Manuel Vögele c787b18fcb Add 1 to hex positions before snapping to avoid rounding issues (fixes #334) 2024-07-28 23:13:23 +02:00
Manuel Vögele c03dbc09ff Always use the token's center as origin for gridless snapping (fixes #336) 2024-07-28 23:03:37 +02:00
Manuel Vögele 27a2b46a8a Revert "Restore rulerOffset for all uses except hex grids (fixes #332)"
This reverts commit ab1f5b4c9b.
2024-07-28 22:47:26 +02:00
8 changed files with 36 additions and 37 deletions
+6
View File
@@ -1,3 +1,9 @@
## 1.14.2
### Bug fixes
- Fixed a bug where tokens would snap to inconsistent distances on gridless scenes
- Fixed a bug that caused the highlighted path on hex grids to be incorrect
## 1.14.1 ## 1.14.1
### Bug fixes ### Bug fixes
- The functionality Drag Ruler on gridless has been restored - The functionality Drag Ruler on gridless has been restored
+6 -2
View File
@@ -1,13 +1,17 @@
[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/staebchenfisch) [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/staebchenfisch)
## Beware of bugs in v12 and onward
Foundry v12 has introduced significant changes to how the grid and the ruler are implemented. While Drag Ruler has now been updated to generally work with v12, quite a lot of bugs remain. This is espeically true for Hex grids, but some bugs affect all the grid types. Some of the issues require a large code rewrite to address them properly. Unfortunately this means that Drag Ruler will not provide the same quality experience (snappyness, bugfreeness) you're used to in v12 (and possibly onward). If you're planning to update to v12 and depend on Drag Ruler, proceed with caution.
# Drag Ruler # Drag Ruler
This module shows a ruler when you drag a token or measurement template to inform you how far you've dragged it from its start point. Additionally, if you're using a grid, the spaces the token will travel though will be colored depending on your tokens speed. By default, three colors are being used: green for spaces that your token can reach by walking normally are colored green, spaces that can only be reached by dashing will be colored yellow and spaces that cannot be reached with the token's speed will be colored red. If you're using a gridless map the ruler color will change to convey this information. This module shows a ruler when you drag a token or measurement template to inform you how far you've dragged it from its start point. Additionally, if you're using a grid, the spaces the token will travel though will be colored depending on your tokens speed. By default, three colors are being used: green for spaces that your token can reach by walking normally are colored green, spaces that can only be reached by dashing will be colored yellow and spaces that cannot be reached with the token's speed will be colored red. If you're using a gridless map the ruler color will change to convey this information.
![Drag Ruler being used on a square grids](https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/709774b25f7dd818a90591165f74b3e6dbc788cc/media/basic_square.webp) ![Drag Ruler being used on a square grids](https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/709774b25f7dd818a90591165f74b3e6dbc788cc/media/basic_square.webp)
![Drag Ruler being used on a gridless scene](https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/709774b25f7dd818a90591165f74b3e6dbc788cc/media/basic_gridless.webp) ![Drag Ruler being used on a gridless scene](https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/709774b25f7dd818a90591165f74b3e6dbc788cc/media/basic_gridless.webp)
![Drag Ruler while dragging a measurement template](https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/709774b25f7dd818a90591165f74b3e6dbc788cc/media/measurement_template.webp) ![Drag Ruler while dragging a measurement template](https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/709774b25f7dd818a90591165f74b3e6dbc788cc/media/measurement_template.webp)
## Supports Tokens of all sizes ## Supports Tokens of all sizes
Terrain ruler has excellent support for tokens of all sizes. The Ruler will always originate from the token's center and will always highlight all the squares that tokens move over. Terrain ruler has excellent support for tokens of all sizes. The Ruler will always originate from the token's center and will always highlight all the squares that tokens move over.
@@ -51,7 +55,7 @@ The game systems that offer Drag Ruler integration are:
- GURPS 4th Edition Game Aid (Unofficial) (starting with version 0.9.1) - GURPS 4th Edition Game Aid (Unofficial) (starting with version 0.9.1)
- Hackmaster (starting with version 0.2.11) - Hackmaster (starting with version 0.2.11)
- Ironclaw Second Edition (starting with version 0.2.2) - Ironclaw Second Edition (starting with version 0.2.2)
- Lancer (via the module [Lancer Speed Provider](https://foundryvtt.com/packages/lancer-speed-provider)) - Lancer (via the module [Lancer Ruler Integration](https://foundryvtt.com/packages/lancer-speed-provider))
- Level Up: Advanced 5th Edition (Official) (via the module [A5E Drag Ruler Integration](https://foundryvtt.com/packages/a5edragruler)) - Level Up: Advanced 5th Edition (Official) (via the module [A5E Drag Ruler Integration](https://foundryvtt.com/packages/a5edragruler))
- Pathfinder 1 (starting with version 0.77.3) - Pathfinder 1 (starting with version 0.77.3)
- Pathfinder 2e (via the module [PF2E Drag Ruler Integration](https://foundryvtt.com/packages/pf2e-dragruler/)) - Pathfinder 2e (via the module [PF2E Drag Ruler Integration](https://foundryvtt.com/packages/pf2e-dragruler/))
+9 -9
View File
@@ -2,11 +2,11 @@
"id": "drag-ruler", "id": "drag-ruler",
"title": "Drag Ruler", "title": "Drag Ruler",
"description": "When dragging a token displays a ruler showing how far you've moved that token.", "description": "When dragging a token displays a ruler showing how far you've moved that token.",
"version": "1.14.1", "version": "1.14.2",
"compatibility": { "compatibility": {
"minimum": "12", "minimum": "12",
"verified": "12", "verified": "12",
"maximum": "12" "maximum": "13"
}, },
"authors": [ "authors": [
{ {
@@ -75,16 +75,16 @@
{ {
"id": "socketlib", "id": "socketlib",
"type": "module", "type": "module",
"manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-socketlib/master/module.json" "manifest": "https://gitea.crovaxon.de/crovaxon/foundryvtt-socketlib/raw/branch/develop/module.json"
} }
] ]
}, },
"socket": true, "socket": true,
"url": "https://github.com/manuelVo/foundryvtt-drag-ruler", "url": "https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler",
"download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.14.1.zip", "download": "https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler/archive/v1.14.2-test.zip",
"manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/master/module.json", "manifest": "https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler/raw/branch/develop/module.json",
"readme": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/README.md", "readme": "https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler/blob/master/README.md",
"changelog": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/CHANGELOG.md", "changelog": "https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler/blob/master/CHANGELOG.md",
"bugs": "https://github.com/manuelVo/foundryvtt-drag-ruler/issues", "bugs": "https://gitea.crovaxon.de/crovaxon/foundryvtt-drag-ruler/issues",
"allowBugReporter": true "allowBugReporter": true
} }
+1 -5
View File
@@ -140,10 +140,6 @@ export function onMouseMove(event) {
x: event.interactionData.destination.x, x: event.interactionData.destination.x,
y: event.interactionData.destination.y, y: event.interactionData.destination.y,
}; };
if (!canvas.grid.isHex) {
destination.x += this.rulerOffset.x;
destination.y += this.rulerOffset.y;
}
// Hide any existing Token HUD // Hide any existing Token HUD
canvas.hud.token.clear(); canvas.hud.token.clear();
@@ -199,7 +195,7 @@ export function highlightMeasurementNative(
const pathUntilSpace = previousSegments.concat([{ray: new Ray(ray.A, center)}]); const pathUntilSpace = previousSegments.concat([{ray: new Ray(ray.A, center)}]);
const distance = sum(canvas.grid.measureDistances(pathUntilSpace, {gridSpaces: true})); const distance = sum(canvas.grid.measureDistances(pathUntilSpace, {gridSpaces: true}));
const color = this.dragRulerGetColorForDistance(distance); const color = this.dragRulerGetColorForDistance(distance);
const snapPoint = getSnapPointForToken(point.x, point.y, this.draggedEntity); const snapPoint = getSnapPointForToken(point.x + 1, point.y + 1, this.draggedEntity);
const [snapX, snapY] = getGridPositionFromPixels(snapPoint.x + 1, snapPoint.y + 1); const [snapX, snapY] = getGridPositionFromPixels(snapPoint.x + 1, snapPoint.y + 1);
highlightTokenShape.call(this, {x: snapX, y: snapY}, tokenShape, color, alpha); highlightTokenShape.call(this, {x: snapX, y: snapY}, tokenShape, color, alpha);
} }
+6 -11
View File
@@ -137,11 +137,6 @@ function onEntityLeftDragStart(wrapped, event) {
const ruler = canvas.controls.ruler; const ruler = canvas.controls.ruler;
ruler.draggedEntity = this; ruler.draggedEntity = this;
const entityCenter = getEntityCenter(this); const entityCenter = getEntityCenter(this);
const isV11 = game.release.generation === 11;
ruler.rulerOffset = {
x: isV11 ? entityCenter.x - event.interactionData.origin.x : 0,
y: isV11 ? entityCenter.y - event.interactionData.origin.y : 0,
};
if (game.settings.get(settingsKey, "autoStartMeasurement")) { if (game.settings.get(settingsKey, "autoStartMeasurement")) {
let options = {}; let options = {};
setSnapParameterOnOptions(ruler, options); setSnapParameterOnOptions(ruler, options);
@@ -150,7 +145,7 @@ function onEntityLeftDragStart(wrapped, event) {
} }
function onEntityLeftDragMoveSnap(wrapped, event) { function onEntityLeftDragMoveSnap(wrapped, event) {
applyGridlessSnapping.call(this, event); applyGridlessSnapping.call(canvas.controls.ruler, event);
onEntityLeftDragMove.call(this, wrapped, event); onEntityLeftDragMove.call(this, wrapped, event);
} }
@@ -218,7 +213,7 @@ function applyGridlessSnapping(event) {
const rasterWidth = 35 / canvas.stage.scale.x; const rasterWidth = 35 / canvas.stage.scale.x;
const tokenX = event.interactionData.destination.x; const tokenX = event.interactionData.destination.x;
const tokenY = event.interactionData.destination.y; const tokenY = event.interactionData.destination.y;
const destination = {x: tokenX + ruler.rulerOffset.x, y: tokenY + ruler.rulerOffset.y}; const destination = {x: tokenX, y: tokenY};
const ranges = getRangesFromSpeedProvider(ruler.draggedEntity); const ranges = getRangesFromSpeedProvider(ruler.draggedEntity);
const terrainRulerAvailable = game.modules.get("terrain-ruler")?.active; const terrainRulerAvailable = game.modules.get("terrain-ruler")?.active;
@@ -242,13 +237,13 @@ function applyGridlessSnapping(event) {
const deltaY = destination.y - rasterLocation.y; const deltaY = destination.y - rasterLocation.y;
const rasterDistance = Math.hypot(deltaX, deltaY); const rasterDistance = Math.hypot(deltaX, deltaY);
if (rasterDistance < rasterWidth) { if (rasterDistance < rasterWidth) {
event.interactionData.destination.x = rasterLocation.x - ruler.rulerOffset.x; event.interactionData.destination.x = rasterLocation.x;
event.interactionData.destination.y = rasterLocation.y - ruler.rulerOffset.y; event.interactionData.destination.y = rasterLocation.y;
} }
} }
} else { } else {
let waypointDistance = 0; let waypointDistance = 0;
let origin = event.interactionData.origin; let origin = this.draggedEntity.getCenterPoint();
if (ruler.waypoints.length > 1) { if (ruler.waypoints.length > 1) {
const segments = ruler.constructor const segments = ruler.constructor
.dragRulerGetRaysFromWaypoints(ruler.waypoints, destination) .dragRulerGetRaysFromWaypoints(ruler.waypoints, destination)
@@ -257,7 +252,7 @@ function applyGridlessSnapping(event) {
}); });
origin = segments.pop().ray.A; origin = segments.pop().ray.A;
waypointDistance = canvas.grid.measureDistances(segments).reduce((a, b) => a + b); waypointDistance = canvas.grid.measureDistances(segments).reduce((a, b) => a + b);
origin = {x: origin.x - ruler.rulerOffset.x, y: origin.y - ruler.rulerOffset.y}; origin = {x: origin.x, y: origin.y};
} }
const deltaX = tokenX - origin.x; const deltaX = tokenX - origin.x;
+3 -7
View File
@@ -391,14 +391,10 @@ export function extendRuler() {
if (this.waypoints.filter(w => !w.isPrevious).length > 1) { if (this.waypoints.filter(w => !w.isPrevious).length > 1) {
event.preventDefault(); event.preventDefault();
const mousePosition = getPointer().getLocalPosition(canvas.tokens); const mousePosition = getPointer().getLocalPosition(canvas.tokens);
const rulerOffset = this.rulerOffset;
// Options are not passed to _removeWaypoint in vanilla Foundry. // Options are not passed to _removeWaypoint in vanilla Foundry.
// Send them in case other modules have overriden that behavior and accept an options parameter (Toggle Snap to Grid) // Send them in case other modules have overriden that behavior and accept an options parameter (Toggle Snap to Grid)
this._removeWaypoint( this._removeWaypoint({x: mousePosition.x, y: mousePosition.y}, options);
{x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y},
options,
);
this.performPostPathfindingActions(options); this.performPostPathfindingActions(options);
} else { } else {
this.dragRulerAbortDrag(event); this.dragRulerAbortDrag(event);
@@ -494,8 +490,8 @@ export function extendRuler() {
ruler.dragRulerAddWaypoint(entityCenter, {snap: false}); ruler.dragRulerAddWaypoint(entityCenter, {snap: false});
const mousePosition = getPointer().getLocalPosition(canvas.tokens); const mousePosition = getPointer().getLocalPosition(canvas.tokens);
const destination = { const destination = {
x: mousePosition.x + ruler.rulerOffset.x, x: mousePosition.x,
y: mousePosition.y + ruler.rulerOffset.y, y: mousePosition.y,
}; };
if (measureImmediately) ruler.measure(destination, options); if (measureImmediately) ruler.measure(destination, options);
} }
+4 -1
View File
@@ -9,7 +9,7 @@ export function getDefaultSpeedAttribute() {
case "dnd5e": case "dnd5e":
return "actor.system.attributes.movement.walk"; return "actor.system.attributes.movement.walk";
case "lancer": case "lancer":
return "actor.system.derived.speed"; return "actor.system.speed";
case "pf1": case "pf1":
case "D35E": case "D35E":
return "actor.system.attributes.speed.land.total"; return "actor.system.attributes.speed.land.total";
@@ -27,6 +27,8 @@ export function getDefaultSpeedAttribute() {
return "actor.system.details.move.walk"; return "actor.system.details.move.walk";
case "crucible": case "crucible":
return "actor.system.movement.stride"; return "actor.system.movement.stride";
case "dragonbane":
return "actor.system.movement.value";
} }
return ""; return "";
} }
@@ -44,6 +46,7 @@ export function getDefaultDashMultiplier() {
case "sfrpg": case "sfrpg":
case "shadowrun5e": case "shadowrun5e":
case "ds4": case "ds4":
case "dragonbane":
return 2; return 2;
case "CoC7": case "CoC7":
return 5; return 5;
+1 -2
View File
@@ -301,8 +301,7 @@ export function getPointer() {
export function getMeasurePosition() { export function getMeasurePosition() {
const mousePosition = getPointer().getLocalPosition(canvas.tokens); const mousePosition = getPointer().getLocalPosition(canvas.tokens);
const rulerOffset = canvas.controls.ruler.rulerOffset; const measurePosition = {x: mousePosition.x, y: mousePosition.y};
const measurePosition = {x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y};
return measurePosition; return measurePosition;
} }