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

Using 'It's A Trap' to trigger 'Token Mod' with an 'APILogic' IF structure involving a 'Fetch' construct in the command

Hi all,  I'm hoping those of you who are more familiar with the Metascripts will be able to assist me with this one.  I've got a specific use question here. I'm trying to use a trap token through It's A Trap to trigger a Token Mod  command that includes an IF logic structure that fetches the night vision distance of the triggering player token in order to toggle it between two values whenever the trap is triggered. This functions as a fog growing and restricting vision as players delve into an ice dragon's lair, and the fog receding as they walk out, passing over the trap token once in each direction.  Here's the command that works outside of It's A Trap to toggle between the two values: !token-mod --current-page --set night_distance|{& if @(selected.nv_dist) = 45}75{& elseif @(selected.nv_dist) = 75}45{& end} It's A Trap  has native Token Mod  mod support that includes the command trigger, but when pasting in the above minus the trigger, it does not work, but I know that is because the 'selected' Fetch property doesn't have anything selected when the command is triggered by It's a Trap .  I have tried using It's A Trap 's VICTIM_ID substitution in place of 'selected' in order for Fetch  to be able to read the triggering token's night vision distance property, but it does not work.  Is there some kind of syntax or deferment or other information I am missing that would enable the Fetch  construct to be used in the needed context?  I already have a workaround of a non-logical version of each distance value being applied to a token by two separate trap tokens (passing through both applies the last one passed), but It's a Trap  requires a chat output message when a trap token is triggered, so that really crowds the chat with unneccesary clutter that could be cut in half if this logical version of the command can function in context. 
1721534089
timmaugh
Pro
API Scripter
Hey, Rocklobster... I have a new metascript nearly ready which handles all sorts of ranging issues like this (closest to a given token/trap). I've been sitting on it because I have to work out the math for elliptical intersections... but that is on my list of to-dos. Short of that script being ready, the next best solution might be a dedicated metascript that could track all recently-interacted-with game objects and return them with some syntax... for example, tracking all token movement and providing a syntax structure to get "the most recently moved token." In this case, that could tell you the trap-springing token's id, since the one that sprung the trap was the one you were moving. However, that would take some consideration and thought to make sure the syntax structures were intuitive and comprehensive. Barring either of those solutions, then, we're left with to do bare-knuckle brawling with the problem in the metascript arena. So. Listen. It ain't pretty. I'm just going to say that now: it ain't pretty. But it should work. OK, assuming that the bars 1 and 2 of the trap token are available (you're not using them for anything else), here is a solution that will use them to track which player token is the closest to the trap... allowing you to add a {&select} structure to your Token-Mod command to make it work: !{{(~)   !token-mod --ids @(TrapToken.token_id) --set bar2_value|   !forselected(^) {^&if "@^(TrapToken.bar2)" = "" || {^& math round(hypot((@^(selected.left)-@^(TrapToken.left)),(@^(selected.top)-@^(TrapToken.left))),0)} < 0@(TrapToken.bar1)}token-mod --ids @(TrapToken.token_id) --set bar1_value|{^& math round(hypot((@^(selected.left)-@^(TrapToken.left)),(@^(selected.top)-@^(TrapToken.left))),0)} bar2_value|@^(selected|token_id){^&end} {~&delay .2} {~&select *, +pc}   !token-mod --current-page --set night_distance|{~& if @~(selected.nv_dist) = 45}75{~& elseif @~(selected.nv_dist) = 75}45{~& end}{~&select @~(TrapToken.bar2)} {~&delay .2} }} That's pretty deep in the meta-pool... but basically the first sub-line resets bar2 on the TrapToken (change that to match the name of your token) to be empty. The second sub-line selects all player tokens on the current map and runs a command for each that compares their distance to the TrapToken (using the hypot() function from MathOps, rounded to 0 places). If the TrapToken has nothing entered in bar2 OR if the calculated distance is LESS than what is in the TrapToken's bar1, then the currently-considered player token is entered in the TrapToken's bar2, and the distance to that token is entered in the TrapToken's bar1. By the end of this, we should have the closest player-token to the trap. The third sub-line is your original TokenMod command, but we add a {&select} statement pulling the token id we stashed in bar2 of the TrapToken. Everything else is deferrals and delays to make sure things have time to run (which I can explain if you want). I've tested the above and it works on its own... but I don't have ItsATrap configured for my game to test that fully. Give it a try and let me know.
timmaugh said: I've tested the above and it works on its own... but I don't have ItsATrap configured for my game to test that fully. Give it a try and let me know. Okay, a couple of things here I think. I understand all of what you explained, and I understand the concept of deferrals, so seeing it written out like that does make sense to me.&nbsp; But,&nbsp; The way ItsATrap works with TokenMod is that you insert the arguments from the TokenMod command you want to use into a single-line text query that stores it inside the GM notes of the trap token to be retrieved/triggered based on the activiation of the trap, which in my case, is whenever a token touches/crosses/passes through the area of the trap token (a tunnel-spanning rectangle, in this case).&nbsp; Knowing that, I tried inputing the whole command you wrote into the generic API Command section that ItsATrap also has, which is also a single-line text query. With that set, I tried it and it crashed the sandbox, ironically with the same exact error information as my other issue you were assisting me with for OnMyTurn and TokenMod from a previous forum post ( <a href="https://app.roll20.net/forum/post/11968260/onmyturn-plus-tokenmod-not-working-together" rel="nofollow">https://app.roll20.net/forum/post/11968260/onmyturn-plus-tokenmod-not-working-together</a> ) For reference, the error message generated was:&nbsp; TypeError: Cannot read properties of undefined (reading 'get') TypeError: Cannot read properties of undefined (reading 'get') at apiscript.js:39022:44 at eval (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:168:1), &lt;anonymous&gt;:65:16) at Object.publish (eval at &lt;anonymous&gt; (/home/node/d20-api-server/api.js:168:1), &lt;anonymous&gt;:70:8) at /home/node/d20-api-server/api.js:1762: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 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:461
1721536204

Edited 1721536253
1721570641

Edited 1721571038
timmaugh
Pro
API Scripter
Yeah, sorry I let that other thread slip, but it does look like the same number... and it looks to be a part of Token Swap. Can you post that code, here, or invite/promote me to your game so I can look at it, there? EDIT: Also, i t's weird that the ScriptInfo message references the line number for the error occurring 2394 lines after the end of DLTool, but I don't see DLTool in your script deck...? Did you uninstall it after running ScriptInfo but prior to taking the screenshot?
timmaugh said: Yeah, sorry I let that other thread slip, but it does look like the same number... and it looks to be a part of Token Swap. Can you post that code, here, or invite/promote me to your game so I can look at it, there? EDIT: Also, i t's weird that the ScriptInfo message references the line number for the error occurring 2394 lines after the end of DLTool, but I don't see DLTool in your script deck...? Did you uninstall it after running ScriptInfo but prior to taking the screenshot? Sure, I'll do both. And Dynamic Lighting Tool is in there, directly above Token Swap. Here's the code for Token Swap: on('ready',function(){ "use strict"; on('chat:message',function(msg){ var args, who; if (msg.type !== "api") { return; } who = getObj('player',msg.playerid).get('_displayname'); args = msg.content.split(/\s+/); switch(args.shift()) { case '!token-swap': { let t1 = getObj('graphic',args[0]); let t2 = getObj('graphic',args[1]); if(!t1 || !t2) { sendChat('TokenSwap', `/w "${who}" Please provide 2 token ids to swap: &lt;code&gt;!token-swap ID1 ID2&lt;/code&gt;`); return; } let p1={ top: t1.get('top'), left: t1.get('left') }; let p2={ top: t2.get('top'), left: t2.get('left') }; t1.set(p2); t2.set(p1); if(!playerIsGM(msg.playerid)){ sendChat('TokenSwap', `/w gm &lt;code&gt;${who}&lt;/code&gt; just swapped &lt;b&gt;${t1.get('name')}&lt;/b&gt; and &lt;b&gt;${t2.get('name')}&lt;/b&gt;. &lt;a href="!token-swap ${t1.id} ${t2.id}"&gt;Swap Back&lt;/a&gt;`); } } break; } }); });
I did just try disabling Token Swap and discovered that it fixed the problem I was having in the other forum post about OnMyTurn, if that helps narrow it down further? I think I just have Token Swap for some situational spell/abilities. I could probably write a Token-Mod --set command for Left and Top using Fetch and targeted tokens in order to swap them that way if Token Swap can't be fixed.&nbsp;
Rocklobster said: Hello, I am curious on some of the api you got, if you dont mind sharing some info please on them: PatrolWaypoints - is this the custom api that allows npc tokens to move in intervals that you assign? I think Nick O did a YT video on it. or something else? Calender Moon fix - curious, I am using Faerun Calender but does this have something else, special? What is Autobutton? SpinTokens? Check Light Levels? Know your Enemy? CFX? Delay? Radar?
Novercalis said: Hello, I am curious on some of the api you got, if you dont mind sharing some info please on them: PatrolWaypoints - is this the custom api that allows npc tokens to move in intervals that you assign? I think Nick O did a YT video on it. or something else? Calender Moon fix - curious, I am using Faerun Calender but does this have something else, special? What is Autobutton? SpinTokens? Check Light Levels? Know your Enemy? CFX? Delay? Radar? Hey there! Yes, let me give you some answers and links.&nbsp; Patrol Waypoints is the script from Nick O.'s youtube video. I think you can get the link to it there.&nbsp; Multi-World Calendar (The Aaron Moon Fix) is a specific version of Kirsty's Multi-World Calendar that fixed an issue with the moon phases not showing correctly. I don't remember where specifically I got it from. If you want it, I can PM it to you.&nbsp; Autobuttons &amp; Autobuttons.js (a fix of the first) is a neat script that's very useful for damage tracking. Whenever a damage template is rolled in the chat, it posts some buttons that the DM can use to apply said damage roll to a selected token.&nbsp; <a href="https://wiki.roll20.net/Script:autoButtons" rel="nofollow">https://wiki.roll20.net/Script:autoButtons</a> SpinTokens lets you animate rotation on otherwise static tokens and objects. <a href="https://app.roll20.net/forum/post/1380961/script-spintokens-allows-the-gm-to-set-a-token-to-spinning-persisted-across-restarts-minimally-active" rel="nofollow">https://app.roll20.net/forum/post/1380961/script-spintokens-allows-the-gm-to-set-a-token-to-spinning-persisted-across-restarts-minimally-active</a> Check Light Levels does what it says, checks the light level a selected token is in, and posts that info in chat. Useful for if a character wants to kow if they are in dim light or similar.&nbsp; <a href="https://app.roll20.net/forum/post/11124325/script-checklightlevel-check-the-current-level-of-light-on-a-token" rel="nofollow">https://app.roll20.net/forum/post/11124325/script-checklightlevel-check-the-current-level-of-light-on-a-token</a> Know Your Enemy is useful for Battlemaster Fighters in DnD 5E, for their subclass feature of the same level.&nbsp; <a href="https://app.roll20.net/forum/post/9713930/know-your-enemy-macro" rel="nofollow">https://app.roll20.net/forum/post/9713930/know-your-enemy-macro</a> CFX is a alternate way of using Roll20 FX is your game. <a href="https://app.roll20.net/forum/post/6534452/script-cfx" rel="nofollow">https://app.roll20.net/forum/post/6534452/script-cfx</a> Delay allows you to (with caveats) delay the output of command run through Delay.&nbsp; <a href="https://app.roll20.net/forum/post/6533907/script-delay" rel="nofollow">https://app.roll20.net/forum/post/6533907/script-delay</a> Radar is useful for abilities like a Paladin's (DnD 5e) Divine Sense, but does have other applications.&nbsp; <a href="https://app.roll20.net/forum/post/9137492/script-radar-an-animated-token-sensor-slash-tremorsense-slash-blindsense-slash-divine-sense-etc-solution-with-optional-dynamic-lighting-interaction/?pagenum=1" rel="nofollow">https://app.roll20.net/forum/post/9137492/script-radar-an-animated-token-sensor-slash-tremorsense-slash-blindsense-slash-divine-sense-etc-solution-with-optional-dynamic-lighting-interaction/?pagenum=1</a>
1721939720
timmaugh
Pro
API Scripter
Hey, Rocklobster... Sorry I haven't had time to jump in and troubleshoot that script, but I agree that you can do that with a pair of TokenMod commands -- a pair of commands that can be helped with the metascript toolbox: !{{ &nbsp; !token-mod --set top|@(selected.top) left|@(selected.left) &nbsp; !token-mod --set top|@(@{target|token_id}.top) left|@(@{target|token_id}.left) }} I'll still try to make time to figure out what is going on with the TokenSwap script, if you want... probably just not before the weekend. Let me know!