Jump to content

[LE] Container script - Detect if specific items are taken / container is empty?


Uledus

Recommended Posts

Folks, the request is for a non-SKSE solution.

There are a few cases to consider and you'll need slightly different approaches to each.
A. You're concerned about making sure the player takes all of the original items, but don't care if the player stores other stuff in the container.
B. You need the player to take the original items and also don't want the player putting anything back.
C. You need to know then the container is completely empty (i.e. the player has the original items and hasn't added anything else.)
D. You need to know when an arbitrary container is empty or not.

Most of the solutions posted above are trying to handle case D and it sounds like you have one of the other three.

Case A is the easiest and IsharaMeradin's solution almost works except that you can still get multiple messages if the player does a Take All on the container since that removes all items at the same time and then fires off the OnItemRemoved for each so every one of them thinks they were the last item removed. Like NexusComa's first reply you can handle that with a simple flag variable (although I prefer a bool variable with a more descriptive name).

Scriptname myContainerScript Extends ObjectReference
 
Formlist Property myContainerItems Auto
Message Property YourMessage Auto

Bool alreadyEmptied = false
 
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
  If CheckForEmptyContainer(myContainerItems) == true
      If alreadyEmptied == false
        alreadyEmptied = true
        YourMessage.Show()
      EndIf
  EndIf
EndEvent
 
Bool Function CheckForEmptyContainer(Formlist Contents)
  Bool empty = true
  Int index = 0
  While index < Contents.GetSize()
    Form Entry = Contents.GetAt(index)
    If Entry.GetItemCount() > 0
      empty = false
      index = Contents.GetSize() ; only need to know if container is empty. no sense continuing loop if we found an item, set index so we can exit early
    EndIf
    index += 1
  EndWhile
  Return empty
EndFunction

 

 

 

For case B, you can simply add on OnItemAdded event that transfers any items the player attempts to put in the container back to the player's inventory.

 

For case C, use OnItemAdded to update the myContainerItems formlist to make sure that there's a matching OnItemRemoved. In that case you may also want to force the alreadyEmptied flag back to false so you can tell if the container is emptied, refilled, and then emptied again.

 

For case D, foamyesque gave the basic method you would need to use. That one is messy enough that the SKSE solution really is much better.

Link to comment
Share on other sites

im pretty sure GetItemCount() has to be called on the container not the Form to be counted.

so instead of

If Entry.GetItemCount() > 0

use this

If self.GetItemCount(Entry) > 0

Also why deal with the loop if you can just pass the Formlist itself as argument? (unless thats also bugged on this func)?

 

And then the alreadyEmptied flag makes more sense to be called before checking the inventory otherwise we didn't need it

 

This is what i would suggest

Scriptname myContainerScript Extends ObjectReference
 
Formlist Property myContainerItems Auto
Message Property YourMessage Auto

Bool alreadyEmptied = false
 
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
  If !alreadyEmptied 
      If !self.GetItemCount(myContainerItems)
         alreadyEmptied = true
         YourMessage.Show()
      EndIf
  EndIf
EndEvent
Link to comment
Share on other sites

Thanks for your help everybody.

IsharaMeradin's approach was a good start and with cdcooley's adjustments everything works as intended in any situation.

I had a quick look on how the Vanilla scripts use GetItemCount before I had a nap yesterday and I noticed the little form error as well(what testiger2 said).

GetItemCount(Entry) > 0  // wrong call --> If Entry.GetItemCount() > 0

Thanks again!

Link to comment
Share on other sites

cdcooley in this case I agree as there are only 2 possible outcomes ... yes and no

I didn't know he still wanted to use the chest or what ever it is.

This is an odd one ... doing the items one at a time fails if you remove one item and close chest then come back.

It also fails if you take them slowly. It would seem the forms list is the best way to go.

Edited by NexusComa
Link to comment
Share on other sites

 

testiger2: Your approach fails if the container has two (or more) types of items in it, and the player removes all of any kind but not all of every kind; it will prematurely display the message box.

Not true.

Tested it beforehand and it works just as intended

 

 

That's my bad: Misread your code, didn't realize you were checking against a formlist. Still only works if you have known items, but that sounds like it is the OP's case, so it should work fine.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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