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...

[Sky] Help Making enemies despawn and a very basic quest


IronBlockGames
 Share

Recommended Posts

Well looks like I will be flooding this board with my questions. :P

So, I'd like to know if there is anyway to make a enemy despawn after a while, or on cel reload? I'm making a sort of thieves den player home and I'd like there to be lved well, thieves inside that you can take out and claim the place for yourself. But I don't want the dead bodys to remain. I like them to go bye bye either after a few days or next time the cell is loaded.
I was given this when I asked on reddit

 

Scriptname NPC_Remover extends ObjectReference 
        Event OnCellDetach()

             If self.IsDead()
               disable()
               deletewhenable()
             ElseIf
             EndIf

         EndEvent

But they didn't really say how to use it, when I try I just get an error that extends script don't exist.

Also how would I get the bandits to be talkative? Not custom lines or anything, just the default stuff that you can hear them muttering in game, are they idle markers or just part of their AI package on some of them and just have to use them as a base?

 

Lastly, I want to tie a quest into this place that will help find it, being a thieves den it is well hidden and there's not many land marks around to guide someone to it. I picked a rather remote area in the eastern mountains near riften.
I wanted a very simple pick up note, add quest to find area with marker, go to area... done.

The issue is every tutorial on making quests always start from an NPC, and is always set to 'go kill someone'. I tried to weed parts of it out for my own, but it's been a no go.. I even looked up the books that give you a quest, but looking at it made my head hurt. I just want a simple 'go here' kind of quest. I don't know if I'll add a quest to it after to kill the bandits inside, I may hint to them already being chased off but warn they may return if no one holds down the area... but also if I can't get them to despawn like I like above, there may be no bandits to kill..

Quests are not my forte fyi.. it's the thing next to scripting I've not been able to wrap my head around very well.. outside the many 'kill this person' kind of quests soo many tutorials show off. So a step by step would be nice.. I'm hoping something like this isn't anywhere near as complex as the 'go kill someone' tutorials show.

Link to comment
Share on other sites

Um... Okay, let me see if my semi competence can help, since you helped me

