Help me stop repeating the same <<IF>> statement

If you are requesting technical assistance with Twine, please specify:
Twine Version: 2.3.13
Story Format: 2.34.1

Hi everyone,

I find myself repeating the same line of code over and over. It works but as I add more options this becomes less workable. There must be a better way.

Given:
A player can get two bonus rewards, one for color and one for the material.

I use the code below to determine which “color reward” or “material reward” the player receives. All rewards come from the same list. In this example, it is more lives, attack, defence. But this list will be longer in my game. I can’t use ‘elseif’ because there are 2 possible rewards. I think I need a place to store these lines of “reward code” to call them in a ‘for’ loop. I am missing the lingo to execute an effective search online, so i hope you can help me.

These is are the first lines of correctly functioning code that i am using now:

<<if $colorreward === 0 or $materialreward === 0>>
<<set $lives = $lives + 1 >>
<</if>>
<<if $colorreward == 1 or $materialreward == 1>>
<<set $attack = $attack + 1 >>
<</if>>
<<if $colorreward == 2 or $materialreward == 2>>
<<set $defense = $defense + 1 >>
<</if>>

To simplify treat $NumberofRewardsBothColorAndMaterial as given and correct.
I think i want to replace my code with a for loop like this :

<<for _x = 0; _x < $NumberofRewardsBothColorAndMaterial; _x++>>
<<if $colorreward == _x or $materialreward == _x>>
/* here i need to call code from a list of rewards or something */
<</if>>
<</for>>

i would like to make a numbered list with rewards like:
0 = <<set $lives = $lives + 1 >>
1 = <<set $attack = $attack + 1 >>
2 = <<set $defense = $defense + 1 >>
3 = <<set $inventory.push etc etc…

Where and how would I store this list? an array, objects. or should I look into those widget/ method things for this? How could i call and execute the code in the loop? Or should I do something else entirely?
Thanks in advance

What you want is the “switch” macro:

<<switch $hairColor>>
<<case "red" "auburn">>
	You ginger.
<<case "black" "brown">>
	Dark haired, eh?
<<case "blonde">>
	You may have more fun.
<</switch>>

$hairColor is the variable being tested, and each of the “case” statements is equivalent to <<if $hairColor = “blonde”>> etc.

full details in the sugarcube docs.

1 Like

Yeah, but with <<switch>> at most one <<case>> can happen, and there are two rewards.

Are the rewards independent? Or can you only get each reward once like your code does? For instance, can you get two lives, one as a color reward and one as a material reward?

SugarCube doesn’t have a particularly great way to store code for later execution, I don’t think. You could put each bit of code in its own passage, named reward0, reward1, etc.

Then the code in your loop could be <<include `"reward" + _x`>> (note the backticks).

1 Like

Hi Josh and DizzyDonut, both of you thanks for your suggestion.

The switch macro is precisely the thing I wanted. But as Josh said it only executes once though.

My first workaround was to make a duplicate code block for each variable(color and material). But then I realized I could just change the variable it checks.

So for anyone that is interested, this is what i did.

 <<set $combireward =  $colorreward>>
<<for _x = 0; _x < 2; _x++>>
<<switch $combireward>>
<<case 0>>
result 0
<<set $lives = $lives + 1 >>
<<case 1>>
result 1
<<set $attack = $attack + 1 >>
<<case 2>>
result 2
2 = <<set $defense = $defense + 1 >>
<<case 3>>
result 3
3 = <<set $inventory.push etc etc…
<</switch>>
<<set $combireward = $marterialreward>>
<</for>>

I thought about storing it in passages like you suggested josh. It thinks it would work but I like to have one list with all the rewards in one place.

Again thank you for your help.

1 Like