Jump to content

OnItemRemoved Firing Twice


Recommended Posts

Hi all! So, I've been trying to figure this function out for the past few weeks, and I'm finally asking for a bit of help. The below script is intended to pass time based on an item being removed from inventory. It queries for the item type, and then if the type is food, it calculates time based on whether it was removed from inventory or via hotkey. The problem is that the hotkey portion of the function (in red) is often firing twice, even though any in-game debug notifications only appear once. The papryus logs show it being executed once sometimes, twice sometimes, but pretty consistently twice. I was reading in the documentation for OnItemRemoved that this is sometimes the case with queued events, but I am trying to understand how to prevent the double firing. Code in yellow is attempting to set true/false to catch the firing, but it doesn't seem to be helping. I also notice that it tends to double up more on the same food item (has the same name), but if you switch food types/names, it fires only once. Can anyone provide insight into this sort of issue? Thanks very much in advance!

 

 

Function handle_removed_item(Form item, int count, \
ObjectReference ref, ObjectReference dst)
if !is_enabled || is_looting || is_trading || UI.isMenuOpen("Console") \
|| removing_item ;; OnItemRemoved will be strangely triggered twice
return
endif
;Debug.Notification("Function Start")
removing_item = True
int type = item.getType()
string name = item.getName()
_debug("Item removed - " + item.getName() + " (" + type + ")")

if is_crafting && mods.handle_removed_item(item)
removing_item = False
return
endif


if type == 46 ;; food
int food_eaten_now = Game.queryStat("Food Eaten")
Bool isInventoryMenuOpen = UI.IsMenuOpen("InventoryMenu")
if food_eaten_now > food_eaten && isInventoryMenuOpen
_debug("Food eaten from inventory")
eating_time_to_pass += eating_minute / 60
food_eaten = food_eaten_now
elseif food_eaten_now > food_eaten && !isInventoryMenuOpen
_debug("Food eaten via hotkey")
eating_time_to_pass = eating_minute / 60
pass_time(eating_time_to_pass)
eating_time_to_pass = 0.0
endif


elseif type == 27 ;; book
int spell_learned_now = Game.queryStat("Spells Learned")
if spell_learned_now > spell_learned
_debug("Spell learned")
pass_time(spell_learning_hour)
spell_learned = spell_learned_now
endif
endif
removing_item = False
EndFunction

 

 

 

Papyrus Log

 

[10/04/2020 - 02:06:43AM] Time Flies: Item removed - Waterskin, 3/3 (46)
[10/04/2020 - 02:06:43AM] Time Flies: Food eaten via hotkey
[10/04/2020 - 02:06:43AM] Time Flies: Time passed - 0 hour(s), 5 minute(s) (0.083333)
[10/04/2020 - 02:06:49AM] Time Flies: Item removed - Waterskin, 2/3 (46)
[10/04/2020 - 02:06:49AM] Time Flies: Food eaten via hotkey
[10/04/2020 - 02:06:49AM] Time Flies: Time passed - 0 hour(s), 5 minute(s) (0.083333)
[10/04/2020 - 02:06:50AM] Time Flies: Item removed - Waterskin, 2/3 (46)
[10/04/2020 - 02:06:50AM] Time Flies: Food eaten via hotkey
[10/04/2020 - 02:06:50AM] Time Flies: Time passed - 0 hour(s), 5 minute(s) (0.083333)

 

Link to comment
Share on other sites

I'm no good with scripts other than basics. Personally I can't help.

 

I'm replying to bump it back up because I see that you have put loads of effort into sorting this yourself... and so deserve a "leg-up", as we'd say in the UK!

 

I hate posts that aren't replied to, let alone posts that appear to be as genuine as this. Hope you find a Papyrus Guru!

 

I'm pretty sure someone will be able to help, if the right person visits the site before your thread disappears off the end into the void/oblivion that is page 2!

Link to comment
Share on other sites

Thanks cumbrianlad -- no worries at all, just wondered if someone else had come across the issue with OnItemRemoved. The odd thing is that all the notifications showing time elapsed report a single fire, but actual time elapsed (using a clock util like A Matter of Time) and the Papyrus log show the time is doubled. I am not seeing a doubling up of any Debug Notifications.

Link to comment
Share on other sites

I'm not sure how to resolve your issue. I can tell you that you will only see one on screen notification because if the text to be displayed is already the most recently displayed text on the screen (i.e. has not started moving down the screen) then the old text will not be "pushed down" but rather refreshed. So... rely on your trace statements for more precise timing of what is going on.

Link to comment
Share on other sites

Now that I think of it, I wonder if the hotkey itself is the cause of the double fire - once when the keystroke is recorded and once when the item is actually removed. The hotkey is from another mod so not sure of all its process. The script is only looking for the absence of the Inventory Menu, perhaps the condition needs to be more strict.

Link to comment
Share on other sites

Tricky because the mod (iNeed) is the one that provides the hotkey eating/drinking feature lol. It's more of a nuisance at this point and the workaround is just setting the time at half what it should be in the MCM. It's just odd that it it's not firing twice all the time, just most of the time! :)

Link to comment
Share on other sites

Now, that's a really good idea -- I was thinking of onKeyPress and looking for that in the documentation -- will experiment with OnKeyDown, Thanks for pointing to it, some good info on that page; I kind of want it to be generic -- on any key press that invokes OnItemRemoved, or check when doing OnItemRemoved for a keypress.

Link to comment
Share on other sites

Well, very interesting indeed. By separating out the hotkey event from the item removed event, I am getting consistent single fire behavior. If I want to be generic in my call for keypresses, no need to set up a register/listener, just do the check to see if food was eaten. The only thing I'm not sure of is how resource intensitve it will be to keep that keypress listener open so widely.

Doh. Never mind, I did set up the listeners for the 2 hotkeys in the OnInit, and I would need to capture them.

 

Event OnKeyDown(Int KeyCode)
int food_eaten_now = Game.queryStat("Food Eaten")
if food_eaten_now > food_eaten
_debug("Food eaten via hotkey")
eating_time_to_pass = eating_minute / 60
pass_time(eating_time_to_pass)
eating_time_to_pass = 0.0
food_eaten = food_eaten_now
endif
EndEvent

 

If I were to register the key that iNeed uses, I'd have to capture what the user has set in its MCM, and not sure I want to delve into another mod's saved state. This may be 'good enough.'

Link to comment
Share on other sites

  • Recently Browsing   0 members

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