Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Multiple true answers of a list?

Hello, I'm compeletly new to twine (using 1.4.2. since I found more solutions to my problems there, still not sure if I should switch to 2 though) and I can't for the life of me figure out how to do what I want to.

What I want to do:
- The player will enter their name
- An NPC will not like that name and give the player a new one out of a list of names (go to Passage 01B)
OR the name the player gave is on that list and the NPC will like it (got to 01A)

I got the first part working:
<<textinput $playername [[Done|01]] >>

<<set $setlistname to either("Carl", "Bob", "Ted")>>
<<$playername>>
<<$setlistname>>

But I can't get the second working. I found a similar topic that explains part of the problem ""Either" only choosing last option on specific variable" , so "Ted" is always true but the others are false... Should I be using a different function/operator? Is there a logic error? Would it be easier and/or should I switch to Twine 2?
<<if $playername is ("Carl", "Bob", "Ted")>> [[NPC likes|01A]] <<else>> [[NPC dislikes|01B]] <<endif>>

Comments

  • edited May 2017
    To your main point, the easiest thing to do here would be to make an array, which is a type of variable that stores multiple values--each value is given an index, which is the number associated with each value (this list of numbers is 0-based). For example, if you make the array <<set $array to [ 'this', 'that', 'the other' ] >>, you can find a specific value in the array by using the 0-based index, so $array[1] would be 'that', and $array[0] would be 'this'. The reason you want to use arrays here is because you can search through arrays to see if a specific value (or set of values) is present. Here's a brief test-case I whipped up:
    <<set $name to ''>>
    <<set $nameList to [
    	'Bob', 'Anne', 'Bill', 'Jim'
    ]>>
    
    <<textinput $name [[Submit|next]]>>
    

    Then, in the 'next' passage, we test the string we've been given against the array:
    <<set $name to $name.trim()>>
    <<set $name to $name.toLowerCase()>>
    <<set $n to $name.charAt(0).toUpperCase()>>
    <<set $name to $name.slice(1)>>
    <<set $name to $n + $name>>
    <<if !$nameList.includes($name)>>
    	<<$name>>, huh?  That's a a stupid name.  I'm gonna call you <<set $index to Math.floor(Math.random()*$nameList.length)>><<set $name to $nameList[$index]>><<$name>> instead.  Now that's a fine name.
    <<else>>
    	<<$name>>, huh? I like that name.
    <<endif>>
    
    [[continue]]
    

    You'll notice things like '.trim()' and '.charAt(0)', etc. These are standard JavaScript methods. Since Twine is JavaScript, you can, in most cases, use them. I'm using the following methods:

    trim(): removes whitespace (so if the player enter ' Jim ' it'll become 'Jim')

    toLowerCase(), CharAt(), toUpperCase, and slice(): I used these methods to format the string to have it's first letter capitalized and the rest lower-case. We need to do this, since 'Jim', which is an acceptable name according to the $nameList array, is not equal to 'jim'. Plus, it'll make it look nice no matter what the player enters.

    includes(): here's the meat and potatoes. We'll check our formatted string to see if the player's entry matches any of the values in our array. I have this <<if>> statement set up with the negation operator ('!') because I want to know if the player isn't using an acceptable name, so I can change it.

    <<set $index to Math.trunc(Math.random()*$nameList.length)>><<set $name to $nameList[$index]>><<$name>>: Using the length of our list of names, we generate a random number, then truncate any potential fractional parts from the number. This will return a random number corresponding to one of our array's indices. We then use the resulting random number to set the players name: <<set $name to $nameList[ a random index ]>>.
    But I can't get the second working. I found a similar topic that explains part of the problem ""Either" only choosing last option on specific variable" , so "Ted" is always true but the others are false... Should I be using a different function/operator?

    I remember answering a post about this a while ago, and if it's the one I'm thinking of, the problem had nothing to do with either(), and everything to do with the author adding a statement that un-randomized the variable.

    They had something like:
    <<set $var to either(1, 2, 3)>>
    
    <<if $var = 1>>...
    <<elseif $var = 2>>...
    <<elseif $var = 3>>...
    <<endif>>
    

    In Twine (and in JavaScript) '=' is not a comparison operator, it's an assignment operator. Essentially, the last <<elseif>> statement was being parsed as though it said <<set $var = 3>>, and so the variable was always 3. You have to use '==' or '===' to compare values (or the Twine keywords 'eq' and 'is', respectively).

    So your value isn't/shouldn't be 'Ted' all the time. If it is, something somewhere else is wrong.
    <<set $setlistname to either("Carl", "Bob", "Ted")>>
    

    You were on the right track, but keep in mind what either() does--it stashes one of the arguments provided in the variable (selected at random), not all of them.

    Finally, you probably shouldn't use Sugarcane, as it isn't actively supported, at least to my knowledge, and SugarCube 2 is a more feature-rich format with very similar syntax. Both SugarCube 1 and 2 are available for Twine 1.4.x. SugarCube would make doing what you want to do here possible in half the lines of code, too.
  • I got it working like I wanted now, better then I would have managed on my own (I would not have even started to think about learning java). Unless I want to get fancy this should be the extent of coding there is to do (besides CSS). Thank you for your time and knowledge.
  • Deviate wrote: »
    I would not have even started to think about learning java.
    That is Javascript.

    Java is a totally unrelated programming language which unfortunately Javascript has a similar name too, this fact has confused many people over the years.
Sign In or Register to comment.