Howdy, Stranger!

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

Sugarcube 2.7.0 — Click & Return macros with Setter for multiple variables?

edited August 2016 in Help! with 2.0
I'm coming up against a wall with this so any help (or maybe a better implementation, if I'm doing something stupid?) would be appreciated.

My inventory system is a page of icons accessible from the sidebar where, ideally, the player clicks between gear they've obtained to put something else on and then the inventory page returns them to wherever story page they were before they clicked Inventory in the sidebar. Also, on clicking on the icon, it needs to set a couple of variables to adjust the stats associated with the item they're newly wearing.

I can get this partly working with the <<click>> macro, but the problem is that I can't seem to also implement the "go back to the page you were on before" because <<click>> requires a link to go to, and I don't want there to be one (just the "go back" part.)

This code works fine for what I want:
<<click "Test" "Text">><<set $no to "Worked!">><<set $go to "Also worked!">><</click>>

The two variables there work fine and everything is lovely.

If I do this, however:
<<click>><<set $no to "Worked!">><<set $go to "Also worked!">><<return>><</click>>

It breaks, because <<click>> requires an explicit link to go to, and the <<return>> part is ignored.

I've tried implementing Engine.backward, but I can't seem to work in the variable setting and it also seems to undo instead of pushing forward to last page before the Inventory one. The regular Text][Setter also only appears to work with a single variable, and I need to be able to change as many as I wish.

Any suggestions?

Comments

  • edited August 2016
    Click doesn't require an explicit link - it requires a title. For example:
    <<click "no link">><<set $variable to 2>><</click>>
    

    Will create a link called "no link" that looks like a normal link but simply activates the set command when clicked and doesn't go anywhere. Your second click macro is hence missing the link title.

    However, I don't think <<return>> can be placed inside a click macro since it is a click macro in itself.

  • edited August 2016
    My inventory system is a page of icons accessible from the sidebar where, ideally, the player clicks between gear they've obtained to put something else on and then the inventory page returns them to wherever story page they were before they clicked Inventory in the sidebar. Also, on clicking on the icon, it needs to set a couple of variables to adjust the stats associated with the item they're newly wearing.

    A better way to approach this would be to create a separate passage type that would have its visibility set to hidden. Then when you click on the sidebar icon it makes this passage visible and the main passages hidden. This is a better solution because the inventory no longer relies on <<return>> to work. It's essentially always there on top of your existing passages, just hidden until it's called up.

    Creating a new passage is as simple as writing this in javascript passage:
    postrender["updateInventory"] = function () {
    	setPageElement("inventory", "Inventory");
    };
    

    Then in the Twine editor, you'd create a new passage called "Inventory" and style it in css. Eg
    #inventory {
    
    }
    

    Also would need to create the div in the source html or attach a div via javascript.

    Then you can use the <<addclass>> macros inside a <<click>> macro to add css classes that control the fade in and out of the inventory and main passages.

    It's kinda complex so I won't explain every step but that's the general gist of it. On the SugarCube website there's a test story called "right hand side box" that introduces these concepts that you can look at for example code.

    http://www.motoslave.net/sugarcube/download.php/1/examples/example-rhs-box.zip

    You'll need to access it using Twine 1.4, though the code can be copied across to your story.
  • This comment in the How to quit a circular previous() thread explains another way to solve your problem, it was written for Twine 1 and SugarCube 1.x

    The only modification needed to make that solution work using Twine 2 and SugarCube 2.x would be to change the instructions and code in point 2 to be.

    2. Put something like the following in your story's Story Javascript area:
    prerender["setReturn"] = function () {
    	if (tags().indexOf("inventory") === -1) {
    		State.variables["return"] = passage();
    	}
    };
    

    If you want to also update variables when the Return link is clicked then change point 3 to either of the following:
    /% Using a Setter Markup Link. %/
    [[Return|$return][$var to "value"]]
    
    /% Using a click macro. %.
    <<click "Return" $return>><<set $var to "value">><</click>>
    
  • Hey greyelf thanks for that — that's probably going to be more helpful for me (although Claretta's suggestion is a nicer-looking implementation, it's probably beyond my skillset to come up with.)

    Unfortunately after adding the code and clicking the Return link, it doesn't return to the previous panel that the player came from and instead just returns to the Inventory page. I have the inventory tag in the passage, so I'm not sure what's going wrong.
  • mixvio wrote: »
    I have the inventory tag in the passage
    You have added the inventory tag to only the passage(s) that actually displays the Inventory contents and options, not in any story based passages?

    eg. Example story consists of 10 story based passages as well as 2 passages used to display and modify the contents of the player's inventory, the 'inventory' tag is only added to the 2 passages!
  • edited August 2016
    greyelf wrote: »
    This comment in the How to quit a circular previous() thread explains another way to solve your problem, it was written for Twine 1 and SugarCube 1.x
    Actually, it was written for Sugarcane, though it will work in some versions of SugarCube.

    For SugarCube 2, I would actually recommend something like the following:
    prerender["setReturn"] = function () {
    	if (tags().contains("inventory")) {
    		State.variables["return"] = passage();
    	}
    };
    

    mixvio wrote: »
    Unfortunately after adding the code and clicking the Return link, it doesn't return to the previous panel that the player came from and instead just returns to the Inventory page. I have the inventory tag in the passage, so I'm not sure what's going wrong.
    You need to tag each and every passage that is part of your inventory with the inventory tag, spelled exactly as it is in the code examples. Also, you must ensure that it is not possible for the player to go to a non-inventory passage, while in the inventory, except by returning from the inventory first.

    mixvio wrote: »
    I've tried implementing Engine.backward, but I can't seem to work in the variable setting and it also seems to undo instead of pushing forward to last page before the Inventory one.
    Directly from its documentation:
    Rewinds the full history by one moment (i.e. undoes the moment)
    I think that's pretty clear about what it does, honestly.

    mixvio wrote: »
    The regular Text][Setter also only appears to work with a single variable, and I need to be able to change as many as I wish.
    The setter portion works exactly like a <<set>> macro does. Meaning that you can set more than one variable by separating each assignment expression with semi-colons or commas. For example, all of these do essentially the same thing:
    /* Using a wiki link markup with setter. */
    [[Return|$return][$a to "value"; $b to 42]]
    
    /* Using a <<click>> macro with one <<set>> macro. */
    <<click "Return" $return>><<set $a to "value"; $b to 42>><</click>>
    
    /* Using a <<click>> macro with two <<set>> macros. */
    <<click "Return" $return>><<set $a to "value">><<set $b to 42>><</click>>
    
  • For SugarCube 2, I would actually recommend something like the following:
    prerender["setReturn"] = function () {
    	if (tags().contains("inventory")) {
    		State.variables["return"] = passage();
    	}
    };
    
    That assigns the name of the current inventory tagged passage to the $return variable, shouldn't the if statement be inverting the true/false value returned by contains?
  • Ah, yes, you are correct. Here's a version with the corrected logic:
    prerender["setReturn"] = function () {
    	if (!tags().contains("inventory")) {
    		State.variables["return"] = passage();
    	}
    };
    
    That's the second time I wasn't paying enough attention today. Going to bed now.
  • edited August 2016
    I used the updated code and still get the same result, IE the returned page is just the inventory one. The "inventory" tag is spelt that way and only used on the single page that is the inventory.

    The Inventory page is only accessible from a link on the sidebar; when clicked it goes to the Inventory passage, and once the player selects the item they wish to "put on" I want it to return to the previous story passage they were on when they clicked the sidebar button. So far, that's not happening even though I'm following everything here.

    I also changed it from the <<click>> macro to the Return one you shared a couple posts up, and all that happened was twine made a new passage titled $return and the link brings me through to that.
  • Actually nevermind; I went back and checked the tag and even though I had put inventory in and moved to other passages, twine was waiting for me to confirm it with a checkmark button. When I did so the <<click>> macro works fine, just not the Link one.

    However now I have a new headache, when the player clicks into the inventory from a passage that handles gameplay logic that runs on landing on it, that logic runs a second time which isn't ideal.

    Is there a way to have the inventory button be disabled on certain passages, or otherwise ensure that the player is returned to the previous page in the same state they left it?
Sign In or Register to comment.