Compare commits

..

16 Commits

Author SHA1 Message Date
Manuel Vögele 334ccbc0f1 Release v1.6.4 2021-05-10 09:13:32 +02:00
Manuel Vögele 1242035744 Catch all errors thrown by a Speed Provider's getCostForStep function 2021-05-10 09:11:29 +02:00
Manuel Vögele 49542a68e5 Simplify foundry fixes 2021-05-06 09:00:50 +02:00
Chris Sharp 27a6235cc1 Mention WWII:OWB Operation WhiteBox system support in the readme 2021-05-05 23:40:40 +02:00
Manuel Vögele c26b39c984 Release v1.6.3 2021-05-05 16:01:52 +02:00
Manuel Vögele e8ab77a62e Update active rulers when the movement history changes 2021-05-05 16:01:13 +02:00
Manuel Vögele 7bed5abd0a Add default settings for shadowrun 5e 2021-05-03 19:39:22 +02:00
Manuel Vögele 4a96348659 Add "Tagmar RPG" and "Shadow of the Demon Lord" to the List of game systems with Drag Ruler integration 2021-05-03 16:00:34 +02:00
Manuel Vögele bed16de575 Release v1.6.2 2021-05-03 10:53:53 +02:00
Manuel Vögele 891bb1b4d8 undefined cannot be transmitted via json, so we use null to reset the movement history instead 2021-05-03 10:52:57 +02:00
Manuel Vögele 43f26088b5 Release v1.6.1 2021-04-30 10:52:00 +02:00
Manuel Vögele 39a0787c79 Add documentation about what needs to be awaited in SpeedProvider.onMovementHistoryUpdate 2021-04-30 10:26:37 +02:00
Manuel Vögele 3be898e49c First move the token, then store it's path. This ensures that getMovedDistance always returns a valid result. 2021-04-30 09:53:53 +02:00
Manuel Vögele 817662bf30 Send a proper token to onMovementHistoryUpdate 2021-04-30 09:51:05 +02:00
Manuel Vögele 56527ccf75 Add a hook that's called when the movement history is updated to the API 2021-04-30 00:10:45 +02:00
Manuel Vögele 6bf8083f7a Add a function for resetting the movement history to the public api 2021-04-30 00:00:15 +02:00
12 changed files with 97 additions and 16 deletions
+24
View File
@@ -1,3 +1,27 @@
## 1.6.4
### Bugfixes
- Fixed a bug where a bug in a Speed Provider could lead to the ruler getting stuck, leaving the token immovable
## 1.6.3
### Bugfixes
- If the movement history for a token is being updated (for example by a history reset by the gm) while a player is currently measuring a distance for that token the history change is now being reflected in the active measurement.
### Compatibility
- Drag Ruler's Generic SpeedProvider is now aware of good default values for the Savage Worlds Adventure Edition game system
## 1.6.2
### Bugfixes
- The reset movement history button now resets the movement history for all players, not just for the GM
## 1.6.1
### API
- Added `onMovementHistoryUpdate` callback to Speed Providers, that allows them to perform game systems specific improvements to the movement history
- Added `dragRuler.resetMovementHistory` that clears the stored movement history for a token.
## 1.6.0 ## 1.6.0
### Performance ### Performance
- Greatly increased the performance when playing on huge maps and when moving many tokens at once. - Greatly increased the performance when playing on huge maps and when moving many tokens at once.
+3
View File
@@ -36,7 +36,10 @@ The game systems that offer Drag Ruler integration are:
- Cypher System (starting with version 1.13.0) - Cypher System (starting with version 1.13.0)
- 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/))
- Tagmar RPG (starting with version 1.1.4)
- Tormenta20 (starting with version 1.1.37) - Tormenta20 (starting with version 1.1.37)
- Shadow of the Demon Lord (starting with version 1.7.15)
- WWII:OWB (starting with version 1.0.4)
## Translations ## Translations
+2 -2
View File
@@ -2,7 +2,7 @@
"name": "drag-ruler", "name": "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.6.0", "version": "1.6.4",
"minimumCoreVersion" : "0.7.9", "minimumCoreVersion" : "0.7.9",
"compatibleCoreVersion" : "0.7.9", "compatibleCoreVersion" : "0.7.9",
"authors": [ "authors": [
@@ -49,7 +49,7 @@
], ],
"socket": true, "socket": true,
"url": "https://github.com/manuelVo/foundryvtt-drag-ruler", "url": "https://github.com/manuelVo/foundryvtt-drag-ruler",
"download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.6.0.zip", "download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.6.4.zip",
"manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/master/module.json", "manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/master/module.json",
"readme": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/README.md", "readme": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/README.md",
"changelog": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/CHANGELOG.md", "changelog": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/CHANGELOG.md",
+6
View File
@@ -101,10 +101,16 @@ export function getUnreachableColorFromSpeedProvider() {
} }
export function getCostFromSpeedProvider(token, area) { export function getCostFromSpeedProvider(token, area) {
try {
if (currentSpeedProvider instanceof Function) { if (currentSpeedProvider instanceof Function) {
return SpeedProvider.prototype.getCostForStep.call(undefined, token, area); return SpeedProvider.prototype.getCostForStep.call(undefined, token, area);
} }
return currentSpeedProvider.getCostForStep(token, area); return currentSpeedProvider.getCostForStep(token, area);
}
catch (e) {
console.error(e);
return 1;
}
} }
export function getMovedDistanceFromToken(token) { export function getMovedDistanceFromToken(token) {
+2 -5
View File
@@ -2,13 +2,10 @@
// https://gitlab.com/foundrynet/foundryvtt/-/issues/4705 // https://gitlab.com/foundrynet/foundryvtt/-/issues/4705
export function getPixelsFromGridPosition(xGrid, yGrid) { export function getPixelsFromGridPosition(xGrid, yGrid) {
if (canvas.grid.isHex) { if (canvas.grid.type !== CONST.GRID_TYPES.GRIDLESS) {
return canvas.grid.grid.getPixelsFromGridPosition(yGrid, xGrid) return canvas.grid.grid.getPixelsFromGridPosition(yGrid, xGrid)
} }
const [x, y] = canvas.grid.grid.getPixelsFromGridPosition(xGrid, yGrid) return canvas.grid.grid.getPixelsFromGridPosition(xGrid, yGrid)
if (canvas.grid.type === CONST.GRID_TYPES.SQUARE)
return [y, x]
return [x, y]
} }
// Wrapper to fix a FoundryVTT bug that causes the return values of canvas.grid.grid.getPixelsFromGridPosition to be ordered inconsistently // Wrapper to fix a FoundryVTT bug that causes the return values of canvas.grid.grid.getPixelsFromGridPosition to be ordered inconsistently
+2 -1
View File
@@ -2,6 +2,7 @@ import {highlightMeasurementTerrainRuler, measureDistances} from "./compatibilit
import {getGridPositionFromPixels} from "./foundry_fixes.js"; import {getGridPositionFromPixels} from "./foundry_fixes.js";
import {getColorForDistance} from "./main.js" import {getColorForDistance} from "./main.js"
import {trackRays} from "./movement_tracking.js" import {trackRays} from "./movement_tracking.js"
import {recalculate} from "./socket.js";
import {applyTokenSizeOffset, getSnapPointForToken, getTokenShape, highlightTokenShape, zip} from "./util.js"; import {applyTokenSizeOffset, getSnapPointForToken, getTokenShape, highlightTokenShape, zip} from "./util.js";
// This is a modified version of Ruler.moveToken from foundry 0.7.9 // This is a modified version of Ruler.moveToken from foundry 0.7.9
@@ -64,7 +65,6 @@ async function animateTokens(tokens, draggedToken, draggedRays, wasPaused) {
return {token, rays: offsetRays, dx, dy}; return {token, rays: offsetRays, dx, dy};
}); });
trackRays(tokenAnimationData.map(({token}) => token), tokenAnimationData.map(({rays}) => rays));
for (const {token, rays} of tokenAnimationData) { for (const {token, rays} of tokenAnimationData) {
token._noAnimate = true; token._noAnimate = true;
} }
@@ -88,6 +88,7 @@ async function animateTokens(tokens, draggedToken, draggedRays, wasPaused) {
for (const {token} of tokenAnimationData) { for (const {token} of tokenAnimationData) {
token._noAnimate = false; token._noAnimate = false;
} }
trackRays(tokens, tokenAnimationData.map(({rays}) => rays)).then(() => recalculate(tokens));
} }
function calculateTokenOffset(tokenA, tokenB) { function calculateTokenOffset(tokenA, tokenB) {
+3
View File
@@ -7,6 +7,7 @@ import {performMigrations} from "./migration.js"
import {DragRulerRuler} from "./ruler.js"; import {DragRulerRuler} from "./ruler.js";
import {getMovementHistory, resetMovementHistory} from "./movement_tracking.js"; import {getMovementHistory, resetMovementHistory} from "./movement_tracking.js";
import {registerSettings, settingsKey} from "./settings.js" import {registerSettings, settingsKey} from "./settings.js"
import {recalculate} from "./socket.js";
import {SpeedProvider} from "./speed_provider.js" import {SpeedProvider} from "./speed_provider.js"
Hooks.once("init", () => { Hooks.once("init", () => {
@@ -22,6 +23,8 @@ Hooks.once("init", () => {
getMovedDistanceFromToken, getMovedDistanceFromToken,
registerModule, registerModule,
registerSystem, registerSystem,
recalculate,
resetMovementHistory,
} }
}) })
+5 -4
View File
@@ -1,5 +1,5 @@
import {measureDistances} from "./compatibility.js"; import {measureDistances} from "./compatibility.js";
import {updateCombatantDragRulerFlags} from "./socket.js"; import {recalculate, updateCombatantDragRulerFlags} from "./socket.js";
import {getTokenShape, zip} from "./util.js"; import {getTokenShape, zip} from "./util.js";
function initTrackingFlag(combatant) { function initTrackingFlag(combatant) {
@@ -86,8 +86,9 @@ export async function resetMovementHistory(combat, combatantId) {
const dragRulerFlags = combatant.flags.dragRuler; const dragRulerFlags = combatant.flags.dragRuler;
if (!dragRulerFlags) if (!dragRulerFlags)
return; return;
dragRulerFlags.passedWaypoints = undefined; dragRulerFlags.passedWaypoints = null;
dragRulerFlags.trackedRound = undefined; dragRulerFlags.trackedRound = null;
dragRulerFlags.rulerState = undefined; dragRulerFlags.rulerState = null;
await updateCombatantDragRulerFlags(combat, [{_id: combatantId, dragRulerFlags}]); await updateCombatantDragRulerFlags(combat, [{_id: combatantId, dragRulerFlags}]);
recalculate();
} }
+22
View File
@@ -1,4 +1,5 @@
import {measure} from "./foundry_imports.js" import {measure} from "./foundry_imports.js"
import {getMovementHistory} from "./movement_tracking.js";
import {settingsKey} from "./settings.js"; import {settingsKey} from "./settings.js";
import {getSnapPointForToken} from "./util.js"; import {getSnapPointForToken} from "./util.js";
@@ -78,6 +79,11 @@ export class DragRulerRuler extends Ruler {
} }
} }
dragRulerClearWaypoints() {
this.waypoints = [];
this.labels.removeChildren().forEach(c => c.destroy());
}
dragRulerDeleteWaypoint(event={preventDefault: () => {return}}) { dragRulerDeleteWaypoint(event={preventDefault: () => {return}}) {
if (this.waypoints.filter(w => !w.isPrevious).length > 1) { if (this.waypoints.filter(w => !w.isPrevious).length > 1) {
event.preventDefault(); event.preventDefault();
@@ -100,6 +106,22 @@ export class DragRulerRuler extends Ruler {
} }
} }
async dragRulerRecalculate(tokenIds) {
if (this._state !== Ruler.STATES.MEASURING)
return;
if (tokenIds && !tokenIds.includes(this.draggedToken.id))
return;
const waypoints = this.waypoints.filter(waypoint => !waypoint.isPrevious);
this.dragRulerClearWaypoints();
if (game.settings.get(settingsKey, "enableMovementHistory"))
this.dragRulerAddWaypointHistory(getMovementHistory(this.draggedToken));
for (const waypoint of waypoints) {
this.dragRulerAddWaypoint(waypoint, false);
}
this.measure(this.destination);
game.user.broadcastActivity({ruler: this});
}
static dragRulerGetRaysFromWaypoints(waypoints, destination) { static dragRulerGetRaysFromWaypoints(waypoints, destination) {
if ( destination ) if ( destination )
waypoints = waypoints.concat([destination]); waypoints = waypoints.concat([destination]);
+14 -1
View File
@@ -1,13 +1,18 @@
import {currentSpeedProvider} from "./api.js";
let socket; let socket;
Hooks.once("socketlib.ready", () => { Hooks.once("socketlib.ready", () => {
socket = socketlib.registerModule("drag-ruler"); socket = socketlib.registerModule("drag-ruler");
socket.register("updateCombatantDragRulerFlags", _socketUpdateCombatantDragRulerFlags); socket.register("updateCombatantDragRulerFlags", _socketUpdateCombatantDragRulerFlags);
socket.register("recalculate", _socketRecalculate);
}); });
export function updateCombatantDragRulerFlags(combat, updates) { export function updateCombatantDragRulerFlags(combat, updates) {
const combatId = combat.id; const combatId = combat.id;
return socket.executeAsGM(_socketUpdateCombatantDragRulerFlags, combatId, updates); // TODO Check if canvas.tokens.get is still neccessary in future foundry versions
return socket.executeAsGM(_socketUpdateCombatantDragRulerFlags, combatId, updates)
.then(() => currentSpeedProvider.onMovementHistoryUpdate(updates.map(update => canvas.tokens.get(combat.getCombatant(update._id).token._id))));
} }
async function _socketUpdateCombatantDragRulerFlags(combatId, updates) { async function _socketUpdateCombatantDragRulerFlags(combatId, updates) {
@@ -28,3 +33,11 @@ async function _socketUpdateCombatantDragRulerFlags(combatId, updates) {
}); });
await combat.updateEmbeddedEntity("Combatant", updates, {diff: false}); await combat.updateEmbeddedEntity("Combatant", updates, {diff: false});
} }
export function recalculate(tokens) {
socket.executeForEveryone(_socketRecalculate, tokens ? tokens.map(token => token.id) : undefined);
}
function _socketRecalculate(tokenIds) {
return canvas.controls.ruler.dragRulerRecalculate(tokenIds);
}
+8
View File
@@ -84,6 +84,14 @@ export class SpeedProvider {
return true return true
} }
/**
* This hook is being called after Drag Ruler has updated the movement history for one or more tokens.
* It'll receive an array of tokens that have been updated.
* If your speed provider is storing any additional values that are relevant for the movement history, this function should
* await until those updates have completed inside foundry.
*/
async onMovementHistoryUpdate(tokens) {}
/** /**
* Returns the value that is currently set for the setting registered with the provided settingId. * Returns the value that is currently set for the setting registered with the provided settingId.
* *
+3
View File
@@ -9,6 +9,8 @@ export function getDefaultSpeedAttribute() {
return "actor.data.data.mech.speed" return "actor.data.data.mech.speed"
case "pf1": case "pf1":
return "actor.data.data.attributes.speed.land.total" return "actor.data.data.attributes.speed.land.total"
case "shadowrun5e":
return "actor.data.data.movement.walk.value";
case "swade": case "swade":
return "actor.data.data.stats.speed.value" return "actor.data.data.stats.speed.value"
} }
@@ -23,6 +25,7 @@ export function getDefaultDashMultiplier() {
case "dnd5e": case "dnd5e":
case "lancer": case "lancer":
case "pf1": case "pf1":
case "shadowrun5e":
return 2 return 2
} }
return 0 return 0