Compare commits

...

19 Commits

Author SHA1 Message Date
Manuel Vögele f0c6ce1bcc Release v1.13.7 2023-06-13 17:01:02 +02:00
Manuel Vögele 7b392e5c9d Update module.json to reflect the new discord name 2023-06-13 17:00:48 +02:00
YenBenGrey efe6eac5aa Add default values for the Crucible system (#283) 2023-06-13 09:53:18 +02:00
Manuel Vögele 52b64c3016 Release v1.13.6 2023-06-12 22:22:54 +02:00
Manuel Vögele 48d0d17628 Use canvas.scene.grid.type instead of cnavas.scene.gridType (which is undefined since v10) (fixes #272) 2023-06-12 22:21:19 +02:00
Manuel Vögele 8101381cc4 Remove redundant & broken code path in _computeDistance (fixes #280) 2023-06-12 21:40:04 +02:00
Manuel Vögele 844df150a6 Release v1.13.5 2023-06-12 19:52:33 +02:00
Manuel Vögele 47715e95f6 Replace newly private functions with public alternatives 2023-06-12 19:50:55 +02:00
Manuel Vögele 1dccbcb081 Reformat with prettier 2023-06-12 19:36:20 +02:00
Manuel Vögele 4c3d7ab42a Add .prettierignore 2023-06-12 19:26:44 +02:00
Manuel Vögele 61fc795f7b Correct a typo in a variable name (fixes #255) 2023-06-11 13:46:09 +02:00
Foundry Hub f10fa049b9 Translated using Weblate (Portuguese (Brazil)) (#268)
Currently translated at 100.0% (59 of 59 strings)

Translation: Drag Ruler/main
Translate-URL: https://weblate.foundryvtt-hub.com/projects/drag-ruler/main/pt_BR/

Co-authored-by: eunaumtenhoid <eunaumtenhoid@outlook.com>
2023-06-11 13:20:55 +02:00
Manuel Vögele c844318836 Update module.json to reflect v11 compatiblility 2023-06-11 13:20:11 +02:00
pkonshik 9af692566c Apply changes for v11 compatibility (#277) 2023-06-11 13:17:36 +02:00
Txus d08416777b Wfrp4e default values (#276) 2023-06-10 10:27:42 +02:00
Manuel Vögele 56f506bad2 Release v1.13.4 2023-03-14 16:27:36 +01:00
Manuel Vögele e1d54ed55d Use "cn" as language code for Simplified Chinese, as is done by foundry 2023-03-14 16:24:16 +01:00
eunaumtenhoid 504c242e86 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (59 of 59 strings)

Translation: Drag Ruler/main
Translate-URL: https://weblate.foundryvtt-hub.com/projects/drag-ruler/main/pt_BR/
2023-03-14 16:22:01 +01:00
eunaumtenhoid a48c199863 Added translation using Weblate (Portuguese (Brazil)) 2023-03-14 16:22:01 +01:00
10 changed files with 209 additions and 52 deletions
+4
View File
@@ -0,0 +1,4 @@
*.md
*.html
*.json
foundry.js
+26
View File
@@ -1,3 +1,29 @@
## 1.13.7
### Compatibility
- Drag Ruler's generic speed provider is now aware of good defaults for the Crucible game system
## 1.13.6
### Bugfixes
- Fixed a bug that caused no measurements to be shown next to the ruler
- Fixed a bug where diagonal paths would sometimes highlight squares that don't blong to the path on square maps
## 1.13.5
### Compatibility
- Drag Ruler is now compatible with Foundry VTT v11 (thanks to pkonshik for doing much of the porting work!)
- Drag Ruler's generic speed provider is now aware of good defaults for Warhammer Fantasy Roleplay 4th Edition
### Translations
- Updated Portugese (Brazil) translation (thanks eunaumtenhoid!)
## 1.13.4
### Translations
- New translation: Portuguese (Brazil) (thanks eunaumtenhoid!)
- Foundry should now be able to detect the Simplified Chenese translation properly
## 1.13.3 ## 1.13.3
### Translations ### Translations
- New translation: Chinese (Simplified) (thanks bnp800!) - New translation: Chinese (Simplified) (thanks bnp800!)
+121
View File
@@ -0,0 +1,121 @@
{
"drag-ruler": {
"dependencies": {
"ok": "Ok",
"terrain-ruler": {
"neverShowAgain": "Nunca mostre isso de novo",
"title": "Como medir terrenos difíceis com o Drag Ruler",
"text": "Você tem o módulo {moduleName} habilitado. Drag Ruler é capaz de medir terreno difícil que foi colocado para baixo usando esse módulo. Para tornar isto possível, Drag Ruler utiliza o módulo Terrain Ruler. Se o Terrain Ruler for instalado e ativado, o Drag Ruler começará automaticamente a respeitar o terreno difícil em suas medições."
},
"socketlib": {
"title": "Módulo Socketlib ausente",
"text": "Drag Ruler requer que o módulo socketlib funcione corretamente. Por favor, ative o módulo socketlib neste mundo."
}
},
"resetMovementHistory": "Redefinir histórico de movimento",
"genericSpeedProvider": {
"settings": {
"dashMultiplier": {
"name": "Traço Multiplicador",
"hint": "Isso pode ser usado para dar aos tokens uma velocidade secundária durante a coloração do caminho medido. Defina-o como 0 para desativar a velocidade secundária."
},
"speedAttribute": {
"name": "Atributo de velocidade",
"hint": "O atributo que define a velocidade de caminhada de um token. Isso é usado durante a coloração do caminho medido."
}
},
"speeds": {
"walk": "andar",
"dash": "traço"
}
},
"keybindings": {
"cancelDrag": "Cancelar o arrasto",
"disableSnap": {
"name": "Desativar encaixe",
"hint": "O encaixe será desativado temporariamente enquanto esta tecla estiver pressionada."
},
"createWaypoint": "Criar parada",
"deleteWaypoint": "Apagar parada",
"togglePathfinding": {
"name": "Alternar localização de caminhos",
"hint": "Ao ser segurado enquanto arrasta um token, a funcionalidade de localização de caminhos será temporariamente habilitada/desabilitada."
},
"moveWithoutAnimation": {
"name": "Desativar animação de token",
"hint": "Ao ser segurado ao soltar um token, o token se moverá para o local de destino sem animação."
}
},
"settings": {
"allowPathfinding": {
"name": "Permitir localização de caminhos para jogadores",
"hint": "Permite que os jogadores usem a funcionalidade de localização de caminhos do Drag Ruler neste mundo. Esteja ciente de que a localização de caminhos pode passar por uma névoa de guerra inexplorada e paredes etéreas, que podem revelar segredos para seus jogadores antes do tempo."
},
"alwaysShowSpeedForPCs": {
"name": "Mostre a velocidade do PJ para todos",
"hint": "Se ativado, a coloração baseada na velocidade do ator para os personagens dos jogadores será mostrada a todos, mesmo que eles não tenham permissão de observador para a ficha de personagem."
},
"autoStartMeasurement": {
"name": "Iniciar a medição automaticamente",
"hint": "Se ativado, Drag Ruler começará a medir assim que o token estiver sendo arrastado. Se desativado, o Drag Ruler permanecerá inativo e só começará a medir quando o botão para adicionar uma parada for pressionado."
},
"autoPathfinding": {
"hint": "Se ativado, arrastar um token usará automaticamente uma régua de localização de caminho.",
"name": "localização de caminho por padrão"
},
"enableMovementHistory": {
"name": "Habilitar histórico de movimento durante o combate",
"hint": "Se ativado, o Drag Ruler lembrará o caminho que um token percorreu durante seu turno em combate e o exibirá quando você pegar o token de volta."
},
"rightClickAction": {
"name": "Ação do botão direito",
"hint": "Que ação deve ser executada ao clicar com o botão direito do mouse enquanto arrasta um token?",
"choices": {
"create": "Criar parada",
"delete": "Apagar parada",
"cancel": "Cancelar arrasto"
}
},
"showGMRulerToPlayers": {
"name": "Mostrar régua do GM aos jogadores",
"hint": "Se desativado, a régua dos GMs não será exibido para jogadores não-GM."
},
"speedProviderSettings": {
"name": "Configurações do provedor de velocidade",
"button": "Configurações do provedor de velocidade",
"windowTitle": "Configurações do provedor de velocidade",
"headers": {
"speedProvider": "Provedor de velocidade",
"speedProviderSettings": "Configurações específicas do provedor de velocidade"
},
"activeProvider": {
"name": "Provedor de velocidade ativo",
"hint": "As configurações mostradas abaixo dependem do provedor de velocidade ativo. Se o GM selecionar um provedor de velocidade diferente, as configurações disponíveis podem mudar."
},
"noSettings": "Este provedor de velocidade não oferece nenhuma opção de configuração.",
"color": {
"name": "Cor para {colorName}",
"hint": "A cor que será usada para colorir os quadrados que estão dentro do intervalo {colorName}.",
"unreachable": {
"name": "inacessível",
"hint": "A cor dos espaços que não podem ser acessados pelo token arrastado."
}
},
"speedProvider": {
"name": "Provedor de configurações de velocidade",
"hint": "Selecione quem fornece informações de velocidade para tokens durante a coloração. Drag Ruler oferece um provedor de velocidade genérico que fornece funcionalidade básica e deve funcionar para todos os sistemas de jogo se configurado corretamente. Mais provedores de velocidade podem ser disponibilizados por meio de sistemas de jogos e módulos instalados. Selecionar um provedor de velocidade diferente do provedor de velocidade genérico pode oferecer uma melhor integração com as regras do sistema de jogo que você está usando. As opções abaixo dependem do provedor de velocidade selecionado aqui.",
"choices": {
"module": "Módulo {name}",
"native": "Genérico",
"system": "Sistema {name}"
}
},
"hint": "As configurações do provedor de velocidade contêm todas as configurações específicas do sistema de jogo."
},
"useGridlessRaster": {
"name": "Use o ajuste baseado em velocidade",
"hint": "Em cenas sem grid, isso faz com que os tokens se encaixem nas faixas de velocidade do token."
}
}
}
}
+11 -6
View File
@@ -2,16 +2,16 @@
"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.13.3", "version": "1.13.7",
"compatibility": { "compatibility": {
"minimum": "10", "minimum": "11",
"verified": "10" "verified": "11"
}, },
"authors": [ "authors": [
{ {
"name": "Manuel Vögele", "name": "Manuel Vögele",
"email": "develop@manuel-voegele.de", "email": "develop@manuel-voegele.de",
"discord": "Stäbchenfisch#5107" "discord": "stabchenfisch"
} }
], ],
"esmodules": [ "esmodules": [
@@ -59,9 +59,14 @@
"path": "lang/zh-tw.json" "path": "lang/zh-tw.json"
}, },
{ {
"lang": "zh-Hans", "lang": "cn",
"name": "中文(简体)", "name": "中文(简体)",
"path": "lang/zh_Hans.json" "path": "lang/zh_Hans.json"
},
{
"lang": "pt-BR",
"name": "Português (Brasil)",
"path": "lang/pt_BR.json"
} }
], ],
"relationships": { "relationships": {
@@ -75,7 +80,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.13.3.zip", "download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.13.7.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",
+1 -1
View File
@@ -18,7 +18,7 @@ export function measureDistances(segments, entity, shape, options = {}) {
const opts = duplicate(options); const opts = duplicate(options);
if (canvas.grid.diagonalRule === "EUCL") { if (canvas.grid.diagonalRule === "EUCL") {
opts.ignoreGrid = true; opts.ignoreGrid = true;
opts.gridSpaes = false; opts.gridSpaces = false;
} }
if (opts.enableTerrainRuler) { if (opts.enableTerrainRuler) {
opts.gridSpaces = true; opts.gridSpaces = true;
+4 -4
View File
@@ -133,8 +133,8 @@ export function onMouseMove(event) {
// Extract event data // Extract event data
const destination = { const destination = {
x: event.data.destination.x + this.rulerOffset.x, x: event.interactionData.destination.x + this.rulerOffset.x,
y: event.data.destination.y + this.rulerOffset.y, y: event.interactionData.destination.y + this.rulerOffset.y,
}; };
// Hide any existing Token HUD // Hide any existing Token HUD
@@ -148,7 +148,7 @@ export function onMouseMove(event) {
function scheduleMeasurement(destination, event) { function scheduleMeasurement(destination, event) {
const measurementInterval = 50; const measurementInterval = 50;
const mt = event._measureTime || 0; const mt = event._measureTime || 0;
const originalEvent = event.data.originalEvent; const originalEvent = event.interactionData.originalEvent;
if (Date.now() - mt > measurementInterval) { if (Date.now() - mt > measurementInterval) {
this.measure(destination, {snap: !disableSnap}); this.measure(destination, {snap: !disableSnap});
event._measureTime = Date.now(); event._measureTime = Date.now();
@@ -185,7 +185,7 @@ export function highlightMeasurementNative(
tokenShape = [{x: 0, y: 0}], tokenShape = [{x: 0, y: 0}],
alpha = 1, alpha = 1,
) { ) {
const spacer = canvas.scene.gridType === CONST.GRID_TYPES.SQUARE ? 1.41 : 1; const spacer = canvas.scene.grid.type === CONST.GRID_TYPES.SQUARE ? 1.41 : 1;
const nMax = Math.max( const nMax = Math.max(
Math.floor(ray.distance / (spacer * Math.min(canvas.grid.w, canvas.grid.h))), Math.floor(ray.distance / (spacer * Math.min(canvas.grid.w, canvas.grid.h))),
1, 1,
+9 -9
View File
@@ -138,8 +138,8 @@ function onEntityLeftDragStart(wrapped, event) {
ruler.draggedEntity = this; ruler.draggedEntity = this;
const entityCenter = getEntityCenter(this); const entityCenter = getEntityCenter(this);
ruler.rulerOffset = { ruler.rulerOffset = {
x: entityCenter.x - event.data.origin.x, x: entityCenter.x - event.interactionData.origin.x,
y: entityCenter.y - event.data.origin.y, y: entityCenter.y - event.interactionData.origin.y,
}; };
if (game.settings.get(settingsKey, "autoStartMeasurement")) { if (game.settings.get(settingsKey, "autoStartMeasurement")) {
let options = {}; let options = {};
@@ -215,8 +215,8 @@ function applyGridlessSnapping(event) {
if (canvas.grid.type !== CONST.GRID_TYPES.GRIDLESS) return; if (canvas.grid.type !== CONST.GRID_TYPES.GRIDLESS) return;
const rasterWidth = 35 / canvas.stage.scale.x; const rasterWidth = 35 / canvas.stage.scale.x;
const tokenX = event.data.destination.x; const tokenX = event.interactionData.destination.x;
const tokenY = event.data.destination.y; const tokenY = event.interactionData.destination.y;
const destination = {x: tokenX + ruler.rulerOffset.x, y: tokenY + ruler.rulerOffset.y}; const destination = {x: tokenX + ruler.rulerOffset.x, y: tokenY + ruler.rulerOffset.y};
const ranges = getRangesFromSpeedProvider(ruler.draggedEntity); const ranges = getRangesFromSpeedProvider(ruler.draggedEntity);
@@ -241,13 +241,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.data.destination.x = rasterLocation.x - ruler.rulerOffset.x; event.interactionData.destination.x = rasterLocation.x - ruler.rulerOffset.x;
event.data.destination.y = rasterLocation.y - ruler.rulerOffset.y; event.interactionData.destination.y = rasterLocation.y - ruler.rulerOffset.y;
} }
} }
} else { } else {
let waypointDistance = 0; let waypointDistance = 0;
let origin = event.data.origin; let origin = event.interactionData.origin;
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)
@@ -271,8 +271,8 @@ function applyGridlessSnapping(event) {
.reduce((a, b) => Math.max(a, b), 0); .reduce((a, b) => Math.max(a, b), 0);
if (targetDistance) { if (targetDistance) {
if (distance < targetDistance + rasterWidth) { if (distance < targetDistance + rasterWidth) {
event.data.destination.x = origin.x + (deltaX * targetDistance) / distance; event.interactionData.destination.x = origin.x + (deltaX * targetDistance) / distance;
event.data.destination.y = origin.y + (deltaY * targetDistance) / distance; event.interactionData.destination.y = origin.y + (deltaY * targetDistance) / distance;
} }
} }
} }
+20 -29
View File
@@ -17,6 +17,7 @@ import {
getTokenShape, getTokenShape,
isPathfindingEnabled, isPathfindingEnabled,
} from "./util.js"; } from "./util.js";
import {getPointer} from "./util.js";
export function extendRuler() { export function extendRuler() {
class DragRulerRuler extends CONFIG.Canvas.rulerClass { class DragRulerRuler extends CONFIG.Canvas.rulerClass {
@@ -261,29 +262,23 @@ export function extendRuler() {
if (!this.isDragRuler) { if (!this.isDragRuler) {
return super._computeDistance(gridSpaces); return super._computeDistance(gridSpaces);
} }
if (!this.dragRulerEnableTerrainRuler) { const shape = this.draggedEntity ? getTokenShape(this.draggedEntity) : null;
if (!this.dragRulerIgnoreGrid) { const options = {
gridSpaces = true; ignoreGrid: this.dragRulerIgnoreGrid,
} gridSpaces,
super._computeDistance(gridSpaces); enableTerrainRuler: this.dragRulerEnableTerrainRuler,
} else { };
const shape = this.draggedEntity ? getTokenShape(this.draggedEntity) : null; const distances = measureDistances(this.segments, this.draggedEntity, shape, options);
const options = { let totalDistance = 0;
ignoreGrid: this.dragRulerIgnoreGrid, for (const [i, d] of distances.entries()) {
gridSpaces, let s = this.segments[i];
enableTerrainRuler: this.dragRulerEnableTerrainRuler, s.startDistance = totalDistance;
}; totalDistance += d;
const distances = measureDistances(this.segments, this.draggedEntity, shape, options); s.last = i === this.segments.length - 1;
let totalDistance = 0; s.distance = d;
for (const [i, d] of distances.entries()) { s.text = this._getSegmentLabel(s, totalDistance);
let s = this.segments[i];
s.startDistance = totalDistance;
totalDistance += d;
s.last = i === this.segments.length - 1;
s.distance = d;
s.text = this._getSegmentLabel(s, totalDistance);
}
} }
for (const [i, segment] of this.segments.entries()) { for (const [i, segment] of this.segments.entries()) {
const unsnappedSegment = this.dragRulerUnsnappedSegments[i]; const unsnappedSegment = this.dragRulerUnsnappedSegments[i];
unsnappedSegment.startDistance = segment.startDistance; unsnappedSegment.startDistance = segment.startDistance;
@@ -379,9 +374,7 @@ export function extendRuler() {
options.snap = options.snap ?? true; options.snap = options.snap ?? true;
if (this.waypoints.filter(w => !w.isPrevious).length > 1) { if (this.waypoints.filter(w => !w.isPrevious).length > 1) {
event.preventDefault(); event.preventDefault();
const mousePosition = canvas.app.renderer.plugins.interaction.mouse.getLocalPosition( const mousePosition = getPointer().getLocalPosition(canvas.tokens);
canvas.tokens,
);
const rulerOffset = this.rulerOffset; const rulerOffset = this.rulerOffset;
// Options are not passed to _removeWaypoint in vanilla Foundry. // Options are not passed to _removeWaypoint in vanilla Foundry.
@@ -416,7 +409,7 @@ export function extendRuler() {
this._endMeasurement(); this._endMeasurement();
// Deactivate the drag workflow in mouse // Deactivate the drag workflow in mouse
token.mouseInteractionManager._deactivateDragEvents(); token.mouseInteractionManager.cancel(event);
token.mouseInteractionManager.state = token.mouseInteractionManager.states.HOVER; token.mouseInteractionManager.state = token.mouseInteractionManager.states.HOVER;
// This will cancel the current drag operation // This will cancel the current drag operation
@@ -483,9 +476,7 @@ export function extendRuler() {
if (isToken && game.settings.get(settingsKey, "enableMovementHistory")) if (isToken && game.settings.get(settingsKey, "enableMovementHistory"))
ruler.dragRulerAddWaypointHistory(getMovementHistory(entity)); ruler.dragRulerAddWaypointHistory(getMovementHistory(entity));
ruler.dragRulerAddWaypoint(entityCenter, {snap: false}); ruler.dragRulerAddWaypoint(entityCenter, {snap: false});
const mousePosition = canvas.app.renderer.plugins.interaction.mouse.getLocalPosition( const mousePosition = getPointer().getLocalPosition(canvas.tokens);
canvas.tokens,
);
const destination = { const destination = {
x: mousePosition.x + ruler.rulerOffset.x, x: mousePosition.x + ruler.rulerOffset.x,
y: mousePosition.y + ruler.rulerOffset.y, y: mousePosition.y + ruler.rulerOffset.y,
+8
View File
@@ -23,6 +23,10 @@ export function getDefaultSpeedAttribute() {
return "actor.system.combatValues.movement.total"; return "actor.system.combatValues.movement.total";
case "splittermond": case "splittermond":
return "actor.derivedValues.speed.value"; return "actor.derivedValues.speed.value";
case "wfrp4e":
return "actor.system.details.move.walk";
case "crucible":
return "actor.system.movement.stride";
} }
return ""; return "";
} }
@@ -45,6 +49,10 @@ export function getDefaultDashMultiplier() {
return 5; return 5;
case "splittermond": case "splittermond":
return 3; return 3;
case "wfrp4e":
return 2;
case "crucible":
return 0;
} }
return 0; return 0;
} }
+5 -3
View File
@@ -285,10 +285,12 @@ export function isClose(a, b, delta) {
return Math.abs(a - b) <= delta; return Math.abs(a - b) <= delta;
} }
export function getPointer() {
return canvas.app.renderer.plugins.interaction?.mouse ?? canvas.app.renderer.events.pointer;
}
export function getMeasurePosition() { export function getMeasurePosition() {
const mousePosition = canvas.app.renderer.plugins.interaction.mouse.getLocalPosition( const mousePosition = getPointer().getLocalPosition(canvas.tokens);
canvas.tokens,
);
const rulerOffset = canvas.controls.ruler.rulerOffset; const rulerOffset = canvas.controls.ruler.rulerOffset;
const measurePosition = {x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y}; const measurePosition = {x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y};
return measurePosition; return measurePosition;