Initial commit
This commit is contained in:
+178
@@ -0,0 +1,178 @@
|
||||
"use strict"
|
||||
|
||||
import {availableSpeedProviders, currentSpeedProvider, registerModule, registerSystem, setCurrentSpeedProvider} from "./api.js"
|
||||
import {registerSettings, settingsKey} from "./settings.js"
|
||||
|
||||
Hooks.once("init", () => {
|
||||
registerSettings()
|
||||
hookTokenDragHandlers()
|
||||
hookRulerHandlers()
|
||||
patchRulerMeasure()
|
||||
patchRulerHighlightMeasurement()
|
||||
|
||||
availableSpeedProviders["native"] = nativeSpeedProvider
|
||||
setCurrentSpeedProvider(nativeSpeedProvider)
|
||||
|
||||
window.dragRuler = {
|
||||
getColorForDistance,
|
||||
registerModule,
|
||||
registerSystem
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
Hooks.once("ready", () => {
|
||||
Hooks.callAll("dragRuler.ready")
|
||||
})
|
||||
|
||||
Hooks.on("canvasReady", () => {
|
||||
canvas.controls.ruler.draggedToken = null
|
||||
Object.defineProperty(canvas.controls.ruler, "isDragRuler", {
|
||||
get: function isDragRuler() {
|
||||
return Boolean(this.draggedToken) // If draggedToken is set this is a drag ruler
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
function hookTokenDragHandlers() {
|
||||
const originalDragLeftStartHandler = Token.prototype._onDragLeftStart
|
||||
Token.prototype._onDragLeftStart = function(event) {
|
||||
originalDragLeftStartHandler.call(this, event)
|
||||
onTokenLeftDragStart.call(this, event)
|
||||
}
|
||||
|
||||
const originalDragLeftMoveHandler = Token.prototype._onDragLeftMove
|
||||
Token.prototype._onDragLeftMove = function (event) {
|
||||
originalDragLeftMoveHandler.call(this, event)
|
||||
onTokenLeftDragMove.call(this, event)
|
||||
}
|
||||
|
||||
const originalDragLeftDropHandler = Token.prototype._onDragLeftDrop
|
||||
Token.prototype._onDragLeftDrop = function (event) {
|
||||
const eventHandled = onTokenDragLeftDrop.call(this, event)
|
||||
if (!eventHandled)
|
||||
originalDragLeftDropHandler.call(this, event)
|
||||
}
|
||||
|
||||
const originalDragLeftCancelHandler = Token.prototype._onDragLeftCancel
|
||||
Token.prototype._onDragLeftCancel = function (event) {
|
||||
const eventHandled = onTokenDragLeftCancel.call(this, event)
|
||||
if (!eventHandled)
|
||||
originalDragLeftCancelHandler.call(this, event)
|
||||
}
|
||||
}
|
||||
|
||||
function hookRulerHandlers() {
|
||||
const originalMoveTokenHandler = Ruler.prototype.moveToken
|
||||
Ruler.prototype.moveToken = function (event) {
|
||||
const eventHandled = onRulerMoveToken.call(this, event)
|
||||
if (!eventHandled)
|
||||
return originalMoveTokenHandler.call(this, event)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
function onTokenLeftDragStart(event) {
|
||||
canvas.controls.ruler._onDragStart(event)
|
||||
canvas.controls.ruler.draggedToken = this
|
||||
}
|
||||
|
||||
function onTokenLeftDragMove(event) {
|
||||
if (canvas.controls.ruler.isDragRuler)
|
||||
canvas.controls.ruler._onMouseMove(event)
|
||||
}
|
||||
|
||||
function onTokenDragLeftDrop(event) {
|
||||
if (!canvas.controls.ruler.isDragRuler)
|
||||
return false
|
||||
canvas.controls.ruler.draggedToken = null
|
||||
canvas.controls.ruler.moveToken(event)
|
||||
return true
|
||||
}
|
||||
|
||||
function onTokenDragLeftCancel(event) {
|
||||
if (!canvas.controls.ruler.isDragRuler)
|
||||
return false
|
||||
if (canvas.controls.ruler._state === Ruler.STATES.MEASURING) {
|
||||
if (canvas.controls.ruler.waypoints.length > 1) {
|
||||
canvas.controls.ruler._removeWaypoint(canvas.app.renderer.plugins.interaction.mouse.getLocalPosition(canvas.tokens), {snap: !event.shiftKey})
|
||||
game.user.broadcastActivity({ruler: canvas.controls.ruler})
|
||||
event.preventDefault()
|
||||
}
|
||||
else {
|
||||
canvas.controls.ruler._endMeasurement()
|
||||
canvas.controls.ruler.draggedToken = null
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function onRulerMoveToken(event) {
|
||||
if (!this.isDragRuler)
|
||||
return false
|
||||
this._addWaypoint(this.destination)
|
||||
return true
|
||||
}
|
||||
|
||||
function strInsertAfter(haystack, needle, strToInsert) {
|
||||
const pos = haystack.indexOf(needle) + needle.length
|
||||
return haystack.slice(0, pos) + strToInsert + haystack.slice(pos)
|
||||
}
|
||||
|
||||
// These patches were written with foundry-0.7.9.js as reference
|
||||
function patchRulerMeasure() {
|
||||
let code = Ruler.prototype.measure.toString()
|
||||
// Remove function signature and closing curly bracket (those are on the first and last line)
|
||||
code = code.slice(code.indexOf("\n"), code.lastIndexOf("\n"))
|
||||
code = strInsertAfter(code, "for ( let [i, d] of distances.entries() ) {\n", "segments[i].startDistance = totalDistance\n")
|
||||
code = strInsertAfter(code, "this._highlightMeasurement(ray", ", s.startDistance")
|
||||
Ruler.prototype.measure = new Function("destination", "{gridSpaces=true}={}", code)
|
||||
}
|
||||
|
||||
function nativeSpeedProvider(token, playercolor) {
|
||||
const speedAttribute = game.settings.get(settingsKey, "speedAttribute")
|
||||
if (!speedAttribute)
|
||||
return []
|
||||
const tokenSpeed = getProperty(token, speedAttribute)
|
||||
if (tokenSpeed === undefined) {
|
||||
console.warn(`Drag Ruler | The configured token speed attribute "${speedAttribute}" didn't return a speed value. To use colors based on drag distance set the setting to the correct value (or clear the box to disable this feature).`)
|
||||
return []
|
||||
}
|
||||
const dashMultiplier = game.settings.get(settingsKey, "dashMultiplier")
|
||||
if (!dashMultiplier)
|
||||
return [{range: tokenSpeed, color: playercolor}]
|
||||
return [{range: tokenSpeed, color: playercolor}, {range: tokenSpeed * dashMultiplier, color: 0xFFFF00}]
|
||||
}
|
||||
|
||||
function getColorForDistance(startDistance, subDistance) {
|
||||
if (!this.isDragRuler)
|
||||
return this.color
|
||||
const distance = startDistance + subDistance
|
||||
const ranges = currentSpeedProvider(this.draggedToken, this.color)
|
||||
if (ranges.length === 0)
|
||||
return this.color
|
||||
const currentRange = ranges.reduce((minRange, currentRange) => {
|
||||
if (distance <= currentRange.range && currentRange.range < minRange.range)
|
||||
return currentRange
|
||||
return minRange
|
||||
}, {range: Infinity, color: 0xFF0000})
|
||||
return currentRange.color
|
||||
}
|
||||
|
||||
// These patches were written with foundry-0.7.9.js as reference
|
||||
function patchRulerHighlightMeasurement() {
|
||||
let code = Ruler.prototype._highlightMeasurement.toString()
|
||||
// Remove function signature and closing curly bracket (those are on the first and last line)
|
||||
code = code.slice(code.indexOf("\n"), code.lastIndexOf("\n"))
|
||||
|
||||
const calcColorCode = `
|
||||
let subDistance = canvas.grid.measureDistances([{ray: new Ray(ray.A, {x: xg, y: yg})}], {gridSpaces: true})[0]
|
||||
let color = dragRuler.getColorForDistance.call(this, startDistance, subDistance)
|
||||
`
|
||||
|
||||
code = strInsertAfter(code, "Position(x1, y1);\n", calcColorCode)
|
||||
code = strInsertAfter(code, "Position(x1h, y1h);\n", calcColorCode.replace("x: xg, y: yg", "x: xgh, y: ygh"))
|
||||
code = code.replace(/color: this\.color\}/g, "color}")
|
||||
Ruler.prototype._highlightMeasurement = new Function("ray", "startDistance=undefined", code)
|
||||
}
|
||||
Reference in New Issue
Block a user