+1 vote
by (510 points)
edited by

Hello there!
I'm trying write my story with interactive surrounding and some RPG mechanics, and i need simple inventory system.
Mr.Google say me, that HiEv have some form me)
And it's realy cool, but i want ask some questions.
All systems work well,but when i try create pick up/drop system, thats work not well as i want)
In theory, we have start point with that conditions:

<<set $PassName = passage()>> /*Take Passage name, and create variable from it*/
<<set $InvName = $PassName>> /*Take our previous var, and create new variable from it, it will be name of bag*/
<<if UInv.CreateBag($InvName)>><<else>><</if>>/*check if we creating bag with name */
You now in  '$PassName', you see there: <<=UInv.DisplayItemList($InvName)>>
----

/*create player backpack*/
<<if UInv.BagExists("Backpack")>><<else>><<button "take Backpack" $InvName>><<set UInv.CreateBag("Backpack")>><</button>>
<</if>>
/*set auto created buttons OFF*/
<<set $auto to 0>>
/*incude 'TakeDrop' code to this passage*/
<<include TakeDrop>>
/*creating links to ONE room, but with different conditions
- in first we create link to auto created buttons ROOM
- in second we create link to buttons created by hand*/
[[Room with auto created buttons|Room][$auto to 1]]
[[Room with buttons created by hands|Room][$auto to 0]]

Now, we create next passage where we create container, items, and create our system.
For me (for ease of use) system must take $var from  passage start , and working with it.

In perfection, system automaticly ceate buttons with name of item that lies in the 'Room', and after click on it, pick up item to player backpack.

For example i create two condition

  1. AUTO crated buttons
  2. buttons created BY NADS

For first create a "ROOM"

<<set $PassName = passage()>> /*Take Passage name, and create variable from it*/
<<set $InvName = $PassName>> /*Take our previous var, and create new variable from it, it will be name of bag*/
<<if UInv.CreateBag($InvName)>> /*Create bag with name what we craete earlier*/
/*Create some items*/
	<<set UInv.CreateItem($InvName, "Belt")>>
	<<set UInv.CreateItem($InvName, "Sword")>>
	<<set UInv.CreateItem($InvName, "Shield")>>
<</if>>

/*Create array with items from bag*/
<<set _Itemz = UInv.GetItemsArray($InvName)>>


----
/*message from system, what we see it room*/
You now in  '$PassName', you see there: <<=UInv.DisplayItemList($InvName)>>
----
/*incude 'TakeDrop' code to this passage*/
<<include TakeDrop>>

/*link to bigining, first passage*/
[[Start]]

now, include some auto/by hand code with conditions

/* if we choose uatocreated buttons*/
<<if $auto is 1>>
/*check, have we something in room, or not*/
<<if UInv.GetItemCount($InvName) > 0>>
----
AUTO CREATED BUTTONS
----
/*check for 'backpack'*/
	<<if UInv.BagExists("Backpack")>>
	/*Create button for pick up all from room*/
		<<button "take all" $PassName>><<set UInv.MoveAllItemsToBag($InvName,"Backpack")>><</button>>
			/*create loop 'for', and it create button for each item in array(bag)*/
			<<for _i = 0; _i < _Itemz.length; _i++>>
				/*create button with function to pick up item*/
   				<<button "take _Itemz[_i]" $PassName>><<set UInv.MoveItem($InvName,"Backpack", _Itemz[_i])>><</button>>
			<</for>>
		<<else>>
			You don't have backpack!
		<</if>>
		----
<</if>>
/*if we choosecreated by hands buttons*/
<<elseif $auto is 0>>
	/*check, have we something in room, or not*/
<<if UInv.GetItemCount($InvName) > 0>>
----
BUTTONS CREATED BY HANDS
----
/*check for 'backpack'*/
	<<if UInv.BagExists("Backpack")>>
	/*Create button for pick up all from room*/
		<<button "take all" $PassName>><<set UInv.MoveAllItemsToBag($InvName,"Backpack")>><</button>>
		/*Check, if we have "Belt" in room, if yes, create button*/
		<<if UInv.BagHasItem($InvName,"Belt")>>
				/*create button with function to pick up item*/
   				<<button "take Belt" $PassName>><<set UInv.MoveItem($InvName,"Backpack", "Belt")>><</button>>
		<<else>>	
		/* do nothing */
		<</if>>
		/*Check, if we have "Sword" in room, if yes, create button*/
		<<if UInv.BagHasItem($InvName,"Sword")>>
				/*create button with function to pick up item*/
   				<<button "take Sword" $PassName>><<set UInv.MoveItem($InvName,"Backpack", "Sword")>><</button>>
		<<else>>	
		/* do nothing */
		<</if>>
				/*Check, if we have "Sword" in room, if yes, create button*/
		<<if UInv.BagHasItem($InvName,"Shield")>>
				/*create button with function to pick up item*/
   				<<button "take Shield" $PassName>><<set UInv.MoveItem($InvName,"Backpack", "Shield")>><</button>>
		<<else>>	
		/* do nothing */
		<</if>>
		<<else>>
			You don't have backpack!
		<</if>>
		----
<</if>>
<</if>>

And for player, create BACKPACK button on the leftside slide menu with some "drop code".

/*setup previous passage like name where we are, and for know where we are drop items*/
<<set $PrevPassName = previous()>>
You now in '$PrevPassName'.
----
/* drop code same like pick up, but reversed*/
In backpack now: <<print UInv.DisplayItemList("Backpack")>>
<<if UInv.GetItemCount("Backpack") > 0>>
<<button "drop all" $PassName>><<set UInv.MoveAllItemsToBag("Backpack",$InvName)>><</button>>
<</if>>
----
<<back>>

What working now:

  • creating 'bag' from name of passage (like "You see room, and some itms in there. ...)
  • pick up/drop system for each one created item (only one by one, and if creating by hands)
  • pick up/drop ALL items from "room" to backpack and back (not only in room that you pick up their)
  • auto creating buttons from array items, with item name on it.

What NOT working now:

  • moving items with auto created button (with created by hands, work perfectly)

For now, everything seems to be.

Sorry for my english, it' not my language.

For testing upload file on git.

Project with inventory

Thanks for listning)

1 Answer

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

The problem is simply that the value of _i has changed between the time that you created the buttons, and the time that the user has clicked on the buttons.  To prevent that, you need to "capture" the value of _i using the <<capture>> macro like this:

/*create loop 'for', and it create button for each item in array(bag)*/
<<capture _i>>
	<<for _i = 0; _i < _Itemz.length; _i++>>
		/*create button with function to pick up item*/
		<<button "take _Itemz[_i]" $PassName>>
			<<set UInv.MoveItem($InvName, "Backpack", _Itemz[_i])>>
		<</button>>
	<</for>>
<</capture>>

If any of the other variables ($InvName or _Itemz) might change before the user clicks on the button, then those variables would also have to be captured.

The <<capture>> macro can be a bit tricky to understand, so if you need further explanation you can see this <<capture>> sample code and explanation here.

Hope that helps!  :-)

by (510 points)
HiEv, thanks!
It's alive!)
I thought about it, but in theory. In practice, I did not know about this macro, but today, when I looked in the SC wiki, at the top of all macros I find this macro and a description of what it does)
And thanks again)
...