FrankFamily Posted May 1, 2016 Share Posted May 1, 2016 (edited) What I need: A container that only accepts a single item, whatever happens, not one stack, just one item. And access from another script to the form of that item to pass it as a parameter for FindClosestReferenceOfTypeFromRef. The container will be accessible by the player "equipping" a misc item but haven't got that far yet...Ideally the weight of the misc item would increase with the content of the container, but that would require skse, right? It's not a main feature anyway and cosnidering you can only place a single item, the amount of weight you can cheat is low. What I have:Some of my concerns as comments within the code. Looks good and reliable? any errors you can spot? Improvements? Scriptname CONTAINERTEST extends ObjectReference {Accepts only a single item and stores its form} Bool IsFull Form Property MyItem Auto ; to be accessed and used by another script as a form parameter ; wiki says you cant "make" a form property as in fill it in ck i guess, but can you store stuff in it? Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If !IsFull IsFull = True MyItem = akBaseItem If aiItemCount > 1 Self.RemoveItem(akBaseItem, aiItemCount - 1, true, akSourceContainer) ;keep 1 item send the rest back, should take care of stacks Endif Else Self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer) ;if full send everything back Endif EndEvent Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) IsFull = False ; if it only accepts one item, whenever anything is removed it should be empty? reliable? endEvent Edited May 1, 2016 by FrankFamily Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 1, 2016 Share Posted May 1, 2016 (edited) I'm not sure about using a property with Form. In theory it should work if all you are doing is storing a form to use on another script. However, if the compiler complains about it... Your OnItemAdded block seems fine as a means of preventing additional items to be added (i.e. remove the excess).Your OnItemRemoved block will be a problem. Each of the removals of excess items will trigger this event. So, you'll be inadvertently resetting the bool when you do not want it to be reset. You may therefore wish to use SKSE's GetNumItems function as a means of limiting the storage of excess rather than using a bool. (EDIT: Code block not tested.) Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) If Self.GetNumItems() == 0 MyItem = akBaseItem ;container was empty - store this item. If aiItemCount > 1 Self.RemoveItem(akBaseItem, aiItemCount - 1, true, akSourceContainer) ;keep 1 item send the rest back, should take care of stacks Endif ElseIf Self.GetNumItems() > 1 Self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer) ;return entire ammount as container is maxed already EndIf EndEvent I have code in my Inventory Management System mod which adds content weight to container weight. It requires SKSE and it is not persistent across saves which means there is required maintenance code to run. So there is code to add weight when items are added and subtract weight when items are removed, and code on a player alias to reset the weight when the game is loaded. You are welcome to break it down and use what you need. Edited May 1, 2016 by IsharaMeradin Link to comment Share on other sites More sharing options...
cdcooley Posted May 1, 2016 Share Posted May 1, 2016 The Form property will be fine. The CK can't fill it but your script can and other scripts can use the value without any problems.There's just one problem I see. When you return the extras OnItemRemoved will trigger and mark the container empty. You need three states to handle the situation not a single boolean. With states the code would be: ScriptName CONTAINERTEST extends ObjectReference {Accepts only a single item and stores its form} Form Property MyItem Auto ; to be accessed and used by another script as a form parameter Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) {Default is to reject any new items.} Self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer) ;if full send everything back EndEvent Auto State IsEmpty ; container starts empty Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) {When empty, container can accept one and only one.} GoToState("") ; reject new items but do not reset if extras need to be removed If aiItemCount > 1 Self.RemoveItem(akBaseItem, aiItemCount - 1, true, akSourceContainer) ;keep 1 item send the rest back, should take care of stacks Endif MyItem = akBaseItem GoToState("IsFull") ; now there is just one EndEvent EndState State IsFull Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) GoToState("IsEmpty") MyItem = None ; should you be clearing MyItem here? EndEvent EndState If you aren't planning to reset the MyItem variable to None like the code I added to OnItemRemoved in my version you can actually get by with something much simpler by returning all items every time. In that case the container would be used to remember the chosen item but the item would go back into the player's inventory and you wouldn't have to worry about weight. Your other script could always check to see if the player still has that item before it does whatever else it is supposed to do. And if the player adds another item it would replace the previous choice. In that situation the simplified code would be: ScriptName CONTAINERTEST2 extends ObjectReference {Remembers the form of the last item placed in the container} Form Property MyItem Auto ; to be accessed and used by another script as a form parameter Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) MyItem = akBaseItem ; remember this new item Self.RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer) ; send everything back EndEvent Link to comment Share on other sites More sharing options...
FrankFamily Posted May 1, 2016 Author Share Posted May 1, 2016 Thanks both for the help:) I wished removeitem wouldn't trigger onitemremoved but yeah it makes more sense that it does.And i'd like to clear the property if no item is inside, forgot that in my script, so i'll go with the states for now. Link to comment Share on other sites More sharing options...
Recommended Posts