0 votes
by (420 points)

I realize this is a dumb question, but I'm having a hard time pinpointing an answer in the documentation. I have an $action variable I use in passages to track the current action the player is taking and open up other options accordingly. I have that part handled, the problem is those checks can get a little... lengthy.

<<if $action isnot "this" and $action isnot "that" and $action isnot "theother" and $action isnot "thatother">>
...Do the thing...
<</if>>

Is there an easier/better way to make this check? Something like <<if $action isnot "this","that","theother">> or something?

This is in Sugarcube 2.21

3 Answers

+1 vote
by (159k points)
selected by
 
Best answer

If all the checks are against the same variable (eg. $action) and the list of values you want to check against has more that a couple of values (*) then you could using the <Array>.includes() function to do the check.

<<set $action to "test">>

<<if not ["this", "that", "theother", "thatother"].includes($action)>>
...Do the thing...
<</if>>

... the message should appear until you change the $action variable to one of the values within the array. (eg. "that")

(*) the reason you wouldn't generally use this technique for a small number of values is because creating an Array is an expensive (system resources) process, as is searching through all the elements contained within that Array. It is generally a lot cheaper to use the IF condition AND condition AND condition statement which fails as soon as one of the supplied condition is not met.

edit: Changed the example to use SugarCube's documented not operator instead of Javascript's ! operator.

by (420 points)
This is perfect, thank you!
0 votes
by (8.9k points)

$action can only ever have one value, so would it not be simpler to just check:

<<if $action is "this">>
  Do this
  <<elseif $action is "that">>
  Do that
<</if>>

 

by (420 points)

Even if I check for is rather than isnot I'd still run into the same problem. A passage may have 10 unique actions the player could be taking, so I could either go.

<<if $action is "A" or $action is "B" or $action is "C" or $action is "D">>
Do action J
<</if>>

or

<<if $action isnot "W" and $action isnot "X" and $action isnot "Y" and $action isnot "Z">>
Do action J
<</if>>

Same result, but same problem.

0 votes
by (63.1k points)
edited by

There's probably a better way to structure your code. There generally is when you wind up with crazy chains of conditions like that (though not always). Without seeing more, though, we can't speak to that. 

I would recommend using either arrays or, if you can swing it, the <<switch>> macro. Example of the former. 

<<if not ["this", "that", "theother", "thatother"].includes($action)>>
...

This method is a bit easier to manage and a bit shorter to write, but will be a bit slower on performance. 

Edit. Greyelf beat me to it, and with a better explanation. 

...