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

(Help) Compare a value and execute a macro depending on if equal or not

December 28 (2 years ago)

Edited December 28 (2 years ago)

Hi! APIs still confuse me a lot, so I need a bit of help here. (Bear with my formatting, I'm on mobile). 


Im working with the official dnd 5e sheets, however im currently Homebrewing my own thing. Imagine something similar to Pokemon, where each creature has a type, noted in @{type}. There are also attacks, which also have types. Since custom compendiums aren't a thing yet I decided to write macros for each attack and simply execute those using @{selected} to fill in the necessary stats. However, I'm stuck on a specific part. 


If the type of @{selected} matches the type of the attack (which are simple numerical values from 1-18), I want to apply a damage bonus which is written down in @{class_resource}. If the type doesn't match the attack, this bonus isnt applied. 


To somehow phrase my thoughts, I want to do something like this:


Damage = [[

If @{selected|type} = 1

Then: 2d8 + @{selected|class_resource}

Else: 2d8 ]] 


Alternatively something like


If @{selected|type} = 1

Then: #macro1

Else: #macro2


What APIs would I have to use to make this happen? 


December 28 (2 years ago)
Gauss
Forum Champion

You may not need an API for this. A macro can probably do it. 

If @{selected|type} is 1 the result is macro 1? 
If @{selected|type} is 2-18 the result is macro 2?

December 28 (2 years ago)
timmaugh
Forum Champion
API Scripter

As Gauss says, if it's simple enough, a macro can do this for you. That said, a mod can help you to abstract things a bit, and maybe cut down on the number of macros you need.

ScriptCards can do a lot of this, or you can go with metascripts like APILogic (for conditionals) and ZeroFrame (for roll management and outputting)... and then optionally using maybe Fetch (for attribute retrieval) and/or Muler (for more complex table lookups).

![\][\]2d8{&if @{selected|type} = 1} + @{selected|class_resource}{&end} \]\]{&simple}

That is a simple example using APILogic and ZeroFrame, including the class_resource if the type matches. But if the mechanic is that the attacker's attack has a type, and the defending character/creature has a type, and it is simply the comparison of those two things, then you might be able to use both the selected token (for the attacker) and a targeted token (for the defender), and automate the check. That would have you down to a single macro for everything.

Here is a thread where I helped someone with something similar... the syntax might seem abstract because that thread is not solving your problem, but hopefully the examples are clear enough to demonstrate the sort of things you can do with metascripts.


December 28 (2 years ago)

Edited December 28 (2 years ago)
GiGs
Pro
Sheet Author
API Scripter

Macros can't usually do if statements, but you can sometimes fake it though the syntax can get complex and if you can use the API, a mod solution is usually easier.

If this is your goal, it might be done with a macro:

Damage = [[
If @{selected|type} = 1

Then: 2d8 + @{selected|class_resource}
Else: 2d8 ]]

Though we'd need to know what the selected|type values could be, and would need to restructure the macro to something like

Damage = [[2d8+ 
// here we put the test to see if your class resource is applied, but we have do it a bit more cleverly to bypass roll20's limitations
]]


December 28 (2 years ago)


timmaugh said:

As Gauss says, if it's simple enough, a macro can do this for you. That said, a mod can help you to abstract things a bit, and maybe cut down on the number of macros you need.

ScriptCards can do a lot of this, or you can go with metascripts like APILogic (for conditionals) and ZeroFrame (for roll management and outputting)... and then optionally using maybe Fetch (for attribute retrieval) and/or Muler (for more complex table lookups).

![\][\]2d8{&if @{selected|type} = 1} + @{selected|class_resource}{&end} \]\]{&simple}

That is a simple example using APILogic and ZeroFrame, including the class_resource if the type matches. But if the mechanic is that the attacker's attack has a type, and the defending character/creature has a type, and it is simply the comparison of those two things, then you might be able to use both the selected token (for the attacker) and a targeted token (for the defender), and automate the check. That would have you down to a single macro for everything.

Here is a thread where I helped someone with something similar... the syntax might seem abstract because that thread is not solving your problem, but hopefully the examples are clear enough to demonstrate the sort of things you can do with metascripts.



First of all thank you for your reply! Ill look later into it!

The macro is not supposed to take resistances etc. into account, I didn't get that far yet. Ill report in the upcoming days if this works for me or not.

December 28 (2 years ago)


GiGs said:

Macros can't usually do if statements, but you can sometimes fake it though the syntax can get complex and if you can use the API, a mod solution is usually easier.

If this is your goal, it might be done with a macro:

Damage = [[
If @{selected|type} = 1

Then: 2d8 + @{selected|class_resource}
Else: 2d8 ]]

Though we'd need to know what the selected|type values could be, and would need to restructure the macro to something like

Damage = [[2d8+ 
// here we put the test to see if your class resource is applied, but we have do it a bit more cleverly to bypass roll20's limitations
]]


Hi! Thank you for your reply! As I mentioned earlier in this post:

The @{type} is a simple number from 1 to 18. It will not change nor will it ever include any letters or special characters. I do manually set this type and its value whenever I create character sheets, so I will never run into the problem of type being uncomparable.

the @{class_resource} is another number, ranging from 1 to 8. Its another number I set manually.


As an example, lets say @{selected|type} equals 1, and @{selected|class_resource} equals 3.

So in this specific example, @{selected|type} equals the numerical value which is asked by the macro, which in returns changes the damage roll to 2d8+3 instead of 2d8.


December 29 (2 years ago)

Edited December 29 (2 years ago)
Gauss
Forum Champion

That can easily be done via a macro, and you don't need to do two macros for it, the only change is the modifier. 

Here you go: 
2d8+ {{@{selected|type},0}>2}*@{selected|class_resource}

