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

Any Way for SpawnDefaultToken to Read the Current Side of Selected Token?

1718912063

Edited 1718912125
Dumbhuman
Pro
Marketplace Creator
I'm using SpawnDefaultToken for a Strahd Zombie so that, as it loses extremities, the main token is replaced with one reflecting the damage done and the appropriate limb/head is placed onto the map as as separate token.  I'm pretty happy with it so far (but don't click the gif below if you aren't happy seeing a zombie fall apart). I have four other variant colors for these tokens and it would be very nice to use them in this setup, but ideally I'd like to keep the colors consistent, so that if a white zombie is decapitated it spawns a headless white zombie and a white zombie head.  I imagine I could do that with a pop-up prompt asking the user to select which color the zombie is, but I'd rather not introduce that amount of delay into playing the game. So does anyone know of a way that SpawnDefaultToken can read the current side of a selected multi-sided token and then pass that information to the --side command so that it requests the same side number as the original selected token?  I did try the syntax "--side| @{selected|side}" just in case it was an undocumented feature, but that produces random results.
A token's current side can be grabbed with the  Fetch  metascript from the  Metascript Toolbox . This is an example that prints the side using Fetch and another Metascript ZeroFrame : !The current side is @(selected.currentSide){&simple}
1718917356
Dumbhuman
Pro
Marketplace Creator
Joshua N. said: A token's current side can be grabbed with the  Fetch  metascript from the  Metascript Toolbox . This is an example that prints the side using Fetch and another Metascript ZeroFrame : !The current side is @(selected.currentSide){&simple} Thank you for the suggestion.  From what I've read thus far, Fetch looked to be exactly what I need, but now I feel a little like Gretchen failing "to make fetch happen".  I no longer get an error message about the attribute not being found, but the result is always the side 1 (the default) even when the selected token is showing side 2. This is the macro I'm using.  Maybe I'm doing something wrong and/or Fetch just doesn't play well with SpawnDefaultToken.  Or possibly it's a problem with two calls being made in the same macro? !Spawn {{   --name| Strahd Zombie Head   --rotation| random   --placement| random 3   --offset| -1,-.7   --side| @(selected.currentside) }} !Spawn {{   --name| Strahd Zombie LostHead   --bar3| [[@{selected|bar3}]]/30   --side| @(selected.currentside)   --deleteSource| yes }}
Interesting. I didn't know this about SpawnDefaultToken but it seems to always subtract 1 from --side but currentSide property is a 0 based array so when you have a currentSide of 2, SpawnDefaultToken picks side 1, which is the second entry in the table. So if you have  MathOps MetaScript  that comes with the metascript toolbox, you can do this !Spawn --name|Corman Alfar --offset|-2,0 --side|{&math @(selected.currentSide) + 1} That works for me to get the same side from Spawn. I guess I never realized Spawn made it more human usable with 1 being the first side in the table so it always subtracted 1 from the number passed into --side. So the above is a workaround for currentSide returning the 0 based array version of the side and Spawn expecting a 1 based array. Hopefully that helps you.
1718926088
Dumbhuman
Pro
Marketplace Creator
Joshua N. said: ...I guess I never realized Spawn made it more human usable with 1 being the first side in the table... TokenMod does this as well, and it does it so well that I completely forgot that Roll20 considers sides to start at 0 rather than 1! I might have remembered that and made the connection on my own if I didn't dive into some drawing instead.  I appreciate you coming up with the solution!  Is the MathOps strictly necessary or would [[@(selected.currentSide)+1]] also work?  I'm putting this together for my DM to run, so I'm just trying to cut down on the number of scripts he'll have to install for this one little trick.
I got an error doing that. I assumed due to an order of operations issue of when Roll20 does inline roll resolution and when the Fetch mod would run but that's a pure guess on my part. Perhaps timmaugh will come along and confirm that but MathOps was the next thing I tried and it worked for me. I have the MetaScript Toolbox installed in my test game so it was included. My guess is that there are other ways to get it to work besides MathOps but I was trying to go one post without mentioning ScriptCards.
1718931741

