greyday01 Posted December 11, 2022 Share Posted December 11, 2022 What is the safest way to remove spawned (not summoned) NPCs and object references if methods differ?Say I have a button when pressed spawns a NPC from a list of creatures. What script would I use to remove it when pressed again? Same for button that spawns say a kettle. Link to comment Share on other sites More sharing options...
maxarturo Posted December 11, 2022 Share Posted December 11, 2022 For actors: Function SetCriticalStage(int aiStage) native https://www.creationkit.com/index.php?title=SetCriticalStage_-_Actor NOTE A: This function will not fire if both npc and player are not in the same cell. NOTE B: This function is the only relaible way to delete an actor. For objects: Function Delete() native https://www.creationkit.com/index.php?title=Delete_-_ObjectReference NOTE A: The deletion of the object from memory and from the save file happens much later from when it was triggered in game regardless if you saw the object being deleted when playing. The deletion happens when at least 2+ cells have been loaded and unloaded, but this depends on the size of the loaded/unloaded cells. So, the 2 cells is not an accurate number. Link to comment Share on other sites More sharing options...
greyday01 Posted December 11, 2022 Author Share Posted December 11, 2022 So if it won't work if you move the npc to a different cell before calling it there is no way to avoid that horrible death sound you get with summoned creatures? If you also don't want a dead npc on the floor would you need to call delete after critical stage or delete and disable? For things like ghosts would it leave ectoplasm or the like behind? I read but didn't really understand the function. If I just wanted to get rid of say a wolf I spawned I could have something like wolf.SetCriticalStage(0) and it would disappear and be removed from my save? Link to comment Share on other sites More sharing options...
maxarturo Posted December 12, 2022 Share Posted December 12, 2022 (edited) So if it won't work if you move the npc to a different cell before calling it there is no way to avoid that horrible death sound you get with summoned creatures? - Yes, the function 'SetCriticalStage(int aiStage)' will never fire if both npc and player are NOT in the same cell, it plays no role if you first move the npc to another cell. This also applies for exterior cell (worldspaces), for example: You can call the function while you have visibility of the npc (LOS), but the npc is 3 or more cells away from you, in this case the function again will not fire. - As for the 'death' sound and/or the death animation: You can remove them both or change them if you wish so. In order to do this you need to edit (and create a new one) the actor's hkx file that exists in the actor's race, this file is what the engine uses/reads for a variaty of the actor's ai functions and behaivior. If you also don't want a dead npc on the floor would you need to call delete after critical stage or delete and disable? - DON'T EVER USE THE FUNCTION "DELETE()" ON ACTORS!!! If you call 'delete()' on an actor, then you will be deleting not the actor you spawned, but the 'BASE' actor from the game. If it's not clear, here you have a simpler explanation: Let's say you create a scripted summon spell that does not uses the game's summon mechanics, but instead you place an actor via script. If you call 'delete()' to remove the actor, it will be removed, but next time you cast your scripted summon spell, the expected npc to spawn will never appear again because the 'Base' actor does no longer exists in game. - Also, there is one more thing I forgot to mention before: The function 'SetCriticalStage(int aiStage)' will not fire if you first disable the actor. For things like ghosts would it leave ectoplasm or the like behind? - No, this is done through script. You can take a look at the game's default 'Ghost' abilty spell and the script living inside the 'Ghost Ability' Magic Effect. The script uses the function: Function AttachAshPile(Form akAshPileBase = None) native https://www.creationkit.com/index.php?title=AttachAshPile_-_Actor When this is used the game will automaticaly place a default 'Ash Pile'. I read but didn't really understand the function. If I just wanted to get rid of say a wolf I spawned I could have something like wolf.SetCriticalStage(0) and it would disappear and be removed from my save? - I will be using your example above for the following script, some explanations will be bellow each script. EVENT OnDying(Actor akKiller) Self.SetCriticalStage(3) ENDEVENT EVENT OnDeath(Actor killer) Self.SetCriticalStage(4) ENDEVENT - The script is living in the actor itself, in the 'Base' actor. So, there is no need to define the actor, instead will be using the function 'Self', since the script is living inside the actor. - Here we call and begin the deletion/cleaning process when the actor starts dying, the moment the actor receives the 'Death Blow' while he is still standing = Self.SetCriticalStage(3) - Once the actor has finished the death process, meaning: Falling down, finishing the death animation and completing its 'Death' dialogue, we call the final function that will remove the actor from our game = Self.SetCriticalStage(4) Important Note: In order for the 'cleaning/deleting actor' process to work correctly you need to use the function in this order: SetCriticalStage(3) SetCriticalStage(4) You can call 'SetCriticalStage(4)' imidiatelly and the actor will disapear from game, but you will find it again lying dead somewhere because the 'SetCriticalStage()' never actually started = SetCriticalStage(3) EVENT OnDeath(Actor killer) Self.SetCriticalStage(3) ENDEVENT EVENT OnCellDetach() Self.SetCriticalStage(4) ENDEVENT - Here we start the clening process when the actor finishes the death process, and we finish it once the player moves to anothe cell dettaching the cell from the player where the function was called. * Both scripts are simple just to explain the functions, if you need to use any of them, then they need further scripting so they can be functionable correclty. I hope I was clear enough. Edited December 12, 2022 by maxarturo Link to comment Share on other sites More sharing options...
greyday01 Posted December 12, 2022 Author Share Posted December 12, 2022 Yes. You explained how to deal with getting rid of something that you killed. I was hoping for something akin to how frostfall has a way to cause a tent to spawn and then removes it when not needed. It seems for creatures the only way would be to have unique unkillable creatures in a holding cell somewhere and just move them between the place you want them and then back to the holding cell. I was hoping for a better way to get creatures to instantly appear and then be instantly removed repeatedly. When a summons time expires you hear the death noise which I suppose comes from the criticalstages bit but then they immediately disappear leaving nothing behind. Are the corpses moved to some garbage cell until the game cleans them up? Or does summoning repeatedly leave a trail of disabled dead creatures behind you? Where DO the bodies go when the summons expires? Link to comment Share on other sites More sharing options...
Sphered Posted December 12, 2022 Share Posted December 12, 2022 There are mitigations available to ease unwanted side effects SetAlpha() so to where you cant see them. ATM dont recall if its 0 or 1 that hides them lol MoveTo() can be used to move them several units below or away before being sanitized Depending on needs and goals, stuff like EnableAI(False) and SetDontMove() etc can potentially help I always removeallitems() but I never got a concrete on how necessary that is to fully delete actors or containers Link to comment Share on other sites More sharing options...
maxarturo Posted December 12, 2022 Share Posted December 12, 2022 (edited) 1) I have no idea what 'frostfall' is, so I can't provide data of how it works. 2) The summon function of the game is 'Hard Coded', so is the summon delete function of the summon. The 'delete actor' function works exactly as the 'SetCriticalStage()' with the only difference that it dosen't care about its equivilant Papyrus function restrictions since it's hard coded, and it will always delete the summoned actor without leaving a trace in the save file and game world. If you explain in simplified details what you are aiming to achieve, someone will be able to provide you with the necessary knowhow. Right now there is no enough data for it. Edited December 12, 2022 by maxarturo Link to comment Share on other sites More sharing options...
greyday01 Posted December 13, 2022 Author Share Posted December 13, 2022 Two things. I wanted the best way to press a button. A random creature appears (not reacheable or killiable, just a living display). Press again the first one disappears, and another appears in its place. The best way I found was moving critters in and out of a holding cell but was hoping there was a better way. The other thing I wanted is when entering a graveyard at night a ghost appears. This one is killiable. If you leave the graveyard or daylight comes it vanishes. Return to the grave again at night it reappears. Trying to figure out how to return things to original never entered the graveyard condition when you leave or daylight comes, whether or not you killed the thing while there.Never figured out why none of the graveyards were haunted. Link to comment Share on other sites More sharing options...
maxarturo Posted December 13, 2022 Share Posted December 13, 2022 (edited) Moving npcs from a holding cell to your 'display' is not a bad approach, but if you are concern about save file size, then except if you are talking about having thousands upon thousands of npcs, we are talking here about a byte size file size increase. Now if you wanna get rid of that byte, you can always spawn the npc > then move the npc away from the player (but in the same cell) to not hear the death sound if you won't be creating a custom hkx file > then run 'SetCriticalStage()' on that npc. For your ghost: There are a couple of ways you can do this, but they require some extend scripting. One way is to utilize the 'Story Manager' (and a quest that will handle the npc) and run an 'OnLocationChange()' event. Event OnLocationChange(Location akOldLoc, Location akNewLoc) https://www.creationkit.com/index.php?title=OnLocationChange_-_Actor Once your location fires the 'Event Node' then in the same script you run a 'GetCurrentGameTime()' function to spawn or not the ghost. https://www.creationkit.com/index.php?title=GetCurrentGameTime_-_Utility Here you have an example about 'Function for Time of Day': https://www.creationkit.com/index.php?title=Function_for_Time_of_Day Trying to figure out how to return things to original never entered the graveyard condition when you leave or daylight comes, whether or not you killed the thing while there. This part is a little confusing, what do you mean by 'return things to original'? Edited December 13, 2022 by maxarturo Link to comment Share on other sites More sharing options...
greyday01 Posted December 13, 2022 Author Share Posted December 13, 2022 Ok, for the display I'll stick with moveto a holding cell. It works but I thought it lacked elegance. For the graveyard what I want is when you enter a trigger the ghost fades in and attacks.I couldn't find any function that would allow it to pass through the ground like coming up from a grave.If you leave the ghost vanishes. If you return the ghost comes back. Wait until daylight without being killed or killing, the ghost vanishes.If you kill the ghost, you've got a blob of ectoplasm. Going in and out of the graveyard the rest of the night, no ghost. Come back the next night, new ghost. Side question. In Solstheim the ash spawn crawl up out of the ground sometimes. How do they do that and avoid collision with it? Oh, and thank you for your explanations. It's hard sometimes to figure out what is going on under the hood of the engine to know what is possible and impossible. Link to comment Share on other sites More sharing options...
Recommended Posts