OnInit fires too many times?

Post » Thu Jun 21, 2012 6:05 am

I put an OnInit on an armor, which checks whether the player is equipping this armor or not. If yes, force player to equip a new armor and remove this armor and then put it back

Event OnInit()   if Game.GetPlayer().IsEquipped(This)      Game.GetPlayer().EquipItem(NewArmor,false,true)      Game.GetPlayer().RemoveItem(this,1,true)      Game.GetPlayer().AddItem(this,1,true)   endif   GotoState("Initialized")EndEvent

However, the item got added too many times, although the remove item is called before adding the item. I also have an OnEquip event in "Initialized" state. Does it have anything to do with this behavior?
User avatar
Catherine N
 
Posts: 3407
Joined: Sat Jan 27, 2007 9:58 pm

Post » Thu Jun 21, 2012 3:29 am

http://www.creationkit.com/OnInit#Notes can fire two times (see notes), so what you want is more like ...
event OnInit()	GoToState("Initialized")	Actor target = Game.GetPlayer()	if (target.IsEquipped(self))		target.EquipItem(NewArmor, false, true)		; What are these two lines are supposed to to? Because they cancel each other out.		target.RemoveItem(self, 1, true)		target.AddItem(self, 1, true)	endifendevent
User avatar
Cat Haines
 
Posts: 3385
Joined: Fri Oct 27, 2006 9:27 am

Post » Wed Jun 20, 2012 2:12 pm

I thought for persistent references, it is called only once (during cell reset?)

I've attached an OnEquip event for the armor. Removing and Adding them again allows the OnEquip to fire correctly without having to drop the item and picking it up again

Also, the item gets added not only twice, but can go as high as 23 times. It's really driving me nuts. I'll try your solution

By the way, I tried "self", for some reason it doesn't work?
User avatar
Kelly Upshall
 
Posts: 3475
Joined: Sat Oct 28, 2006 6:26 pm

Post » Thu Jun 21, 2012 3:02 am

Each instance of the script will run the init().
So if an object adds a copy of itself then in theory you've created an endless chain.
User avatar
Mari martnez Martinez
 
Posts: 3500
Joined: Sat Aug 11, 2007 9:39 am

Post » Wed Jun 20, 2012 10:11 pm

Well pretty much everything that is an ObjectReference can be reset and thus has a chance for OnInit to fire twice.

I'd have to take a guess, but I'm quite sure the OnInit/OnEquipped is what is causing the 23 items, in which case switching states (GoToState) might help but might not be enough. But I can't know without seeing the whole script.

About self, it depends on what self is, in your case that would be ObjectReference, which should work just fine because it extends Form which is what all used functions expect.
User avatar
zoe
 
Posts: 3298
Joined: Sun Nov 12, 2006 1:09 pm

Post » Thu Jun 21, 2012 12:15 am

Each instance of the script will run the init().
So if an object adds a copy of itself then in theory you've created an endless chain.
That... does make sense...


Then this means I need some sort of checker. How do I refer to properties of other scripts? I'm sure in Oblivion it was a matter of calling the script's name. What about Papyrus?

@Xethrill:
No, for some reason it doesn't work. I thought it would work just fine too, but it doesn't.

EDIT:
I' d like to tackle this from a different perspective. Is there a GetEquippedArmor version of GetEquippedShield?

EDIT2:
Looks like I can use WornHasKeyword for my purposes
User avatar
Juan Cerda
 
Posts: 3426
Joined: Thu Jul 12, 2007 8:49 pm

Post » Wed Jun 20, 2012 8:46 pm

Scripts talking to each other is just like with any other property, expect that you might need an mediator (a Quest).

But it could be that this turns out to be overkill, if you can get rid of the OnInit event.


Edit:
@Xethrill:
No, for some reason it doesn't work. I thought it would work just fine too, but it doesn't.
That points to an underlying and yet undiscovered problem another reason to post the script, otherwise this is mostly guesswork.
User avatar
Poetic Vice
 
Posts: 3440
Joined: Wed Oct 31, 2007 8:19 pm

Post » Wed Jun 20, 2012 11:15 pm

Scripts talking to each other is just like with any other property, expect that you might need an mediator (a Quest).

But it could be that this turns out to be overkill, if you can get rid of the OnInit event.
Hmmm... how do I get around that? I'd say it's overkill just to get an initialization, yes.

Oh well... I'll see what I can get my hands on. Thanks mate!

