bmarian / token-tooltip-alt

A module that adds a tooltip next to the currently hovered token to show some useful information for players and DMs.
MIT License
9 stars 15 forks source link

[FE] A function to calculate the distance between two tokens #91

Open aliasmask opened 2 years ago

aliasmask commented 2 years ago

System This should work for any 1:2:1 movement system, including PF and PF2

Data source token1 - moused over token (target), token2 - selected token (source) x - position of token in pixels in x direction y - position of token in pixels in y direction elevation - position of token in feet in z direction width - size of token in grid units

Short description of your function Measures the distance between 2 tokens at their closest points in 3 dimensions.

function measureDistancePF2_AM(token1, token2) {
/* return the number of feet between 2 tokens at their closest points */
   const gs = canvas.dimensions.size;

   /* convert x,y,z to grid units */
   var t1 = {
      size: token1.data.width,
      x1: Math.floor(token1.data.x/gs),
      x2: this.x1 + this.size,
      y1: Math.floor(token1.data.y/gs),
      y2: this.y1 + this.size,
      z1: Math.floor(token1.data.elevation/5),
      z2: this.z1 + this.size
   }

   var t2 = {
      size: token2.data.width,
      x1: Math.floor(token2.data.x/gs),
      x2: this.x1 + this.size,
      y1: Math.floor(token2.data.y/gs),
      y2: this.y1 + this.size,
      z1: Math.floor(token2.data.elevation/5),
      z2: this.z1 + this.size
   }

   /* check for overlap, set to 0, otherwise get diff from the ends of token in x,y,z direction */
   var dx = Math.max(t2.x1-t1.x2+1, t1.x1-t2.x2+1, 0);
   var dy = Math.max(t2.y1-t1.y2+1, t1.y1-t2.y2+1, 0);
   var dz = Math.max(t2.z1-t1.z2+1, t1.z1-t2.z2+1, 0);

   /* aRTy big brain formula */
   var dim = [dx, dy, dz];
   dim.sort(function(a, b){return a-b});
   let distance = Math.floor(0.5 * dim[1] + dim[2]);

   return parseInt(distance * 5);
}

I don't usually code in js, so I'm not absolutely sure about the syntax, but the logic is good. This function assumes token1 and token2 have valid values of x,y,elevation and width and that canvas.dimensions.size returns a value. _AM is just a programming moniker I use to identify functions written by me, so function name can be whatever. I go by Trey "aliasmask" Randall. aRTy is another programmer who I was discussing the math with and we came up with a nice boiled down formula for 3 dimensions where diagonals in 2 or 3 dimensions measure at 1.5 units. The formula uses a sorted array from low to high. For systems that use a 2:1:2 model, you can change the Math.floor to Math.ceiling to determine distance.

The problem with the current formula is that is uses 1:2:1 distance for part of it and actual distance for elevation rounding up. It also doesn't account for token size.

bmarian commented 2 years ago

This is extremely cool and overly complicated. Exactly the spirit of this module 😂

I will add it to the examples after I test it in game a bit.