Deactivate NPC during the day

Post » Tue Jun 19, 2012 9:18 am

Hi all,
I'm trying to make a ghost who only appears during a few hours at night, patrols between some markers, and disappears in the morning.
Is there an "easy" way to activate/deactivate NPC on a schedule ?
Thanks!
User avatar
brian adkins
 
Posts: 3452
Joined: Mon Oct 01, 2007 8:51 am

Post » Tue Jun 19, 2012 2:28 am

I'm not sure if you can do this in an AI Package (which has a schedule). Anyway scripts are useful, as always. There seems to be a cool function http://www.creationkit.com/WaitGameTime_-_Utility. So I would create a quest script that would go like this:

Spoiler
Scriptname GhostScript extends QuestProperty Actor Ghost  Autoint i = 0auto State Initialization    Event OnInit()        Registerforupdate(300)    EndEvent    Event OnUpdate()        ; Here we've got to figure out the current hour that will be checked every 5 minutes.        ; Unfortunately I'm not sure how to do this.        ; Although there is a GameTimeToString function that sort of fits our task.        ; If the time is right, i.e. it is night and the ghost should be enabled...        ; the script goes like this (it should be inside if/endif).        UnregisterForUpdate()        GoToState("Schedule")    EndEventEndStateState Schedule    Event OnInit()        while i >= 0            Ghost.enable()            WaitGameTime(5)            ; The script now pauses for 5 in-game hours.            Ghost.disable()            WaitGameTime(19)            i = i + 1            ; After pausing for 19 hours the script will go from the beggining,            ; enabling the ghost, then waiting, disabling him and so on.        endwhile    EndEventEndState
User avatar
Nichola Haynes
 
Posts: 3457
Joined: Tue Aug 01, 2006 4:54 pm

Post » Tue Jun 19, 2012 2:16 pm

Wow thanks. As i'm nowhere near beginning to understand this kind of scripting, i'll need time to carefully break down your example, but i'm sure it'll help me to find a general lead.
Thanks a lot anyway.
User avatar
Music Show
 
Posts: 3512
Joined: Sun Sep 09, 2007 10:53 am

Post » Tue Jun 19, 2012 6:11 am

The CritterSpawn script implements a similar kind of timer. Here are the code sections that help CritterSpawn decide whether it's the right time to be actively spawning critters. The Critter script (or individual critter scripts like critterMoth seem to handle despawning critters when needed), but I haven't looked at those as much.... Hope this helps!

GlobalVariable property GameHour auto{ Make this point to the GameHour global }float property fStartSpawnTime = 6.0 auto{ The Time after which this spawner can be active}float property fEndSpawnTime = 11.0 auto{ The Time before which this spawner can be active}


bool Function IsActiveTime()	  bool binTimeRange = false	  if (fEndSpawnTime >= fStartSpawnTime)  			  binTimeRange = (GameHour.GetValue() >= fStartSpawnTime) && (GameHour.GetValue() < fEndSpawnTime)	  else			  binTimeRange = (GameHour.GetValue() >= fStartSpawnTime) || (GameHour.GetValue() < fEndSpawnTime)	  endIf	  ; this script also takes into account weather conditions - Ashs	  return binTimeRange && ((Weather.GetCurrentWeather() == none) || (Weather.GetCurrentWeather().GetClassification() < 2) || (bSpawnInPrecipitation == TRUE))endFunction
User avatar
Bones47
 
Posts: 3399
Joined: Fri Nov 09, 2007 11:15 pm

Post » Tue Jun 19, 2012 6:45 am

Ashs, this is great! I didn't know about this GameHour global. So I'm pasting an updated version of my script (note that I made a mistake previously, writing: "Property Actor" when it should be "Actor Property"). I can't know for sure whether it will work or not, so you've got to try yourself.

Scriptname GhostScript extends QuestActor Property Ghost  Autoint i = 0GlobalVariable Property GameHour Autoauto State Initialization    Event OnInit()        Registerforupdate(300)    EndEvent    Event OnUpdate()        if GameHour.GetValue() >= 24.0 ; It's possible that it should be value 0.0. You could also just say 23 and be safe.            UnregisterForUpdate()            GoToState("Schedule")        endif    EndEventEndStateState Schedule    Event OnInit()        while i >= 0            Ghost.enable()            WaitGameTime(5)            ; The script now pauses for 5 in-game hours.            Ghost.disable()            WaitGameTime(19)            i = i + 1            ; After pausing for 19 hours the script will go from the beggining,            ; enabling the ghost, then waiting, disabling him and so on.        endwhile    EndEventEndState
User avatar
alicia hillier
 
