Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Calculate Range Between 2 Objects on Player Active Page - Including Hex Grid Maps

March 18 (8 years ago)

Edited March 29 (8 years ago)
March 29, 2017
Updated to v1.03 including suggestions/updates from 'The Aaron', many thanks to him and 'Jim W.' for finding and resolving some issues.
2D only version https://gist.github.com/kilthar/724f03cf2ad327d71f...
3D version https://gist.github.com/kilthar/4decaa1d45def15929...
!range @{target|1st Target|token_id},@{target|2nd Target|token_id}

March 19, 2017
I've just finished (hopefully) a modified version of "Range Finder by Peter W." to include all measurement types for Square and Hex grid maps.
For Hex maps it also calculates the distance between objects in the same hex (typically "Is Drawing" objects) to 3 decimal places.
File can be found https://gist.github.com/kilthar/724f03cf2ad327d71f...

Usage is changed to token_id - thanks SkyCaptainXIII:
!range @{target|1st Target|token_name},@{target|2nd Target|token_name}
!range @{target|1st Target|token_id},@{target|2nd Target|token_id}

1st version of calculating distance including height for 4e and 3e/pathfinder taking into account that you are 1unit square in size. Others to follow.
This uses Bar 2 (blue bar left box) for the tokens height for 4e/3e/pathfinder in feet

File can be found https://gist.github.com/kilthar/4decaa1d45def15929...
Usage is:
!range @{target|1st Target|token_id},@{target|2nd Target|token_id}
Set the Bar 2 (blue bar left box) to the tokens height in the units you use eg. 30 for 30 feet
March 19 (8 years ago)
It might be better to use token_id instead of token_name since token_id should be unique.
March 19 (8 years ago)
Great script - modified it to give me distance in feet; rounded to hex size as that is what I need for my game - the game range. 
March 20 (8 years ago)
Next project for me is to change this to calculate range to a Flying creature!
March 20 (8 years ago)

Edited March 20 (8 years ago)
I was thinking on that one as well probably utilising Bar3 and a something like !range @{target|1st Target|token_id},@{target|2nd Target|token_id},3D to enable that calculation.
March 20 (8 years ago)

Edited March 20 (8 years ago)
Mine uses the fluffy-wings and angel-outfit settings for 'hex' and '10xhex' height - so can reach 9x5+9x50 feet
March 25 (8 years ago)

Edited March 25 (8 years ago)
While amending/Testing my changes 4 days ago I suddenly ran into strange errors that did not relate to changes I was making .. and as seemed so random, gave up.

Today I have reinstalled the api script from the github and disabled other scripts and still getting these errors.

Tested in a new game without any other api scripts or char sheet - same issue:-
TypeError: Cannot read property 'get' of undefined TypeError: Cannot read property 'get' of undefined at apiscript.js:34:28 at eval (eval at <anonymous> (/home/node/d20-api-server/api.js:146:1), <anonymous>:65:16) at Object.publish (eval at <anonymous> (/home/node/d20-api-server/api.js:146:1), <anonymous>:70:8) at /home/node/d20-api-server/api.js:1510:12 at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:560 at hc (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:39:147) at Kd (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:546) at Id.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:93:489) at Zd.Ld.Mb (/home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:94:425) at /home/node/d20-api-server/node_modules/firebase/lib/firebase-node.js:111:400

Something must(?) have changed on the Roll20 implementation?

Are you using !range @{target|1st Target|token_id},@{target|2nd Target|token_id}
March 26 (8 years ago)

d100GM said:

Are you using !range @{target|1st Target|token_id},@{target|2nd Target|token_id}

