Jump to content

DOWNLOAD MODS

Are you looking for something shiny for your load order? We have many exclusive mods and resources you won't find anywhere else. Start your search now...

LEARN MODDING

Ready to try your hand at making your own mod creations? Visit the Enclave, the original ES/FO modding school, and learn the tricks of the trade from veteran modders...

JOIN THE ALLIANCE

Membership is free and registering unlocks image galleries, project hosting, live chat, unlimited downloads, & more...

[Solved] Using a function to delete objects through another script


Kotep
 Share

Recommended Posts

I've set up some scripting in a mod of mine where copies of an enemy spawn in OnHit.  I have no problem with this--the problem is with trying to clean up after them.  I'd like to be able to Kill and/or Delete all of them once I'm done, so that they're not cluttering up the place.

 

What I have on each of the enemies (applied to the base NPC, so that each enemy spawns with a copy of the script):

Scriptname EnemyScript extends ObjectReference

Function KillAllEnemies()
	Self.Delete()
endFunction

And then, from there, I want to use another script to delete them from afar.  What I tried was:

Scriptname KillScript extends EnemyScript

Event OnActivate(ObjectReference akActionRef)
	KillAllEnemies()
EndEvent

While I didn't get any actual errors, the problem was that when I called KillAllEnemies, it used Self on the activator I had attached KillScript to, not on the enemies.  I know that I could accomplish this with SKSE and a GetNumRefs/GetNthRef script, but for reasons of compatibility, I'm trying to figure out some way to do this without using SKSE functions.  The difficult part is that I can't, say, set properties that point to the enemies, because of the way they'll spawn in.

 

At the moment, I'm using an OnCellDetach event in the EnemyScript to handle it, and while it works, I'd like to find a way to make this more flexible.

Edited by Kotep
Link to comment
Share on other sites

That all sounds more complicated than it needs to be.

 

There are two ways I can think of doing this.

 

1.

First, create a global variable.

Then you put a script on the NPC's you want to die at a certain time or event. This will check the global variable and if its set, kill and delete the NPC.

You will have code in another script, such as an activator, that will set the global variable when you want all the NPC's dead and gone.

 

2.

You can make a large area effect spell, that checks if the target of the spell is in a faction you create for them, and if it is, it kills and deletes them. The spell can be cast from the activator, or what-ever is controlling when they should die.

Event OnEffectStart(Actor akTarget, Actor akCaster)

   if akTarget.IsInFaction(myDeathFaction)

Link to comment
Share on other sites

I wasn't exactly sure how to use OnUpdate. Is that what you'd suggest using if I wanted to take the first option?  For example, I'd put something on the enemy's script along the lines of (ripped from the CK wiki):

Event OnInit()
	RegisterForSingleUpdate(10.0) 
EndEvent

Event OnUpdate()
	Bool bKeepUpdating = True
	If Quest.GetStage() == EndStage 
		Self.Delete()
		bKeepUpdating = False
	EndIf
	If bKeepUpdating
		RegisterForSingleUpdate(10.0)
	EndIf
EndEvent

So that it'll check every 10 seconds and if the quest stage is completed (or the global variable is ticked, or whatever conditions I put in there) then it deletes itself?

Edited by Kotep
Link to comment
Share on other sites

In theory, that should work. But with all coding, you never know until you try it.

 

Instead of self.delete()

You may want to kill it first, since its an NPC. Seems the game likes to clean up dead NPC's better.

And since the script is ON the NPC being killed and deleted, you do not need the 'self.' part of the script. Just this:

Kill()

Delete()

All functions will work on the object its attached to, if no reference is specified.

Link to comment
Share on other sites

I did have to switch the script from an ObjectReference to an Actor script, but since Actor extends ObjectReference, there was no problem with that.

 

The other thing I changed was that I didn't want the update starting OnInit, since that means it's running the whole game.  Because new enemies were getting summoned in, OnCellAttach wouldn't work because enemies would get summoned without triggering their own OnCellAttach.  In the end, since I wanted the cleanup to happen once you're outside of the cell, I had the RegisterForSingleUpdate chain start OnCellDetach.  It reduces the time between starting and ending the update as much as possible.

 

I'll do a stress test to make sure that if you accidentally fill up the place with fifty replicated enemies it doesn't crash when each of them has their own update script running, but other than that, it seems like the script is working perfectly now.  Thanks a lot!

Edited by Kotep
Link to comment
Share on other sites

I use OnLoad for my summoned creatures. So when the instance of the NPC is loaded, it starts the script. (not the whole game)

 

Just remember, OnLoad will not work if the NPC is in the cell already, and you load your game where the NPC is. But that should not be a problem here since, if they save the game, the OnLoad would have already kicked off when the NPC was spawned in the cell.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...