Compare commits
15 Commits
v1.14.1
...
v1.14.2-test
| Author | SHA1 | Date | |
|---|---|---|---|
| 0372b6a3b9 | |||
| 3bd945b6e2 | |||
| 63b946051a | |||
| 179cc73fa1 | |||
| 9eed5d4245 | |||
| f31c2c0f8a | |||
| 72a646ab89 | |||
| e0c57ce78b | |||
| a21085ca5b | |||
| 21533a0075 | |||
| 8d67ca01c3 | |||
| 80ff8832fd | |||
| c787b18fcb | |||
| c03dbc09ff | |||
| 27a2b46a8a |
@@ -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
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
[](https://ko-fi.com/staebchenfisch)
|
[](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.
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## 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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user