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 .
×

dropping graphic adjacent to selected char token matching rotation

We are playing Gaslands and have used the api scripts to automate a number of cool features. There are these movement templates that for now we just drag around. Looking for way to drop the graphic abutted to the selcted token and matching its rotation. The array of templates is about a dozen or so. Any ideas would appreciated.
1607961781
The Aaron
Roll20 Production Team
API Scripter
Are the rotation's in even increments (like only on 45º, or 90º), or could it be any rotation? Are all the templates oriented the same way, as in, natively, the token would always be adjacent to the bottom in the absence of any rotation? Finally, are the tokens always the same size? I think you could actually do this with TokenCondition , provided tokens area always the same size.  You'd need to name the templates appropriately.  Assuming a template that is 3 units tall, and would natively be placed on the top of an unrotated token, something like: Condition: My Template [mirror:rotation|top:-140] :should work.  The 140 is 35 for half the token's size and 105 for half the template's size. I'll have to look, that might not actually work right...  But if it doesn't, you could create your graphics such that they have empty space around them so where the token sits is where the center of the graphic is.  Then this would likely work: Condition: My Template [mirror:rotation] If none of that works, I can probably whip you up a little script that just does the alignment when you drop the token in.
Thanks for reply man! I will definitely mess around with re-making tokens all same size with empty space around them, and place the need part at the bottom of the space. great idea. here are then answers to your questions. The rotation would be totally arbitray to match whatever the --sel had active, and we play with grid turned off out of neccesity. The complicated part is the the token drop would need to align with the front edge (original top) of the char token regardless of orientation  I tried making them a macro drop of a rollable table token, but it squished the templates as they are not the same size( though I am gonna work on that) Here are two examples below. And we using basic cars for the character tokens they need to drop next too.
1607966551
The Aaron
Roll20 Production Team
API Scripter
Ah, nice!  This reminds me of Car Wars!  Ah, sweet nostalgia...  So, using TokenCondition isn't going to be ideal for this, as I assume after placing the template, next will be moving the token to be aligned to the far end of the template.  TokenCondition is designed to keep a condition attacked to a token, and mirror properties of it, so as soon as you moved the vehicle, this template would also move and the same for rotation.  However, I think there's a script here that wouldn't be too hard to write, just doing a one-time alignment and rotation (and a pushback), then leaving the template as is. Templates like this would probably be ideal: With a 70px box at the center and the template set on top of it.
hehe.. oh man I loved car wars!! sprawled all over the kitchen floor with the giant fold out mats. ok, so I will get tokens remade, start with 70x70 clear box in middle and then place template so that it aligns with that perfectly. 
1607968806
The Aaron
Roll20 Production Team
API Scripter
Somewhere I still have a giant map we drew on about 30 sheets of graph paper tapped together. =D
1608008221

Edited 1608082528
The Aaron
Roll20 Production Team
API Scripter
Ok, give this a try: Just create a character named "Template: <something>" or "Guide: <something>", then set a template token to represent it, and set it as the default token for the character.  When you want to use it, just drag it out onto a token, it will adjust its position and rotation to the targeted token. Here's the code: on('ready',()=>{ const isOverlappedDist = (obj1, obj2) => { let dx = Math.abs(obj1.get('left')-obj2.get('left')); let dy = Math.abs(obj1.get('top')-obj2.get('top')); let lx = ((0+obj1.get('width') + obj2.get('width'))/2); let ly = ((0+obj1.get('height') + obj2.get('height'))/2); if(dx < lx && dy < ly){ return (dy*dy+dx*dx); } return false; }; const findTargetToken = (obj) => findObjs({ type: 'graphic', layer: obj.get('layer'), pageid: obj.get('pageid') }) .filter((o) => o.id !== obj.id) .map(o=> ({overlap: isOverlappedDist(obj,o), token: o})) .filter((o) => false !== o.overlap) .sort((a,b)=>a.overlap-b.overlap); const getTopTokenForPage = (tokens, pid) => { let page = getObj('page',pid); if(page){ let ids = tokens.map(t=>t.id); let id = page.get('zorder').split(/,/).filter( id => ids.includes(id)).pop(); if(id){ let token = tokens.find(t => t.id===id); if(token){ return token; } } } return tokens[0]; // in an error, return the first token in the list }; on('add:graphic',(obj)=>{ let character = getObj('character',obj.get('represents')); if(character){ let match =(character||{get:()=>''}).get('name').match(/^\s*(template|guide)\s*:/i); if(match){ let toks = findTargetToken(obj); let token = [toks[0]||{}].token; if(toks.length>1){ let tList = toks.filter(o => o.overlap === toks[0].overlap).map(o=>o.token); token = getTopTokenForPage(tList,obj.get('pageid')); } if(token){ obj.set({ rotation: token.get('rotation'), left: token.get('left'), top: token.get('top') }); toBack(obj); } } } }); });
dude, wow YOU ARE AWESOME!!!!!!!!!!!!!!!!!!
1608048876
The Aaron
Roll20 Production Team
API Scripter
HAHAHAHAHAHA!!  Hope that works for you. =D  Now I want to go dig out my Car Wars stuff and give it a go with that.  =D
1608053537

Edited 1608053594
ok I must be doing something wrong, as it looks freeking perfect in your footage. I copy and pasted the script to new script in api for game and saved it as td.js and restarted sandbox. it looks active I made a new version of template positioned in a larger square. I made a character named Template: shortnew I set the default token to the shortnew template image but when I drag it onto a token it does not do the neato little trick :-)
1608054314
The Aaron
Roll20 Production Team
API Scripter
Did you set the token to represent the character?
I think so ?! I selected the template I wanted, then I opened up character and chose 'use selected token as default token', then clicked on token and selected the character sheet for represents 
1608056440
The Aaron
Roll20 Production Team
API Scripter
You need to set the token to represents before setting it as the default token.  Otherwise, you end up with a default token that doesn't represent the character.
yep! I was doing it in wrong order LOL no wonder in all my games I keep having to reassign the damnable tokens working great, I just need to adjust my scale for the cars and viola! You rock man! if ever want to come get your gaslands on we having open games on sunday afternoon right now I should have my tokens scale issues squared away by this weekend thanks again man!
1608057833
The Aaron
Roll20 Production Team
API Scripter
No problem!
wow it works really really well now that I spent a few minute scaling the template's graphics one small observation... if you make a mistake and drag it onto playing field without selecting a token first, it breaks and I have to log out and restart sandbox. I will tell my players that is a no-no, but if there was any easy way to fix that I would welcome that with open arms :-)
1608074405
Kraynic
Pro
Sheet Author
You should be able to have the api settings page open in another tab and reset it while logged into the game.  Just to save you a little time on that bit.
Oh thanks Kraynic, that is actually a great tip, not worried about my regulars but for the noobs prob a good idea :-)
1608082551
The Aaron
Roll20 Production Team
API Scripter
Whoops!  How embarrassing!  =D  Fixed in the code above. =D
lol....  you dah man!