Everything I've seen on "self" is that it is another way to refer to the Player, so not sure why it's written that way. But the essential concept seems sound (also, I'm not sure why the bodies don't disappear on their own as per Skyrim's normal thing, but anyway...) The DIsable seems the way to go. If you used the Random NPC generator thing, then you would have a property like "ObjectReference Property RandomThief1 Auto" and fill it with the random generator thing. (obviously doing this for each generator.)

So then at the final stage of the quest, say Stage 100, you have it run your disable function. Which is basically...

Function CorpseCleanup()

RandomThief01.Disable()
RandomThief02.DIsable()
{etc}

EndFunction
{this will also keep them from respawning}


If they are NPCs you made and placed in the house, you would substitute Actor Property for ObjectReference and the rest would basically be the same.

(I hope that makes some sort of sense. If not, I can try again)

As for the dialogue, that seems to have to do with Factions. As in, I think when the game goes looking for what random dialogue to fill a place with, it looks at the character's faction and puts that in there.

I haven't perfected the whole "Go here for next part of quest thing" but this video has some info on that and it talks about the courier which may or may not help you https://www.youtube.com/watch?v=iustaHoHnEE

Hope that helps in some way
 

Link to comment
Share on other sites

See I don't want the NPC's tied to the quest, as I'm not even sure I can get them to work right. I just want a simple quest of go to location and that be the end of it.

As is the script I have don't seem to do anything, that or I am adding it in wrong. I apply it to the NPC but they remain forever after death. I've waited a whole month in game away from the cell and returning the bodys still linger.

First time messing with these kind of things I thought I was going as simple as I could for a step in learning.. but it's turned into a ongoing battle @.x

At this rate instead of a quest I'd settle for the map marker to just be added when you look at the note x.x

Edited by IronBlockGames
Link to comment
Share on other sites

I have not done anything like that myself, but having messed around a bit with Papyrus, I think it might be something worth a try to extend Actor script instead of ObjectReference script, as it seems Actor already extends ObjectReference. So if Actor properly inherits everything from ObjectReference, it should also inherit all the Disable commands, so using Actor could make it possible to use IsDead, as well, since, if Papyrus works logically, traits move from top down in hierarchy, so using the lowest one with the commands you need (Actor in this case) will also net you all the traits from its ancestors, in this case, ObjectReference which it extends. IsDead is not defined in ObjectReference but only in Actor.

Hopefully that makes sense. It is the way I think it should work, at least. The 'normal' Delete command indeed had some notes about conditions needed to be met before the deletion would take place. But if DeleteWhenAble works without issues, the following might work, too (and always remember to prefix your scripts, and everything else, it is a good habit and will help you avoid conflicts, as all .pex files are put in the same folder for the game to find):

ScriptName NPC_Remover Extends Actor

; Prefix the name with something <= 4 chars, like "IGB_", so it would become
; IBG_NPC_Remover for easier sorthing and telling them apart from other scripts

Event OnDeath(Actor akKiller)
    If(Self.IsDeleted() == False)
        Self.DeleteWhenAble()
    EndIf
EndEvent

IsDeleted just checks if the thing is alread flagged (listed on the object reference script page). Also, there is this note at the bottom of the Actor script page (in case anyone reading this has used leveled lists and run into issues):

You may not attach a script to an actor if that actor would be used by a leveled actor list. If an actor is used in a leveled actor list, its "Scripts" section will be disabled.

Hopefully that helps a little. If not, feel free to blame me. I can then see if I could make more sense out of it. :P

Also, I have never used Self anywhere. So I do not know if it really returns the object reference or the script. Hopefully the object reference. If Self does not return the object reference, or the actor in this case, that will not work at all. But I cannot test it at the moment.

Edited by PhilippePetain
edited a bit
Link to comment
Share on other sites

Yeah that also didn't seem to work at all either. Now I am using a template data bit, will that effect it any? I'm using it as I really don't know how to make an npc an enemy. Or make em adjust to your lv.

 

edit: just tested it with a npc that has no template and still the same.. they don't poof. Why is 90% of tutorials on npc's all about making them followers...  with the rest being merchents or basic npc's.. @.x

Edited by IronBlockGames
Link to comment
Share on other sites

Odd. Some said adding NPCs to aliases or other such things would prevent them getting removed. But I do not think that is the case there, unless some other mod does it. This is frustrating, I have not worked with anything quest-related for Skyrim yet, the system frightens me, too. :P

Did you check the Papyrus log? Does it say anything about it? Also, try using Debug.MessageBox to track what actually happens. I suspect you know how it works, but still.

ScriptName NPC_Remover Extends Actor

Event OnDeath(Actor akKiller)
    If(Self.IsDeleted() == False)
        Debug.MessageBox("A bandit died, marked for delete.")
        Self.DeleteWhenAble()
    Else
        Debug.MessageBox("A bandit died, already marked for delete.")
    EndIf
EndEvent

That should get one of the boxes displayed when a bandit dies. If neither show, the script did work at all. In case it prints either, but nothing happens, it might be that Self returns the script and not the actor, in which case you can make a script, add it to the base record, then double-click every reference to that base record (every placed bandit) and fill the Myself property for the following script (the same, but definitely refers to the bandit NPC reference and nothing else) separately on every instance of that bandit, so they point to the reference you are filling the property for:

ScriptName NPC_Remover Extends Actor

Property Actor Myself Auto    ; This to be filled, points to the actor reference

Event OnDeath(Actor akKiller)
    If(Myself.IsDeleted() == False)
        Debug.MessageBox("A bandit died, marked for delete.")
        Myself.DeleteWhenAble()
    Else
        Debug.MessageBox("A bandit died, already marked for delete.")
    EndIf
EndEvent

And hopefully at least that helps a bit.

Link to comment
Share on other sites

If no messages are printed, are you sure the script actually is on the NPCs? That would be the first thing to check. Just put a simple script like that on them and kill them, then mess around until you get it to show somehow:

ScriptName NPC_Remover Extends Actor

Event OnDeath(Actor akKiller)
    Debug.MessageBox("Someone died! It works!")
EndEvent

So the first thing would be to make sure the scripts are there, on the NPCs, and receive the events. When that is done, more can be added as necessary. I do not know how templates and such work, so I cannot comment on it. Just be sure to check if the actor editing panel has some checkboxes for what an actor inherits from the template, in case there is something script-related there.

And definitely get some sleep. My brain stops working properly at 23 PM, no matter what, so I would personally get nothing done at that hour. Speaking from experience, that is. Never leave university assignments you need to return for the last night, it never ends up well. :whistling:

Edited by PhilippePetain
fixed a typo
Link to comment
Share on other sites

This is driving me crazy. I don't know what I am doing wrong. I even found the default script WIDeadBodyCleanupScript that has the bonus of also moving the npc's inv to a container before it's removed... but even setting it to clean up after one day, and waiting a week, the body still lingers! Why can I not get this to work?!

Okay, know what, FINE. How about a moveto command, to move the bodies to an x marker or something? So I can stuff them somewhere in the void and not worry about them sense they seem so darn insistent on hanging around! >.<

Link to comment
Share on other sites

This is driving me crazy. I don't know what I am doing wrong. I even found the default script WIDeadBodyCleanupScript that has the bonus of also moving the npc's inv to a container before it's removed... but even setting it to clean up after one day, and waiting a week, the body still lingers! Why can I not get this to work?!

Okay, know what, FINE. How about a moveto command, to move the bodies to an x marker or something? So I can stuff them somewhere in the void and not worry about them sense they seem so darn insistent on hanging around! >.<

Okay, so one thing I notice is that your script actually extends the Object reference, not the actor. Actually, first it extends Object reference and THEN Actor. It can't do both.

When you make the new script, in the place where you name it, it says "extends." Replace Object Reference with Actor. I haven't messed with this sort of thing before, but all of Phillipe's sample scripts extend Actor.

Try that first before taking a hammer to things. :)

