The Aaron said:
Note that if TokenMod does not show the Custom Token Markers, you probably still need to upload them to the game on the Game Details page.
Would that also be the case if libTokenMarkers isn't installed?
The Aaron said:
Note that if TokenMod does not show the Custom Token Markers, you probably still need to upload them to the game on the Game Details page.
Would that also be the case if libTokenMarkers isn't installed?
So I'm having some issues with understanding how to do something specific, or if it's even possible to do this.
I have a value, let's call it Sprite, of 100 out of 100. Whenever someone uses an ability or skill it will remove 5 Sprite.
Sprite is set as Bar 3 and HP is Bar 1.
I want to be able to adjust the Token's Bar 3 "Sprite" to get reduced when using a skill, while still being able to target another Token for clarification.
So example: "Oliver casts Fireball on Rogue!" Fireball removes 5 Sprite from Oliver's Bar 3, but also removes 8d6 from Rogue's Bar 1.
How would I do that?
Joyishi said:
So I'm having some issues with understanding how to do something specific, or if it's even possible to do this.
I have a value, let's call it Sprite, of 100 out of 100. Whenever someone uses an ability or skill it will remove 5 Sprite.Sprite is set as Bar 3 and HP is Bar 1.
I want to be able to adjust the Token's Bar 3 "Sprite" to get reduced when using a skill, while still being able to target another Token for clarification.
So example: "Oliver casts Fireball on Rogue!" Fireball removes 5 Sprite from Oliver's Bar 3, but also removes 8d6 from Rogue's Bar 1.
How would I do that?
Does this work?
!token-mod --set bar3_current|-5 --ids @{selected|token_id} --set bar1_current|-[[8d6]] --ids @{target|token_id}
vÍnce said:
Does this work?
!token-mod --set bar3_current|-5 --ids @{selected|token_id} --set bar1_current|-[[8d6]] --ids @{target|token_id}
It removes bar1 and bar3 for both tokens instead of just bar3 for Oliver and bar1 for Rogue.
But it DOES work at least more than what I tried so thank you so much!
My bad. I only dabble in tokenmod. There's soooo many features and uses.
Maybe try splitting into two commands (one macro but a command on each line)
!token-mod --set bar3_current|-5 --ids @{selected|token_id}
!token-mod --set bar1_current|-[[8d6]] --ids @{target|token_id}
vÍnce said:
My bad. I only dabble in tokenmod. There's soooo many features and uses.
Maybe try splitting into two commands (one macro but a command on each line)!token-mod --set bar3_current|-5 --ids @{selected|token_id}
!token-mod --set bar1_current|-[[8d6]] --ids @{target|token_id}
YES Thank you this works like a charm!
Though I did find a pretty annoying bug. If you're using this with "&{template:default}" stuff, make sure the macro is only useable with "Show as Token Action" so players don't accidentally try to macro it without having their token selected. As using both together without having the token selected will glitch the chat and make it to where nobody can talk in the chat box or use other macros without rollbacking the game.
That should not be within the reach of a script. What was the command you used, and what was the behavior you saw? Did you try rebooting the API sandbox before you went so far to roll back the game?
That's weird, I'll have to try and repro that. When the chat breaks, clearing chat usually fixes it.
timmaugh said:
That should not be within the reach of a script. What was the command you used, and what was the behavior you saw? Did you try rebooting the API sandbox before you went so far to roll back the game?
Yes, I did try rebooting the API and it was still broken.
The Aaron said:
That's weird, I'll have to try and repro that. When the chat breaks, clearing chat usually fixes it.
I didn't try clearing the chat, sadly I'm still new to Roll20 so I didn't know I could do that until after I rolled back. Sorry about that.
I had the macros as "Show in Macro Bar" so the players could see and use them whenever.
As for the code, I used this:
&{template:default} {{name=@{name} uses Scratch}} {{Type=Normal, Melee}} {{Hunger= -1}} {{Action= @{Name} scratches @{target|name}!}} {{Accuracy= [[1d20 + @{Prof}[Prof] + @{Str}[Str]]]}} {{Damage= [[1d6 + @{Str}]]}} !token-mod --set bar3_current|-1 --ids @{selected|token_id} !token-mod --set bar1_current|-[[1d6]] --ids @{target|token_id}
But there was a moment where I accidentally clicked the macro without having a token selected and still proceeded to select a target and that's when chat broke for me.
You don't have the right syntax. It should be:
!token-mod --set statusmarkers|+Concentration::3239103
It will affect selected tokens by default. I added + so it adds the status marker instead of replacing all current ones with that one.
If you want to toggle, you can do:
!token-mod --set statusmarkers|!Concentration::3239103
You can find more help in the TokenMod help handout, or by running:
!token-mod --help
Hi there.
Any way to add an IF into the current side?
Basically, a mage has multiple effects and I've set a multisided token for the different mixtures, and I was curious if I could have a side change based on the current side.
So if 1 is nothing, 2 is Shadowblade, 3 is Shield and Shadowblade, and 4 is Shield.
I'd like to use a 'removeShield' macro and either +1 to 1 or -1 to 2 based on the currentside value at the time.
If there is already a way to do this, I haven't seen it.
I don't believe there's a way to do this just using TokenMod.
Using ZeroFrame, APILogic, and Fetch you could use [have not tested]:
!{& define ([CurSide] @(selected.currentside))}tokenmod --set currentside|{& if CurSide = 2}1{& elseif CurSide = 3}0{& else}CurSide{& end}
This does 4 things:
One thing you should make sure to remember is that token sides are 0-indexed, so the "base" side is 0.
Colin C. said:
I don't believe there's a way to do this just using TokenMod.
Using ZeroFrame, APILogic, and Fetch you could use [have not tested]:
!{& define ([CurSide] @(selected.currentside))}tokenmod --set currentside|{& if CurSide = 2}1{& elseif CurSide = 3}0{& else}CurSide{& end}
This looks right to me, too -- to remove shield, you'd go from (as Essen described the token) Side 3 (Shield) to Side 0 (nothing), and you'd go from Side 2 (Shield & Shadowblade) to Side 1 (Shadowblade).
Hey Aaron - been a long time. I was wondering if there was a way to erase a token a marker across all tokens on the screen. I use yellow orb when a player is done with their turn and at the end of the round, I would like to press a single button and erase the yellow orb across all tokens.
Thank you sir!!
Hmm. Not with TokenMod, but possibly with a Meta Script, or I can write you a one-off for it tomorrow.
The best that I can do with a metascript would be to come up with the list of tokens that might need to be affected by this command, and include them in a SelectManager {& select ... } statement. Basically, that would "virtually" select those tokens for the purposes of TokenMod. By the time TM saw the message, the tokens would be in the "selected" state, and TM could act to remove the yellow circle.
The {& select ... } statement takes a comma separated list of token identifiers... that could be IDs or names.
{& select Brutus, Puffmallow, Wonkadoo McAllister}
Install SelectManager and drop that anywhere in your TokenMod command line, and those tokens will be selected, if they are found.
That isn't the "select the current set of all tokens on the page" level of ad hoc-ness, but it does get you away from having to physically select the tokens. Truly ad hoc selection would require the Query metascript, which I haven't finished/release yet.
Here's a little snippet that will do the clearing:
!clear-marker --yellow
You can specify multiple if you like. be sure to use the tag form of the status marker if you're using custom token markers:
!clear-marker --blue --yellow --something::1341512
Code:
on('ready',()=>{ const getPageForPlayer = (playerid) => { let player = getObj('player',playerid); if(playerIsGM(playerid)){ return player.get('lastpage') || Campaign().get('playerpageid'); } let psp = Campaign().get('playerspecificpages'); if(psp[playerid]){ return psp[playerid]; } return Campaign().get('playerpageid'); }; const unpackSM = (stats) => stats.split(/,/).reduce((m,v) => { let p = v.split(/@/); let n = (undefined === p[1] ? true : parseInt(p[1] || '0', 10)); if(p[0].length) { m[p[0]] = n; } return m; },{}); const packSM = (o) => Object.keys(o) .reduce( (m,k)=> (false===o[k] ? m : [...m,( ('dead'===k || true === o[k]) ? k : `${k}@${Math.max(Math.min(parseInt(o[k]),9),0)}` )] ) ,[]) .join(','); const clearStatuses = (o,ss) => { let sm = unpackSM(o.get('statusmarkers')); ss.forEach(s=>delete sm[s]); o.set('statusmarkers',packSM(sm)); }; on('chat:message',msg=>{ if('api'===msg.type && /^!clear-marker(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){ let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'); let pageid = getPageForPlayer(msg.playerid); let ss = msg.content.split(/\s+--/).slice(1); if(ss.length){ findObjs({ type:'graphic', pageid }) .filter(g=>(['objects','gmlayer'].includes(g.get('layer')) && '' !== g.get('represents'))) .forEach(g=>clearStatuses(g,ss)); } else { sendChat('',`/w "${who}" <div><b>Usage:</b> <code>!clear-marker --[status name] [--[status name] ...]</code></div>`); } } }); });
You could also try this, using ScriptCards and SelectManager:
!script {{ --#hideCard|1 --~CharTokens|array;pagetokens;@{selected|token_id};char --#parameterdelimeter|, --~TIDs|array;stringify;CharTokens --@token-mod|{^&select [&TIDs]} --set statusmarkers|-yellow }}
That should grab all tokens on the board and remove yellow statusmarkers from them all.
Hello “The Aaron’
Some help please,
I have seen it in many api and in yours.
When I enter in chat the command “!token-mod --flip lockMovement” or any command it works fine – no problems.
When I try to use it inside another custom api with the use of the “sendChat("info", "!token-mod --flip lockMovement ");” it will not work.
I think it is because when I execute it, I am the GM, when the “sendChat” use it it could be anyone…
Any idea how to overcome this?
Thank you!
To call it from a Mod Script, you either need to turn on Players Can IDs and pass an ID in:
Do this once to set the configuration
!token-mod --players-can-ids
Call from a Mod Script with an ID:
sendChat("info", `!token-mod --flip lockMovement --ids ${SomeTokenIDVariable}`);
Or, you need to pass a player ID to treat as the calling player:
sendChat("info", `!token-mod --flip lockMovement --api-as ${SomePlayerIDVariable} --ids ${SomeTokenIDVariable}`);
Either way, you must pass one or more ids to act on. Mod Scripts that call Mod Script Commands won't have a selected array to operate on.
All that said, if you're writing a script, there's no reason you need to depend on TokenMod to manipulate properties on a token. You can just do it directly:
on('ready',()=>{ on('chat:message',msg=>{ if('api'===msg.type && /^!flip-lock(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){ (msg.selected || []) .map(o=>getObj('graphic',o._id)) .filter(g=>undefined !== g) .forEach(t => t.set("lockMovement", ! t.get("lockMovement"))) ; } }); });
That's a bit harder proposition. There are a few problems to solve to make it happen:
on('ready',()=>{ const buildArgs = (str) => { let firstWhitespace = str.search(/\s/); if(-1 === firstWhitespace){ return [str]; } return [str.slice(0,firstWhitespace),str.slice(firstWhitespace+1)]; }; const keyFormat = (text) => (text && text.toLowerCase().replace(/\s+/g,'')) || undefined; const fuzzyNameMatch = (p,n) => RegExp(`${keyFormat(p)}`,'i').test(keyFormat(n)); const getPlayerByName = (n) => findObjs({type:"player"}).filter(p=>fuzzyNameMatch(n,p.get("_displayname")))[0]; const setControlledBy = (t,pid) => { let c = getObj('character',t.get('represents')); if(c) { let cb = c.get('controlledby'); c.set('controlledby',[...new Set([...(cb?cb.split(/,/):[]),pid])].join(',')); } else { let cb = t.get('controlledby'); t.set('controlledby',[...new Set([...(cb?cb.split(/,/):[]),pid])].join(',')); } }; on('chat:message',msg=>{ if('api'===msg.type && /^!add-player-control(\b\s|$)/i.test(msg.content) && playerIsGM(msg.playerid)){ let who = (getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'); let args = buildArgs(msg.content).slice(1); if(args.length){ let p = getPlayerByName(args[0]); if(p){ (msg.selected || []) .map(o=>getObj('graphic',o._id)) .filter(g=>undefined !== g) .forEach(t=>setControlledBy(t,p.id)) ; } else { sendChat('',`/w "${who}" <div><code><b>Error:</b> No player found that matches "${args[0]}".</code></div>`); } } else { sendChat('',`/w "${who}" <div><b>Usage:</b> <code>!add-player-control <Player Name Fragment></code></div>`); } } }); });
!add-player-control bob the slayer
Im not a scripter but i have been messing around with this and I love it. I have hit a wall though and maybe you have covered it already, and i appreciate the time for your help.
I have a macro written with Ispawn, that i would like to include separate status markers to the caster based on the spell that is cast.
!Spawn {{
--name| Area Attack Marker
--offset|1,0
}}
!Spawn{{
--name|?{Which Cantrip?|Control Flames|Create Bonfire}
--targets|1
--qty|1
--fx|?{Cantrip FX?|Control Flames,explode-fire|Create Bonfire,explode-fire}
--light|10,0
--order|tofront
--force|yes
--expand|10,50
--deleteTarget|true
--layer|?{Cantrip Layer?|Control Flames,tok|Create Bonfire,map}
}}
!splay Magic 2
/fx burst-magic @{selected|token_id}
is there away to apply or remove a different statusmarker automatically to the caster token based on the spell that is chosen from the dropdown list?
Not directly with TokenMod. It would be easier to write a 1-off script that could translate the text from ?{Which Cantrip?} into a status marker to set.
UnicornCoatrack said:
is there away to apply or remove a different statusmarker automatically to the caster token based on the spell that is chosen from the dropdown list?
Using a metascript like Muler, a query response can be turned into a different value -- like a second meaning for the query's response. There's a good example of a potential usage already in your code: you pick the Cantrip first, then you pick the FX, but those are a static 1:1 relationship. You can get that to a single query just by storying the second set of data as values associated with your cantrip list. You'd set up your list of cantrips exactly matching the options for the query, and set them equal to their desired fx (in this case):
Control Flames=explode-fire
Create Bonfire=explode-fire
You chose the same FX for each of these, above, but you could choose whichever you want.
Then just drop that in the appropriate place in your Spawn:
!Spawn {{
--name|?{Which Cantrip?|Control Flames|Create Bonfire}
...
--fx|get.mulecharacter.fxtable.?{Which Cantrip}/get.
...
}}{&mule mulcharacter.fxtable}
There's a little more setup than that, but that gets the point across. By the time Spawn sees the message, the Muler code will have rendered down to the selections you want.
I got things to work!!
/w gm &{template:desc} {{desc=**Spell Status Conditions**
[Control Flames](!token-mod --set statusmarkers#!ControlFlames)
[Create Bonfire](!token-mod --set statusmarkers#!Concentration --set statusmarkers#!CreateBonfire)
[Druidcraft](!token-mod --set statusmarkers#!Druidcraft)
[Frostbite](!token-mod --set statusmarkers#!Frostbite)
[Guidance](!token-mod --set statusmarkers#!Concentration --set statusmarkers#!Guidance)
[Gust](!token-mod --set statusmarkers#!Gust)
[Infestation](!token-mod --set statusmarkers#!Infestation)
Now the next question how can i use !roll20AM within the same table without breaking it? I have a separate start of a table but would prefer only one table with either one button or two buttons for each spell. I am slowly building a single Macro that incorporates all of the cantrips of a druid in a single table slowly getting there. Below is the table for sound effects:
/w gm &{template:desc} {{desc=**Spell Audio**
[Control Flames](!roll20AM --nomenu,audio,play|Fire)
[Create Bonfire](!roll20AM --!roll20AM --nomenu,audio,play|Fire)}}
UnicornCoatrack said:
Now the next question how can i use !roll20AM within the same table without breaking it? I have a separate start of a table but would prefer only one table with either one button or two buttons for each spell. I am slowly building a single Macro that incorporates all of the cantrips of a druid in a single table slowly getting there. Below is the table for sound effects:
/w gm &{template:desc} {{desc=**Spell Audio**
[Control Flames](!roll20AM --nomenu,audio,play|Fire)
[Create Bonfire](!roll20AM --!roll20AM --nomenu,audio,play|Fire)}}
You might look into Plugger, a metascript that will let you embed one command (your roll20AM line) in another (your token-mod line). Your button is going to dispatch 1 message event, but the metascript will detect the embedded r20am syntax and dispatch a second message while removing that syntax from the TM command before TM sees it.
Hi im struggling with what should be a simple macro.
im using a set up where all players can see the same screen, so to show them what each token can see im using
!token-mod --Flip light_hassight
as a token action, but its having no effect.
i have the token mod api installed and i am pro sub.
any ideas?
Tim said:
Hi im struggling with what should be a simple macro.
im using a set up where all players can see the same screen, so to show them what each token can see im using
!token-mod --Flip light_hassightas a token action, but its having no effect.
i have the token mod api installed and i am pro sub.
any ideas?
Who controls the token that is receiving this command? If it is linked to a character sheet, who has edit permissions to the sheet? Basically, if the players don't have the correct permissions for the token, giving it sight won't change what they are able to see.
Update v0.8.75 -- Changing bars that are linked will now make the change on the attribute using setWithWorker() to force sheet worker updates. (Thanks vÍnce )
light_hassight is an LDL setting. If you're using UDL, you'll want to be setting has_bright_light_vision (or the alias bright_vision):
!token-mod --flip has_bright_light_vision
Also, TokenMod is case sensitive, so --Flip won't work, it needs to be --flip.
Tim said:
Hi im struggling with what should be a simple macro.
im using a set up where all players can see the same screen, so to show them what each token can see im using
!token-mod --Flip light_hassightas a token action, but its having no effect.
i have the token mod api installed and i am pro sub.
any ideas?
Hi All,
Can someone help me on that silly stuff ??
I'm trying to affect a custom statusmarker with a number to a a token using this :
!token-mod{{
--set
statusmarkers|+Bard::5422520:3
-- ids
@{target|token_id}
}}
And it doesn't seem to work...
Is there a trick with the double columns ?
I tried without the targeting, no change..
You need to have a space after !token-mod:
!token-mod {{
--set
statusmarkers|+Bard::5422520:3
--ids
@{target|token_id}
}}
Also, take the space out after -- before ids. It seems like it works with a space, but I wouldn't count on that behavior continuing, it's not supposed to.
hey, out of curiosity
i try to change the bar layout of my tokens, but when i try to change it in one command, it apply values of new stat in previous barlink stat, is there a way to do this sequentially to prevent this or i didn't read enough ?
this is my command line
!token-mod --set bar1_link| bar2_link| bar3_link| bar1_reset| bar2_reset| bar3_reset| bar1_link|health-displayed bar2_link|displayed-essence bar3_link|willpower showplayers_bar1|1 playersedit_bar1|0 showplayers_bar2|1 playersedit_bar2|0
Thanks for all the work, your script is a huge part of my automatisation x)
The way TokenMod works is largely by building up a large single change object which is then applied to the token. For the most part, that means that if you explicitly set something, a future change in the same command will overwrite it. For example:
!token-mod --set statusmarkers|=blue statusmarkers|=red
Will result in a red mark, but no blue mark.
There are a few exceptions (setting defaultoken will force an intermediate update so that the token will have the snapshot taken at the point where all prior changs have been made, but future changes have not), but that's basically how it operates.
For the above, I would suggest breaking this across a few commands to make sure things happen the way you want them to:
!token-mod {{ --set bar1_link| bar2_link| bar3_link| bar1_reset| bar2_reset| bar3_reset| }} !token-mod {{ --set bar1_link|health-displayed bar2_link|displayed-essence bar3_link|willpower showplayers_bar1|1 playersedit_bar1|0 showplayers_bar2|1 playersedit_bar2|0 }}
I love this mod - thank you so much for all your efforts!
How would I select all player tokens with !token-mod?
I'm wanting to take actions via macros to all the player tokens on the current screen - e.g. flip the lock status etc
Hmm. There's not a great automated way to do it, but you could use the character ids:
!token-mod {{ --flip lockMovement --current-page --ids @{Bob the slayer|character_id} @{Tim the mage|character_id} @{The Aaron|character_id} }}
That will select all the tokens for those characters that are on the current page. If you split the party and want to flip the lock on them across pages, you can use --active-pages instead of --current-page.
For a quick application, if one at a time:
!token-mod {{
--flip lockMovement
--current-page
--ids
@{selected|character_id}
}}
The Aaron said:
The way TokenMod works is largely by building up [...]
Thanks a lot dear sir !
Each day i use more and more TokenMod, so you deserve a huge thanks for that, and even more for all the help you provide on this forum :)
Have a great day