<center><h3><<print UInv.Version()>></h3></center>This is some simple sample code intended to show you how you can use the Universal Inventory System (UInv) functions in your Twine project.
It's best if you open this sample code in the Twine editor, and have the story playing on one side of the screen while looking at the source code in the Twine editor on the other side of the screen. That way you can see what the code is doing and read how it does it at the same time.
<i class="fa fa-exclamation-circle" /> Before running this from inside the Twine editor you'll want to change the file paths used in your JavaScript and Stylesheet sections to use the correct file path for your computer. See [[here for details]].
If you aren't already, you may want to close this window and run this from the Twine editor using "Test" mode. That would allow you to watch the values change inside the {{{$UInvBags}}} variable as you move through the story passages. See the animation below if you don't know how to use "Test" mode in Twine.
<img @src='setup.Path + "images/HowToWatchVariables.gif"' style='color: lawngreen;' alt='(If you are seeing this text instead of an image, please edit the setup.Path variable at the top of the JavaScript section to point to the correct directory.)'>
''Note:'' You should see two error messages pop up when you try to go to the next passage if you have
{{{<<run UInv.SetUserAlerts(UInv.ERROR_SHOW_ALERT + UInv.ERROR_SHOW_PASSAGE_NAME)>>}}}
in the StoryInit passage (by default that line is commented out). This is done intentionally as an example of how UInv can help you spot and prevent errors in your code.
<i class="fa fa-exclamation-circle" /> You can also type "xyzzy" at any time, which will toggle a "debug mode", which determines whether UInv errors will appear in the console window or not. You can hit {{{F12}}} or {{{CTRL+SHIFT+I}}} to open the console window in most browsers.
[[Let's begin.]]
- or -
[[Let's skip ahead to the good stuff.|passage 7][UInv.AddBag("Treasures")]]
''Note:'' You should see two error messages below if you have
{{{<<run UInv.SetUserAlerts(UInv.ERROR_THROW_ERROR + UInv.ERROR_SHOW_PASSAGE_NAME)>>}}}
in the StoryInit passage (by default that line is commented out). This is done intentionally as an example of how UInv can help you spot and prevent errors in your code.
''Create bag "Test":'' <<if UInv.CreateBag("Test")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Create bag "Test":'' <<if UInv.CreateBag("Test")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Add item "belt" to bag "Test":'' <<if UInv.AddItem("Test", "belt")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Add item "blort" to bag "Test":'' <<if UInv.AddItem("Test", "blort")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of items in "Test":'' <<print UInv.DisplayItemList("Test")>>
''Add item "belt" to bag "Test":'' <<if UInv.AddItem("Test", "belt")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Add item "black belt" as type "belt" to bag "Test":'' <<if UInv.AddItem("Test", "belt", 1, "black belt")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of items in "Test":'' <<set _Items = UInv.GetItemsArray("Test")>><<if _Items.length == 0>>(empty)<<else>><<for _i = 0; _i < _Items.length; _i++>>_Items[_i] (<<print UInv.BagHasItem("Test", _Items[_i])>>)<<if _i < _Items.length - 2>>, <<elseif _i < _Items.length - 1>><<if _Items.length > 2>>,<</if>> & <</if>><</for>><</if>>
-- ''Note:'' Even though "black belt" has the same default //type// as "belt", it will be grouped separately, since it has a different item //name//. --
''List of "belt" properties and values in "Test":''<<set _Item = UInv.GetItemObject("Test", "belt")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''List of "black belt" properties and values in "Test":''<<set _Item = UInv.GetItemObject("Test", "black belt")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''Note:'' You can see that the "belt" and "black belt" items are nearly identical except for the quantity (because we added a "belt" item twice and a "black belt" item only once) and the "UInvDefaultItemType" property on the "black belt" item. The reason why the black belt has "UInvDefaultItemType = belt" is because its name ("black belt") is not the same as its item type ("belt"). The "UInvDefaultItemType" property preserves that item type in order to save memory and reduce the size of the save data.
Go to [[passage 2]]
''Add "dagger" to bag "Test":'' <<if UInv.AddItem("Test", "dagger")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of items in "Test":'' <<set _Items = UInv.GetItemsArray("Test")>><<if _Items.length == 0>>(empty)<<else>><<for _i = 0; _i < _Items.length; _i++>>_Items[_i] (<<print UInv.BagHasItem("Test", _Items[_i])>>)<<if _i < _Items.length - 2>>, <<elseif _i < _Items.length - 1>><<if _Items.length > 2>>,<</if>> & <</if>><</for>><</if>>
''Show "dagger" type:'' <<print UInv.GetItemObject("Test", "dagger").type>>
''Set "dagger" type to ["item"]:'' <<if UInv.SetItemPropertyValue("Test", "dagger", "type", ["item"])>>Success.<<else>>$UInvLastErrorMessage<</if>><<set _Item = UInv.GetItemObject("Test", "dagger")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''Set "dagger" type back to ["weapon", "stabbing", "1-handed"]:'' <<if UInv.SetItemPropertyValue("Test", "dagger", "type", ["weapon", "stabbing", "1-handed"])>>Success.<<else>>$UInvLastErrorMessage<</if>><<set _Item = UInv.GetItemObject("Test", "dagger")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''Create bag "Test2":'' <<if UInv.CreateBag("Test2")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Copy "dagger" from "Test" to "Test2":'' <<if UInv.CopyItem("Test", "Test2", "dagger")>>Success.<<else>>$UInvLastErrorMessage<</if>><<set _Item = UInv.GetItemObject("Test2", "dagger")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''Note:'' You should see one error message pop up when you go to the next passage if you have error displaying enabled. This is done intentionally as an example of how UInv can help you spot and prevent errors in your code.
Go to [[passage 4]]
''Note:'' You should see one error message below if you have
{{{<<run UInv.SetUserAlerts(UInv.ERROR_THROW_ERROR + UInv.ERROR_SHOW_PASSAGE_NAME)>>}}}
in the StoryInit passage (by default that line is commented out). This is done intentionally as an example of how UInv can help you spot and prevent errors in your code.
''Copy bag "Test2" to "Test3":'' <<if UInv.CopyBag("Test2", "Test3")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of items in "Test":'' <<print UInv.DisplayItemList("Test")>>
''List of items in "Test1":'' <<print UInv.DisplayItemList("Test1")>>
''List of items in "Test2":'' <<print UInv.DisplayItemList("Test2")>>
''List of items in "Test3":'' <<print UInv.DisplayItemList("Test3")>>
''Add "pants" to bag "Test2":'' <<if UInv.AddItem("Test2", "pants")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of all bags:'' <<set _Bags = UInv.GetBagsArray()>><<if _Bags.length == 0>>(empty)<<else>><<for _i = 0; _i < _Bags.length; _i++>>_Bags[_i]<<if _i < _Bags.length - 1>> & <</if>><</for>><</if>>
-- ''Note:'' As examples, some of the previous parts of the code showed a couple of different ways to display the list of items in a bag. In the code below it shows the best ways to display them using the {{{DisplayItemList}}} function and the SugarCube {{{<<print>>}}} macro. --
''List of items in "Test":'' <<print UInv.DisplayItemList("Test", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Test2":'' <<=UInv.DisplayItemList("Test2", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Test3":'' <<=UInv.DisplayItemList("Test3", "plural", "nothing", ",", "and", "singular")>>
''Total unique items in bags "Test" and "Test3":'' <<print UInv.GetItemCount(["Test", "Test3"])>>
''Total items in bags "Test" and "Test3":'' <<print UInv.GetItemCountFull(["Test", "Test3"])>>
''Rename "black belt" property "magic" to "magic bonus":'' <<if UInv.RenameItemProperty("Test", "black belt", "magic", "magic bonus")>>Success<<else>>$UInvLastErrorMessage<</if>>
''Set the black belt's "description" property to the value of "A magic belt.":'' <<if UInv.SetItemPropertyValue("Test", "black belt", "description", "A magic belt.")>>Success<<else>>$UInvLastErrorMessage<</if>>
''Set the black belt's "singular" property to the value of "a magic belt":'' <<if UInv.SetItemPropertyValue("Test", "black belt", "singular", "a magic belt")>>Success<<else>>$UInvLastErrorMessage<</if>>
''Set the black belt's "plural" property to the value of "magic belts":'' <<if UInv.SetItemPropertyValue("Test", "black belt", "plural", "magic belts")>>Success<<else>>$UInvLastErrorMessage<</if>><<set _Item = UInv.GetItemObject("Test", "black belt")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''Rename "black belt" to "magic belt":'' <<if UInv.RenameItem("Test", "black belt", "magic belt")>>Success<<else>>$UInvLastErrorMessage<</if>>
''List of item names in "Test":'' <<print UInv.GetItemsArray("Test")>>
''List of items in "Test":'' <<=UInv.DisplayItemList("Test", "plural", "nothing", ",", "and", "singular")>>
''Note:'' You should see one error message pop up when you go to the next passage if you have error displaying enabled. This is done intentionally as an example of how UInv can help you spot and prevent errors in your code.
Go to [[passage 5]]
''Note:'' You should see one error message below if you have
{{{<<run UInv.SetUserAlerts(UInv.ERROR_THROW_ERROR + UInv.ERROR_SHOW_PASSAGE_NAME)>>}}}
in the StoryInit passage (by default that line is commented out). This is done intentionally as an example of how UInv can help you spot and prevent errors in your code.
''List of items in "Test":'' <<=UInv.DisplayItemList("Test", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Test2":'' <<=UInv.DisplayItemList("Test2", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Test3":'' <<=UInv.DisplayItemList("Test3", "plural", "nothing", ",", "and", "singular")>>
''Move 1 "belt" from bag "Test" to bag "Test2":'' <<if UInv.MoveItem("Test", "Test2", "belt", 1)>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Move "pants" from bag "Test" to bag "Test3":'' <<if UInv.MoveItem("Test", "Test3", "pants", 1)>>Success.<<else>>$UInvLastErrorMessage<</if>>
''Move "magic belt" from bag "Test" to bag "Test3":'' <<if UInv.MoveItem("Test", "Test3", "magic belt")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of items in "Test":'' <<=UInv.DisplayItemList("Test", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Test2":'' <<=UInv.DisplayItemList("Test2", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Test3":'' <<=UInv.DisplayItemList("Test3", "plural", "nothing", ",", "and", "singular")>>
''List of properties for the "magic belt":'' <<set _Item = UInv.GetItemObject("Test3", "magic belt")>><<if UInv.isObject(_Item)>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>><<else>>$UInvLastErrorMessage<</if>>
''Add bag "Test1" as bag type "backpack":'' <<if UInv.AddBag("Test1", "backpack")>>Success.<<else>>$UInvLastErrorMessage<</if>>
''List of items in "Test1":'' <<=UInv.DisplayItemList("Test1", "plural", "nothing", ",", "and", "singular")>>
''Add bag "Treasures":'' <<if UInv.AddBag("Treasures")>>Success.<<else>>$UInvLastErrorMessage<</if>>
-- ''Note:'' Because of how the potion is defined in ''ItemData'', it returns a random colored potion when it is added. If you go either back or forward a passage, and then return to this passage, the potion here will likely be a different color. --
''List of items in "Treasures":'' <<=UInv.DisplayItemList("Treasures", "plural", "nothing", ",", "and", "singular")>>
''Add bag "Treasure bag":'' <<if UInv.AddBag("Treasure bag")>>Success.<<else>>$UInvLastErrorMessage<</if>>
-- ''Note:'' Because of how "Treasure bag" is defined in ''BagData'', it returns a random amount of coins and a random item from the "treasures" bag's default item list when it is added. If you go either back or forward a passage, and then return to this passage, the "Treasure bag" here will likely have different items. --
''List of items in "Treasure bag":'' <<=UInv.DisplayItemList("Treasure bag", "plural", "nothing", ",", "and", "singular")>>
Go to [[passage 6]]
-- ''Note:'' In the following SetItemPropertyValue examples, "true" means that it modified an existing item property, and "false" means that it created a new item property. --
''Set "black belt" "description" property to "It's a black belt.":'' <<print UInv.SetItemPropertyValue("Test", "black belt", "description", "It's a black belt.")>>
''Set "black belt" "magic" property to 1:'' <<print UInv.SetItemPropertyValue("Test", "black belt", "magic", 1)>>
''Set "black belt" "singular" property to "a black belt":'' <<print UInv.SetItemPropertyValue("Test", "black belt", "singular", "a black belt")>>
''Set "black belt" "plural" property to "black belts":'' <<print UInv.SetItemPropertyValue("Test", "black belt", "plural", "black belts")>>
''List of items in "Test":'' <<set _Items = UInv.GetItemsArray("Test")>><<if _Items.length == 0>>(empty)<<else>><<for _i = 0; _i < _Items.length; _i++>>_Items[_i] (<<print UInv.BagHasItem("Test", _Items[_i])>>)<<if _i < _Items.length - 2>>, <<elseif _i < _Items.length - 1>><<if _Items.length > 2>>,<</if>> & <</if>><</for>><</if>>
''List of "belt" properties and values in "Test":''<<set _Item = UInv.GetItemObject("Test", "belt")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''List of "black belt" properties and values in "Test":''<<set _Item = UInv.GetItemObject("Test", "black belt")>><<for _Prop, _Val range _Item>><br>- _Prop = _Val<</for>>
''Alternate way of showing quantity:'' <<print UInv.GetItemsArray("Test")[0]>> = <<print UInv.GetItemObject("Test", UInv.GetItemsArray("Test")[0]).UInvQuantity>>
Go to [[passage 3]]
/* <<set UInv.SetUserAlerts(UInv.ERROR_THROW_ERROR + UInv.ERROR_SHOW_PASSAGE_NAME)>> */
/* <<set UInv.SetUserAlerts(UInv.ERROR_SHOW_ALERT + UInv.ERROR_SHOW_PASSAGE_NAME)>> */
/* <<set UInv.SetUserAlerts(UInv.ERROR_TO_CONSOLE + UInv.ERROR_SHOW_PASSAGE_NAME)>> */
''List of items in "Treasures":'' <<=UInv.DisplayItemList("Treasures", "plural", "nothing", ",", "and", "singular")>>
''List of items in "Treasure bag":'' <<=UInv.DisplayItemList("Treasure bag", "plural", "nothing", ",", "and", "singular")>>
''Create bag "Potions":'' <<if UInv.CreateBag("Potions")>>Success.<<else>>$UInvLastErrorMessage<</if>>
-- ''Note:'' The "rainbow potion" item is set up in ''ItemData'' to randomly return a red, orange, yellow, green, blue, or purple potion. This means that this is a variable item, which also meanings that it needs to have a "UInvVariableType" property. Because of the "UInvVariableType" property that this item has, UInv will try to group items of this same type together if they are completely identical (other than their quantity), otherwise it will create a new stack of items. Keep clicking the "add" button below to see how the matching items automatically stack together.
Since variable items may have multiple item names, you can find the variable items by looking for items of that default type. Thet "Delete" button below uses the ''GetItemByType'' function to find a random item of the "rainbow potion" type to be deleted. --
''Add item "rainbow potion" to bag "Potions":'' <<button "Click to add a potion">><<if UInv.AddItem("Potions", "rainbow potion")>>Success.<<else>>$UInvLastErrorMessage<</if>><<replace "#Potions">>''List of items in "Potions":'' <<=UInv.DisplayItemList("Potions", "plural", "none", ",", "and", "singular")>><</replace>><</button>>
''Delete "rainbow potion" items from bag "Potions":'' <<button "Click to delete 'rainbow potions'">><<set _tmp = UInv.GetItemByType("Potions", "rainbow potion")>><<if (_tmp != "") && (UInv.DeleteItem("Potions", _tmp))>>Success.<<else>>$UInvLastErrorMessage<</if>><<replace "#Potions">>''List of items in "Potions":'' <<=UInv.DisplayItemList("Potions", "plural", "none", ",", "and", "singular")>><</replace>><</button>>
<span id="Potions">''List of items in "Potions":'' <<=UInv.DisplayItemList("Potions", "plural", "none", ",", "and", "singular")>></span>
Go to [[passage 7]]
Here's a version of what you saw on the previous page, but in an item table format.
Treasures:
<div data-uinv="table" class="Treasures-table" id="Treasures" data-rowclass="Treasures-row" data-cellclass="Treasures-cell" data-itemclass="Treasures-item" data-iconclass="Treasures-icon" data-textclass="Treasures-text" data-cellrows="3" data-cellcolumns="5" data-cellmargin="5" data-bordermargin="4"></div>
''Add item "rainbow potion" to bag "Treasures":'' <<button "Click to add a potion">><<if UInv.AddItem("Treasures", "rainbow potion")>>Success.<<else>>$UInvLastErrorMessage<</if>><<replace "#TreasureList">>''List of items in "Treasures":'' <<=UInv.DisplayItemList("Treasures", "plural", "none", ",", "and", "singular")>><</replace>><</button>>
''Delete "rainbow potion" items from bag "Treasures":'' <<button "Click to delete 'rainbow potions'">><<set _tmp = UInv.GetItemByType("Treasures", "rainbow potion")>><<if (_tmp != "") && (UInv.DeleteItem("Treasures", _tmp))>>Success.<<else>>$UInvLastErrorMessage<</if>><<replace "#TreasureList">>''List of items in "Treasures":'' <<=UInv.DisplayItemList("Treasures", "plural", "none", ",", "and", "singular")>><</replace>><</button>>
<span id="TreasureList">''List of items in "Treasures":'' <<=UInv.DisplayItemList("Treasures", "plural", "none", ",", "and", "singular")>></span>
[[Reload current passage|passage 7]]
Go to [[passage 8]]
<<if !UInv.BagExists("Chest")>><<run UInv.CreateBag("Chest")>><</if>>
And here's an example of how you can transfer items between "bags". You can click anywhere (not including the UI bar on the left or the scrollbars) to cancel the radial menu.
Treasures:
<div data-uinv="table" class="Treasures-table" id="Treasures" data-rowclass="Treasures-row" data-cellclass="Treasures-cell" data-itemclass="Treasures-item" data-iconclass="Treasures-icon" data-textclass="Treasures-text" data-cellrows="3" data-cellcolumns="5" data-cellmargin="5" data-bordermargin="4"></div>
Chest:
<div data-uinv="table" class="Chest-table" id="Chest" data-rowclass="Chest-row" data-cellclass="Chest-cell" data-itemclass="Chest-item" data-iconclass="Chest-icon" data-textclass="Chest-text" data-cellrows="3" data-cellcolumns="3" data-cellmargin="3" data-bordermargin="7"></div>
(more function tests/examples will go here later)
[[Reload current passage|passage 8]]
Go to [[passage 9]]
<<if !UInv.BagExists("CoinPouch")>><<run UInv.CreateBag("CoinPouch")>><</if>>
[[Return to Start|Start]]
To make this sample code work properly when run from the Twine editor, you'll need to change the default file path used in the JavaScript and Stylesheet sections.
Right near the top of the JavaScript section you'll see this code:
<div class="cm-default"><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-keyword">if</span> (<span class="cm-variable">window</span>.<span class="cm-property">hasOwnProperty</span>(<span class="cm-string">"storyFormat"</span>) <span class="cm-operator">||</span> (<span class="cm-variable">document</span>.<span class="cm-property">location</span>.<span class="cm-property">href</span>.<span class="cm-property">indexOf</span>(<span class="cm-string">"AppData"</span>) <span class="cm-operator">!==</span> <span class="cm-operator">-</span><span class="cm-number">1</span>)) {</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-comment">// Change this to the path where this HTML file is</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-comment">// located if you want to run this from inside Twine.</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="arrow">→</span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-variable">setup</span>.<span class="cm-property">Path</span> <span class="cm-operator">=</span> <span class="cm-string">"C:/Games/Universal Inventory System/"</span>; <span class="cm-comment">// Running inside Twine application</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">} <span class="cm-keyword">else</span> { </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-variable">setup</span>.<span class="cm-property">Path</span> <span class="cm-operator">=</span> <span class="cm-string">""</span>; <span class="cm-comment">// Running in a browser</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div>
Just change the path there from <span class="cm-string">"C:/Games/Universal Inventory System/"</span> to the path where the HTML files are located on your computer. (Make sure you don't use backslashes "\" in your file path like Windows does, since for file paths in HTML you should only use slashes "/".)
Then do the same path edits at these locations in the Stylesheet section:
<div class="cm-default"><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-def">@import</span> <span class="cm-atom">url</span>(<span class="cm-string">'https://use.fontawesome.com/releases/v5.3.1/css/all.css'</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span class="arrow">→</span><span role="presentation" style="padding-right: 0.1px;"><span class="cm-def">@import</span> <span class="cm-atom">url</span>(<span class="cm-string">'C:/Games/Universal Inventory System/all.css'</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-def">@import</span> <span class="cm-atom">url</span>(<span class="cm-string">'all.css'</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">(...)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-atom">linear-gradient</span>(<span class="cm-atom">to</span> <span class="cm-atom">bottom</span>, <span class="cm-atom">rgba</span>(<span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">0.5</span>), <span class="cm-atom">rgba</span>(<span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">0</span>) <span class="cm-number">5px</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span class="arrow">→</span><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span> <span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-atom">url</span>(<span class="cm-string">"C:/Games/Universal Inventory System/images/woodtexture7.jpg"</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-atom">url</span>(<span class="cm-string">"images/woodtexture7.jpg"</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">(...)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-atom">linear-gradient</span>(<span class="cm-atom">to</span> <span class="cm-atom">bottom</span>, <span class="cm-atom">rgba</span>(<span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">0.5</span>), <span class="cm-atom">rgba</span>(<span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">255</span>, <span class="cm-number">0</span>) <span class="cm-number">5px</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="arrow">→</span><span class="cm-tab" role="presentation" cm-text=" "> </span> <span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-atom">url</span>(<span class="cm-string">"C:/Games/Universal Inventory System/images/reflective-brushed-metal.jpg"</span>),</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-tab" role="presentation" cm-text=" "> </span><span class="cm-atom">url</span>(<span class="cm-string">"images/reflective-brushed-metal.jpg"</span>);</span></pre></div>
Once you've done that, in order for the changes you've made to take effect, you'll need to close this window and then start the story again from Twine.
[[Return to Start|Start]]
<<link "Close Window">><<run window.top.close()>><</link>><<run UInv.AddItem("Treasures", "gold coin", 50)>><<run UInv.SetBagPropertyValue("CoinPouch", "acceptedType", ["money"])>><<run UInv.AddEventHandler("table", "Accept", "acceptTest")>>Here's an example of how you can limit the transfer of items between "bags" by adding an event handler which checks the item's type. You can click anywhere (not including the UI bar on the left or the scrollbars) to cancel the radial menu.
Treasures:
<div data-uinv="table" class="Treasures-table" id="Treasures" data-rowclass="Treasures-row" data-cellclass="Treasures-cell" data-itemclass="Treasures-item" data-iconclass="Treasures-icon" data-textclass="Treasures-text" data-cellrows="3" data-cellcolumns="5" data-cellmargin="5" data-bordermargin="4"></div>
CoinPouch: (only accepts gold coins)
<div data-uinv="table" class="Chest-table" id="CoinPouch" data-rowclass="Chest-row" data-cellclass="Chest-cell" data-itemclass="Chest-item" data-iconclass="Chest-icon" data-textclass="Chest-text" data-cellrows="1" data-cellcolumns="3" data-cellmargin="3" data-bordermargin="7"></div>
This is done by putting the following code in this passage:
{{{
<<run UInv.AddEventHandler("table", "Accept", "acceptTest")>>
}}}
And having an {{{<<acceptTest>>}}} widget (in a different "widget" tagged passage) like this:
{{{
<<widget "acceptTest">>
<<set _e = $args[0]>>
<<if _e.destBag == "CoinPouch">>
<<set _UInvReturn = {
acceptVal: !!UInv.ItemHasTag(_e.srcBag, _e.draggedItem, "type", "money")
}>>
<</if>>
<</widget>>
}}}
The {{{<<acceptTest>>}}} widget will get called whenever the mouse is moved over a table's cell. If the table the item is being dragged over is the "CoinPouch" table, then it will only allow the dragged item to be dropped if the item has the "money" tag in its "type" property.
Alternately, you could add an "acceptedType" property to your bags, which would contain an array of any valid "type" tags an item must have at least one of, in order to be allowed in the bag. Bags without an "acceptedType" property would allow all items.
For this example, you could put the following code in your JavaScript section:
{{{
setup.eventCheckItemType = function (event) {
var bagDestAcceptedTypeArray = UInv.GetBagPropertyValue(event.destBag, "acceptedType");
var srcItemToDestBag = true;
var destItemToSrcBag = true;
if (UInv.isArray(bagDestAcceptedTypeArray)) {
srcItemToDestBag = UInv.ItemHasAnyTag(event.srcBag, event.draggedItem, "type", bagDestAcceptedTypeArray);
if (!srcItemToDestBag) {
return { acceptVal: false };
}
}
if (event.droppedOnItem != "") {
var bagSrcAcceptedTypeArray = UInv.GetBagPropertyValue(event.srcBag, "acceptedType");
if (UInv.isArray(bagSrcAcceptedTypeArray)) {
destItemToSrcBag = UInv.ItemHasAnyTag(event.destBag, event.droppedOnItem, "type", bagSrcAcceptedTypeArray);
}
}
return { acceptVal: destItemToSrcBag };
}
}}}
If one item is dropped on another, then the drop will be rejected if either item can't go into the other item's bag.
You would enable that event handler by doing:
{{{
<<run UInv.AddEventHandler("table", "Accept", "eventCheckItemType")>>
}}}
[[Reload current passage|passage 9]]
<<widget "acceptTest">>
<<set _e = $args[0]>>
<<if _e.destBag == "CoinPouch">>
<<set _UInvReturn = {
acceptVal: !!UInv.ItemHasTag(_e.srcBag, _e.draggedItem, "type", "money")
}>>
<</if>>
<</widget>>