Combining <<if>> and <<if hasVisited>>

Twine Version: 2.3.14
Sugarcube 2.34.1

I am having trouble with the <<if>> macro when combining it with <<hasVisited>>. I have two versions of text that appear if you’ve visited the passage more than once, but I’m also trying to combine this with <<hasVisited>> to show a third version of text if they’ve visited a certain passage. I’m wondering if I’ll have to find a different work around since the two <<if>> statements are conflicting.

Here’s how it’s laid out in the passage:

<<if visited() == 1>><<set $clothes to true>>
You pull open the wardrobe. 
You get changed into a suit and throw on your white coat.

[[Desk]] 

[[Rocking chair]] 

[[Answer the door]] 

<<elseif visited() gte 1>><span class="Phil">It's a miracle these clothes fit at all.</span>

[[Desk]]
[[Rocking chair]]
[[Answer the door]] 

<</if>>

<<if hasVisited("Phil's room cont.") gte 0>> The clothes hang loosely on your body. The hem of your white coat, faded and smudged with dust and debris.

[[Desk]] 

[[Rocking chair]] 
</if>

The error I’m getting when playing through the passage is Error: cannot find a closing tag for macro <<if>> over the <<hasVisited>> passage. The passage worked fine until I added the additional <<hasVisited>> line.

TIA!

Because you have </if> at the end instead of <</if>>. You are missing a set of < >

2 Likes

@Hituro is right about why you’re getting the error message you’re getting, but also, (1) hasVisited() returns a boolean value rather than a number, so you shouldn’t really be using gte with it, and (2) gte means “greater than or equal to,” so even if you were using visited() (which does return a number), what you’re saying right now is “if the player has visited this passage any number of times or has not visited it at all” – which is to say that that “if” condition will always fire. Assuming what you want is for the message to display if “Phil’s room cont.” has been visited and not if it hasn’t, what you want is <<if hasVisited("Phil's room cont.")>>.

(If you did want to work with a numerical value instead, it would be <<if visited("Phil's room cont.") gt 0>> – note that that’s gt, not gte.)

2 Likes

Thanks for clarifying! I’ve changed my hasVisited lines to <<if hasVisited("Phil's room cont.")>>. I’ve also repositioned the conditions in the passage and it seems to be working. Below is the new version of the previous code:

<<if visited() == 1>><<set $clothes to true>>
You pull open the wardrobe. 
You get changed into a suit and throw on your white coat.

[[Desk]] 

[[Rocking chair]] 

[[Answer the door]] 


<</if>>

<<if hasVisited("Phil's room cont.")>> The clothes hang loosely on your body. The hem of your white coat, faded and smudged with dust and debris.

[[Desk]] 

[[Rocking chair]]

<<elseif visited() == 2>><span class="Phil">It's a miracle these clothes fit at all.</span>

[[Desk]]

[[Rocking chair]]

[[Answer the door]]
<</if>>

I guess my question now is, does position of conditions within the passage really effect how it runs or did I just stumble into a solution? To compare, this passage fires both the <<elseif visited() == 2>> and the if hasVisited("Phil's room cont.")>> lines in the old order:

<<if visited() == 1>>On the desk are four little notes with <span class="handwriting">"Thank you!"</span> written on the cover.

[[Read the thank you notes|Thank you notes]]

[[Look around the room|Phil's room]]

[[Answer the door]] 

<<elseif visited() == 2>> Etchings from the previous owner left grooves and ditches in the sapped wood.

[[Thank you notes]]  

[[Look around the room|Phil's room]]

[[Answer the door]] 
<</if>>

<<if hasVisited("Phil's room cont.")>>Four thank you notes are proped up on the dilapidated desk.

[[Thank you notes]] 

[[Look around the room|Phil's's room cont.]]

<</if>>
1 Like

(Forgive me if this isn’t the question you were asking) yes, the position matters in these ways - the passage is interpreted from start to finish in that order; and elseif is only tested if the preceding if and elseifs are false.

So in the first version above, if you have visited this passage once before, and have visited “Phil’s room cont.”, the first if is true so that is printed, the second if is also true, so that is printed, and then the else-if is ignored (and is false anyway). But if you have visited this passage twice before, and visited “Phil’s room cont.”, the first if is false, so doesn’t print, the second if is true, so that is printed, and the elseif is ignored even though it is true.

Whereas if you haven’t visited “Phil’s room cont.” but you have visited this passage three times, nothing is printed as all statements are false. And so on.

1 Like

This was exactly my question, thank you! This has been a big help!

I think you got it, but to put it another way…

A set of <<if>> ... <<elseif>> ... <<elseif>> ... <<else>> ... <</if>> is a single unit and you can only run one of those clauses. The later conditions only get checked if the earlier ones fail.

But when you have separate <<if>> ... <</if>> and <<if>> ... <</if>> blocks, then both of them can run if their conditions allow: they don’t know anything about each other.

2 Likes