huderlem / poryscript

High-level scripting language for gen 3 pokemon decompilation projects
https://www.huderlem.com/poryscript-playground/
MIT License
191 stars 21 forks source link

Nested OR statement expecting conditional operator #40

Closed Jademalo closed 3 years ago

Jademalo commented 3 years ago

I'm trying to check the result of an encounter, to give different outcomes depending on the result.

I assumed that the following would be possible, nesting the two possible outcomes in brackets and ORing between them;

if(var(VAR_RESULT) == (B_OUTCOME_RAN || B_OUTCOME_PLAYER_TELEPORTED))

However, this throws the following error;

PORYSCRIPT ERROR: line 347: left side of binary expression must be var(), flag(), or defeated() operator. Instead, found 'B_OUTCOME_PLAYER_TELEPORTED'

In the documentation, it says the following;

# Group nested conditions together with another set of parentheses.
if (flag(FLAG_IS_CHAMPION) && !(flag(FLAG_SYS_TOWER_GOLD) || flag(FLAG_SYS_DOME_GOLD))) {

My assumption is that the interpreter doesn't handle OR statements in the way I assumed it would, and that at least one side of the OR needs to be either flag, var, or defeated. However, I'm not sure if this is intended or if it's a bug.

Is this behaviour correct, or is it incorrectly assuming something beside an OR has to be a flag, var, or defeated?

The following works to get the result I want, but feels less elegant than my original assumption.

if(var(VAR_RESULT) == B_OUTCOME_RAN || var(VAR_RESULT) == B_OUTCOME_PLAYER_TELEPORTED){
huderlem commented 3 years ago

You've made a common logical error with your conditionals, unrelated to poryscript. The following two lines of code have very different meanings. I'll write them in C to take poryscript out of the equation:

if (var_result == (B_OUTCOME_RAN || B_OUTCOME_PLAYER_TELEPORTED))
if (var_result == B_OUTCOME_RAN || var_result == B_OUTCOME_PLAYER_TELEPORTED)

The first line is the same as:

if (var_result == 1)
// This is because B_OUTCOME_RAN  = 4, B_OUTCOME_PLAYER_TELEPORTED = 5
// The logical OR operator, ||, results in the following evaluation: 4 || 5 = 1

while the second line does exactly what you want--check if the player teleported or fled. So, your "elegant" line of code doesn't do what you want, regardless of poryscript syntax.

As for the poryscript syntax error you're receiving, that's by design. The only things that can cause a script jump in the pokemon scripting engine are the flag, var, and defeated operations, which set a comparison flag that can be acted upon. This is why the || requires one of those operators on the left side.

Jademalo commented 3 years ago

Alright, thanks for the explanation! That makes sense - I hadn't realised that it was evaluating the OR, as you said I assumed I was getting a test on both outcomes. I'm extremely new to this all lol, mostly just reading and adapting other code.

The irony is I made this same mistake a couple of weeks ago in c, and just totally and utterly forgot again. I even knew the solution! =p

Thanks!