Posts: 3387
Joined: Tue Feb 06, 2007 2:57 am

Post » Tue Jun 19, 2012 1:35 am

Thanks to you two!
Now, keep in mind i've actually zero experience in the scripting field, so don't be surprised if i try/say silly things :) I added Universal's script to my quest scripts tab, and the compilation returns the following errors :
(8,4): function oninit cannot be defined in state initialization without also being defined in the empty state(24,12): WaitGameTime is not a function or does not exist(27,12): WaitGameTime is not a function or does not exist(21,4): function oninit cannot be defined in state schedule without also being defined in the empty state

Did i miss something ? Or maybe there is actually some mistake in the script ? Thanks anyway !
User avatar
Claudia Cook
 
Posts: 3450
Joined: Mon Oct 30, 2006 10:22 am

Post » Tue Jun 19, 2012 8:26 am

Those were my mistakes. Try this:

Spoiler
Scriptname GhostScript extends QuestActor Property Ghost  Autoint i = 0GlobalVariable Property GameHour Auto    Event OnInit()        Registerforupdate(300)    EndEvent    Event OnUpdate()        if GameHour.GetValue() >= 24.0 ; It's possible that it should be value 0.0. You could also just say 23 and be safe.            UnregisterForUpdate()            GoToState("Schedule")        endif    EndEventState Schedule    Event OnBeginState()        while i >= 0            Ghost.enable()            Utility.WaitGameTime(5)            ; The script now pauses for 5 in-game hours.            Ghost.disable()            Utility.WaitGameTime(19)            i = i + 1            ; After pausing for 19 hours the script will go from the beggining,            ; enabling the ghost, then waiting, disabling him and so on.        endwhile    EndEventEndState
User avatar
Jeffrey Lawson
 
Posts: 3485
Joined: Tue Oct 16, 2007 5:36 pm

Post » Tue Jun 19, 2012 9:46 am

Might be easier with two states:

State GhostOn    Event OnBeginState()        Ghost.enable()        Utility.WaitGameTime(5)        GoToState("GhostOff");    EndEventEndStateState GhostOff    Event OnBeginState()        Ghost.disable()        Utility.WaitGameTime(19)        GoToState("GhostOn");    EndEventEndState
User avatar
Amy Smith
 
Posts: 3339
Joined: Mon Feb 05, 2007 10:04 pm

Post » Mon Jun 18, 2012 10:40 pm

Well, maybe the first part of my script should be in a state after all and then "OnInit()" should be replaced with "OnBeginState()"... But DocClox, what you're forgetting is that you can't just enable the ghost at any hour. You must first check if the starting hour is right, THEN create a "schedule" script.
User avatar
Jamie Moysey
 
Posts: 3452
Joined: Sun May 13, 2007 6:31 am

Post » Mon Jun 18, 2012 11:02 pm

Well, maybe the first part of my script should be in a state after all and then "OnInit()" should be replaced with "OnBeginState()"...

I thought onBeginState didn't trigger in the empty state? Which isn't to say Papyrus might not want it defined, I suppose.

But DocClox, what you're forgetting is that you can't just enable the ghost at any hour. You must first check if the starting hour is right, THEN create a "schedule" script.

Sure. All you do is enter GhostOn state at midnight instead of Schedule :) Then it should work the same way.
User avatar
Sarah Knight
 
Posts: 3416
Joined: Mon Jun 19, 2006 5:02 am

Post » Tue Jun 19, 2012 5:13 am

I thought onBeginState didn't trigger in the empty state? Which isn't to say Papyrus might not want it defined, I suppose.
Heh, now I'm not sure whether you read what I wrote wrong or vice versa.

I said that the first part of my script should be in a state, call it Initialization like in my first attempt to script this. So "RegisterForUpdate(300)" would be inside "Event OnBeginState()" and it would be inside "auto State Initialization". I believe it would work then.