EDIT:
Looks like I can still use some help. I gave myself 5 armors, and used OnInit. OnInit removed them all. I DO need a checker after all.

I want to remove the objects to a container, and take them back. I tried to use a COntainer type property, but RemoveItem requires ObjectReference. How do I use this 4th parameter?
User avatar
Wanda Maximoff
 
Posts: 3493
Joined: Mon Jun 12, 2006 7:05 am

Post » Wed Jun 20, 2012 9:30 pm

Just use an ObjectReference property and point it to a container.

After reading the thread, I still don't quite understand what you're trying to do. Why do you remove the armor and then add it back in right away?
User avatar
Kristian Perez
 
Posts: 3365
Joined: Thu Aug 23, 2007 3:03 am

Post » Wed Jun 20, 2012 6:54 pm

Just use an ObjectReference property and point it to a container.

After reading the thread, I still don't quite understand what you're trying to do. Why do you remove the armor and then add it back in right away?
The problem is how do I point it to the container? I use the Edit Property window to give properties value, and it is not reflected in the script. If I try to use ObjectReference it would ask me to point to a cell and get the object. I understand that perhaps I should not be so lazy, but I don't want to mess with anything. That NavMesh bug is bugging me, and I'm holding back from 1.5 because they say it kills performance

It's driving me nuts, Oblivion was so much easier

I attached an OnEquip event to the armor. If on game start said armor is already in your possession, OnEquip won't fire. it's as if they only do addEventListener during OnItemAdded.

That said, I no longer need to do that, so it's over for now :P
User avatar
Michael Russ
 
Posts: 3380
Joined: Thu Jul 05, 2007 3:33 am

Post » Wed Jun 20, 2012 6:49 pm

You need to use an ObjectReference property in order to point at a specific container in the game. If you are placing something in a container, you have to know which container you're placing it in. Just using a container property will not refer to a specific container (not to mention it doesn't work with the function).

Or perhaps I am misunderstanding what you're trying to say.
User avatar
Britney Lopez
 
Posts: 3469
Joined: Fri Feb 09, 2007 5:22 pm

Post » Wed Jun 20, 2012 7:21 pm

You need to use an ObjectReference property in order to point at a specific container in the game. If you are placing something in a container, you have to know which container you're placing it in. Just using a container property will not refer to a specific container (not to mention it doesn't work with the function).

Or perhaps I am misunderstanding what you're trying to say.
See, if I declare a property to be of ObjectReference, I have to put the container in the game world first, thus modifying the vanilla spaces. People say that modifying them the wrong way may cause NavMesh problems (or so I heard). I heard 1.5 update fixes this, but it kills performance, and I don't want that, so yeah.

If I declare a property with type Container, I can directly refer to a container I haven't placed in the game world, but RemoveItem function won't take it as an argument (type doesn't match, and can't typecast)
User avatar
luis dejesus
 
Posts: 3451
Joined: Sun Aug 19, 2007 7:40 am

Post » Thu Jun 21, 2012 12:41 am

Well, no matter what you're going to need to use an ObjectReference property. I haven't noticed anything wrong with placing one in the game, but if you're so worried, just use one of the vanilla containers...

Otherwise I guess you could create one at run-time and refer to that in your script... Something like this:

Scriptname SomeScript extends QuestContainer property ContainerBaseObject autoObjectReference property PlacedContainer autoEvent OnInit()    RegisterForSingleUpdate(1)    ;i don't know any other way to prevent the code here from firing twiceEndEventEvent OnUpdate()    UnregisterForUpdate()    PlacedContainer = Game.GetPlayer().PlaceAtMe(Container)    PlacedContainer.MoveTo(PlacedContainer, 0, 0, -30000)EndEvent

Then in your armor's script, just use the PlacedContainer property in your quest script.
User avatar
Scott Clemmons
 
Posts: 3333
Joined: Sun Sep 16, 2007 5:35 pm

Post » Thu Jun 21, 2012 12:08 am

Or perhaps making an unaccessable cell as a place for the container to exist. Something like the "WICourier" cell

- Hypno
User avatar
Dalley hussain
 
Posts: 3480
Joined: Sun Jun 18, 2006 2:45 am

Post » Thu Jun 21, 2012 5:52 am

Otherwise it's like the tophat in The Prestige...
User avatar
Claudia Cook
 
Posts: 3450
Joined: Mon Oct 30, 2006 10:22 am


Return to V - Skyrim