Link to comment
Share on other sites

Okay, so one thing I notice is that your script actually extends the Object reference, not the actor. Actually, first it extends Object reference and THEN Actor. It can't do both.

When you make the new script, in the place where you name it, it says "extends." Replace Object Reference with Actor. I haven't messed with this sort of thing before, but all of Phillipe's sample scripts extend Actor.

Try that first before taking a hammer to things. :)

I also noticed that after I made the screenshot and fixed it.. It however didn't fix anything.. the npc's wil still linger around forever..  even with the existing WIDeadBodyCleanupScript skyrim has, the npc's are not poofing.

 

Good news is I finally figured out how to do a 'go to location' quest (or rather go to trigger), when you pick up a book... the bad news is I don't have a clue how to set it so if location is already found (a.k.a you already crossed the trigger) to not pick up the quest when the books read. *sigh* one step forward, two steps back.

Link to comment
Share on other sites

I also noticed that after I made the screenshot and fixed it.. It however didn't fix anything.. the npc's wil still linger around forever..  even with the existing WIDeadBodyCleanupScript skyrim has, the npc's are not poofing.

 

Good news is I finally figured out how to do a 'go to location' quest (or rather go to trigger), when you pick up a book... the bad news is I don't have a clue how to set it so if location is already found (a.k.a you already crossed the trigger) to not pick up the quest when the books read. *sigh* one step forward, two steps back.

Okay. Well, here's what I can tell you about the first thing.

I made a test Mod thingy. I went to Alvor (Riverwood Blacksmith) in the CK Actor list, clicked on "add script", created a new script that extended Actor, pasted in the code as per Phillipe's suggestion, the one you used, went into game, killed Alvor and the message came up.
And was promptly arrested. Sheesh....

So, possibly the confusion with the Objectreference/Actor messed up the script and you need a new one. But using that code and the method I described, I know the messagebox does in fact appear. That may help you or it may cause you to drink heavily... :)
 

Now, onto the second part... Okay, so you have a Quest and when you read a book it sets the Quest to, say, stage 20 and lets you know you need to go to a certain place on the map. So the quest is then at Stage 20 after reading the book (in this example).

When you enter the triggerbox, then, the stage should be set to 30.  So you need a script attached to your trigger box.

