Event in Script attached to Misc Item only firing once?

Post » Tue Jun 19, 2012 6:16 am

Let me give a bit of background. I want the player to be able to place campsite equipment on the ground. The way I've designed it, requires 3 separate objects: a "MiscObject" item that the player can put in his inventory, a "Packed" activator (world object), and an "Unpacked" activator (world object).

In the case of a bedroll, this would be the rolled up Misc Item, which the player would drop. This would spawn a "packed" (in this case, rolled up) Bedroll activator. when the player is happy with where it is, he activates it to spawn an "unpacked" (unrolled) activator. He can activate that to pick it back up, and it should be returned as the Misc Item again.

I have the following script attached to the Misc Item:

Scriptname _DE_Bedroll_MISC_Script extends ObjectReference{Swaps the dropped Bedroll for the Activator variant.}Activator property _DE_CampBedroll_Packed_ACT auto{Reference to the packed Activator Bedroll.}Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)	if akOldContainer && !akNewContainer  		Debug.notification("We have been dropped!")		Game.GetPlayer().PlaceAtMe(_DE_CampBedroll_Packed_ACT)		self.Disable(false)	elseif !akOldContainer && akNewContainer		debug.notification("We were just picked up!")	endIfendEvent

Straight forward enough. When the player drops the item, it converts to an Activator properly (by PlaceAtMe and Disable, as above). When I activate it and select "Pick Up", it does exactly what it's supposed to, adds the Misc Item to my inventory.

The problem comes when I try to drop it again. When I do so, it drops and stays as a Misc Item, never firing the Event to swap with an activator.

Anyone know why this would be? It doesn't make sense to me. Surely items added via scripting have their associated scripts still attached to them?
User avatar
Casey
 
Posts: 3376
Joined: Mon Nov 12, 2007 8:38 am

Post » Mon Jun 18, 2012 9:42 pm

Update: The problem has something to do with having more than one of the item in your inventory at once. If you already have one of said item in your inventory when you drop it, the OnContainerChange event related to being dropped may not fire. The inverse is true, if you have one of said item in your inventory when you pick it up, the OnContainerChange event related to being picked up may not fire.

When only one of said item is in your inventory, the script seems to work pretty reliably. It is very hit-and-miss when there is more than one.
User avatar
Kim Kay
 
Posts: 3427
Joined: Fri Oct 13, 2006 10:45 am

Post » Mon Jun 18, 2012 10:31 pm

Thanks for the update, I've been looking at this thread and scratching my head trying to think of what the problem might be.

I'd appreciate it if you could add your findings to the wiki's documentation of http://www.creationkit.com/OnContainerChanged_-_ObjectReference.

Cipscis
User avatar
Bellismydesi
 
Posts: 3360
Joined: Sun Jun 18, 2006 7:25 am

Post » Tue Jun 19, 2012 5:56 am

Ok, I did some testing with the following script. Mostly the same as before, but without the Disable function and more condition checks.

Scriptname _DE_Bedroll_MISC_Script extends ObjectReference{Swaps the dropped Bedroll for the Activator variant.}import debugActivator property _DE_CampBedroll_Packed_ACT auto{Reference to the packed Activator Bedroll.}Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)     notification("The event fired!")	if akOldContainer && !akNewContainer  		notification("We have been dropped!")	 elseif !akOldContainer && akNewContainer		  notification("We were just picked up!")	 elseif !akOldContainer && !akNewContainer		  notification("Both conditions returned false!")	 elseif akOldContainer && akNewContainer		  notification("Both conditions returned true!")	 else		  notification("None of these conditions returned true!")	endIfendEvent

Here is what I found:
  • If you have only one of a type of item that runs a script with the OnContainerChanged Event in your inventory, and you drop it, the event (and its correct logic) will always fire.
  • If you have none of a type of item that runs a script with the OnContainerChanged Event in your inventory, and you pick one up, the event (and its correct logic) will always fire.
  • If you have two such items in your inventory, and you drop one, the first one will fire the event. The second one dropped will never fire the event itself (or execute any contained logic).
  • If you have none of such items in your inventory and you pick one up, the first one will fire the event and logic. If you pick up a second one, it will never fire the event itself (or execute any contained logic).
  • If you have two such items in your inventory, and you drop one, the first one will fire the event. Then, if you pick it up, and drop it again, over and over, the item will almost never fire the event.
That complicated enough for you? :tongue: I will see about posting this on the wiki. Note that the items in question are stacking in my inventory; I assume that has something to do with it, and the game not having a unique reference ID for the individual items in my inventory.
User avatar
kiss my weasel
 
Posts: 3221
Joined: Tue Feb 20, 2007 9:08 am

Post » Tue Jun 19, 2012 4:55 am

Great, thanks.

