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 .
×
Pre-order D&D 2024 now and get an exclusive bonus, only on Roll20!
Create a free account

[Help] GroupCheck—Using ability mod if skill mod is empty

I'd like to set up groupcheck so that if an NPC doesn't have a modifier for a given skill, then it instead uses the relevant ability modifier. For example: !group-check-config --add { "Stealth" : { "name" : "Stealth", "formula" : "\[1d20 + (\at{stealth})\]"} } If an NPC's stealth attribute is empty (not just 0), is there a way to configure this so it'll use \at{dexterity_modifier} in its place? I tried using a {}k1 function and a max() function, but the former didn't work well with empty values or negative modifiers and the latter didn't work at all.
1612619238

Edited 1612621282
timmaugh
Pro
API Scripter
Seems like an opportunity for APILogic. !group-check-config --add { "Stealth" : { "name" : "Stealth", "formula" : "\[1d20 + (\at{{& if @{Selected|stealth} != '' && @{Selected|stealth} > 0}stealth{& else}dexterity_mofifier{& end}})\]"} } I typed this from my phone, so hopefully I didn't mess it up. Also, I went with "selected", where you might want to go another way (explicitly reference the particular NPC. EDIT : Testing showed I had to use 2 conditions: 1) testing that it wasn't an empty string, and 2) testing that it was greater than 0. The above line has been altered to incorporate both tests. EDIT 2 : Just posting to say I'm not familiar enough with groupcheck to know if I've adequately addressed the problem. Does it create checks for multiple characters/NPCs at once, so an @{Selected} isn't the best solution? I will have to leave it to you to bring that expertise and shape the command line as necessary.
@timmaugh, I'm getting a crash with this error after installing libInline ReferenceError: Cannot access 'apiproject' before initialization Unfortunately I don't think that'll work for this situation anyway. The command I shared is only to configure the formula for future use, and when the script uses the formula later it's usually for multiple selected NPCs at once (that's why it uses the \at{attr} format, as it duplicates the formula as [[1d20 + (@{stealth})]] for each token). The actual command used that calls the formula would look like !group-check --whisper --Stealth That's why I'm hoping that either     a) there's a more efficient math function than {}k1 that will account for empty values     b) there's a way to do this that's built into the GroupCheck script I appreciate the suggestion tho!
1612652824
timmaugh
Pro
API Scripter
First, thanks for the catch on libInline. Some sloppy last minute formatting for submission to the 1-click, there. It's fixed in my repo and in the pull request to the Roll20 repo. Second, I should have taken time to wake up before I answered your post. I realized after I'd posted what you were trying to get GroupInit to do... and, you're right... that part of the script (passing over each token) is handled internally to that script, and it means APILogic won't help, there. ...but... I did try this formation in the chat, and it worked (attributes are slightly different because of a different system, but you get the idea): [[ {@{Heretic|stealth}+1-1, @{Heretic|DEX}}k1]] That works whether stealth is 0, empty, or negative. However, it does always return the larger of the 2 values... which might not be a problem for you.
1612658145
Oosh
Sheet Author
API Scripter
Persephone said: I'd like to set up groupcheck so that if an NPC doesn't have a modifier for a given skill, then it instead uses the relevant ability modifier. For example: !group-check-config --add { "Stealth" : { "name" : "Stealth", "formula" : "\[1d20 + (\at{stealth})\]"} } If an NPC's stealth attribute is empty (not just 0), is there a way to configure this so it'll use \at{dexterity_modifier} in its place? I tried using a {}k1 function and a max() function, but the former didn't work well with empty values or negative modifiers and the latter didn't work at all. Did you try with the leading 0 trick? I'm not familiar with group-check's escaping requirements, but something like: {0\at{stealth}, 0\at{dexterity_modifier}}k1 That should prevent empty Attributes from crashing R20's math parser.
timmaugh said: [...] However, it does always return the larger of the 2 values... which might not be a problem for you. That's another reason the k1 function won't work out either, sadly, even if using one of those tricks to treat an empty value as 0. If an empty skill mod is treated as zero but the NPC has a negative ability mod, the roll would use 0, which is basically the same behaviour that is currently happening: NPCs an empty skill mod just roll a flat d20. Ideally, I'd want it to check if the skill mod is empty for each NPCs roll, and for those with empty mods, use a specified ability mod as a fallback value.
1612664090
timmaugh
Pro
API Scripter
I can see a way that a scriptlet could solve that problem. If it performed a check for each NPC, tested which of those mods to use, and copied to a new attribute of some name. Run it whenever you need to initialize any NPC. Have GroupCheck set up to use the new attribute....
1612669202

Edited 1612669282
Oosh
Sheet Author
API Scripter
Hrmmm, I think this works: [[[[ceil(abs((0@{selected|stealth})/1000))*(0@{selected|stealth})]][STL] + [[abs(ceil(abs(0@{selected|stealth}/1000)-1))*(0@{selected|dexterity_modifier})]][DEX]]] There's a load of parentheses in there... the leading zero stops empty values from crashing the roll, but then you need to wrap it, otherwise a negative value for the Attribute will give "0-2", and the subtraction gets bumped down the order of operations, spoiling the drinking water. Aaaaanyway, I think this works? Any non-zero value of stealth, between -1000 and +1000, will give the second part of the equation a value of zero, and return the value of @{stealth}. A zero or blank value for @{stealth} should return the value of @{dexterity_modifier}. Maaaaaybe..... :) .... and a scriptlet would probably be prettier....
1612677329

