Howdy, Stranger!

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

Sugarcube 2.7.0 - Temporarily trigger text format on event

Hello Twine Community,

@.shudder format for a second, and then stop.

I've read some other threads, and I can see how to apply the custom style to specific text in a passage. Ideally, I'd like to add code to the widget macro, so that each time the experience value changes, the text shudders briefly so the player notices it, then stops. The macro I'm using is:
<<widget "stats">>\
<<if $checkloginteacher is true>><<set $player.experience to $player.experience + 5>><</if>>\
<<if $checkopenteams is true>><<set $player.experience to $player.experience + 5>><</if>>\
<b>Experience: <<=$player.experience>>
Rank:<<if $player.experience lt 20>> What is TEAMS? <<elseif $player.experience lt 40>> Novice <<elseif $player.experience lt 60>> I'm starting to get it <<elseif $player.experience lt 80>> Almost there <<elseif $player.experience lt 100>> Master TEAMS Player
</b><</if>>\
<</widget>>

Is it possible to add an <<if>> clause such that when an experience value changes, a custom effect is applied to $player.experience?

Thank you!

Comments

  • Before I get to your question. Code like the following, where you compare a sub-expression to one of the boolean literals:
    <<if $checkloginteacher is true>>
    
    Don't do that. Conditional expressions resolve to booleans, so testing a boolean value against a boolean literal, just to yield another boolean, is redundant. If your sub-expression yields a boolean value by itself, then simply use the sub-expression as the full conditional. For example:
    → BAD
    <<if $checkloginteacher is true>>
    
    → GOOD
    <<if $checkloginteacher>>
    


    Now, on to your question.

    First. Unless you already have a way to shake/shudder/rumble your text, you will probably want to download the <<shake>> macro set add-on from SugarCube 2's website (under: Downloads > Add-ons). Installation and usage instructions are included within the package.

    Once you have a way to shake your text, how you might apply that when the player's experience changes depends on where/how you're using your <<stats>> widget. So, yeah, we're going to need some details.
  • Cool. Thanks for the tips and the link. I've altered my conditionals to use only the sub-expressions as the conditionals.

    I've downloaded and installed the <<shake>> macro. As far as the usage of the stats macro goes, I'm including it at the top of each passage to display the running experience points and rank of the player.

    I can write an <<if>> conditional that checks $player.experience, but I'm not sure what operator to use, since I haven't found one for "increase value."

    I did try to work <<shake>> into the macro by having it execute on $player.experience along with the existing <<if>>, but that only displayed $player.experience and shook it in front of the macro, not as a part of the macro:
    <<widget "stats">>\
    <<if $checkloginteacher>><<set $player.experience to $player.experience + 5>><<shake 1s>>$player.experience<</shake>><</if>>\
    

    I also thought I may be able to shake the value by just executing the macro around the <<if>> result:
    <<if $checkloginteacher>><<shake 1s>><<set $player.experience to $player.experience + 5>><</shake>><</if>>\
    

    Thanks so much for taking the time to answer these.
  • If you want the experience value you're normally printing to shake, then try something like the following:
    <<widget "stats">>\
    <<if $checkloginteacher>><<set $player.experience to $player.experience + 5>><</if>>\
    <<if $checkopenteams>><<set $player.experience to $player.experience + 5>><</if>>\
    <b>Experience: <<if $checkloginteacher or $checkopenteams>><<shake 1s>>$player.experience<</shake>><<else>>$player.experience<</if>>
    Rank: <<if $player.experience lt 20>>What is TEAMS?<<elseif $player.experience lt 40>>Novice<<elseif $player.experience lt 60>>I'm starting to get it<<elseif $player.experience lt 80>>Almost there<<elseif $player.experience lt 100>>Master TEAMS Player<</if>></b>\
    <</widget>>
    
    Assuming that your widget is the only place you increase $player.experience, that will shake the experience value whenever either of the conditions which result in experience being gained are true, otherwise it will be printed normally.

    Also, based on your code, your closing bold tag should probably be outside of the rank <<if>>, rather than with the final <<elseif>>—I've done so in my example above.
  • Thanks. I just noticed that "Rank: Master TEAMS Player" was printing with </b> after...

    I'm going to be adding quite a few additional variables other than $checkloginteacher and $checkopenteams, so to avoid having to enter all of them into the <<if>>, I'd like to find a way to say:
    <<if $player.experience != previous>><<shake 1s>>$player.experience<</shake>>
    <<else>>$player.experience
    <</if>>
    

    My concern here is that since usually, I award experience on the slide after something was done, the program won't see that the change was made until the third passage in a sequence. For example:

    Passage 1:
    What is the student ID number? 
    <<textbox "$q2" "">>
    

    Passage 2:
    <<$q2 is "106700">>
    	That's correct! Nice job!
    	<<set $player.experience to $player.experience + 10>>
    <<stats>>
    

    After the experience is calculated, the stats macro runs to display the total running exp so far. Since the experience is updated on the same passage, I'm worried that the <<shake>> wouldn't take effect until the next slide.

    As an alternative, is there a way to calculate input on the same passage where it is input?I thought about trying to use postdisplay or postrender, but those are a bit above my skill level.
  • hausrath wrote: »
    I'm going to be adding quite a few additional variables other than $checkloginteacher and $checkopenteams, so to avoid having to enter all of them into the <<if>>, I'd like to find a way to say:
    <<if $player.experience != previous>><<shake 1s>>$player.experience<</shake>>
    <<else>>$player.experience
    <</if>>
    
    You may do almost exactly that. You simply need to update the "previous" value within the same clause as the shake. The only change would be that you'd need to use another story variable—or another property on $player—to hold the "previous" value. For example: (whitespace added for readability)
    <<if $player.experience isnot $player.previousExp>>\
    	<<shake 1s>>$player.experience<</shake>>\
    	<<set $player.previousExp to $player.experience>>\
    <<else>>\
    	$player.experience\
    <</if>>
    

    hausrath wrote: »
    My concern here is that since usually, I award experience on the slide after something was done, the program won't see that the change was made until the third passage in a sequence. For example:

    […]

    After the experience is calculated, the stats macro runs to display the total running exp so far. Since the experience is updated on the same passage, I'm worried that the <<shake>> wouldn't take effect until the next slide.
    The shake will take effect as part of the invocation of <<stats>>, since that's where it's located.

    As far as the ordering goes, passages are processed top down. As long as the call to <<stats>> happens after any experience modifications within the same passage, or prior to it, then the widget should be able to respond to them without issue.

    hausrath wrote: »
    As an alternative, is there a way to calculate input on the same passage where it is input?I thought about trying to use postdisplay or postrender, but those are a bit above my skill level.
    Assuming you mean with a macro like <<textbox>>, then no. They weren't written with that in mind.
  • Very nice. Thanks once again. It works perfectly as designed.
Sign In or Register to comment.