Jump to content

[LE] Get container currently accessed by player


Lazauya

Recommended Posts

Container currently accessed...

 

You could wait till the player transfers an item. Using OnItemAdded and OnItemRemoved on a player alias script you will be able to use the akSourceContainer parameter in OnItemAdded and akDestContainer parameter in OnItemRemoved to obtain the container being interacted with. If the akDestContainer value is NONE then the item was dropped or simply removed with no destination (some scripts do this). If akSourceContainer value is NONE then the item was picked up.

 

But if the player doesn't transfer an item, then you will have no idea what container they are currently accessing.

 

You might be able to use OnCrosshairRefChange (an SKSE event) to obtain the object that the player is pointing at and hope that this is the container that they actually opened. But experience has shown me that this event will process with everything in range that it points to and even with the best filtering can still backup papyrus and cause stack dumps. I don't recommend it.

 

A third approach could be to set up a hotkey that the user can use to open containers instead of the normal activation. By using your hotkey, they could then trigger GetCurrentCrosshairRef just prior to using Activate to simulate having used the real activation key. Drawback is that if they don't use your key, then you won't know if they accessed the container. Also, there are some cases where the object interacted with is not the actual container and so the returned object will not be a valid container.

 

If there is any other way, I don't know it.

 

I would suggest a combination of the first and third approaches. The first as a backup in case the player doesn't use the hotkey to open a container and as a filter to confirm that the returned object is the actual container. It would also cover those players that don't use SKSE.

Link to comment
Share on other sites

Container currently accessed...

Â

You could wait till the player transfers an item. Â Using OnItemAdded and OnItemRemoved on a player alias script you will be able to use the akSourceContainer parameter in OnItemAdded and akDestContainer parameter in OnItemRemoved to obtain the container being interacted with. Â If the akDestContainer value is NONE then the item was dropped or simply removed with no destination (some scripts do this). Â If akSourceContainer value is NONE then the item was picked up.

Â

But if the player doesn't transfer an item, then you will have no idea what container they are currently accessing.

Â

You might be able to use OnCrosshairRefChange (an SKSE event) to obtain the object that the player is pointing at and hope that this is the container that they actually opened. Â But experience has shown me that this event will process with everything in range that it points to and even with the best filtering can still backup papyrus and cause stack dumps. Â I don't recommend it.

Â

A third approach could be to set up a hotkey that the user can use to open containers instead of the normal activation. Â By using your hotkey, they could then trigger GetCurrentCrosshairRef just prior to using Activate to simulate having used the real activation key. Â Drawback is that if they don't use your key, then you won't know if they accessed the container. Â Also, there are some cases where the object interacted with is not the actual container and so the returned object will not be a valid container.

Â

If there is any other way, I don't know it.

Â

I would suggest a combination of the first and third approaches. Â The first as a backup in case the player doesn't use the hotkey to open a container and as a filter to confirm that the returned object is the actual container. Â It would also cover those players that don't use SKSE. Â

Hm... I'll look into these, but they seem a little slow. I though of using the crosshair ref tactick. Would these be able to account for inventories the player doesnt look at? I.e., if a script opens a container menu for the player?

Link to comment
Share on other sites

The first approach would work with a container that has been scripted to open with the player, provided the player interacts with said container and adds or removes an item.

The second and third approaches would not work as the object being pointed to is not the container being accessed.

The combination approach covers the most possible situations. But will not catch all situations if the player does not transfer any objects.

 

Hope that helps.

Link to comment
Share on other sites

Using OnItemAdded and OnItemRemoved with the script on the container is how this is done ...

Sure IF you want to edit every container in the game that you want to deal with. And again, it won't trigger if the player doesn't add or remove an object.

Using a player alias script is more compatible when dealing with containers that are not of your creation.

 

I prefer to go the route of compatibility.

Link to comment
Share on other sites

What it comes down to is: if you only need to detect the container after the player has moved an item into or out of it, then you can use the OnItemAdded/Removed method. If you need to know what container the player is interacting with before they move something in or out, Papyrus is not up to the task. GetCrossHairRef or a perk entry point won't detect scripted containers or merchant containers.
Link to comment
Share on other sites

Could use you use RegisterForMenu(ContainerMenu) and OnMenuOpen(ContainerMen) in conjunction with a container ref walking script? Then you could use GetType for 28 (kContainer), starting with the closest? Im looking for something like IsActive(), or IsOpen(), but finding none.

MiscUtil from PapyrusUtil has ObjectReference[] function ScanCellObjects(int formType, ObjectReference CenterOn, float radius = 5000.0, Keyword HasKeyword = none) global native.

I think its possible to be creative to get this accomplished but Im fairly new to skyrim scripting.

for example: run a while loop inside OnMenuOpen(ContainerMenu) event. Something like:


event OnMenuOpen(ContainerMenu)
form[] ObjectsNearPlayer=new form[128]
bool containerFound=false
float searchRadius=.01
while searchRadius<=10 && containerFound==false
ObjectsNearPlayer=MiscUtil.ScanCellObjects(28, playerRef, searchRadius)
nObjectsInRadius=ObjectsNearPlayer.length
int x=0
while x<nObjectsInRadius
formType=ObjectsNearPlayer[x]
if formType==28
;this is probably the container that has been opened.

containerFound=true
else

x+=1
endif
searchRadius+=.01
endWhile
endEvent

If you are in a container, that container should be detected in a very small search radius. It couldn't hurt to test. If it works, you now have a function GetOpenContainer(). if you are looking for a specific container you could just attach a script to it, but there is a keyword parameter to that ScanCellObjects() function.

Another note is that this script wouldn't in principle work for remote containers, like DeepStorage spell, but you might be able to use keyword to detect remote containers too because there are not many of them.

Edited by irswat
Link to comment
Share on other sites

If you are gonna use it on more then one container, as in more then a few just put the script on the Base and create a new name for it.

I myself don't even know how to do the "alias" version could you show us an example ...

 

 

Using OnItemAdded and OnItemRemoved with the script on the container is how this is done ...

Sure IF you want to edit every container in the game that you want to deal with. And again, it won't trigger if the player doesn't add or remove an object.

Using a player alias script is more compatible when dealing with containers that are not of your creation.

 

I prefer to go the route of compatibility.

 

 

If you are gonna use it on more then one container, as in more then a few just put the script on the Base and create a new name for it.

I myself don't even know how to do the "alias" version could you show us an example ...

Link to comment
Share on other sites

  • Recently Browsing   0 members

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