Jump to content

Containers - transfering items


Recommended Posts

You can add a script to your container to accomplish this:

 

Scriptname TM_ObjectRefScript extends ObjectReference 

ObjectReference Property TransferContainer Auto ;the container to transfer items to

Event OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) 
    If akDestContainer == Game.GetPlayer() ;if the player is removing items from this container 
        Game.GetPlayer().RemoveItem(akBaseItem, aiItemCount, true, TransferContainer) ;remove items just added to the player to the transfer container silently. 
    Endif
Endevent

Name the script something different for your mod.

Link to comment
Share on other sites

The script by dylbill accomplishes the end result. It takes the item the player chooses from container A and moves it into container B. But if you are wanting to actually view container A alongside container B, that is not possible with papyrus alone. And if it were possible with some sort of DLL plugin and / or SWF editing, I have no idea.

Link to comment
Share on other sites

Hey, you can still fake that functionality with a script. When you open a container, it defaults to taking items, then you can switch to your inventory to give items to the container. With using SKSE, you can set up a hotkey to open the other container. Left Alt is the default key to switch tabs in SkyUI, So I used that in this example script:

 

Scriptname TM_ObjectRefScript extends ObjectReference 

ObjectReference Property TransferContainer Auto ;the container to transfer items to
Bool Property TransferItems Auto

Event OnActivate(ObjectReference akActionRef) 
    If akActionRef == Game.GetPlayer() 
        RegisterForMenu("ContainerMenu")
        RegisterForKey(56) ; left alt 
    Endif
EndEvent 

Event OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
    If TransferItems == True
        If akDestContainer == Game.GetPlayer() ;if the player is removing items from this container 
            Game.GetPlayer().RemoveItem(akBaseItem, aiItemCount, true, TransferContainer) ;remove items just added to the player to the transfer container silently. 
        Endif
    Endif
Endevent

Event OnKeyDown(Int keyCode) 
    Input.TapKey(1) ;escape. force close menu so other container menu can open
    Utility.Wait(0.2)
    TransferContainer.Activate(Game.GetPlayer()) ;open TransferContainer
    
EndEvent

Event OnMenuClose(String menuName) 
    UnregisterForKey(56) ; Left Alt 
    UnRegisterForMenu("ContainerMenu")
EndEvent

Add the script to both containers. Set the TransferContainer to the other container. If you set TransferItems to True on both, they will just swap items between them only, without you being able to put items in your inventory. Set it to false on 1 to retrieve items from that container. You can still give both containers items from your inventory. I tested it and it does work.

Link to comment
Share on other sites

I cringe at the stack dump potential if take all is used to transfer from one to the other when there are a large number of items. That pass through the player inventory, a lot of wasted processing with the OnItemAdded and OnItemRemoved events on player based scripts.

Link to comment
Share on other sites

@dylbill… interesting piece of code I’ll keep it in mind… but not sure it would do what I’m attempting though.

@IsHaraMeradin… Tend to agree.

 

Currently I’m looking at the possibility to use a hidden npc… or create a new race just for it... as the source/store container and have that npc open the receiving container… not sure if that would open a menu to allow the player to then transfer items between the two… perhaps with something like RecievingContainer. Activate(<MyHiddenNPC>, false) being called from a menu option.

I’ll try testing it out later.

Link to comment
Share on other sites

I guess I'm still confused as to what you're trying to do. If you want your container to link to another, instead of making it a container you can make it an activator instead and then have it open the other container:

 

Scriptname TM_ObjectRefScript extends ObjectReference 

ObjectReference Property TransferContainer Auto ;the container to transfer items to

Event OnActivate(ObjectReference akActionRef) 
    If akActionRef == Game.GetPlayer()
        TransferContainer.Activate(Game.GetPlayer()) ;open TransferContainer
    Endif
EndEvent

Or, if you're trying to set up a storage container for an NPC and have the player access that container, you can put a custom dialogue line for the NPC, then use the Dialogue End papyrus fragment to open the container. TransferContainer.Activate(Game.GetPlayer()) ;open TransferContainer

Link to comment
Share on other sites

Okay I may not have explained what it is I'm trying to do very well :D

 

What I'm trying to do is have a container with items in it that the player has previously put in it then be able to open another container and instead of the menu for that container being between the player and that container have it open between the two containers so the player can transfer items between them.

So as it doesn't seem to be able to be done between two normal containers I'm thinking to try and make the first container a type of npc (maybe a type of container race) so it can open the other container menu with itself and not the player but have the player control the transfers between the two item by item in either direction.

 

Not sure that makes anymore sense though or if it can even work...

Edited by TheWanderer001
Link to comment
Share on other sites

Ok I think I understand better. You want two containers to be linked, with the ability to add or take items from either container. I would still set this up with hotkeys using SKSE. You can use two containers without using an actor. Attach this script to each container. When filling properties, set the TransferContainer to the other one.

 

Scriptname TM_ObjectRefScript extends ObjectReference 

ObjectReference Property TransferContainer Auto ;the container to transfer items to

Event OnActivate(ObjectReference akActionRef) 
    If akActionRef == Game.GetPlayer()       
        RegisterForMenu("ContainerMenu")
        RegisterForKey(56) ; left alt 
    Endif
EndEvent 

Event OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) 
    
    If akSourceContainer == Game.GetPlayer() ;Is the player adding items to this container?
        If Input.IsKeyPressed(29) ;left control
            Self.RemoveItem(akBaseItem, aiItemCount, True, TransferContainer) 
        Endif 
    Endif
    
EndEvent

Event OnKeyDown(Int keyCode) 
    Input.TapKey(1) ;1 = escape key. force close menu so other container menu can open
    Utility.Wait(0.2)
    TransferContainer.Activate(Game.GetPlayer()) ;open TransferContainer
EndEvent

Event OnMenuClose(String menuName) 
    UnregisterForKey(56) ; Left Alt 
    UnRegisterForMenu("ContainerMenu")
EndEvent

Hold Left Control while adding items to the container for it to automatically transfer the items to the other container. Press Left Alt to view the other container. Since it's using the OnItemAdded you don't need to worry about the Take All button as there isn't a Give All button. Even if doing it the other way you could add a condition !IsKeyPressed(19) for the R key to negate transfer when taking all.

 

You can change the keys if you wish, check here for more info: https://www.creationkit.com/index.php?title=Input_Script#DXScanCodes

 

Edit: I forgot to add change the script name to something more unique for your mod.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...