Sure. All you do is enter GhostOn state at midnight instead of Schedule :smile: Then it should work the same way.
Can you do that? Hm, I guess you can... But you know, then Lemsama could just create an AI Package with schedule set to begin in the evening and end, say, 5 hours later, and with scripts in the Begin and End Papyrus fragments that would be just "Ghost.Enable" and "Ghost.Disable".

So I guess some things are just possible to accomplish in a multitude of ways.
User avatar
Add Me
 
Posts: 3486
Joined: Thu Jul 05, 2007 8:21 am

Post » Tue Jun 19, 2012 9:52 am

For another example you could look at the headless horseman actor and see what is done to make him only show up at night.
User avatar
Britta Gronkowski
 
Posts: 3475
Joined: Mon Apr 09, 2007 3:14 pm

Post » Tue Jun 19, 2012 11:26 am

Well, I tried Universal's corrected script, I tried the script using DocClox states instead of the original schedule, I even tried to put the script in the AI Package fragments as Universal suggested. It seems i'm not able to make anything work :P
There's probably something wrong on my side. Oh well, i guess i still lack more basic knowledge to make use of your generous help :) Anyway, thanks to you all, i still learned useful things, and i will keep trying.

@Riakon : Yup, it's the first thing i checked before starting this, but i'm afraid i couldn't find any leads when i looked at this actor, his quest, scripts, etc. Thanks for the idea!
User avatar
Amanda Leis
 
Posts: 3518
Joined: Sun Dec 24, 2006 1:57 am

Post » Tue Jun 19, 2012 9:50 am

I'm a little surprised that none of the methods suggested worked... If it returns any errors on compilation, copy/paste them. Anyway, good luck and sorry that my advices didn't help. Learn and try to make it work and if you have any specific problem, just write.
User avatar
Alyna
 
Posts: 3412
Joined: Wed Aug 30, 2006 4:54 am

Post » Tue Jun 19, 2012 1:13 am

Can you do that? Hm, I guess you can... But you know, then Lemsama could just create an AI Package with schedule set to begin in the evening and end, say, 5 hours later, and with scripts in the Begin and End Papyrus fragments that would be just "Ghost.Enable" and "Ghost.Disable".

So I guess some things are just possible to accomplish in a multitude of ways.

Sure. I didn't mean to suggest there was anything wrong with your approach. I just suggested using two states because it cleaned the logic up a little.

Of course, none of this matters if the thing doesn't work at all. I should have access to my CK instance tonight. I might see what I can do with that.
User avatar
Enny Labinjo
 
Posts: 3480
Joined: Tue Aug 01, 2006 3:04 pm

Post » Tue Jun 19, 2012 6:35 am

Hey, Doc, no problem! I'm not so easily offended.
User avatar
Shannon Lockwood
 
Posts: 3373
Joined: Wed Aug 08, 2007 12:38 pm

Post » Tue Jun 19, 2012 4:31 am

I'm a little surprised that none of the methods suggested worked... If it returns any errors on compilation, copy/paste them. Anyway, good luck and sorry that my advices didn't help. Learn and try to make it work and if you have any specific problem, just write.

Actually, there are no compilation errors. That's why i guess the issue is certainly on my side. I think the script is fine, but i may not trigger it properly. I don't really know if I should put it in the quest scripts, in the alias scripts, in the actor scripts, ... I tried it all actually, but even then, i'm not sure if i need to do something more to trigger it correctly, and if the actor should be checked as "initially disabled".
My brain is melting ! (I'm sure tomorrow i'll realize i was just missing a stupid single obvious thing)
User avatar
Prohibited
 
Posts: 3293
Joined: Tue Jun 12, 2007 6:13 am

Post » Tue Jun 19, 2012 12:33 pm

It should be in quest scripts, the quest should be running and you may want to wait a little in-game time, like 24 hours, to get the script started and then just wait till evening.
User avatar
James Smart
 
Posts: 3362
Joined: Sun Nov 04, 2007 7:49 pm

Post » Tue Jun 19, 2012 6:20 am

One of the points in the notes section of that page is
  • The total wait time may longer in certain cases where the game clock jumps ahead by a large amount (i.e. fast travel).
How reliable is this function? How much longer would the wait be if the player fast traveled?
User avatar
Emily Graham
 
Posts: 3447
Joined: Sat Jul 22, 2006 11:34 am


Return to V - Skyrim