Two more tests you (or anyone else - I don't have access to the Creation Kit or Skyrim just right now) could do - if you drop or pick up items in a stack (I think you need 5 or more by default), what happens, and what happens if you move items about via Papyrus functions (one at a time or together)?

Cipscis
User avatar
Johnny
 
Posts: 3390
Joined: Fri Jul 06, 2007 11:32 am

Post » Mon Jun 18, 2012 7:59 pm

I dropped 10 out of 20, and the event fired. I dropped the other 10, and the event did not fire.

So it would seem like stacked dropped items only have one script associated to them.

(also, strangely, when I dropped the other 10, it dropped one stack of 9, and a single, even though I dropped them as a lump sum of 10)
User avatar
Taylor Bakos
 
Posts: 3408
Joined: Mon Jan 15, 2007 12:05 am

Post » Mon Jun 18, 2012 8:56 pm

Another update, more weirdness.

So I attach the following script to a misc item, and have another script add two of them to my inventory when the game starts.

Scriptname _DE_MISC_Script extends ObjectReference{misc object test script.}Event OnInit()	int i = 1	int myid = utility.randomint()		while i == 1		utility.wait(10)		float myposx = self.GetPositionX()		debug.notification("posx" + myposx + " ID:" + myid)	endwhileendEvent

What this will do is let me identify each instance of a running script with a random number. So I get in game, and see the following output:

posx0.000000 ID:100posx0.000000 ID:2

So far so good. We have both items in my inventory, so logically they wouldn't have a position. I drop one. Then I get the following:

posx1728.72978 ID:100posx0.000000 ID:2posx0.000000 ID:36

So the item with script ID 100 gets dropped into the world, and is reporting his X Pos. But... where did 36 come from?

So I drop the other item, and get the following:

posx1728.72978 ID:100posx0.000000 ID:2posx0.000000 ID:36posx1649.72962 ID:39

So ID 2 still reports having no position, and a new script instance, 39, reports a world position. This is different from the first drop, where an existing script instance started reporting world position, and not the new one.

Why is another script instance being generated at all? This makes no sense.
User avatar
Sheila Reyes
 
Posts: 3386
Joined: Thu Dec 28, 2006 7:40 am

Post » Tue Jun 19, 2012 6:02 am

(Yet another) update:

Narrowed the problem down to the way the scripted items were being added to my inventory.

There is a script attached to a Start Enabled quest that performs the following:

MiscObject Property _DE_CampBedroll_MISC autoMiscObject Property _DE_CampFireKit_MISC autoMiscObject Property _DE_CampTent_MISC autoevent OnInit()	 RegisterForUpdate(5)	 utility.wait(10)	 Game.GetPlayer().AddItem(_DE_CampBedroll_MISC)	 gotoState("polling")	endevent

For some reason, the above AddItem commands add two of the items to my inventory, instead of the default 1. Even specifying explicitly "1" still results in 2 being added. (And yes, I performed the negative test of commenting out these additem lines, and indeed, none are added).

So I performed the following test with this script attached to the items:

Event OnInit()	int i = 1	while i == 1		utility.wait(2)		messagebox(self)	 endwhileendEvent

This returns whatever string representation of Self is. This gave me the following output in-game:

[_DE_CampBedroll_MISC ]
[_DE_CampBedroll_MISC ]

So there's an item being added to my inventory with no reference ID from that AddItem call earlier.

So then, I got rid of the AddItem calls and just added the items to the world space outside of Riverwood. And... it seems to work perfectly so far. Both items have reference IDs, and the game seems to be keeping track of them perfectly. No duplicate script instances. No items without reference IDs.

So for some reason that AddItem call is borked up in some way that it's creating a duplicate item with no Reference ID, which causes problems later trying to keep track of it with scripts.

Anyone have any ideas why AddItem is behaving this way?

Edit: The case that I said worked perfectly (when adding the items to the worldspace directly) did not stand up to stress testing. Picking them up / dropping them over and over eventually causes a condition where OnContainerChanged events no longer fire. Then it randomly starts working again. Very hit-and-miss.
User avatar
Grace Francis
 
Posts: 3431
Joined: Wed Jul 19, 2006 2:51 pm

Post » Mon Jun 18, 2012 5:22 pm

Cipscis, what would you recommmend that I post on the wiki? "Attempting to detect a container change on items that are part of a stack may cause strange, unpredictable behavior such as scripts attached to those items no longer working?"

For now I've solved the problem by circumventing miscellaneous items entirely and using an item in the inventory that you "equip" that pulls up a menu and allows you to "drop" (PlaceAtMe activator) objects into the world space. Their count is kept track of with a global var.
User avatar
Kirsty Wood
 
Posts: 3461
Joined: Tue Aug 15, 2006 10:41 am

Post » Mon Jun 18, 2012 4:22 pm


(also, strangely, when I dropped the other 10, it dropped one stack of 9, and a single, even though I dropped them as a lump sum of 10)

Did one of them have a "Stolen" flag? I know it splits stolen and unstolen items when you drop them.
User avatar
xxLindsAffec
 
Posts: 3604
Joined: Sun Jan 14, 2007 10:39 pm

Post » Tue Jun 19, 2012 6:40 am

It didn't seem to, no. When I picked them all back up again, they were combined into a stack of 20.

Edit: I foundhttp://www.gamesas.com/topic/1346756-help-with-a-script-please/page__view__findpost__p__20294947 which may explain the double additem behavior i'm seeing.
User avatar
Avril Louise
 
Posts: 3408
Joined: Thu Jun 15, 2006 10:37 pm


Return to V - Skyrim