0 votes
by (960 points)
edited by

Just about an error with the prototype I created...


$player_Shoes story variable Init on StoryInit...
<<set $player_Shoes = ['Sport shoes', 'Casual shoes', 'Hells', 'Slippers']>>
Player Init on StoryInit
<<set $clothes = {
	top: ['White T-shirt'],
	bottom: ['Feminine simple jeans'],
	bra: ['Black full cup bra'],
	undewear: ['Black simple panties'],
	shoes: ['Flats shoes']
Player Closet on the passage
<<for _a, _shoes range $player.Shoes>>
	<<link '_shoes' 'Closet'>>
		<<set $player_Tops.push($clothes.top[0])>>
		<<set $clothes.top[0] = $player_Tops.deleteAt(_a)>>

As in my previous post I was instructed on deleteAt although the current list only exchanges the first item in the list, I tried something like...

To avoid more errors here are the prints...

As I show in practice too, the only real error is the selection of the item to use. _a does not seem to work for this. The actual error is that in a list of items like in the last print, when you select any of them the item is not selected, it seems to be an error with _a.

2 Answers

+1 vote
by (35.5k points)
selected by
Best answer

There were a bunch of errors in your code.  Mainly, you were mixing code for tops and shoes together.  The corrected code should look like this:

<<for _a, _shoes range $player_Shoes>>
	<<capture _a>>
		<<link _shoes "Closet">>
			<<set $player_Shoes.push($clothes.shoes[0])>>
			<<set $clothes.shoes[0] = $player_Shoes.deleteAt(_a)[0]>>

Here were the errors:

  1. You had "$player.Shoes" instead of "$player_Shoes" inside the <<for>> macro.
  2. You needed to use the <<capture>> macro as greyelf pointed out.
  3. Technically, you shouldn't have "_shoes" in quotes in quotes inside the <<link>> macro.
  4. You had "$player_Tops" instead of "$player_Shoes" inside the <<set>> macros.
  5. You had "$clothes.top[0]" instead of "$clothes.shoes[0]" inside the <<set>> macros.
  6. Because the .deleteAt() method returns an array, you need a "[0]" at the end to get the value of the first element in that array (as explained earlier).
  7. Also, you misspelled "Heels" as "Hells".  :-P

Now that that's all sorted out it should work.

Also, if you want to make it so that the passage doesn't have to refresh every time you click an item, you could create another passage, let's call it "Display Closet", and use an <<include>> macro inside of a <span> or <div> element with a unique ID to include the "Closet" passage in that new passage.  Then, in the "Closet" passage, remove the "Closet" part from your <<link>> and add a <<replace>> macro after the <<set>> macros which replaces the contents of the <span> or <div> with that same <<include "Closet">> line from earlier.  That will cause the text there to be updated with the new information every time the user clicks an item.

In other words your "Display Closet" passage would look like this:

<div id="contents"><<include "Closet">></div>

And the code in the "Closet" passage would have to be changed like this:

<<for _a, _shoes range $player_Shoes>>
	<<capture _a>>
		<<link _shoes>>
			<<set _tmp = $clothes.shoes[0]>>
			<<set $clothes.shoes[0] = $player_Shoes[_a]>>
			<<set $player_Shoes[_a] = _tmp>>
			<<replace "#contents">>
				<<include "Closet">>

(I also changed the code to swap items, because it will look better when displayed this way.)

That would make it basically reload the "Closet" passage within the "Display Closet" passage, without causing the "refresh blink" you're seeing currently.  Then you'd just need to change any links to "Closet" elsewhere in your code to open the "Display Closet" passage instead.

If that's a little confusing, see this "Simple Update Without Reload" sample code which explains how it all works.  (Click the "Jump to Start" link in the UI bar to see other sample code.)

The one downside to this method is that if you change your clothes and then save your game without going to another passage first, then when you reload your clothes will be back to what they were when the passage originally loaded, instead of what they were when you saved.  If you go to another passage before saving then everything will be saved just fine.  There is a workaround for that problem, if you're interested.

Have fun!  :-)

EDIT: If you saw a version of this within the first 45 minutes of posting, I caught another error I missed earlier and added a few more notes.

by (960 points)
I have remaked my steps earlier, in fact I need to pay attention to those little details but I appreciate the response.
+1 vote
by (144k points)

The contents of your <<link>> macro isn't executed until after the end-user has selected that link, which means the value of the _a variable will not be available at that time due to it being a temporary variable owned by the <<for>> macro.

The issue would still exist even If you changed that variable to be a story variable instead, because the current value of such a story variable would equal a different value to it had at the time that the link was created.

You need to use the <<capture>> macro to get around this issue. (untested code)

<<for _a, _shoes range $player.Shoes>>\
	<<capture _a>>
		<<link '_shoes' 'Closet'>>
			<<set $player_Tops.push($clothes.top[0])>>
			<<set $clothes.top[0] = $player_Tops.deleteAt(_a)>>


by (960 points)
To be honest even with <<capture>> the result is the same.
by (144k points)

You don't show how you initialised the $player_Tops story variable, the $clothes.top property, or the $player.Shoes property, and this makes it difficult for us to debug your code examples.

You also didn't explain what exactly isn't working.

So I can only check for obvious errors like you trying to reference the _a temporary variable outside the Scope that it exists in, which is why I explain the need to use the <<capture>> macro.

by (960 points)
I understand and I'm sorry, it was my mistake, I'm going to re-create my post with the information.
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.