Event OnTriggerEnter(ObjectReference akTriggerRef)
	if akTriggerRef == Game.GetPlayer()
			MyThiefyThiefQuest.SetStage(30)
		endif
	endif
EndEvent



So if you enter the trigger first, the quest is set to 30 (or even completed, if you're done with it). Then if you later read the book, it won't be able to set the stage to 20 because Skyrim can't set a stage to a number lower than the current stage. So the thing that happens at Stage 20, the pointing thingy, won't happen. It will just be skipped.

Yes? Yes. I think that makes sense.


 

Link to comment
Share on other sites

Every time I tried adding a script I started with a new one, I never reused an older one. (and yes that means I have several copies of the darn thing x.x) What else could be effecting the script, or even the actor that would make it not trigger? Cell type? Hidden settings somewhere I'm overlooking?

Thus far, not a single script I've tried from here, reddit, or the nexus forums have had any effect what so ever, and it is making me wonder if there is some other force stopping them from running. So far I been testing everything in a side mod just for this, with a basic unique npc, and no information, location, nada on the cell.

https://www.dropbox.com/s/c88qpg418prne5b/TIB - QuestTesting.esp?dl=0

My little test thing.. coc aaquesttest

my quest thing is on the table in the room, the npc is in the other, they are two split cells.

So far I've kinda gotten the quest thing to work.. sort of. but the npc wont budge. I've tried linking em to a xmarker for a teleport to get them out of view, as well as a all these atempts to disable. Nothing has triggered.

I'm aiming to have the quest continue into a new quest to kill the npc's but will need a check to finish once there all dead.

Link to comment
Share on other sites

Well, something seems very wrong with something. Because I did in your mod what I did with my test and it worked fine. So here is the first thing we should check. Here is your test mod file, altered by me to remove the old script (yours, which was not included) from the actor and with my script attached--it's the same script I used on Alvor. My script is in the second link. If you drop the esp into the data folder and the pex into the script folder, it should function normally, just like installing a mod.

If the debug message fails to appear, then I really don't know. That would seem to be a problem with your Skyrim or something else way beyond my skill set.

If it does appear, then... Well, I don't know what went wrong with your scripts. But we'll have made progress.

https://www.dropbox.com/s/i05dfqggo9x2pxy/TIBQuestTesting.esp?dl=0
https://www.dropbox.com/s/oq3eg7fmh5r0bco/DeathTest.pex?dl=0

Link to comment
Share on other sites

About the screenshot you displayed, it has the whole script, except for the header sort of thingy (name+extension) in a sort of 'comment'. Papyrus does not need any {...} around the function, it is just used for the automatic comments thingies when using the CK to make scripts. I use Sublime Text 3 with Sublime Papyrus myself, makes it easier to write things, so I did not even think about the automatic thingies.

This is what you have in the screenshot (with corrected extends) which does not work:

ScriptName TIBNPC_Remover Extends Actor
{ScriptName TIBNPC_Remover Extends Actor

Event OnDeath(Actor akKiller)
    Debug.MessageBox("Someone died! It works!")
EndEvent}

Because, in reality, the only thing the game ever sees is this:

ScriptName TIBNPC_Remover Extends Actor

The rest is a sort of a comment, starting with { and ending with }. Mostly used to describe the function of the script when browsing through the CK script list, I think. The game or Papyrus compiler never processes that part. You could have written anything in there:

ScriptName TIBNPC_Remover Extends Actor

{From Wikipedia: Prior to the outbreak of the First World War, the strength
of the British Indian Army was 155,000. Either in 1914 or before, a ninth
division had been formed, the 9th (Secunderabad) Division. By November
1918, the Indian Army rose in size to 573,000 men. Before the war, the
British government had decided that their forces in that part of the empire
could afford to provide two infantry divisions and a cavalry brigade in the
event of a European war. 140,000 soldiers saw active service on the Western
Front in France and Belgium – 90,000 in the front-line Indian Corps, and
some 50,000 in auxiliary battalions.}

And it would compile just wonderfully, but have no effect in-game. Just as an example. The following is everything you should have in the script (open the script, CTRL+A, delete, paste the script below, save and compile), nothing more, nothing less, it is all there needs to be for the messagebox to appear:

ScriptName TIBNPC_Remover Extends Actor

Event OnDeath(Actor akKiller)
    Debug.MessageBox("Someone died! It works!")
EndEvent

And just forget the bracket thingies, whatever they are in English, completely. Maybe that helps a bit, too? If you need to know how scripts work, I can try to explain. Understanding how it works makes it easier to... umm... shoot troubles? :P

Edited by PhilippePetain
corrected a bit
  • Upvote 1
Link to comment
Share on other sites

WI was given this when I asked on reddit

Scriptname NPC_Remover extends ObjectReference 
        Event OnCellDetach()

             If self.IsDead()
               disable()
               deletewhenable()
             ElseIf
             EndIf

         EndEvent

But they didn't really say how to use it, when I try I just get an error that extends script don't exist.

Self refers to the reference the script is attached to. In your case, it should be the bandits. Try adding a script to one of your bandits, use the "create" button not the add one, name your script and when created, add

Event OnCellDetach()
    If self.IsDead()
        disable()
        deletewhenable()
    EndIf
EndEvent

in the body of the script. I don't see why it shouldn't compile but if it doesn't, well, we'll see further. :)