Yes and both your script and my modified one broke at same time!
Strange I've been using it without any issues over the past week.
Just tried the original and 3D versions and both worked.
March 26 (8 years ago)
Odd then.. must be something my end.  Cannot even guess what it might be though.
Could it be a conflict with another API?
Try creating a new game with only that API loaded, if that works start adding each other API you use and see if you can identify any conflict.
March 26 (8 years ago)
As stated above - already did that :(


Was that a new game or an existing one? (just in case there is/was something corrupt)
March 27 (8 years ago)
Now I have 3 games, all with the identical script.  2 work and one does not.  Oddly all 3 did not work yesterday, only the SKT game does not work now ..crashes with the error as above.

I use hex maps and one reason I changed the code [I no longer have the changes as I deleted this version!] was that I needed the range to come in hex sized answers, not to 3 decimal places.
March 27 (8 years ago)
The Aaron
Pro
API Scripter
My guess is that one of the tokens (token1 or token2) is not found and the .get() on line 34 or 35 is causing the error.  Moving them down a few lines inside the if check should resolve it:
        var token1 =  findObjs({_type: "graphic", layer:"objects", _pageid: curPageID, _id: tokenid1})[0];
        var token2 =  findObjs({_type: "graphic", layer:"objects", _pageid: curPageID, _id: tokenid2})[0];
        var name1 =  token1.get("name");
        var name2 =  token2.get("name");

        if (token1 && token2)
        {
            var name1 =  token1.get("name");
            var name2 =  token2.get("name");

            // DnD 4.0 Distance Calculation
			if (curDiagonalType == "foure" && curGridType == "square")
			{

You could also add some checks in other places you're calling .get(), though they are less likely to be issues.  Using the short-circuiting OR (||) for this works really well:
        var curPageID = (findObjs({_type: "campaign"})[0]||{get:()=>''}).get("playerpageid");
        var curPage = (findObjs({_type: "page", _id: curPageID})[0]||{get:()=>''}); //var currentPage = getObj("page", Campaign().get("playerpageid"));
        var curScale = (curPage.get("scale_number")||{get:()=>1}); // scale for 1 unit, eg. 1 unit = 5ft 
	var curUnit = (curPage.get("scale_units")||{get:()=>'ft'}); // ft, m, km, mi etc.
	var curDiagonalType = (curPage.get("diagonaltype")||{get:()=>'foure'}); // One of "foure", "pythagorean" (Euclidean), "threefive", or "manhattan"
	var curGridType = (curPage.get("grid_type")||{get:()=>'square'}); // One of "square", "hex", or "hexr". (hex corresponds to Hex(V), and hexr corresponds to Hex(H))
I'm not sure why you're doing a findObjs() for campaign, when you can get it directly with Campaign().  My guess is it's just left over from a bughunt.
March 27 (8 years ago)
I'll test that change now.  Although the rest of the comments are for the author not me!
March 27 (8 years ago)

Edited March 27 (8 years ago)
OK so getting token not defined, but there is a token as I am clicking on it.

                  Token not found undefined      
                  Token not found undefined      

I get two errors so seems every (?) token in SKT is not found

Ah hang on a minute, reading the code it seems to look on the current player page.  As GM I am often on a different page.  So moving the Players marker to the same page seems to fix this.

So limits are: Current page must be the current Players Page and tokens must be on Token layer.

Given I have started to use mapchange to allow players to roam the maps....something to know!

Thanks TheAaron for helping me debug to find what was happening!


March 27 (8 years ago)
The Aaron
Pro
API Scripter
This should fix the player page restriction.  (UNTESTED):
on("chat:message", function(msg) {
	
	var findPlayerPage = function(playerid){
		if(playerIsGM(playerid)){
			let player=getObj('player',playerid),
				page=getObj('page',player.get('lastpage'));
			if(page){
				return page;
			}
		}
		if(_.has(Campaign().get('playerspecificpages'),msg.playerid)) {
			let page=getObj('page',Campaign().get('playerspecificpages')[msg.playerid]);
			if(page){
				return page;
			}
		}
		return getObj('page',Campaign().get('playerpageid'));
	};


    if(msg.type == "api" && msg.content.indexOf("!range") != -1)
    {
        var useHeight = true; // true = use Target height difference, false to ignore height
        
        if (msg.content.indexOf("!range ") != -1)
        {
            var m = msg.content;
            m = m.replace("!range ","");    
            var l = m.length;
            
            var p = m.indexOf(",");
            tokenid1 = m.substring(0,p);
            tokenid2 = m.substring(p+1,l);
        }
            
	var curPage = findPlayerPage(msg.playerid);
        var curScale = curPage.get("scale_number"); // scale for 1 unit, eg. 1 unit = 5ft 
	var curUnit = curPage.get("scale_units"); // ft, m, km, mi etc.
	var curDiagonalType = curPage.get("diagonaltype"); // One of "foure", "pythagorean" (Euclidean), "threefive", or "manhattan"
	var curGridType = curPage.get("grid_type"); // One of "square", "hex", or "hexr". (hex corresponds to Hex(V), and hexr corresponds to Hex(H))
	var gridSize = 70;
		
        var token1 =  findObjs({_type: "graphic", layer:"objects", _pageid: curPage.id, _id: tokenid1})[0];
        var token2 =  findObjs({_type: "graphic", layer:"objects", _pageid: curPage.id, _id: tokenid2})[0];


March 27 (8 years ago)
While on this, the SKT map I am using has 10' per unit, and 0.5 unit grid, yet range is specified in terms of 10' grids.  Roll20 correctly adds a 5' grid.  So need to add the Grid Size to the calculations?


March 27 (8 years ago)
Thanks! Changing those 3 sections does fix the GM/Player page difference. 
Thanks "The Aaron" I'll implement those changes

Jim W. said:

While on this, the SKT map I am using has 10' per unit, and 0.5 unit grid, yet range is specified in terms of 10' grids.  Roll20 correctly adds a 5' grid.  So need to add the Grid Size to the calculations?



It should be using the scale and unit in the calculatiions. I'll have a look tonight using your setting to test. Currently I've only used 1 unit and 5 feet.