Edited 1612677401
@Oosh, thank you! That's doing just what I wanted :) I knew there had to be a way to do it with math, I super appreciate you figuring that out! Now I've got this to config GroupCheck for PF2e, if anyone's interested: !group-check-config --add { "Perception" : { "name" : "Perception", "formula" : "\[1d20 + (\[ceil(abs((0\at{perception})/1000))*(0\at{perception})\] + \[abs(ceil(abs(0\at{perception}/1000)-1))*(0\at{wisdom_modifier})\])\]"} } ! !group-check-config --add { "Stealth" : { "name" : "Stealth", "formula" : "\[1d20 + (\[ceil(abs((0\at{stealth})/1000))*(0\at{stealth})\] + \[abs(ceil(abs(0\at{stealth}/1000)-1))*(0\at{dexterity_modifier})\])\]"} } ! !group-check-config --add { "Fortitude" : { "name" : "Fortitude", "formula" : "\[1d20 + (\at{saving_throws_fortitude})\]"} } ! !group-check-config --add { "Reflex" : { "name" : "Reflex", "formula" : "\[1d20 + (\at{saving_throws_reflex})\]"} } ! !group-check-config --add { "Will" : { "name" : "Will", "formula" : "\[1d20 + (\at{saving_throws_will})\]"} } ! !group-check-config --add { "Diplomacy" : { "name" : "Diplomacy", "formula" : "\[1d20 + (\[ceil(abs((0\at{diplomacy})/1000))*(0\at{diplomacy})\] + \[abs(ceil(abs(0\at{diplomacy}/1000)-1))*(0\at{charisma_modifier})\])\]"} } ! !group-check-config --add { "Deception" : { "name" : "Deception", "formula" : "\[1d20 + (\[ceil(abs((0\at{deception})/1000))*(0\at{deception})\] + \[abs(ceil(abs(0\at{deception}/1000)-1))*(0\at{charisma_modifier})\])\]"} } ! !group-check-config --add { "Acrobatics" : { "name" : "Acrobatics", "formula" : "\[1d20 + (\[ceil(abs((0\at{acrobatics})/1000))*(0\at{acrobatics})\] + \[abs(ceil(abs(0\at{acrobatics}/1000)-1))*(0\at{dexterity_modifier})\])\]"} } ! !group-check-config --add { "Arcana" : { "name" : "Arcana", "formula" : "\[1d20 + (\[ceil(abs((0\at{arcana})/1000))*(0\at{arcana})\] + \[abs(ceil(abs(0\at{arcana}/1000)-1))*(0\at{intelligence_modifier})\])\]"} } ! !group-check-config --add { "Athletics" : { "name" : "Athletics", "formula" : "\[1d20 + (\[ceil(abs((0\at{athletics})/1000))*(0\at{athletics})\] + \[abs(ceil(abs(0\at{athletics}/1000)-1))*(0\at{strength_modifier})\])\]"} } ! !group-check-config --add { "Crafting" : { "name" : "Crafting", "formula" : "\[1d20 + (\[ceil(abs((0\at{crafting})/1000))*(0\at{crafting})\] + \[abs(ceil(abs(0\at{crafting}/1000)-1))*(0\at{intelligence_modifier})\])\]"} } ! !group-check-config --add { "Intimidation" : { "name" : "Intimidation", "formula" : "\[1d20 + (\[ceil(abs((0\at{intimidation})/1000))*(0\at{intimidation})\] + \[abs(ceil(abs(0\at{intimidation}/1000)-1))*(0\at{charisma_modifier})\])\]"} } ! !group-check-config --add { "Medicine" : { "name" : "Medicine", "formula" : "\[1d20 + (\[ceil(abs((0\at{medicine})/1000))*(0\at{medicine})\] + \[abs(ceil(abs(0\at{medicine}/1000)-1))*(0\at{wisdom_modifier})\])\]"} } ! !group-check-config --add { "Nature" : { "name" : "Nature", "formula" : "\[1d20 + (\[ceil(abs((0\at{nature})/1000))*(0\at{nature})\] + \[abs(ceil(abs(0\at{nature}/1000)-1))*(0\at{wisdom_modifier})\])\]"} } ! !group-check-config --add { "Occultism" : { "name" : "Occultism", "formula" : "\[1d20 + (\[ceil(abs((0\at{occultism})/1000))*(0\at{occultism})\] + \[abs(ceil(abs(0\at{occultism}/1000)-1))*(0\at{intelligence_modifier})\])\]"} } ! !group-check-config --add { "Performance" : { "name" : "Performance", "formula" : "\[1d20 + (\[ceil(abs((0\at{performance})/1000))*(0\at{performance})\] + \[abs(ceil(abs(0\at{performance}/1000)-1))*(0\at{charisma_modifier})\]))\]"} } ! !group-check-config --add { "Religion" : { "name" : "Religion", "formula" : "\[1d20 + (\[ceil(abs((0\at{religion})/1000))*(0\at{religion})\] + \[abs(ceil(abs(0\at{religion}/1000)-1))*(0\at{wisdom_modifier})\])\]"} } ! !group-check-config --add { "Society" : { "name" : "Society", "formula" : "\[1d20 + (\[ceil(abs((0\at{society})/1000))*(0\at{society})\] + \[abs(ceil(abs(0\at{society}/1000)-1))*(0\at{intelligence_modifier})\])\]"} } ! !group-check-config --add { "Survival" : { "name" : "Survival", "formula" : "\[1d20 + (\[ceil(abs((0\at{survival})/1000))*(0\at{survival})\] + \[abs(ceil(abs(0\at{survival}/1000)-1))*(0\at{wisdom_modifier})\])\]"} } ! !group-check-config --add { "Thievery" : { "name" : "Thievery", "formula" : "\[1d20 + (\[ceil(abs((0\at{thievery})/1000))*(0\at{thievery})\] + \[abs(ceil(abs(0\at{thievery}/1000)-1))*(0\at{dexterity_modifier})\])\]"} } !