- Joined
- Dec 29, 2017
- RedCents
- 19,244¢
So a lot of people I've noticed don't really understand conditions and how to compare something to something else. In order to understand conditions with comparisons we should first start with the basics of how MQ2 Interprets information. This is relevant for macros as a whole, and any "conditions". You might use for MQ2Melee holyshit/downshit or even KissAssist Conditions.
To start, you should probably understand an if statement.
/if (Condition) /dothis
That's saying that if the condition is true, then dothis.
So if I say
/if (${Me.Level}) /dothis
Then I'm saying if ${Me.Level} has a value other than 0 then I want to execute the slash command /dothis
You can also compare values in addition to the above example.
/if (${Me.Level} > 10) /echo I am over level 10
Where I'm saying if my level is greater than 10, then I want to echo (output to the mq2 window) a text that I am over level 10.
So what are some other ways that we can compare information? Well, first we need to understand the different types of information available to us.
Primarily we have numbers, and we have strings.
A number should be self explanatory. It's a number output, which is what you would get from ${Me.Level} or ${Me.PctHPs} where when used in a /echo it will output the related information. So if your level is 51 and your health is currently at 83% then /echo Level: ${Me.Level} Health: ${Me.PctHPs} will output
[MQ2] Level: 51 Health: 83
A string is a collection of characters in order, such as ${Me.Name} which will output your characters name. So if I did /echo Name: ${Me.Name} it would output
[MQ2] Name: Chatwiththisname
Depending on what type of output you get when you echo the information on what method you will use to compare the information. I'm going to start with all numbered values.
Integer: an integer is a whole number value. IE: 1, 2, 3, 4, 583, etc
Float: is a value with a decimal place in it. IE: 1.35, 3.14, 188.73
Floating point values are less common than integers, but you will often get them as returns when dealing with things like ${Target.Distance} where the distance is a mathematical calculation that you would have learned in Algebra when calculating the distance between two points on a Cartesian coordinate chart. The formula is irrelevant for the purpose of this tutorial.
Comparing Integers and Float uses comparators such as:
Greater Than: >
Less Than: <
Equal to: ==
Not Equal: !=
Less Than OR Equal: <=
Greater Than OR Equal: >=
You'll notice that the Not Equal comparators shows an exclamation point "!". This was not a mistake. This means NOT in all programming languages I've personally dealt with (that doesn't necessarily mean all).
So I'll give examples and then explain each of the above options.
/if (${Me.Level} > 10) /echo I'm higher than level 10
I should hope this shows that if my level is higher than 10 (not including 10) then I should issue the slash command.
/if (${Me.Level} < 10) /echo I'm lower than level 10
If my level is lower than level 10 (not including 10) then I should issue the slash command.
/if (${Me.Level} == 50) /echo I am level 50
If my level is EXACTLY 50, issue the slash command.
/if (${Me.Level} != 50) /echo I am not level 50
if my level is ANYTHING EXCEPT 50, issue the slash command.
/if (${Me.Level} <= 20) /echo I am lower than level 21.
If my level is Less than OR EQUAL to 20 (20 included) then issue the slash command
/if (${Me.Level} >= 20) /echo I am higher than level 19.
If my level is Greater than OR EQUAL to 20 (20 included) then issue the slash command
These comparisons also work when using Floating point values. /if (${Target.Distance} < 200) /casting "Fervid Renewal"
Distance is almost assuredly going to be a floating point number if you do a /echo ${Target.Distance}, but it compares the same way. If the distance is 199.99 or less then it would return a valid comparison and issue the slash command, which in this case would be to cast a heal spell.
Strings
So I mentioned strings earlier because I wanted to make sure we understand that these are definitively vastly different from numbers. If you try to use comparators we used on numbers earlier, then you'll find yourself getting errors for unparsable in calculations, non-numeric encountered. For example.
/if (${Me.Name} > ${Target.Name}) /echo I'm greater than my target.
so let us say eqmule is my target. the output would be something like.
Unparsable in Calculation: 'C'
Failed to parse /if condition '(Chatwiththisname > eqmule)', non-numeric encountered
If you are using this as a holyflag, downflag or condition in KISS then it would spam it so much you'd see nothing but this on your screen whenever it tried to parse the information.
The correct way to check is using a member of the string datatype would be to use one of the following:
Find
Length
Compare
CompareCS
Equal
NotEqual
EqualCS
NotEqualCS
The above are pulled from my data.ini (which I will attach to this post) and are for use with the string datatype.
/if (${Me.Name.Find[Chatwith]}) /echo I found Chatwith in ${Me.Name}.
If I find a substring inside of the string with the text in the [SquareBrackets] then issue the slash command
/if (${Me.Name.Length}) /echo My name has a length of ${Me.Name.Length} characters.
If the string has character count greater than zero, then issue the slash command.
/if (${Me.Name.Compare[eqmule]} == 0) /echo I keep MQ2 running for everyone.
If my name is eqmule regardless of character case then issue the slash command. IE: EqMuLe is considered the same as eqmule
/if (${Me.Name.Equal[eqmule]}) /echo I keep MQ2 running for everyone.
If my name is equal to eqmule regardless of character case, issue the slash command.
/if (${Me.Name.NotEqual[eqmule]}) /echo I'm not eqmule.
If my name is NOT equal to eqmule regardless of character case, issue the slash command.
You also have some case-sensitive options.
CompareCS
EqualCS
NotEqualCS
Which are used as shown in the example above, but are case sensitive. IE: /if (${Me.Name.EqualCS[ChAtWiThThIsNaMe]}) /echo I am ChAtWiThThIsNaMe
That would return false because it is case sensitive.
Operands and you.
Well, now that we know the difference in comparing information from a string and comparing information from a number. What if I need to check multiple things in a single condition?
So much like the comparators you need a way to say things like "AND" and "OR" when checking some conditions. IE: I need to make sure I am in range of casting a spell, and I need to make sure I have enough mana to cast it, but I also don't want to be moving, or already casting, or do it when I'm invisible. So....how do I do that?!
Okay, so we'll start with going about this on a single line because a user will typically need to put this all into a single line for a condition, holyshit, or downshit.
Operands
&& means AND
|| means OR
/if (${Target.Distance} < 200 && ${Me.CurrentMana} > 2774 && !${Me.Moving} && !${Me.Casting.ID} && !${Me.Invis}) /casting "Fervid Renewal"
So above I've looked at the spell information in-game for Fervid Renewal and got the Spell name, the spell range, and the mana it requires to cast. Then I've used the information to decide if I should cast it.
Fervid Renewal
Range: 200
Mana: 2774
${Me.Casting.ID} would return the ID of the spell I was currently casting if I was casting a spell. Which would result in returning a value greater than 0. IE: 43241 is the ID of Fervid Renewal.
If I am invisible, then ${Me.Invis} would return TRUE, and if I was moving then ${Me.Moving} would return TRUE.
So if you did an echo for all this information. It could look something like.
[MQ2] 12.05 < 200 && 130331 > 2774 && !FALSE && !NULL && !TRUE
This is how the information is evaluated by MQ2 to decide if it should execute the slash command following the issue statement.
So the distance is 12.05 < 200, so that would pass the test.
My mana is 130331 > 2774, so that would pass the test
I'm moving would be FALSE. But since I put "!" at the beginning, if you recall, that means NOT. So I'm saying if this is NOT TRUE then it's TRUE (double negative??). So this one passes.
${Me.Casting.ID} returned !NULL, which means I was not casting a spell, but since I used "!" not I'm saying if I'm NOT CASTING a spell then it passes. So this one passes.
${Me.Invis} returned !TRUE Which means I was invisible, but I only want it to pass if I'm NOT invisible because I used "!" at the start. Since !TRUE means it failed, the entire conditional statement fails the test and is not used.
Next is the || OR Operand. This means THIS OR THIS needs to be true in order for me to do something.
/if (${Target.Named} || ${Me.PctHPs} < 30) /disc Stout Defense
Which means I want to use my Stout Defense disc anytime I have a named targeted OR my HPs is below 30%. So in this case, only one of the two conditions needs to pass in order for it to be true. So unless both fail to pass the checks, then it will issue the slash command.
Okay, so all this is good information. But how do I do the ${Me.StatGoesHere.MuchoPigSelf.SuperPunch[SomeStuffHere]}
the short answer is that there is a WIKI for all the TLO's.
https://www.redguides.com/wiki/Category:Top-Level_Objects
Each one of those will tell you what it has access to and the members of that datatype.
For Example. ${Me} is a TLO https://www.redguides.com/wiki/TLO:Me
Here it shows you Access to Types
Where it will list all the types you have access to members of.
Additionally, I've managed to create a simple macro that pulls all the members of a datatype and outputs them to an INI file. To my knowledge, this works on all builds of MQ2, IE: UF, RoF, RoF2, etc. I'll provide a copy of the macro and a copy of the INI from the last live run I did.
The information is in the following format.
[datatype]
Member#=nameOfMember
IE: The string datatype is as follows.
[string]
Member1=Arg
Member2=Mid
Member3=Left
Member4=Right
Member5=Find
Member6=Length
Member7=Upper
Member8=Lower
Member9=Compare
Member10=CompareCS
Member11=Equal
Member12=NotEqual
Member13=EqualCS
Member14=NotEqualCS
Member15=Count
Member16=Token
Member17=Replace
So anything that is a string can use those as a member.
An example is ${Me.Name} is a string of characters. I can use any of the above members with that string.
${Me.Name.Find[Chat]}
${Me.Name.Arg[1,|]}
${Me.Name.Length}
How to use each of the members will likely be something that you'll want to check examples of on the WIKI.
Please keep in mind that I may have some information in the data.ini that is not available on the WIKI. That's because the WIKI is a user run series of pages where individuals like yourself add information to it to make it more complete. If you learn something that isn't available on the wiki and can find the time to update the Wiki, please do so!
Please feel free to ask questions in this thread if you are having trouble understanding. Please understand that TLO's and their Members are case sensitive. IE: ${Me.Name} is not the same as ${me.name}
As always, I can be found on discord https://discord.gg/GUeSzr9 for additional assistance, but your thanks on my posts help keep me subbed and active in game. I also do custom coded macros for a fee and accept donations.
Video was made from my live stream going over basically the same information that is found here.
To start, you should probably understand an if statement.
/if (Condition) /dothis
That's saying that if the condition is true, then dothis.
So if I say
/if (${Me.Level}) /dothis
Then I'm saying if ${Me.Level} has a value other than 0 then I want to execute the slash command /dothis
You can also compare values in addition to the above example.
/if (${Me.Level} > 10) /echo I am over level 10
Where I'm saying if my level is greater than 10, then I want to echo (output to the mq2 window) a text that I am over level 10.
So what are some other ways that we can compare information? Well, first we need to understand the different types of information available to us.
Primarily we have numbers, and we have strings.
A number should be self explanatory. It's a number output, which is what you would get from ${Me.Level} or ${Me.PctHPs} where when used in a /echo it will output the related information. So if your level is 51 and your health is currently at 83% then /echo Level: ${Me.Level} Health: ${Me.PctHPs} will output
[MQ2] Level: 51 Health: 83
A string is a collection of characters in order, such as ${Me.Name} which will output your characters name. So if I did /echo Name: ${Me.Name} it would output
[MQ2] Name: Chatwiththisname
Depending on what type of output you get when you echo the information on what method you will use to compare the information. I'm going to start with all numbered values.
Integer: an integer is a whole number value. IE: 1, 2, 3, 4, 583, etc
Float: is a value with a decimal place in it. IE: 1.35, 3.14, 188.73
Floating point values are less common than integers, but you will often get them as returns when dealing with things like ${Target.Distance} where the distance is a mathematical calculation that you would have learned in Algebra when calculating the distance between two points on a Cartesian coordinate chart. The formula is irrelevant for the purpose of this tutorial.
Comparing Integers and Float uses comparators such as:
Greater Than: >
Less Than: <
Equal to: ==
Not Equal: !=
Less Than OR Equal: <=
Greater Than OR Equal: >=
You'll notice that the Not Equal comparators shows an exclamation point "!". This was not a mistake. This means NOT in all programming languages I've personally dealt with (that doesn't necessarily mean all).
So I'll give examples and then explain each of the above options.
/if (${Me.Level} > 10) /echo I'm higher than level 10
I should hope this shows that if my level is higher than 10 (not including 10) then I should issue the slash command.
/if (${Me.Level} < 10) /echo I'm lower than level 10
If my level is lower than level 10 (not including 10) then I should issue the slash command.
/if (${Me.Level} == 50) /echo I am level 50
If my level is EXACTLY 50, issue the slash command.
/if (${Me.Level} != 50) /echo I am not level 50
if my level is ANYTHING EXCEPT 50, issue the slash command.
/if (${Me.Level} <= 20) /echo I am lower than level 21.
If my level is Less than OR EQUAL to 20 (20 included) then issue the slash command
/if (${Me.Level} >= 20) /echo I am higher than level 19.
If my level is Greater than OR EQUAL to 20 (20 included) then issue the slash command
These comparisons also work when using Floating point values. /if (${Target.Distance} < 200) /casting "Fervid Renewal"
Distance is almost assuredly going to be a floating point number if you do a /echo ${Target.Distance}, but it compares the same way. If the distance is 199.99 or less then it would return a valid comparison and issue the slash command, which in this case would be to cast a heal spell.
Strings
So I mentioned strings earlier because I wanted to make sure we understand that these are definitively vastly different from numbers. If you try to use comparators we used on numbers earlier, then you'll find yourself getting errors for unparsable in calculations, non-numeric encountered. For example.
/if (${Me.Name} > ${Target.Name}) /echo I'm greater than my target.
so let us say eqmule is my target. the output would be something like.
Unparsable in Calculation: 'C'
Failed to parse /if condition '(Chatwiththisname > eqmule)', non-numeric encountered
If you are using this as a holyflag, downflag or condition in KISS then it would spam it so much you'd see nothing but this on your screen whenever it tried to parse the information.
The correct way to check is using a member of the string datatype would be to use one of the following:
Find
Length
Compare
CompareCS
Equal
NotEqual
EqualCS
NotEqualCS
The above are pulled from my data.ini (which I will attach to this post) and are for use with the string datatype.
/if (${Me.Name.Find[Chatwith]}) /echo I found Chatwith in ${Me.Name}.
If I find a substring inside of the string with the text in the [SquareBrackets] then issue the slash command
/if (${Me.Name.Length}) /echo My name has a length of ${Me.Name.Length} characters.
If the string has character count greater than zero, then issue the slash command.
/if (${Me.Name.Compare[eqmule]} == 0) /echo I keep MQ2 running for everyone.
If my name is eqmule regardless of character case then issue the slash command. IE: EqMuLe is considered the same as eqmule
/if (${Me.Name.Equal[eqmule]}) /echo I keep MQ2 running for everyone.
If my name is equal to eqmule regardless of character case, issue the slash command.
/if (${Me.Name.NotEqual[eqmule]}) /echo I'm not eqmule.
If my name is NOT equal to eqmule regardless of character case, issue the slash command.
You also have some case-sensitive options.
CompareCS
EqualCS
NotEqualCS
Which are used as shown in the example above, but are case sensitive. IE: /if (${Me.Name.EqualCS[ChAtWiThThIsNaMe]}) /echo I am ChAtWiThThIsNaMe
That would return false because it is case sensitive.
Operands and you.
Well, now that we know the difference in comparing information from a string and comparing information from a number. What if I need to check multiple things in a single condition?
So much like the comparators you need a way to say things like "AND" and "OR" when checking some conditions. IE: I need to make sure I am in range of casting a spell, and I need to make sure I have enough mana to cast it, but I also don't want to be moving, or already casting, or do it when I'm invisible. So....how do I do that?!
Okay, so we'll start with going about this on a single line because a user will typically need to put this all into a single line for a condition, holyshit, or downshit.
Operands
&& means AND
|| means OR
/if (${Target.Distance} < 200 && ${Me.CurrentMana} > 2774 && !${Me.Moving} && !${Me.Casting.ID} && !${Me.Invis}) /casting "Fervid Renewal"
So above I've looked at the spell information in-game for Fervid Renewal and got the Spell name, the spell range, and the mana it requires to cast. Then I've used the information to decide if I should cast it.
Fervid Renewal
Range: 200
Mana: 2774
${Me.Casting.ID} would return the ID of the spell I was currently casting if I was casting a spell. Which would result in returning a value greater than 0. IE: 43241 is the ID of Fervid Renewal.
If I am invisible, then ${Me.Invis} would return TRUE, and if I was moving then ${Me.Moving} would return TRUE.
So if you did an echo for all this information. It could look something like.
[MQ2] 12.05 < 200 && 130331 > 2774 && !FALSE && !NULL && !TRUE
This is how the information is evaluated by MQ2 to decide if it should execute the slash command following the issue statement.
So the distance is 12.05 < 200, so that would pass the test.
My mana is 130331 > 2774, so that would pass the test
I'm moving would be FALSE. But since I put "!" at the beginning, if you recall, that means NOT. So I'm saying if this is NOT TRUE then it's TRUE (double negative??). So this one passes.
${Me.Casting.ID} returned !NULL, which means I was not casting a spell, but since I used "!" not I'm saying if I'm NOT CASTING a spell then it passes. So this one passes.
${Me.Invis} returned !TRUE Which means I was invisible, but I only want it to pass if I'm NOT invisible because I used "!" at the start. Since !TRUE means it failed, the entire conditional statement fails the test and is not used.
Next is the || OR Operand. This means THIS OR THIS needs to be true in order for me to do something.
/if (${Target.Named} || ${Me.PctHPs} < 30) /disc Stout Defense
Which means I want to use my Stout Defense disc anytime I have a named targeted OR my HPs is below 30%. So in this case, only one of the two conditions needs to pass in order for it to be true. So unless both fail to pass the checks, then it will issue the slash command.
Okay, so all this is good information. But how do I do the ${Me.StatGoesHere.MuchoPigSelf.SuperPunch[SomeStuffHere]}
the short answer is that there is a WIKI for all the TLO's.
https://www.redguides.com/wiki/Category:Top-Level_Objects
Each one of those will tell you what it has access to and the members of that datatype.
For Example. ${Me} is a TLO https://www.redguides.com/wiki/TLO:Me
Here it shows you Access to Types
Where it will list all the types you have access to members of.
Additionally, I've managed to create a simple macro that pulls all the members of a datatype and outputs them to an INI file. To my knowledge, this works on all builds of MQ2, IE: UF, RoF, RoF2, etc. I'll provide a copy of the macro and a copy of the INI from the last live run I did.
The information is in the following format.
[datatype]
Member#=nameOfMember
IE: The string datatype is as follows.
[string]
Member1=Arg
Member2=Mid
Member3=Left
Member4=Right
Member5=Find
Member6=Length
Member7=Upper
Member8=Lower
Member9=Compare
Member10=CompareCS
Member11=Equal
Member12=NotEqual
Member13=EqualCS
Member14=NotEqualCS
Member15=Count
Member16=Token
Member17=Replace
So anything that is a string can use those as a member.
An example is ${Me.Name} is a string of characters. I can use any of the above members with that string.
${Me.Name.Find[Chat]}
${Me.Name.Arg[1,|]}
${Me.Name.Length}
How to use each of the members will likely be something that you'll want to check examples of on the WIKI.
Please keep in mind that I may have some information in the data.ini that is not available on the WIKI. That's because the WIKI is a user run series of pages where individuals like yourself add information to it to make it more complete. If you learn something that isn't available on the wiki and can find the time to update the Wiki, please do so!
Please feel free to ask questions in this thread if you are having trouble understanding. Please understand that TLO's and their Members are case sensitive. IE: ${Me.Name} is not the same as ${me.name}
As always, I can be found on discord https://discord.gg/GUeSzr9 for additional assistance, but your thanks on my posts help keep me subbed and active in game. I also do custom coded macros for a fee and accept donations.
Video was made from my live stream going over basically the same information that is found here.
Attachments
Last edited: