If/elseif/else command not working

I’m new to choicescript so I’m sure I’m doing something wrong. I have 6 stats for the main character (based on dungeons and dragons), and based on each of those numbers, I’m trying to get a modifier stat for each to display a +#, -#, or 0. The result I’m getting is 0 for all except the strength modifier, which returns the correct value.

Here’s my code. It’s very long so apologies in advance.

stats code
	*set str 13
	*set dex 10
	*set con 9
	*set int 12
	*set wis 12
	*set cha 10

	*if str = 1
		*set str_mod "-5"
		*goto name
	*elseif (str >= 2) and (str <= 3)
		*set str_mod "-4"
		*goto name
	*elseif (str >=4) and (str <= 5)
		*set str_mod "-3"
		*goto name
	*elseif (str >= 6) and (str <= 7)
		*set str_mod "-2"
		*goto name
	*elseif (str >= 8) and (str <= 9)
		*set str_mod "-1"
		*goto name
	*elseif (str >= 10) and (str <= 11)
		*set str_mod "0"
		*goto name
	*elseif (str >= 12) and (str <= 13)
		*set str_mod "+1"
		*goto name
	*elseif (str >= 14) and (str <= 15)
		*set str_mod "+2"
		*goto name
	*elseif (str >= 16) and (str <= 17)
		*set str_mod "+3"
		*goto name
	*elseif (str >= 18) and (str <= 19)
		*set str_mod "+4"
		*goto name
	*elseif (str >= 20) and (str <= 21)
		*set str_mod "+5"
		*goto name
	*elseif (str >= 22) and (str <= 23)
		*set str_mod "+6"
		*goto name
	*elseif (str >= 24) and (str <= 25)
		*set str_mod "+7"
		*goto name
	*elseif (str >= 26) and (str <= 27)
		*set str_mod "+8"
		*goto name
	*elseif (str >= 28) and (str <= 29)
		*set str_mod "+9"
		*goto name
	*elseif
		*set str_mod "+10"
		*goto name

	*if dex = 1
		*set dex_mod "-5"
		*goto name
	*elseif (dex >= 2) and (dex <= 3)
		*set dex_mod "-4"
		*goto name
	*elseif (dex >= 4) and (dex <= 5)
		*set dex_mod "-3"
		*goto name
	*elseif (dex >= 6) and (dex <= 7)
		*set dex_mod "-2"
		*goto name
	*elseif (dex >= 8) and (dex <= 9)
		*set dex_mod "-1"
		*goto name
	*elseif (dex >= 10) and (dex <= 11)
		*set dex_mod "0"
		*goto name
	*elseif (dex >= 12) and (dex <= 13)
		*set dex_mod "+1"
		*goto name
	*elseif (dex >= 14) and (dex <= 15)
		*set dex_mod "+2"
		*goto name
	*elseif (dex >= 16) and (dex <= 17)
		*set dex_mod "+3"
		*goto name
	*elseif (dex >= 17) and (dex <= 19)
		*set dex_mod "+4"
		*goto name
	*elseif (dex >= 20) and (dex <= 21)
		*set dex_mod "+5"
		*goto name
	*elseif (dex >= 22) and (dex <= 23)
		*set dex_mod "+6"
		*goto name
	*elseif (dex >= 24) and (dex <= 25)
		*set dex_mod "+7"
		*goto name
	*elseif (dex >= 26) and (dex <= 27)
		*set dex_mod "+8"
		*goto name
	*elseif (dex >= 28) and (dex <= 29)
		*set dex_mod "+9"
		*goto name
	*elseif
		*set dex_mod "+10"
		*goto name

	*if con = 1
		*set con_mod "-5"
		*goto name
	*elseif (con >= 2) and (con <= 3)
		*set con_mod "-4"
		*goto name
	*elseif (con >= 4) and (con <= 5)
		*set con_mod "-3"
		*goto name
	*elseif (con >= 6) and (con <= 7)
		*set con_mod "-2"
		*goto name
	*elseif (con >= 8) and (con <= 9)
		*set con_mod "-1"
		*goto name
	*elseif (con >= 10) and (con <= 11)
		*set con_mod "0"
		*goto name
	*elseif (con >= 12) and (con <= 13)
		*set con_mod "+1"
		*goto name
	*elseif (con >= 14) and (con <= 15)
		*set con_mod "+2"
		*goto name
	*elseif (con >= 16) and (con <= 17)
		*set con_mod "+3"
		*goto name
	*elseif (con >= 18) and (con <= 19)
		*set con_mod "+4"
		*goto name
	*elseif (con >= 20) and (con <= 21)
		*set con_mod "+5"
		*goto name
	*elseif (con >= 22) and (con <= 23)
		*set con_mod "+6"
		*goto name
	*elseif (con >= 24) and (con <= 25)
		*set con_mod "+7"
		*goto name
	*elseif (con >= 26) and (con <= 27)
		*set con_mod "+8"
		*goto name
	*elseif (con >= 28) and (con <= 29)
		*set con_mod "+9"
		*goto name
	*elseif
		*set con_mod "+10"
		*goto name

	*if int = 1
		*set int_mod "-5"
		*goto name
	*elseif (int >= 2) and (int <= 3)
		*set int_mod "-4"
		*goto name
	*elseif (int >= 4) and (int <= 5)
		*set int_mod "-3"
		*goto name
	*elseif (int >= 6) and (int <= 7)
		*set int_mod "-2"
		*goto name
	*elseif (int >= 8) and (int <= 9)
		*set int_mod "-1"
		*goto name
	*elseif (int >= 10) and (int <= 11)
		*set int_mod "0"
		*goto name
	*elseif (int >= 12) and (int <= 13)
		*set int_mod "+1"
		*goto name
	*elseif (int >= 14) and (int <= 15)
		*set int_mod "+2"
		*goto name
	*elseif (int >= 16) and (int <= 17)
		*set int_mod "+3"
		*goto name
	*elseif (int >= 18) and (int <= 19)
		*set int_mod "+4"
		*goto name
	*elseif (int >= 20) and (int <= 21)
		*set int_mod "+5"
		*goto name
	*elseif (int >= 22) and (int <= 23)
		*set int_mod "+6"
		*goto name
	*elseif (int >= 24) and (int <= 25)
		*set int_mod "+7"
		*goto name
	*elseif (int >= 26) and (int <= 27)
		*set int_mod "+8"
		*goto name
	*elseif (int >= 28) and (int <= 29)
		*set int_mod "+9"
		*goto name
	*elseif
		*set int_mod "+10"
		*goto name

	*if wis = 1
		*set wis_mod "-5"
		*goto name
	*elseif (wis >= 2) and (wis <= 3)
		*set wis_mod "-4"
		*goto name
	*elseif (wis >= 4) and (wis <= 5)
		*set wis_mod "-3"
		*goto name
	*elseif (wis >= 6) and (wis <= 7)
		*set wis_mod "-2"
		*goto name
	*elseif (wis >= 8) and (wis <= 9)
		*set wis_mod "-1"
		*goto name
	*elseif (wis >= 10) and (wis <= 11)
		*set wis_mod "0"
		*goto name
	*elseif (wis >= 12) and (wis <= 13)
		*set wis_mod "+1"
		*goto name
	*elseif (wis >= 14) and (wis <= 15)
		*set wis_mod "+2"
		*goto name
	*elseif (wis >= 16) and (wis <= 17)
		*set wis_mod "+3"
		*goto name
	*elseif (wis >= 18) and (wis <= 19)
		*set wis_mod "+4"
		*goto name
	*elseif (wis >= 20) and (wis <= 21)
		*set wis_mod "+5"
		*goto name
	*elseif (wis >= 22) and (wis <= 23)
		*set wis_mod "+6"
		*goto name
	*elseif (wis >= 24) and (wis <= 25)
		*set wis_mod "+7"
		*goto name
	*elseif (wis >= 26) and (wis <= 27)
		*set wis_mod "+8"
		*goto name
	*elseif (wis >= 28) and (wis <= 29)
		*set wis_mod "+9"
		*goto name
	*elseif
		*set wis_mod "+10"
		*goto name

	*if cha = 1
		*set cha_mod "-5"
		*goto name
	*elseif (cha >= 2) and (cha <= 3)
		*set cha_mod "-4"
		*goto name
	*elseif (cha >= 4) and (cha <= 5)
		*set cha_mod "-3"
		*goto name
	*elseif (cha >= 6) and (cha <= 7)
		*set cha_mod "-2"
		*goto name
	*elseif (cha >= 8) and (cha <= 9)
		*set cha_mod "-1"
		*goto name
	*elseif (cha >= 10) and (cha <= 11)
		*set cha_mod "0"
		*goto name
	*elseif (cha >= 12) and (cha <= 13)
		*set cha_mod "+1"
		*goto name
	*elseif (cha >= 14) and (cha <= 15)
		*set cha_mod "+2"
		*goto name
	*elseif (cha >= 16) and (cha <= 17)
		*set cha_mod "+3"
		*goto name
	*elseif (cha >= 18) and (cha <= 19)
		*set cha_mod "+4"
		*goto name
	*elseif (cha >= 20) and (cha <= 21)
		*set cha_mod "+5"
		*goto name
	*elseif (cha >= 22) and (cha <= 23)
		*set cha_mod "+6"
		*goto name
	*elseif (cha >= 24) and (cha <= 25)
		*set cha_mod "+7"
		*goto name
	*elseif (cha >= 26) and (cha <= 27)
		*set cha_mod "+8"
		*goto name
	*elseif (cha >= 28) and (cha <= 29)
		*set cha_mod "+9"
		*goto name
	*elseif
		*set cha_mod "+10"
		*goto name

A couple of things:

  • the last *elseif lacks a conditional, which… doesn’t look right. (You could use *else, but then it would override all other stats. It wouldn’t know what stat you’re checking.)
  • But more importantly: what I believe is happening is that once the first modifier is set, the *goto name makes the code to skip over the rest of the checks, since it goes to the label name.
1 Like

I added the conditional to the last elseif and removed all but the last *goto name. Now it’s returning an error saying “It is illegal to fall in to an *else statement; you must goto or finish before the end of the indented block.” This error is recorded at the line for the strength stat between 14 and 15.

I’m not sure what the problem is now, but here’s the new code.

new stats code
	*comment character stats
	*set str 13
	*set dex 10
	*set con 9
	*set int 12
	*set wis 12
	*set cha 10
	*comment strength modifier
	*if str = 1
		*set str_mod "-5"
	*elseif (str >= 2) and (str <= 3)
		*set str_mod "-4"
	*elseif (str >=4) and (str <= 5)
		*set str_mod "-3"
	*elseif (str >= 6) and (str <= 7)
		*set str_mod "-2"
	*elseif (str >= 8) and (str <= 9)
		*set str_mod "-1"
	*elseif (str >= 10) and (str <= 11)
		*set str_mod "0"
	*elseif (str >= 12) and (str <= 13)
		*set str_mod "+1"
	*elseif (str >= 14) and (str <= 15)
		*set str_mod "+2"
	*elseif (str >= 16) and (str <= 17)
		*set str_mod "+3"
	*elseif (str >= 18) and (str <= 19)
		*set str_mod "+4"
	*elseif (str >= 20) and (str <= 21)
		*set str_mod "+5"
	*elseif (str >= 22) and (str <= 23)
		*set str_mod "+6"
	*elseif (str >= 24) and (str <= 25)
		*set str_mod "+7"
	*elseif (str >= 26) and (str <= 27)
		*set str_mod "+8"
	*elseif (str >= 28) and (str <= 29)
		*set str_mod "+9"
	*else
		*set str_mod "+10"
	*comment dexterity modifier
	*if dex = 1
		*set dex_mod "-5"
	*elseif (dex >= 2) and (dex <= 3)
		*set dex_mod "-4"
	*elseif (dex >= 4) and (dex <= 5)
		*set dex_mod "-3"
	*elseif (dex >= 6) and (dex <= 7)
		*set dex_mod "-2"
	*elseif (dex >= 8) and (dex <= 9)
		*set dex_mod "-1"
	*elseif (dex >= 10) and (dex <= 11)
		*set dex_mod "0"
	*elseif (dex >= 12) and (dex <= 13)
		*set dex_mod "+1"
	*elseif (dex >= 14) and (dex <= 15)
		*set dex_mod "+2"
	*elseif (dex >= 16) and (dex <= 17)
		*set dex_mod "+3"
	*elseif (dex >= 17) and (dex <= 19)
		*set dex_mod "+4"
	*elseif (dex >= 20) and (dex <= 21)
		*set dex_mod "+5"
	*elseif (dex >= 22) and (dex <= 23)
		*set dex_mod "+6"
	*elseif (dex >= 24) and (dex <= 25)
		*set dex_mod "+7"
	*elseif (dex >= 26) and (dex <= 27)
		*set dex_mod "+8"
	*elseif (dex >= 28) and (dex <= 29)
		*set dex_mod "+9"
	*elseif dex = 30
		*set dex_mod "+10"
	*comment constitution modifier
	*if con = 1
		*set con_mod "-5"
	*elseif (con >= 2) and (con <= 3)
		*set con_mod "-4"
	*elseif (con >= 4) and (con <= 5)
		*set con_mod "-3"
	*elseif (con >= 6) and (con <= 7)
		*set con_mod "-2"
	*elseif (con >= 8) and (con <= 9)
		*set con_mod "-1"
	*elseif (con >= 10) and (con <= 11)
		*set con_mod "0"
	*elseif (con >= 12) and (con <= 13)
		*set con_mod "+1"
	*elseif (con >= 14) and (con <= 15)
		*set con_mod "+2"
	*elseif (con >= 16) and (con <= 17)
		*set con_mod "+3"
	*elseif (con >= 18) and (con <= 19)
		*set con_mod "+4"
	*elseif (con >= 20) and (con <= 21)
		*set con_mod "+5"
	*elseif (con >= 22) and (con <= 23)
		*set con_mod "+6"
	*elseif (con >= 24) and (con <= 25)
		*set con_mod "+7"
	*elseif (con >= 26) and (con <= 27)
		*set con_mod "+8"
	*elseif (con >= 28) and (con <= 29)
		*set con_mod "+9"
	*elseif con = 30
		*set con_mod "+10"
	*comment intelligence modifier
	*if int = 1
		*set int_mod "-5"
	*elseif (int >= 2) and (int <= 3)
		*set int_mod "-4"
	*elseif (int >= 4) and (int <= 5)
		*set int_mod "-3"
	*elseif (int >= 6) and (int <= 7)
		*set int_mod "-2"
	*elseif (int >= 8) and (int <= 9)
		*set int_mod "-1"
	*elseif (int >= 10) and (int <= 11)
		*set int_mod "0"
	*elseif (int >= 12) and (int <= 13)
		*set int_mod "+1"
	*elseif (int >= 14) and (int <= 15)
		*set int_mod "+2"
	*elseif (int >= 16) and (int <= 17)
		*set int_mod "+3"
	*elseif (int >= 18) and (int <= 19)
		*set int_mod "+4"
	*elseif (int >= 20) and (int <= 21)
		*set int_mod "+5"
	*elseif (int >= 22) and (int <= 23)
		*set int_mod "+6"
	*elseif (int >= 24) and (int <= 25)
		*set int_mod "+7"
	*elseif (int >= 26) and (int <= 27)
		*set int_mod "+8"
	*elseif (int >= 28) and (int <= 29)
		*set int_mod "+9"
	*elseif int = 30
		*set int_mod "+10"
	*comment wisdom modifier
	*if wis = 1
		*set wis_mod "-5"
	*elseif (wis >= 2) and (wis <= 3)
		*set wis_mod "-4"
	*elseif (wis >= 4) and (wis <= 5)
		*set wis_mod "-3"
	*elseif (wis >= 6) and (wis <= 7)
		*set wis_mod "-2"
	*elseif (wis >= 8) and (wis <= 9)
		*set wis_mod "-1"
	*elseif (wis >= 10) and (wis <= 11)
		*set wis_mod "0"
	*elseif (wis >= 12) and (wis <= 13)
		*set wis_mod "+1"
	*elseif (wis >= 14) and (wis <= 15)
		*set wis_mod "+2"
	*elseif (wis >= 16) and (wis <= 17)
		*set wis_mod "+3"
	*elseif (wis >= 18) and (wis <= 19)
		*set wis_mod "+4"
	*elseif (wis >= 20) and (wis <= 21)
		*set wis_mod "+5"
	*elseif (wis >= 22) and (wis <= 23)
		*set wis_mod "+6"
	*elseif (wis >= 24) and (wis <= 25)
		*set wis_mod "+7"
	*elseif (wis >= 26) and (wis <= 27)
		*set wis_mod "+8"
	*elseif (wis >= 28) and (wis <= 29)
		*set wis_mod "+9"
	*elseif wis = 30
		*set wis_mod "+10"
	*comment charisma modifier
	*if cha = 1
		*set cha_mod "-5"
	*elseif (cha >= 2) and (cha <= 3)
		*set cha_mod "-4"
	*elseif (cha >= 4) and (cha <= 5)
		*set cha_mod "-3"
	*elseif (cha >= 6) and (cha <= 7)
		*set cha_mod "-2"
	*elseif (cha >= 8) and (cha <= 9)
		*set cha_mod "-1"
	*elseif (cha >= 10) and (cha <= 11)
		*set cha_mod "0"
	*elseif (cha >= 12) and (cha <= 13)
		*set cha_mod "+1"
	*elseif (cha >= 14) and (cha <= 15)
		*set cha_mod "+2"
	*elseif (cha >= 16) and (cha <= 17)
		*set cha_mod "+3"
	*elseif (cha >= 18) and (cha <= 19)
		*set cha_mod "+4"
	*elseif (cha >= 20) and (cha <= 21)
		*set cha_mod "+5"
	*elseif (cha >= 22) and (cha <= 23)
		*set cha_mod "+6"
	*elseif (cha >= 24) and (cha <= 25)
		*set cha_mod "+7"
	*elseif (cha >= 26) and (cha <= 27)
		*set cha_mod "+8"
	*elseif (cha >= 28) and (cha <= 29)
		*set cha_mod "+9"
	*elseif cha = 30
		*set cha_mod "+10"
		*goto name

I suggest using a loop (and an array with the name of the stats), since the logic for each stat seems to be the same. Also, am I right to guess you’re using DnD’s mod formula (-10, dive by 2, round down)? If so, why not use the formula, instead of hard-code the value mapping?

Here’s my take on it, using the loop and DnD’s formula.

*comment @startup.txt
*create_array stats 6 "str" "dex" "con" "int" "wis" "cha"
*comment length of the array
*create stats_length 6

*create str 13
*create dex 10
*create con  9
*create int 12
*create wis 12
*create cha 10

*create str_mod 0
*create dex_mod 0
*create con_mod 0
*create int_mod 0
*create wis_mod 0
*create cha_mod 0


*gosub update_mods
*finish


*comment @utils.txt
*label update_mods
*temp i_ 1
*label update_mods__loop_start
*comment 
*set { stats[i_]&"_mod" } round((({stats[i_]}-10)/2)-0.5)
${stats[i_]}: ${{stats[i_]&"_mod"}}[n/]
*comment 
*set i_ +1
*if (i_ <= stats_length)
    *goto update_mods__loop start
*return

I’m not super familiar with loops so I’ll have to do some research on that. As for the dnd mod formula, I was using a chart as I was not aware there was a formula. That will definitely make it easier.

Thanks for including code! Would you mind explain the last bit from the comment @ utils.txt?

An array is a list of values, in this case, strings (pieces of text). We saved the name of the variables.

*create_array stats 6 "str" "dex" "con" "int" "wis" "cha"

We’ll use the array_length to check for the end of the loop.

To make a loop, you declare a counter (i_) to track the current iteration, at the end of each iteration you increment it by one (*set i_ +1) and check against a condition (*if (i_ <= stats_length)) to see if the loop should continue (*goto update_mods__loop start).

Inside the loop, we use the array to get the name of the variable (stats[i_]) and concatenate with the suffix “_mod” (stats[i_]&"_mod"). Then we use the reference syntax ({ stats[i_]&"_mod" }) to set the value. When you use curly braces around a string, ChoiceScript will interpret that string as the name of a variable.

Suppose stats[i_] yields “str”, then stats[i_]&"_mod" will be “str_mod”. Using reference syntax, *set { "str_mod" } ... is the same as *set str_mod ..., but we’re doing it dynamically.

Finally, we use the DnD formula: attribute minus 10, dived by 2, rounded down.

Attribute: {stats[i_]} (reference syntax)
Minus 10: {stats[i_]}-10
Divided by 2: ({stats[i_]}-10)/2
Rounded down: round((({stats[i_]}-10)/2)-0.5)

Notice I subtract -0.5 before rounding. This is a neat trick to guarantee it’s going to round down. The function round always rounds to the nearest integer, either up or down. So a decimal on the upper half (e.g. 1.8) would round up (to 2), but if we subtract 0.5 first, we guarantee it goes to the bottom half (i.e. 1.3) and round down. On the other hand, if it’s already on the bottom half (1.3) it would lower to the upper half of the previous integer (from 1.3 to 0.8) and then round up back to the previous integer of the original value (i.e. 1).

2 Likes

Thank you! Your explanation is super helpful. I understand the code better now. I really appreciate your help.

Not to pile on with more problems but there’s a new error. It’s saying there’s “Too many arguments; expected name, size, and (optionally) a default value.” I want to make sure I did this right.

I put this in startup.txt

This in the chapter file I want to loop in.

And this in a new utils.txt file.

I’m guessing the error is from the create_array command, right? Are you sure yours is exactly like mine? It works fine for me. This is how the create_array works:

*create_array <name> <length> <values in order>

In values, you either pass a single value, which is going to be set for all slots of the array, or you pass as many values as the length of the array, so it will save each velue in one slot in order.

Could it be a difference in ChoiceScript version? :thinking:


FYI, you’ll have to update the gosub command to gosub_scene to call the subroutine in a different file.

*gosub_scene utils update_mods

I copied it exactly. The text is all white though. I’m using CSIDE if that matters. And I’m pretty sure I have the latest version of CSIDE and ChoiceScript. I downloaded it all like 2 weeks ago.

You might want to ask in the CSIDE thread, I know there’s been some issues with the auto-update recently, so you might not actually have the latest. I used the web version and it worked fine.

I any case, you might try this instead:

*create_array stats 6 ""

*comment these "set" commands will have to go at the end of startup file after all the "create" commands

*set stats[1] "str" 
*set stats[2] "dex" 
. 
. 
. 

Manually set all the stat names to the stats array.

1 Like

I switched to the web version of CSIDE, and the array works now. Except, I’m getting this error now “line 11 of utils: bad label update_mods__loop start”.

___

Never mind. I fixed the error :laughing:

1 Like

You’re missing an underscore between loop and start. It should be a single word. You can call it anything you like, though. I was just being didactic.

1 Like