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

[API?] Map grid cell access

February 02 (9 years ago)
Hello all,

I posted a suggestion thread about getting access to grid cell information.  Has anyone already written something like this?

February 02 (9 years ago)

Edited February 02 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
https://gist.github.com/BaldarSilveraxe/4be1d7c163...

That is a start.... need to work out the math.

I think I did this once before... but can't find the script.

edit:
Here’s specific Roll20 dimensions for certain graphic elements.
https://wiki.roll20.net/Image_Best_Practices_for_R...

And there was an odd thing about grid_type.... 'hexr'= Hex(H) for some reason. 
grid_type"square"One of "square", "hex", or "hexr". (hex corresponds to Hex(V), and hexr corresponds to Hex(H))

February 02 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Updated the script..... 

But I would check my math.... should give you the "row" and "column" spammed in chat.... based on whatever the page setting is set to.

Good reading on hex can be found here: http://www.redblobgames.com/grids/hexagons/


February 02 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Lifer4700 said:
CURRENTLY
Using the UI, players can drag-and-drop tokens and they will (by default) snap to the cells on the map grid.
The UI can label these cells automatically (I refer to this as the cell's "address" below)
This this is independent of scale, units, or type (hexH, hexV, or square)

PROBLEMS
Roll20 Hex Math is Hard.
The existing distance between hex "centers" isn't 70.
The distance between hex centers is different in two of the directions compared to the third.
The distances between hex centers are different in H and V modes.
These distances aren't nice, whole, rational, counting numbers. Not even close.
That's 4 different "distance" values that need to be tracked (in addition to 70 for squares), two for HexH, two for HexV. Since they're not nice numbers, there is an error introduced that compounds over range.

DESIRED
I would like to be able to utilize the existing UI grid system from the API (or macro) to be able to:
retrieve a token's current cell address, or nearest cell if not snapped
move and snap a token to a specific cell using the cell address
Optionally, I would also like to be able to (in order of desire):find the number of cells between two tokens.squares are easy, and should be based on the map setting (either Manhattan or 4e, Euclidean and Pathfinder wouldn't apply in this case)
hexes are pretty much always Manhattan style

obtain a list of cells the token occupies if it is a "large" token - fully or partially would be two options
rotate a token to face a given cell face (4 choices for square, 6 for hexes)this brings up the question of which direction a token is facing in the first place

be able to "drive" a token forward one cell (move and snap to the adjacent cell)this also brings up the question of which direction a token is facing in the first place


ASSUMPTIONS
Obviously, in order for these cell addresses to be of any value, snap-to-grid should be enabled on the map.
February 02 (9 years ago)

Edited February 02 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Script as is should provide and "retrieve a token's current cell address, or nearest cell if not snapped."

If that is correct.... the rest should be easy.
February 02 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Its a tad off over a long distance... looking at it.
February 03 (9 years ago)

Edited February 03 (9 years ago)
Here's the math that I had come up with when I first looked at this back in November.

TL;DR

  • If you use HexH (which,strangely, aligns the hexes vertically), the distances between the hexes in 2 of the directions is ~80.2, and in the other direction, its ~79.9
  • If you use HexV (which,strangely, aligns the hexes horizontally), the distances between the hexes in 2 of the directions is ~76.8, and in the other direction, its ~75.2

LONG VERSION

In each table I show the "x,y" coordinates of three identical tokens - A, B, & C - that have been snapped to the grid using the UI in three adjacent cells.  Then I show the distance from one token to another, which represents all three primary directions on a hex map.

HEXR (Hex H) vertical
Token L->R T->B
A 116.070255 79.68878998
B 46.48512749 119.533185
C 46.48512749 39.84439499
A-B 80.18519676
B-C 79.68878998
C-A 80.18519676
HEX (Hex V) horizontal
Token L->R T->B
A 37.59928099 43.86582782
B 75.19856198 110.8316556
C 112.797843 43.86582782
A-B 76.79927101
B-C 76.79927101
C-A 75.19856198

February 03 (9 years ago)
Here's a file that I put together for my own reference.

Hex Math
February 03 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Aaron gave me a big clue to solving this.... I have to travel, may take me a few days to circle back to this.

But snapping might be solved.
February 03 (9 years ago)
You are SUCH a tease!!!

I'm looking forward to what you've learned.
February 04 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
/*global sendChat, on, getObj */
/*jslint white: true, bitwise: true, for: true, multivar: true, browser: true */
var mapGrid = mapGrid || (function(){
'use strict';
var version = 0.2,
//size = 91.14378277661477,
left_h = 46.48512749037782,
top_h = 39.8443949917523,
left_step_h = 69.585127490378,
top_step_h = 39.84439499,
left_v = 37.5992809922301,
top_v = 43.8658278242683,
left_step_v = 37.5992809922301,
top_step_v = 66.9658278242677,
square_left_right = function(l){
var x = ~~((l/70) - 0.5);
return x + 1;
},
hex_v_left = function(l){
var x = ( ~~l === ~~left_v ) ? 0 : ~~((l-left_v)/left_step_v );
return x + 1;
},
hex_v_top = function(t){
var y = ( ~~t === ~~top_v ) ? 0 : ~~((t-top_v)/top_step_v );
return y + 1;
},
hex_h_left = function(l){
var x = Math.round( (l-left_h)/left_step_h );
return x + 1;
},
hex_h_top = function(t){
var y = Math.round( (t-top_h)/top_step_h );
return y + 1;
},
handleGraphicChange = function (obj) {
var html = '',
page=getObj('page',obj.get('pageid')),
grid_type = page.get('grid_type'),
objlft = obj.get('left'),
objtp = obj.get('top'),
gridLeft = (grid_type==='square') ? square_left_right(objlft) : (grid_type==='hex') ? hex_v_left(objlft) : hex_h_left(objlft),
gridTop = (grid_type==='square') ? square_left_right(objtp) : (grid_type==='hex') ? hex_v_top(objtp) : hex_h_top(objtp);
page.set('gridlabels',true);
html += '/direct '
+ '<br>Grid Type: ' + grid_type
+ '<br>objlft: ' + ~~objlft
+ '<br>objtp: ' + ~~objtp
+ '<br>GridLeft: ' + gridLeft
+ '<br>GridTop: ' + gridTop;
sendChat(Math.random().toString(36).substring(7),html);
},
registerEventHandlers = function() {
on('change:graphic', handleGraphicChange);
};
return {
RegisterEventHandlers: registerEventHandlers
};
}());
on('ready',function(){
'use strict';
mapGrid.RegisterEventHandlers();
});
February 04 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
Thanks to Aaron.. I think that gets you to your grid values.
February 05 (9 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
map_coordinates = function(obj){
var g,l,t,s,v,h,rv,
//size = 91.14378277661477,
//side = 50,
left_h = 46.48512749037782,
top_h = 39.8443949917523,
left_step_h = 69.585127490378,
top_step_h = 39.84439499,
left_v = 37.5992809922301,
top_v = 43.8658278242683,
left_step_v = 37.5992809922301,
top_step_v = 66.9658278242677;
if(!_.has(obj,'remove') && !_.isFunction(obj.remove) ){
return {c:0, r:0, g: 'unknown', valid: false};
}
s = function(d){ return ~~((d/70) - 0.5) + 1; };
v = function(d,sd,sv){ return ( ~~d === ~~sd ) ? 1 : ~~((d-sd)/sv ) + 1; };
h = function(d,sd,sv){ return Math.round( (d-sd)/sv) + 1; };
g = getObj('page',obj.get('pageid')).get('grid_type');
l = obj.get('left');
t = obj.get('top');
rv = ('square' === g ) ? {c: s(l), r: s(t), g :g, valid: true} :
('hex' === g ) ? {c: v(l,left_v,left_step_v), r: v(t,top_v,top_step_v), g: g, valid: true} :
('hexr' === g ) ? {c: h(l,left_h,left_step_h), r: h(t,top_h,top_step_h), g: g, valid: true} :
{c:0, r:0, g: 'unknown', valid: false};
return rv;
}
February 05 (9 years ago)

Edited July 02 (8 years ago)
Stephen S.
Pro
Marketplace Creator
Sheet Author
API Scripter
That function should return {c: [column], r: [row], g: [grid type], valid: [true/false]}

If you pass a non-obj (undefined obj most common) it should return {c:0, r:0, g: 'unknown', valid: false} rather than crash the API.

All valid cases should give you the location or snapping location... works with all three grid types.
February 05 (9 years ago)
The Aaron
Pro
API Scripter
Cool. :)