Note: if you want to hide the math you can wrap them in inline brackets: 
2d8+ [[[[{{@{selected|type},0}>2}]]*@{selected|class_resource}]]

This way, if type is a 1, then it automagically zeros out the class_resource damage, if it is higher than a 1 then class_resource damage is added. Only one macro required. 

This is based on "Multiple Sub-Roll Successes" used as an on/off switch. 
{{X,0}>Z} gives you a 0 or 1 that you can then use to multiple against another number. 

December 31 (2 years ago)


Gauss said:

That can easily be done via a macro, and you don't need to do two macros for it, the only change is the modifier. 

Here you go: 
2d8+ {{@{selected|type},0}>2}*@{selected|class_resource}

Note: if you want to hide the math you can wrap them in inline brackets: 
2d8+ [[[[{{@{selected|type},0}>2}]]*@{selected|class_resource}]]

This way, if type is a 1, then it automagically zeros out the class_resource damage, if it is higher than a 1 then class_resource damage is added. Only one macro required. 

This is based on "Multiple Sub-Roll Successes" used as an on/off switch. 
{{X,0}>Z} gives you a 0 or 1 that you can then use to multiple against another number. 


Hello Gauss, this is already a very good start and its very good to know that you can compare values using > and <.

However, this presents me with another problem here:

In another example @{selected|type} is 16. As presented earlier, type can be any number from 1-18. Now I want to check if the type is 16 or not.


If I use your example from earlier, I would have to change the macro to this:

2d8+ {{@{selected|type},0}>15}*@{selected|class_resource}


However, this only checks whether type is larger than 15, which would mean that any type larger than 15 (=16, 17, 18) would get their class resource bonus to the damage roll. However, I only want type=16 to have the class resource bonus in this example.


Do you have any advice how I could compare whether the type is smaller than 17, but larger than 15 (which would only allow 16 to be a valid option) and apply the class_resource bonus based on that?

December 31 (2 years ago)

Update: I figured it out after some testing! Special thanks to Gauss for getting me on the right path!


In the Macro Gauss has suggested, one can not only compare values using > and <, but also =

Which means that this:

2d8+ {{@{selected|type},0}=16}*@{selected|class_resource}

is a perfectly valid way of checking if my type does actually match the given type of the macro or not. I also understand the logic behind it now lol.


The part {{@{selected|type},0}=16} compares whether @{selected|type} or 0 equals 16. If one of these values does match (which can only be @{selected|type}, as 0 will never be equal to 16), the macro says "hey, there is 1 match in this equation!"

So this part basically checks how many matches of the presented number are present, and multiplies the amount of matches with my class resource. As there can either be 1 or 0 matches, it is either multiplied by 1 (which equals the class_resource) or by 0 (which is of course 0).


This also solved another problem for me which I didn't even know that I had until now. As my dare-to-say pokemon ripoff can have two types (which will never be the same), I can now compare If either the primary or secondary type does match the required value, by using:


2d8+ {{@{selected|type},@{selected|secondary_type}}=16}*@{selected|class_resource}


This is an amazing, yet easy solution. Thank you so much Gauss and happy new year!

December 31 (2 years ago)
Gauss
Forum Champion

Happy to help. :)

December 31 (2 years ago)

Edited December 31 (2 years ago)


Gauss said:

This is based on "Multiple Sub-Roll Successes" used as an on/off switch. 
{{X,0}>Z} gives you a 0 or 1 that you can then use to multiple against another number. 


I have a follow-up question to this though: Can Z be several values?

Lets say that I want to check if X is 5, 6, 7, 8 or 9. Everything below 5 (1, 2, 3, 4) and everything above 9 (10, 11.....) is supposed to give me a 0, but 5, 6, 7, 8, 9 is supposed to give me a 1.

Do you know a way to express that?



Edit 1: Found a solution myself, which looks like this:

[[ {{@{selected|type},0}>5}+{{@{selected|type},10}<9} -1 ]]*@{selected|class_resource}


This checks if one or two conditions are met (which are the only possibilities) and substracts one, so instead of multiplying by 1 or 2 it multiplies by 0 or 1.

December 31 (2 years ago)

Edited December 31 (2 years ago)
timmaugh
Forum Champion
API Scripter

I'll leave it to others to tell you if that "parser halting" approach will work for more complex setups. I am afraid that the syntax will start to get more complex and less readable the more cases you try to add.

I tend to go to metascripts (even for more simple setups, like your initial request) because I find that they extend more easily. My initial suggest for your initial need was:

![\][\]2d8{&if @{selected|type} = 1} + @{selected|class_resource}{&end} \]\]{&simple}

But that can be extended to "everything below 5 and above 9" like this:

![\][\]2d8{&if @{selected|type} < 5 || @{selected|type} > 9} + @{selected|class_resource}{&end} \]\]{&simple}

But everyone has their preferred method, and I'm sure you'll get another suggestion or two with different ways to do it.

December 31 (2 years ago)

Edited December 31 (2 years ago)
Gauss
Forum Champion

timmaugh is correct, after a certain point it is easier to go the API route.

However, what you want is doable without the API route. What we do is set up multiple checks that are multiplied against each other. 

{{X,0}>Z1}*{{X,(Z2+1)}<Z2 }
Z1 is 5
Z2 is 9
Note that we cannot use 0 in the Z2 second check as 0 would always make it true. We have to go the opposite direction, a larger number than would ever happen. 

The Z1 check will be true if it is 5 or higher while Z2 is true if the check is 9 or less
1-4 = 0*1 = 0
5-9 = 1*1 = 1
10+ = 1*0 = 0

How that looks with your setup (using the original version): 
2d8+ {{@{selected|type},0}>5}*{{@{selected|type},10}<9}*@{selected|class_resource}