0 votes
by (170 points)
edited by

Hello! I've been doing an exhaustive research and still can't find a solution to my problem, if you could help me figure it out it would be much appreciated.

I'm creating an inventory system in a not very efficient way, but since I'm new to Twine hard coding seemed like the most safe approach.

I've populated an array with items(datamaps) which have a bool stating if the player has the item or not.

In an inventory widget, I use a for loop to take those items with the bool set to true and proceed to create a div wich displays an image of the object, it's name and description.

<<set $imageName to "--image">>

<<set $inventory to Object.keys($objects)>>
<<for _i to 0; _i< $inventory.length; _i++>>
    <<set _obj to $objects[$inventory[_i]]>>
	<<set $imageIndex to _i>>
	<<set $imageIndex +=1>>
	<<set $imageName to $imageName + $imageIndex>>

    <<capture _obj>>
      <<if _obj.hasItem>>
	  <div class = "row">
        <div class = "column left" style="background-image: var($imageName);"> </div>\
        <div class = "column right">\
        <b><i>_obj.name</i></b>

        _obj.description
        </div>
        </div>
      <</if>>
    <</capture>>
<</for>>

In the stylesheet i have a couple of variables containing the url to be displayed in each case:

:root {
  --image1: url(https://vignette.wikia.nocookie.net/fallout/images/0/0a/Scrap_metal.png/revision/latest?cb=20140406155837);
  --image2: url(https://image.freepik.com/free-icon/bandage-cross_318-61786.jpg);
}

This works just fine if in "background-image" when passing the css var name i just put --image1. It does not when I use $imageName (which is also --image1).

This is a problem because i need the index of the image to change for each object.

 

Thank you very much in advance.

 

Edit: I tried making a new parameter named imageurl in each object and using that instead. No errors but image doesn't show :/

2 Answers

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

note: You didn't supply the CSS for your .row, .column, .left, and .right classes so I had to guess what it looked like, as the background images won't show without the related div elements having a height value.

1. The main issue with your 1st example is that you are trying to reference the $imageName story variable directly within the String value being assigned to style attribute, and you can't do that without using Attribute Directive markup. The following is a modified version of your example.

/* Some test data. */
<<set $objects to {
	"banana": {
		name: "Banana",
		description: "A Banana",
		hasItem: true
	},
	"apple": {
		name: "Apple",
		description: "An Apple",
		hasItem: true
	}
}>>

/* Show the inventory. */
<<set _inventory to Object.keys($objects)>>\
<<for _i to 0; _i< _inventory.length; _i++>>
	\<<set _obj to $objects[_inventory[_i]]>>
	\<<set _style to "background-image: var(--image" + (_i + 1) + ");">>
	\<<if _obj.hasItem>>
		\<div class="row">
			\<div class="column left" @style="_style"></div>
			\<div class="column right">
				\<b><i>_obj.name</i></b>
				\<br>_obj.description
			\</div>
		\</div>
	\<</if>>
\<</for>>


2. Your solution is also using some advanced CSS functionality like the :root pseudo-class and the CSS variables var() function, and neither of these features are available within all the commonly used web-browsers (as you can see in the Browser compatibility section of the MDN pages I linked to).

The following example uses your suggestion of changing the items with the $object variable to include an imageurl property.

/* Some test data. */
<<set $objects to {
	"banana": {
		name: "Banana",
		description: "A Banana",
		imageUrl: "https://vignette.wikia.nocookie.net/fallout/images/0/0a/Scrap_metal.png/revision/latest?cb=20140406155837",
		hasItem: true
	},
	"apple": {
		name: "Apple",
		description: "An Apple",
		imageUrl: "https://image.freepik.com/free-icon/bandage-cross_318-61786.jpg",
		hasItem: true
	}
}>>

/* Show the inventory. */
<<set _inventory to Object.keys($objects)>>\
<<for _i to 0; _i< _inventory.length; _i++>>
	\<<set _obj to $objects[_inventory[_i]]>>
	\<<set _style to "background-image: url('" + _obj.imageUrl + "');">>
	\<<if _obj.hasItem>>
		\<div class="row">
			\<div class="column left" @style="_style"></div>
			\<div class="column right">
				\<b><i>_obj.name</i></b>
				\<br>_obj.description
			\</div>
		\</div>
	\<</if>>
\<</for>>

 

by (170 points)
Greyelf,

Thank you very much for your answer. I have chosen to follow your modification of my given example and adding the url via the style attribute fixed it.
+1 vote
by (44.7k points)

For this you can use SugarCube's HTML attribute directive.  So you'd change this:

<div class="column left" style="background-image: var($imageName);">

which wouldn't work, to this:

<div class="column left" @style="'background-image: url(\''+$imageName+'\');'">

which will work.

FYI - The \' (slash+apostrophe) puts an apostrophe inside the text of the string instead of ending the string.

The @ basically turns the value inside that attribute into something like what you would normally use to set the value of a variable.  So, the @ tells SugarCube to translate the part inside the "..." in the above element into this (assuming $imageName = "Test.jpg"):

<div class="column left" style="background-image: url('Test.jpg');">

Note: There was a bug in pre-v2.23.5 versions of SugarCube which could cause problems with attribute directives sometimes, so you might want to download and update to the latest version of SugarCube (currently v2.28.2).  Installation instructions can be found here if you need them.

Also, I'm working on a Twine/SugarCube "plugin" to make working with inventories in Twine much easier.  It's called the Universal Inventory System, or "UInv" for short.  It's still in pre-release, but it's pretty far along.  You can take a look at an early version of the UInv Help File here, or some simple UInv Sample Code here.  If you're interested, you can download the .ZIP file with everything you need from UInv's GitHub directory.  Also, keep an eye out, since I expect to have a major update out for it within the next couple of days.

Hope that helps!  :-)

...