Edited 1718935606
timmaugh
Pro
API Scripter
Joshua N. said: My guess is that there are other ways to get it to work besides MathOps but I was trying to go one post without mentioning ScriptCards. Hee hee. =D Dumbhuman, yes, you can use an inline roll. You just have to defer it one time. Basically, you need to "hide" the roll syntax (the double brackets) from the Roll20 parsers so that the Script Moderator hands the message off to the scripts... then Fetch has time to return the value (since this would come after the Roll20 parsing). After that, because ZeroFrame runs in a loop, the line is "un-deferred"... your roll constructions are now visible to the Roll20 parsers, and ZeroFrame sends the message through them again to get your roll. The command line with the deferred roll would look like this: !Spawn --name|Corman Alfar --offset|-2,0 --side|[\][\]@(selected.currentSide) + 1 \]\] Try that, and you shouldn't receive an error. If you want to bound the resulting side to a number that is within the range of available sides (that is, you don't set the currentside to a value that is out of scope), Fetch also provides a sidescount property for the token. With that, you could do a "keep low" operation in your roll: [\][\] {[\][\]@(selected.currentside) + 1\]\], @(selected.sidescount)}kl1 \]\] Untested, but you get the idea!
Dumbhuman said: Thank you for the suggestion.  From what I've read thus far, Fetch looked to be exactly what I need, but now I feel a little like Gretchen failing "to make fetch happen".  I wish I had something to help you, but I just had to give you way less credit than you deserve for that reference. Good luck!
1718938461
Dumbhuman
Pro
Marketplace Creator
timmaugh said: Dumbhuman, yes, you can use an inline roll. You just have to defer it one time. Basically, you need to "hide" the roll syntax (the double brackets) from the Roll20 parsers so that the Script Moderator hands the message off to the scripts... then Fetch has time to return the value (since this would come after the Roll20 parsing). After that, because ZeroFrame runs in a loop, the line is "un-deferred"... your roll constructions are now visible to the Roll20 parsers, and ZeroFrame sends the message through them again to get your roll. Okay, so it sounds like it's either MathOps or ZeroFrame needed in addition to Fetch (and its dependencies) to get this working.  In that case, I'll opt for MathOps since that syntax seems easier for me to parse as the Dumbhuman I am.  I'm new to the whole meta-script world, so it'll be baby steps for now, but thanks for making even greater things possible! Dr DM said: Dumbhuman said: Thank you for the suggestion.  From what I've read thus far, Fetch looked to be exactly what I need, but now I feel a little like Gretchen failing "to make fetch happen".  I wish I had something to help you, but I just had to give you way less credit than you deserve for that reference. Good luck! Just expressing an appreciation for a silly reference is always helpful enough!
1718939489
timmaugh
Pro
API Scripter
I would still install the full Metascript Toolbox (you can find it in the 1-click). It packages up all of the metascripts and other dependencies. I suggest that chiefly because ZeroFrame sets an order to the progression of the metascripts, and a way to change that order. Without ZeroFrame, the metascripts will operate in the order you have them installed... which might be a problem. In your case, you need MathOps to do math on an item returned by Fetch. That means that you need Fetch to resolve *first*, then MathOps. If you happen to have MathOps installed first, however, it will try to perform math before Fetch has returned the value. But, even if you have them installed correctly for *this* command... next time you might want to pull an item off a game object using Fetch... but you want to determine the item to pull using a math operation. That would mean you'd need MathOps to complete first, then Fetch. Having ZeroFrame installed means that you have a default run order, no matter what the installation order is for the metascripts (it happens to be that Fetch runs before MathOps). It also means that if you wanted to slow a Fetch construction down until a MathOps construction had processed, you could (with deferrals). It also ALSO means that you could *re-order* the metascripts to run in a different sequence for a given message, if you needed to. There are a lot of benefits to installing the full toolbox, even if you don't explicitly need every script for this or that particular command.
1718997567
Dumbhuman
Pro
Marketplace Creator
I went ahead and installed Metascript Toolbox from the drop down menu and it prompted me to install the other dependencies (not MathOps and Fetch plus its three dependencies since I already had those).  I'm still running into some trouble, which I'm guessing is an order of operations problem that perhaps could be fixed with some ZeroFrame syntax.  The ability macro I'm triggering contains two API calls: !Spawn {{   --name| Strahd Zombie Head   --rotation| random   --placement| random 3   --offset| -1,-.7   --side| {&math @(selected.currentSide) + 1} }} !Spawn {{   --name| Strahd Zombie LostHead   --bar3| [[@{selected|bar3}]]/30   --deleteSource| yes   --side| {&math @(selected.currentSide) + 1} }} The first one always runs, creating the head set to the specific side I want which is great!  The second one sometimes runs and sometimes doesn't... which isn't so great.  This intermittent failure is new behavior that wasn't present before the metascript syntax was added, which is why I expect there's probably an easy metascript solution to it that I'm just not familiar with yet. Gif showing the issue and how it seems to happen randomly regardless of which side the original token is using:
1719001882
timmaugh
Pro
API Scripter
You are likely running into the dropped command line bug ... and, yes, there is a way to work around that. If you batch those commands up with ZeroFrame batching syntax , they become a single command which ZeroFrame then parses out and issues independently. Before you do that, you definitely want to configure SelectManager to give back properties to Spawn. Run this command one time in your game: !smconfig +playerid +who Spawn requires those properties to be filled with player information, and if ZeroFrame issues the Spawn command itself (rather than you doing it directly), we lose those properties. By running the above command, you configure SelectManager to give the properties back to the message before Spawn sees it. Then, doing the changes that are required for batching, your command would look more like: !{{ !Spawn ({)   --name| Strahd Zombie Head   --rotation| random   --placement| random 3   --offset| -1,-.7   --side| {&math @(selected.currentSide) + 1} (}) !Spawn ({)   --name| Strahd Zombie LostHead   --bar3| [[@{selected|bar3}]]/30   --deleteSource| yes   --side| {&math @(selected.currentSide) + 1} (}) }} Give that a run and see if you have better luck!
1719018550
Dumbhuman
Pro
Marketplace Creator
timmaugh said: Give that a run and see if you have better luck! Thank you very much!  Everything seems to be working well now and rewriting all those macros even helped me fix a few existing errors in the chain.  Just in time for game night too!