Link to comment
Share on other sites

Alright, I -think- I finally got it to work. I gave the WIDeadBodyCleanupScript another try, apparently it didn't like that I wasn't assigning a container for the items to go into if you leave loot on the bodies. Though the chest I tied the loot to gets a stolen tag added along with all the items, even though its a player owned container? Thought to tie their loot to the random chests about, but the stolen tag killed the idea, so its a chest hidden behind the carts at the entrance.

https://www.dropbox.com/s/exp2zr9bke930fz/TIB - Owl Rock Cave - A Thieves Hideout - DESPAWN TEST.rar?dl=0

Anyone care to give it a test run to be sure it is working? Also a test of my npc making skills. They should be tied to the lv list but they feel very weak.. less thats just how the bandit types are. there's also patrolls added for good messure. I also added a bandit outside to guard though he seems to be unable to sit on his seat marker. 

coc aaowlrock will dump you right inside.

If this all works out the very last step will be to add in the quest. Getting excited!

 

Link to comment
Share on other sites

Okay... I thought I had wrapped my head around how to do the quest I need... but in the end it is getting borked up big time.

I have two ALIASES. 0 pointing to a trigger out front of the cave, the other 10 to the boss of the bandits inside (though like it to point to all of them I dunno how to do that)  In the trigger I have it set to advace the quest to the next stage 10, the boss dude has one to advance to a stage 20 where the quest finishes. There is also a book that starts the quest and sets it to stage 0.

All of these work fine... but the stages I have set do not.

If I did it from start to end the quest runs fine and smooth. It's if you go to the cave before picking up the note that is causing me issues.

Stage 0 Quest Start - Go to Location
Started from Book set stage 0 using: defaultonreadsetqueststagenoalias
In stage:
SetActive()
SetObjectiveDisplayed(0) ;points to trigger


Stage 10 Location Gone to - Set Kill dude
Set stage 10 done by Trigger with: defaultSetStageTrigSCRIPT
In stage:

SetObjectiveCompleted(0); triggers been touched
  SetActive()
SetObjectiveDisplayed(10) ; points to the bandit


Stage 20 Dude Killed - quest end

 

Well.. it kinda works fine.  The deal is that if you go to the location first then  go back and pick up the note, it resets the quest to stage 0.

I tried adding into stage 0

if (GetStageDone(0))
;do nothing, locations been quest stage set to 10 found notes just a note
Else
  SetActive()
SetObjectiveDisplayed(0) ;no stage set, note picked up
EndIf

So that if the stage been advanced by going to the location, the note would do nothing... well instead it just makes the note do nothing at all even if picked up to start the quest.

I don't know how to fix this, everything I read says quests wont go back to past stages.. but they are, guessing set stage overrides that but that is how I see even the default quests do their stages.

I'm wondering if it just be easier to make it so when you hit the trigger before you pick up the note, if the note isn't just disabled from the world.

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...