Compare commits

...

7 Commits

Author SHA1 Message Date
Manuel Vögele 9042b79967 Release v1.7.4 2021-06-18 13:58:54 +02:00
Manuel Vögele 4159d20e18 Verified to work with Foundry 0.8.7 2021-06-18 13:39:10 +02:00
Manuel Vögele 3897577756 Allow the "Monk's Active Tile Triggers" module to interrupt a token movement early 2021-06-18 13:37:26 +02:00
irbian 5c29f401d6 Support D&D 3.5 (#76) 2021-05-27 01:09:12 +02:00
Manuel Vögele 1328d52f94 Send the info whether the dragged entity is a token or a template to the other players (fixes a snapping issue in other players clients) 2021-05-26 16:17:23 +02:00
Manuel Vögele eef05553c0 Release v1.7.3 2021-05-22 22:00:46 +02:00
Manuel Vögele 7ba89e4229 Update code for Foundry 0.8.5 2021-05-22 21:57:59 +02:00
8 changed files with 58 additions and 26 deletions
+14
View File
@@ -1,3 +1,17 @@
## 1.7.4
### Bugfixes
- Fixed a bug where the ruler would wrongly snap to the grid center for other players when dragging a measurement template
### Compatibility
- Drag Ruler is now compatiblie with the "Monk's Active Tile Triggers" module
- Drag Ruler's Generic Speed Provider is now aware of good default values for the D&D 3.5 game system
- Drag Ruler is now compatible with Foundry 0.8.7
## 1.7.3
### Compatibility
- Drag Ruler is now compatible with Foundry 0.8.5
## 1.7.2 ## 1.7.2
### Bugfixes ### Bugfixes
- Fixed a bug that prevented waypoints for measurement templates from snapping to any other point than a grid cell corner (or grid cell center on hex) - Fixed a bug that prevented waypoints for measurement templates from snapping to any other point than a grid cell corner (or grid cell center on hex)
+4 -4
View File
@@ -2,9 +2,9 @@
"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.7.2", "version": "1.7.4",
"minimumCoreVersion" : "0.7.9", "minimumCoreVersion" : "0.8.5",
"compatibleCoreVersion" : "0.7.9", "compatibleCoreVersion" : "0.8.7",
"authors": [ "authors": [
{ {
"name": "Manuel Vögele", "name": "Manuel Vögele",
@@ -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.7.2.zip", "download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.7.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",
+11 -1
View File
@@ -72,6 +72,10 @@ async function animateEntities(entities, draggedEntity, draggedRays, wasPaused)
const isToken = draggedEntity instanceof Token; const isToken = draggedEntity instanceof Token;
const animate = isToken && !game.keyboard.isDown("Alt"); const animate = isToken && !game.keyboard.isDown("Alt");
const startWaypoint = animate ? 0 : entityAnimationData[0].rays.length - 1; const startWaypoint = animate ? 0 : entityAnimationData[0].rays.length - 1;
// This is a flag of the "Monk's Active Tile Triggers" module that signals that the movement should be cancelled early
this.cancelMovement = false;
for (let i = startWaypoint;i < entityAnimationData[0].rays.length; i++) { for (let i = startWaypoint;i < entityAnimationData[0].rays.length; i++) {
if (!wasPaused && game.paused) break; if (!wasPaused && game.paused) break;
const entityPaths = entityAnimationData.map(({entity, rays, dx, dy}) => { const entityPaths = entityAnimationData.map(({entity, rays, dx, dy}) => {
@@ -83,9 +87,15 @@ async function animateEntities(entities, draggedEntity, draggedRays, wasPaused)
const updates = entityPaths.map(({entity, path}) => { const updates = entityPaths.map(({entity, path}) => {
return {x: path.B.x, y: path.B.y, _id: entity.id}; return {x: path.B.x, y: path.B.y, _id: entity.id};
}); });
await draggedEntity.scene.updateEmbeddedEntity(draggedEntity.constructor.embeddedName, updates, {animate}); await draggedEntity.scene.updateEmbeddedDocuments(draggedEntity.constructor.embeddedName, updates, {animate});
if (animate) if (animate)
await Promise.all(entityPaths.map(({entity, path}) => entity.animateMovement(path))); await Promise.all(entityPaths.map(({entity, path}) => entity.animateMovement(path)));
// This is a flag of the "Monk's Active Tile Triggers" module that signals that the movement should be cancelled early
if (this.cancelMovement) {
entityAnimationData.forEach(ead => ead.rays = ead.rays.slice(0, i + 1));
break;
}
} }
if (isToken) if (isToken)
trackRays(entities, entityAnimationData.map(({rays}) => rays)).then(() => recalculate(entities)); trackRays(entities, entityAnimationData.map(({rays}) => rays)).then(() => recalculate(entities));
+1 -1
View File
@@ -50,7 +50,7 @@ Hooks.on("getCombatTrackerEntryContext", function (html, menu) {
const entry = { const entry = {
name: "drag-ruler.resetMovementHistory", name: "drag-ruler.resetMovementHistory",
icon: '<i class="fas fa-undo-alt"></i>', icon: '<i class="fas fa-undo-alt"></i>',
callback: li => resetMovementHistory(ui.combat.combat, li.data('combatant-id')), callback: li => resetMovementHistory(ui.combat.viewed, li.data('combatant-id')),
}; };
menu.splice(1, 0, entry); menu.splice(1, 0, entry);
}); });
+12 -12
View File
@@ -4,19 +4,19 @@ import {getTokenShape, zip} from "./util.js";
function initTrackingFlag(combatant) { function initTrackingFlag(combatant) {
const initialFlag = {passedWaypoints: [], trackedRound: 0}; const initialFlag = {passedWaypoints: [], trackedRound: 0};
let dragRulerFlag = combatant.flags?.dragRuler; let dragRulerFlag = combatant.data.flags.dragRuler;
if (dragRulerFlag) { if (dragRulerFlag) {
if (isNaN(dragRulerFlag.trackedRound)) { if (isNaN(dragRulerFlag.trackedRound)) {
mergeObject(dragRulerFlag, initialFlag); mergeObject(dragRulerFlag, initialFlag);
} }
} }
else { else {
combatant.flags.dragRuler = initialFlag; combatant.data.flags.dragRuler = initialFlag;
} }
} }
function getInitializedCombatant(token, combat) { function getInitializedCombatant(token, combat) {
const combatant = combat.getCombatantByToken(token.data._id); const combatant = combat.getCombatantByToken(token.id);
if (!combatant) if (!combatant)
return undefined; return undefined;
initTrackingFlag(combatant); initTrackingFlag(combatant);
@@ -43,14 +43,14 @@ function calculateUpdate(combat, token, rays) {
return; return;
// Check if we have entered a new round. If so, remove the currently stored path // Check if we have entered a new round. If so, remove the currently stored path
if (combat.data.round > combatant.flags.dragRuler.trackedRound) { if (combat.data.round > combatant.data.flags.dragRuler.trackedRound) {
combatant.flags.dragRuler.passedWaypoints = []; combatant.data.flags.dragRuler.passedWaypoints = [];
combatant.flags.dragRuler.trackedRound = combat.data.round; combatant.data.flags.dragRuler.trackedRound = combat.data.round;
} }
// Add the passed waypoints to the combatant // Add the passed waypoints to the combatant
const terrainRulerAvailable = game.modules.get("terrain-ruler")?.active && (!game.modules.get("TerrainLayer")?.active || canvas.grid.type !== CONST.GRID_TYPES.GRIDLESS); const terrainRulerAvailable = game.modules.get("terrain-ruler")?.active && (!game.modules.get("TerrainLayer")?.active || canvas.grid.type !== CONST.GRID_TYPES.GRIDLESS);
const dragRulerFlags = combatant.flags.dragRuler; const dragRulerFlags = combatant.data.flags.dragRuler;
const waypoints = dragRulerFlags.passedWaypoints; const waypoints = dragRulerFlags.passedWaypoints;
for (const ray of rays) { for (const ray of rays) {
// Ignore rays that have the same start and end coordinates // Ignore rays that have the same start and end coordinates
@@ -63,17 +63,17 @@ function calculateUpdate(combat, token, rays) {
waypoints.push(ray.A); waypoints.push(ray.A);
} }
} }
return {_id: combatant._id, dragRulerFlags}; return {_id: combatant.id, dragRulerFlags};
} }
export function getMovementHistory(token) { export function getMovementHistory(token) {
const combat = game.combat; const combat = game.combat;
if (!combat) if (!combat)
return []; return [];
const combatant = combat.getCombatantByToken(token.data._id); const combatant = combat.getCombatantByToken(token.id);
if (!combatant) if (!combatant)
return []; return [];
const dragRulerFlags = combatant.flags.dragRuler; const dragRulerFlags = combatant.data.flags.dragRuler;
if (!dragRulerFlags) if (!dragRulerFlags)
return []; return [];
if (combat.data.round > dragRulerFlags.trackedRound) if (combat.data.round > dragRulerFlags.trackedRound)
@@ -82,8 +82,8 @@ export function getMovementHistory(token) {
} }
export async function resetMovementHistory(combat, combatantId) { export async function resetMovementHistory(combat, combatantId) {
const combatant = combat.getCombatant(combatantId); const combatant = combat.combatants.get(combatantId);
const dragRulerFlags = combatant.flags.dragRuler; const dragRulerFlags = combatant.data.flags.dragRuler;
if (!dragRulerFlags) if (!dragRulerFlags)
return; return;
dragRulerFlags.passedWaypoints = null; dragRulerFlags.passedWaypoints = null;
+9 -3
View File
@@ -33,8 +33,11 @@ export class DragRulerRuler extends Ruler {
toJSON() { toJSON() {
const json = super.toJSON(); const json = super.toJSON();
if (this.draggedEntity) if (this.draggedEntity) {
json["draggedEntity"] = this.draggedEntity.data._id; const isToken = this.draggedEntity instanceof Token;
json["draggedEntityIsToken"] = isToken;
json["draggedEntity"] = this.draggedEntity.id;
}
return json; return json;
} }
@@ -44,7 +47,10 @@ export class DragRulerRuler extends Ruler {
return; return;
if (data.draggedEntity) { if (data.draggedEntity) {
this.draggedEntity = canvas.tokens.get(data.draggedEntity); if (data.draggedEntityIsToken)
this.draggedEntity = canvas.tokens.get(data.draggedEntity);
else
this.draggedEntity = canvas.templates.get(data.draggedEntity);
} }
super.update(data); super.update(data);
} }
+4 -4
View File
@@ -12,7 +12,7 @@ export function updateCombatantDragRulerFlags(combat, updates) {
const combatId = combat.id; const combatId = combat.id;
// TODO Check if canvas.tokens.get is still neccessary in future foundry versions // TODO Check if canvas.tokens.get is still neccessary in future foundry versions
return socket.executeAsGM(_socketUpdateCombatantDragRulerFlags, combatId, updates) return socket.executeAsGM(_socketUpdateCombatantDragRulerFlags, combatId, updates)
.then(() => currentSpeedProvider.onMovementHistoryUpdate(updates.map(update => canvas.tokens.get(combat.getCombatant(update._id).token._id)))); .then(() => currentSpeedProvider.onMovementHistoryUpdate(updates.map(update => canvas.tokens.get(combat.combatants.get(update._id).token.id))));
} }
async function _socketUpdateCombatantDragRulerFlags(combatId, updates) { async function _socketUpdateCombatantDragRulerFlags(combatId, updates) {
@@ -20,10 +20,10 @@ async function _socketUpdateCombatantDragRulerFlags(combatId, updates) {
const combat = game.combats.get(combatId); const combat = game.combats.get(combatId);
const requestedUpdates = updates.length; const requestedUpdates = updates.length;
updates = updates.filter(update => { updates = updates.filter(update => {
const actor = combat.getCombatant(update._id).actor; const actor = combat.combatants.get(update._id).actor;
if (!actor) if (!actor)
return false; return false;
return actor.hasPerm(user, "OWNER"); return actor.testUserPermission(user, "OWNER");
}); });
if (updates.length !== requestedUpdates) { if (updates.length !== requestedUpdates) {
console.warn(`Some of the movement history updates requested by user '${game.users.get(this.socketdata.userId).name}' were not performed because the user lacks owner permissions for those tokens`); console.warn(`Some of the movement history updates requested by user '${game.users.get(this.socketdata.userId).name}' were not performed because the user lacks owner permissions for those tokens`);
@@ -31,7 +31,7 @@ async function _socketUpdateCombatantDragRulerFlags(combatId, updates) {
updates = updates.map(update => { updates = updates.map(update => {
return {_id: update._id, flags: {dragRuler: update.dragRulerFlags}}; return {_id: update._id, flags: {dragRuler: update.dragRulerFlags}};
}); });
await combat.updateEmbeddedEntity("Combatant", updates, {diff: false}); await combat.updateEmbeddedDocuments("Combatant", updates, {diff: false});
} }
export function recalculate(tokens) { export function recalculate(tokens) {
+3 -1
View File
@@ -8,7 +8,8 @@ export function getDefaultSpeedAttribute() {
case "lancer": case "lancer":
return "actor.data.data.mech.speed" return "actor.data.data.mech.speed"
case "pf1": case "pf1":
return "actor.data.data.attributes.speed.land.total" case "D35E":
return "actor.data.data.attributes.speed.land.total"
case "sfrpg": case "sfrpg":
return "actor.data.data.attributes.speed.value"; return "actor.data.data.attributes.speed.value";
case "shadowrun5e": case "shadowrun5e":
@@ -27,6 +28,7 @@ export function getDefaultDashMultiplier() {
case "dnd5e": case "dnd5e":
case "lancer": case "lancer":
case "pf1": case "pf1":
case "D35E":
case "sfrpg": case "sfrpg":
case "shadowrun5e": case "shadowrun5e":
return 2 return 2