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

[Script] Improved Hex Range Distance

1476389770

Edited 1476470577
Thorin
Sheet Author
Austin B. posted a great script at the link below that lets you automatically determine the distance between any two tokens on a hex grid.&nbsp; <a href="https://app.roll20.net/forum/post/973044/script-he" rel="nofollow">https://app.roll20.net/forum/post/973044/script-he</a>... The problem I had with the script, however, is that it does not account for changing the grid unit size. For example, I'm planning to run a GURPS game and want to change the hex unit size to 0.6 so that I can use GURPS' 1 yd. hexes with maps scaled to D&D's 5 ft. squares. I thought I would share my modified script, and the referenced thread is locked. The script is below. EDIT: Is there a better way to post code in this forum? Like a way to add a &lt;pre&gt; tag or something? // Computes the distances between 2 tokens by ID // Use the macro target picker to fill in the ID // Script command // !range @{target|1st Target|token_id} @{target|2nd Target|token_id}&nbsp; on("chat:message", function(msg) { &nbsp; &nbsp; if(msg.type == "api" && msg.content.indexOf("!range") != -1) { &nbsp; &nbsp; &nbsp; &nbsp; log(msg); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var n = msg.content.split(" ", 4) &nbsp; &nbsp; &nbsp; &nbsp; var cmd = n[0]; &nbsp; &nbsp; &nbsp; &nbsp; var id1 = n[1]; &nbsp; &nbsp; &nbsp; &nbsp; var id2 = n[2]; &nbsp; &nbsp; &nbsp; &nbsp; var token1 = &nbsp;getObj("graphic", id1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var token2 = &nbsp;getObj("graphic", id2); &nbsp; &nbsp; &nbsp; &nbsp; if (token1 && token2) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var distance = tokenDistance(token1, token2); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat("", "/desc Distance between Token1 & Token2 is " + distance); &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!token1) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat("Range Finder","/w " + msg.who + " Could not locate first token!"); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!token2) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat("Range Finder","/w " + msg.who + " Could not locate second token!"); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } }); function tokenDistance(token1, token2) { &nbsp; &nbsp; if (token1.get('pageid') != token2.get('pageid')) { &nbsp; &nbsp; &nbsp; &nbsp; log('Cannot measure distance between tokens on different pages'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; var distance; &nbsp; &nbsp; var page = getObj('page', token1.get('pageid')); &nbsp; &nbsp; var gridType = page.get('grid_type'); &nbsp; &nbsp; var scale = page.get('snapping_increment'); &nbsp; &nbsp; switch(gridType) { &nbsp; &nbsp; &nbsp; &nbsp; case 'hex': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distance = hexVDistance([token1.get("left"), token1.get("top")], [token2.get("left"), token2.get("top")], scale); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; case 'hexr': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distance = hexHDistance([token1.get("left"), token1.get("top")], [token2.get("left"), token2.get("top")], scale); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; } &nbsp; &nbsp; return distance; } function hexHDistance(unit1, unit2, scale) { &nbsp; &nbsp; var q1, q2, r1, r2; &nbsp; &nbsp; q1 = Math.round((unit1[0] - 46.48512749037782) / (69.58512749037783 * scale)); &nbsp; &nbsp; r1 = Math.round((unit1[1] - (39.8443949917523 * scale)) / (39.8443949917523 * scale)); &nbsp; &nbsp; r1 = Math.floor(r1 / 2); &nbsp; &nbsp; q2 = Math.round((unit2[0] - 46.48512749037782) / (69.58512749037783 * scale)); &nbsp; &nbsp; r2 = Math.round((unit2[1] - (39.8443949917523 * scale)) / (39.8443949917523 * scale)); &nbsp; &nbsp; r2 = Math.floor(r2 / 2); &nbsp; &nbsp; return cubeDistance(oddQToCube(q1, r1), oddQToCube(q2, r2)); } function hexVDistance(unit1, unit2, scale) { &nbsp; &nbsp; var q1, q2, r1, r2; &nbsp; &nbsp; q1 = Math.round((unit1[0] - (37.59928099223013 * scale)) / (37.59928099223013 * scale)); &nbsp; &nbsp; r1 = Math.round((unit1[1] - 43.86582782426834) / (66.96582782426833 * scale)); &nbsp; &nbsp; q1 = Math.floor(q1 / 2); &nbsp; &nbsp; q2 = Math.round((unit2[0] - (37.59928099223013 * scale)) / (37.59928099223013 * scale)); &nbsp; &nbsp; r2 = Math.round((unit2[1] - 43.86582782426834) / (66.96582782426833 * scale)); &nbsp; &nbsp; q2 = Math.floor(q2 / 2); &nbsp; &nbsp; return cubeDistance(oddRToCube(q1, r1), oddRToCube(q2, r2)); } function oddRToCube(q, r) { &nbsp; &nbsp; var x, y, z; &nbsp; &nbsp; x = q - (r - (r & 1)) / 2; &nbsp; &nbsp; z = r; &nbsp; &nbsp; y = -x - z; &nbsp; &nbsp; return [x, y, z]; } function oddQToCube(q, r) { &nbsp; &nbsp; var x, y, z; &nbsp; &nbsp; x = q; &nbsp; &nbsp; z = r - (q - (q & 1)) / 2; &nbsp; &nbsp; y = -x - z; &nbsp; &nbsp; return [x, y, z]; } function cubeDistance(cube1, cube2) { &nbsp; &nbsp; return Math.max(Math.abs(cube1[0] - cube2[0]), Math.abs(cube1[1] - cube2[1]), Math.abs(cube1[2] - cube2[2])); }
1476398045
The Aaron
Roll20 Production Team
API Scripter
There is the code format in the Paragraph Mark Menu (&nbsp; ¶&nbsp; ) at the top left. &nbsp;I adjusted your post for you. &nbsp;
1479198274
Mike W.
Pro
Sheet Author
Nice script I just started using it in my GURPS game as well. Question:&nbsp;I am not a programmer so does this script auto adjust for the hex size? The reason I as is that my maps are at 1.0 and you mentioned you made the script to work for a hex size of 0.6, however the script works fine - am I missing something?
1479339849
Thorin
Sheet Author
Yes, this script should auto adjust for hex size. I have several more GURPS scripts in the works as well, but they're not cleaned up enough to post yet.
Solid Script. It currently sets the distance as single units (essentially the unit distance), is there anyway to mutliply it? i.e. if a unit is 5 ft?
1482254801
Thorin
Sheet Author
Here would be the way I would implement this (not tested, but ought to work). Just replace the tokenDistance function in the script above with the one shown below: function tokenDistance(token1, token2) { &nbsp; &nbsp; if (token1.get('pageid') != token2.get('pageid')) { &nbsp; &nbsp; &nbsp; &nbsp; log('Cannot measure distance between tokens on different pages'); &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; } &nbsp; &nbsp; var distance; &nbsp; &nbsp; var page = getObj('page', token1.get('pageid')); &nbsp; &nbsp; var gridType = page.get('grid_type'); &nbsp; &nbsp; var scale = page.get('snapping_increment'); var hex_size = page.get('scale_number'); &nbsp; &nbsp; switch(gridType) { &nbsp; &nbsp; &nbsp; &nbsp; case 'hex': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distance = hexVDistance([token1.get("left"), token1.get("top")], [token2.get("left"), token2.get("top")], scale * hex_size); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; case 'hexr': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; distance = hexHDistance([token1.get("left"), token1.get("top")], [token2.get("left"), token2.get("top")], scale * hex_size); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; } &nbsp; &nbsp; return distance; }
Thorin, This looks like a solid script, but i'm having trouble getting it to work. I've created a macro using this command: !range @{target|1st Target|token_id} @{target|2nd Target|token_id} But I get the following type of message when I pick tokens (the character strings differ depending upon the tokens that are picked): !range -KcT6BJA6rhnz26q-sdi -KcT6C84PIsDeD6Wy9we OR... !range -Kc6DFpJYdNnB8OeYDoi -Kc6DEFnHAEmKzAnFRfz I get a similar message when I introduced the modified tokenDistance function from above. Any help would be greatly appreciated.
1486618051
Thorin
Sheet Author
The bits that look like -KcT6C84PIsDeD6Wy9we are the token IDs of the tokens you've selected. It sounds like the macro is succeeding to look them up and pass them to the script, but failing somewhere in the script itself. The place where you're getting that message, is it in the chat console or the script's log? If it's in the log, then it sounds like you're getting as far as:&nbsp; on("chat:message", function(msg) { &nbsp; &nbsp; if(msg.type == "api" && msg.content.indexOf("!range") != -1) { &nbsp; &nbsp; &nbsp; &nbsp; log(msg); but failing somewhere after that. I noticed that in the script above, the next line: var n = msg.content.split(" ", 4) doesn't have a semicolon at the end of the line. I don't think that would be enough cause the script to fail, but it's worth adding the semicolon and trying again, just in case. If that doesn't work, it's worth figuring out which line the script is failing on.