Changes in Remove Item code? (1.6)

Post » Thu Jun 21, 2012 9:04 pm

Hi,

I've got a couple of mods that started behaving strangely after I updated my Skyrim to the 1.6 beta, and I don't know if it's because it's a beta, or because some changes made to Skyrim coding. I didn't touch my mods in weeks, even months, that's for sure, and they worked before.

I have this code to check if an specific item has been consumed by the player (it's on a player alias, inside a quest enabled as game-start, under the OnItemRemoved() event):

if(akDestContainer == none && akItemReference == none)

The thing is that the game seems to go into that "if" when I consume the item (which is correct), but also when the game itself removes it after consuming (which makes the script run twice), and it also runs when item gets removed via RemoveItem method run from another script (incorrect, as I didn't consume it). If I drop the item to the ground, nothing happens (correct).

Anyone else experiencing an issue like this? Any ideas?

Thanks in advance,
Regards.
User avatar
Scott Clemmons
 
Posts: 3333
Joined: Sun Sep 16, 2007 5:35 pm

Post » Thu Jun 21, 2012 3:14 pm

I'm not sure about the double-remove issue, but OnItemRemoved has always been triggered by any removal in my experience. So when I'm trying to do scripted removal of items I also have to explicitly block that function.

If you really only want to detect items that were consumed I think you have to use a dynamic quest started from the story manager which can distinguish between the various ways an item might get removed.
User avatar
Nikki Hype
 
Posts: 3429
Joined: Mon Jan 01, 2007 12:38 pm

Post » Fri Jun 22, 2012 12:24 am

I'm not sure about the double-remove issue, but OnItemRemoved has always been triggered by any removal in my experience. So when I'm trying to do scripted removal of items I also have to explicitly block that function.

If you really only want to detect items that were consumed I think you have to use a dynamic quest started from the story manager which can distinguish between the various ways an item might get removed.

Thanks for the reply.

Anyway maybe I wasn't clear enough. These two mods used to work perfectly. The "if" condition I posted above only returned "true" if the item was actually consumed. Now, after several tests, I can confirm that it also returns true when the item is REMOVED from the game world. I placed a simple script with a player.RemoveItem(xx,xx) method, and the script was triggered, when it wasn't before.
User avatar
Spaceman
 
Posts: 3429
Joined: Wed May 23, 2007 10:09 am

Post » Thu Jun 21, 2012 12:29 pm

The item removal checks weren't working well in previous versions. Removeallitems for instance didn't check the onitemremoved event. There are also similar isues with unequipitem, that is not checked when an item is unequiped because a different one is ocuping it's former slot.

Obviously as beth developers find that they are unable to do certain things that they should, the code is corrected. Which is a good thing as a whole, but could make us need to adjust some things after making our mods work with the previous unnatural scripts behavior.
User avatar
Connor Wing
 
Posts: 3465
Joined: Wed Jun 20, 2007 1:22 am

Post » Thu Jun 21, 2012 9:21 am

The item removal checks weren't working well in previous versions. Removeallitems for instance didn't check the onitemremoved event. There are also similar isues with unequipitem, that is not checked when an item is unequiped because a different one is ocuping it's former slot.

Obviously as beth developers find that they are unable to do certain things that they should, the code is corrected. Which is a good thing as a whole, but could make us need to adjust some things after making our mods work with the previous unnatural scripts behavior.

Thanks, wasn't aware of those recent changes. But in any case, something weird is happening.

I added 3 messagebox notifications in my OnItemRemoved event (attached to a quest, player alias), just as a debug to see what's going on while trying things.

If I remove an item using player.RemoveItem(), I get 3 message boxes.
If item gets consumed (eaten / drunk), I get 6 message boxes. As if the game triggers this same even twice.

Also, DestContainer and ItemReference were both "none" when the item was consumed, therefor my script worked. Now, it returns same values when item is removed via RemoveItem.

Basically what I'm trying to say is that, as far as I know, I have no way of knowing if the item was deleted from the game world (removeitem), or consumed, and even if it was consumed, the game runs the OnItemRemoved() event twice.

I hope this is because it's a beta, because these two mods need this event to be of some use...
User avatar
Heather M
 
Posts: 3487
Joined: Mon Aug 27, 2007 5:40 am

Post » Thu Jun 21, 2012 1:03 pm

Hopefully, they fix this. Because I also use OnRemoveItem () for different purposes depending on whether the player simply dropped it, put in a container or the item was lost (i.e. consumed).
User avatar
Scotties Hottie
 
Posts: 3406
Joined: Thu Jun 08, 2006 1:40 am

Post » Thu Jun 21, 2012 8:49 pm

Maybe when you consume an item, the game removes it from the inventory, then adds a new instance of it for you to drink? I don't know, but maybe you can try adding an OnItemAdded to your script and see what happens?
User avatar
DarkGypsy
 
Posts: 3309
Joined: Tue Jan 23, 2007 11:32 am

Post » Thu Jun 21, 2012 11:40 pm

Maybe when you consume an item, the game removes it from the inventory, then adds a new instance of it for you to drink? I don't know, but maybe you can try adding an OnItemAdded to your script and see what happens?
Not a bad idea. Also the amount of removing event activation could be used if it's a constant. You can't be sure if 6 activation means a consumed item or two uses of removeitem, but 3 activations would mean that the item hasn't been consumed. Not much, but at least a little idea to start acomodating to the new weirdnessess.
User avatar
Eire Charlotta
 
Posts: 3394
Joined: Thu Nov 09, 2006 6:00 pm

Post » Thu Jun 21, 2012 11:11 am

Maybe when you consume an item, the game removes it from the inventory, then adds a new instance of it for you to drink? I don't know, but maybe you can try adding an OnItemAdded to your script and see what happens?

Confirmed. When consuming the item, the OnItemAdded() event is run.

I added some debug lines on this event (under a quest, player alias), and when I consumed a cider bottle that is supposed to just create an "empty wine bottle" item, the following happens:
- Game destroys (removes) the cider bottle.
- My script detects it and creates an empty wine bottle.
- Game adds a cider bottle, to be consumed I guess.
- Game destroys (consumes) this bottle.
- My script once again detects the item removal, and creates an empty wine bottle.

The result is that only 1 cider is drunk, but 2 bottles are created. This didn't happen before.

I don't know if this is going to be fixed, or it's the way it's going to work from now on, but I guess I'll have to think on some workaround.
User avatar
aisha jamil
 
Posts: 3436
Joined: Sun Jul 02, 2006 11:54 am

Post » Thu Jun 21, 2012 6:17 pm

Onitemremoved, you could change a variable or a property if it's not already changed and if it is you could add the emply bottle. That way the first removal would prepare the script for the second one, that is when you would add the bottle. Of course you'll need to be aware about future changes and be ready to make changes again.
User avatar
Chris BEvan
 
Posts: 3359
Joined: Mon Jul 02, 2007 4:40 pm

Post » Thu Jun 21, 2012 8:45 am

In general, Bethesda has assumed that quests and their scripts will be started and stopped from the Story Manager and not be constantly running like we did in previous games. And I'll stand by my previous statement. The official and most reliable method for detecting something being consumed is to use the Story Manager because it explicitly has checks for that which simply aren't available anywhere else.

Bethesda have corrected OnItemRemoved to work as it's supposed to work, the fact that the game is adding and removing items in the background is just now visible to us.

Try putting the portion of your code that adds the empty bottles into a small isolated quest and script. Then tell the story manager which events should trigger the code (i.e. player consumes particular items) rather than our old-fashioned method of writing a chunk of code which detects all item removals and then checks to see if it's the ones we want.

We need to un-learn our old methods of doing things. For example one of our old standbys was:
Begin GameMode ; or MenuModeif state == 0   if something_interesting_happens      set state to 1   endifelseif state == 1   ; do something (usually more than once)   if we_have_done_enough      set state to 2   endifelseif state == 2   ; finish up and reset some stuff   set state to 0endifEnd
Now we usually get to write something more like this:
Event OnSomeGeneralEvent   if something_interesting_to_us_has_happened      while we_have_not_done_enough         ; do something      endwhile   endifEndEvent

But we really should be using the Story Manager to do that filtering for the "something_interesting_to_us_has_happened" instead of writing it into our scripts. It's the new Bethesda strategy.
User avatar
Danii Brown
 
Posts: 3337
Joined: Tue Aug 22, 2006 7:13 am

Post » Thu Jun 21, 2012 12:12 pm

Thanks for the detailed reply cdcooley, but it's definitely bad news for me. Well, may be good if I end up fixing this, but for now I have 3 mods to re-write, not to mention learn how the Story Manager works, because right now I rely on game-start quests and player aliases.

Well, sounds like a good chance to dive into the SM, like it or not.
User avatar
Yama Pi
 
Posts: 3384
Joined: Wed Apr 18, 2007 3:51 am

Post » Thu Jun 21, 2012 11:13 am

The SM is great. Just remember to call Stop() at the end of your quest, or it won't restart when the event happens again.
User avatar
Anne marie
 
Posts: 3454
Joined: Tue Jul 11, 2006 1:05 pm

Post » Thu Jun 21, 2012 12:22 pm

It would be good if all those Story Manager triggers worked. E.g. crafted item story manager crashes the game to the desktop 100% of the time. And there are Bethesda scripts that for crafting that look like they were written to avoid the SM. I.e. Bethesda knew it was fails for crafting. I wonder how many other events are broken. (Another forum poster, whose name I can't remember, found the actual script and it does look like this was the case.)
User avatar
Steve Fallon
 
Posts: 3503
Joined: Thu Aug 23, 2007 12:29 am

Post » Thu Jun 21, 2012 12:13 pm

Hi,

As an update, I have to say I found a small quick fix, but not 100% accurate. It works sometimes, so it's just something temporary until I get the SM working. I would appreciate input http://www.gamesas.com/topic/1382182-story-manager-and-remove-item/ from anyone that has worked with these events before in the SM, as my experience is zero, and I'm completely lost and can't understand why it doesn't work.

So, here is the "fix", in case helps someone:
- "Switch" global variable.
- "Filling" global variable.

The OnRemoveItem() event was going into an "if" I didn't want to, that happened when I ran the method RemoveItem(), so I use the "filling" variable as a lock. I set it to "1", then run the remove item method, and then set it back to "0". I only run the item removed event when "filling" is "0". This fixed my problem of potions and bottles being removed by me and created back by the game, when I just wanted them to be deleted (the player is filling them, so I remove the empty one, and create a filled one).

Also, I detected that the game is NOT running a remove, add item, and remove item again. When player consumes an item (in my case a bottle or potion), the game runs TWO item removed events at SAME time. Don't know the exact reason, but that's what's happening. So, on the first line of my event I put this:
If switch == 0, then switch = 1
else if switch == 1, then switch = 0

Then, I only run the event if Switch == 1.
This seems to block 80-90% of the duplicated events, meaning that the first one starts, and even if it hasn't finished yet, the second one finds the global variable changed, so it doesn't run. Sometimes they seem to run at same time, because both events go through the code.

I tried adding a Wait() with a random float number, so one thread finds a wait bigger than the other one, but this seemed to complicate things even more, and was less accurate.

In any case, at least my mod is a bit more usable while I find a better solution.
User avatar
Francesca
 
Posts: 3485
Joined: Thu Jun 22, 2006 5:26 pm

Post » Thu Jun 21, 2012 12:15 pm

Another thing that changed, somehow, is Papyrus' Enable/DisablePlayerControls. Formerly...
Game.DisablePlayerControls(abMenu = True)
...would suffice in lieu of...
Game.DisablePlayerControls(False, False, False, False, False, True)
...but now the former unequips the player's weapon if one is drawn and the latter performs as the former used to. Game.PSC doesn't show any new parameters or anything...
User avatar
Rachael
 
Posts: 3412
Joined: Sat Feb 17, 2007 2:10 pm


Return to V - Skyrim