baloney8sammich Posted January 11, 2019 Share Posted January 11, 2019 Can the "OnLoad" papyrus event be used in a script attached to an Actor (NPC_ record)? If not, is there any way for a script attached to an Actor to run once when a reference to the actor spawns (or shortly thereafter)? Link to comment Share on other sites More sharing options...
SKKmods Posted January 11, 2019 Share Posted January 11, 2019 (edited) Sure thing the base game has plenty of scripts that look like; Scriptname TurretMountedScript extends Actor EVENT OnLoad() ;do stuff EndEvent If the actor is not unique and you only want to attach the script to one instance of the actor, don't attach it to the actor form, better to use use a quest ReferenceAlias. Edit: and to be clear you can spawn actors outside of the uGridsToLoad loaded area, the event will not fire until the cell that the actor is in loads 3D. Spawning and loading can be separate events, and a fantastic source of stacking uncontrolled spawning CTDs. Edited January 12, 2019 by SKK50 Link to comment Share on other sites More sharing options...
baloney8sammich Posted January 12, 2019 Author Share Posted January 12, 2019 (edited) Thanks for the response. Your edit raises some other questions though. Aren't spawning and loading always separate events? Upon entering a small interior cell for example, I would assume actors must spawn before loading. And when loading a save made immediately after entering the cell, the actors will already have spawned but will load again. I'm not trying to be pedantic; suppose the script had to run before the actor loaded (and ideally run only once per instance), would there be any way to accomplish that? Edit: Would OnInit be the event to use in this case? Edited January 12, 2019 by baloney8sammich Link to comment Share on other sites More sharing options...
SKKmods Posted January 12, 2019 Share Posted January 12, 2019 (edited) Pedantry is not a problem if it helps deliver a quality outcome. Spawning is not a technical function, its imprecise language we seem to use when referring to creating ObjectReferences in the running world. Having a quest alias create a reference or a scripted PlaceAtMe/PlaceActorAtMe can be "spawns". A static placed actor or M marker activating is typically not a spawn. After an ObjectReference is placed/created/spawned, attached scripts (direct or through quest aliases if running) will run OnInt() once whether the object is loaded or not. You will see a stack of debug errors from things like elevators complaining about OnInit trying to do animations with the object unloaded. Managing the state of quests and aliases can avoid that sort of script garbage if elegance is important to you. If the Object is created/spawned within the uGridsToLoad active player radius then OnLoad() will fire, else it will not fire until the cell attaches. If the player runs away so the cell detaches and OnUnload() fires, then OnLoad() will fire again when the player returns. You can include a state or DoOnce variable flag so it only runs once: Bool bAlreadyRun = FALSE Event OnLoad() If (bAlreadyRun == FALSE) bAlreadyRun = TRUE ;do stuff Endif EndEvent Auto State DoOnce Event OnLoad() ;do stuff GoToState("Done") EndEvent EndState State Done ;blank EndState This does mean that the script can not be Const (holds no data), so the game has to maintain a unique instance per object if that is a performance factor. Edited January 12, 2019 by SKK50 Link to comment Share on other sites More sharing options...
baloney8sammich Posted January 12, 2019 Author Share Posted January 12, 2019 (edited) Thank you for all the information. After some tinkering I came up with this: Scriptname ChangeOutfitIfFemale extends Actor Const Outfit Property FemaleOutfit auto const mandatory EVENT onLoad() if GetLeveledActorBase().GetSex() == 1 Debug.Trace("female") SetOutfit(FemaleOutfit) endif endEVENTDespite what I was expecting based on the description of SetOutfit on the CK wiki, it does what I want when run OnLoad (and not when run OnInit). It's run by every reference based on all of the LvlRaider* records, and I may eventually attach it to other Lvl* records. Because of that it seemed like a good idea to make it Const based on your last post. I've done some very basic testing with it and it works as expected, but I expect it's going to have some unanticipated effects. I should probably open a new thread about that though. Edited January 12, 2019 by baloney8sammich Link to comment Share on other sites More sharing options...
Recommended Posts