Scripting your quest to start via a timer

Post » Wed Jun 20, 2012 1:27 pm

I'm trying to relearn how to do stuff with papyrus that I could easily do with the GECK's scripting and need a little help. Basically, I want my quest to start enabled, and check to see if the "Unbound" quest has been completed. Then a defined number of game days later (probably 3 or 4) a timer would set the next stage in my quest and enable a courier who would deliver a message to the player. In the GECK I would have just made a quest script that would check in that quest was completed, if it was set a timer to count 3 days, and then set my proper stage, but I hate to admit I'm lost with how to do this now. Any help would be appreciated.
User avatar
Laura Mclean
 
Posts: 3471
Joined: Mon Oct 30, 2006 12:15 pm

Post » Wed Jun 20, 2012 1:28 pm

One simple way to do this would be to just set down a trigger zone outside of the Helgen cave exit to start the timer. To do it through a script, I would register for updates every couple of minutes, and check whether or not the Unbound quest is still running or not.

Quest property MQ101 autoEvent OnInit()    RegisterForSingleUpdate(300)    EndEventEvent OnUpdate()    if (MQ101.IsRunning())        RegisterForSingleUpdate(300)        Return    else        ;start timer    endifEndEvent
User avatar
Juan Cerda
 
Posts: 3426
Joined: Thu Jul 12, 2007 8:49 pm

Post » Wed Jun 20, 2012 2:31 am

One simple way to do this would be to just set down a trigger zone outside of the Helgen cave exit to start the timer. To do it through a script, I would register for updates every couple of minutes, and check whether or not the Unbound quest is still running or not.

The only problem with that is that it would only work for a new game. For players already deep into the game they would have to run back to that cave entrance to trigger the quest which wouldn't be very immersive.
User avatar
Penny Wills
 
Posts: 3474
Joined: Wed Sep 27, 2006 6:16 pm

Post » Wed Jun 20, 2012 2:19 pm

Put this in stage 0 of your quest:

RegisterForUpdate(100000) ; How many seconds are a game day? I dunno...

Then paste this after the "Don't edit anything before this comment" in your fragment code.

Quest Property HelgenEscapeQuest AutoEvent OnUpdate()   if HelgenEscapeQuest.IsCompleted()  ; Code to send your letter here - advance the quest as well, unless your letter already does that.	   UnRegisterForUpdate()   endifEndEvent

Set the property to MQ101 and it should work perfectly.
User avatar
Brandon Bernardi
 
Posts: 3481
Joined: Tue Sep 25, 2007 9:06 am

Post » Wed Jun 20, 2012 3:49 pm

You could in another way use :

GlobalVariable Property GameDaysPassed Auto
Int Property Day Auto

Day = GameDaysPassed.GetValueInt() + 3

then

if ( Day < GameDaysPassed.GetValueInt() )
; your stuff
endif
User avatar
Lizs
 
Posts: 3497
Joined: Mon Jul 17, 2006 11:45 pm

Post » Wed Jun 20, 2012 2:23 pm

Actually, the code I posted was meant for a quest script, in case you didn't want to go with using a trigger for the reasons which you stated.

If you use Redwood Elf's code, I suggest using RegisterForUpdateGameTime() instead. Otherwise you might be completely off depending on whether or not the player changed his/her timescale.
User avatar
Mario Alcantar
 
Posts: 3416
Joined: Sat Aug 18, 2007 8:26 am

Post » Wed Jun 20, 2012 2:13 pm

EDIT: LOL, I think I figured it out. I was using IsRunning, and using coc to get to Helgen from the main menu. Since MQ101 hadn't started yet, in other words it wasn't running, it was starting my timer quest before I needed it to. :blush2:

I switched it around a bit and this seems to be working correctly upon first test. Anybody see a problem with this script?

Scriptname BalokMQ101CheckSCRIPT extends QuestQuest property MQ101 autoQuest Property BalokCourierTimer  AutoQuest Property BalokMQ101Check  AutoEvent OnInit()	 RegisterForSingleUpdateGameTime(1)EndEventEvent OnUpdate()    if (MQ101.IsCompleted())	    BalokCourierTimer.Start()	    Debug.Notification("Courier Timer has started")	    BalokMQ101Check.Stop()		        else	    RegisterForSingleUpdateGameTime(1)	    Debug.Notification("MQ101 is not completed")	    Return        endifEndEvent
User avatar
sara OMAR
 
Posts: 3451
Joined: Wed Jul 05, 2006 11:18 pm

Post » Wed Jun 20, 2012 2:15 pm

Note that http://www.creationkit.com/OnUpdate_-_Form and http://www.creationkit.com/OnUpdateGameTime_-_Form are two separate native events. You need to make sure you're defining the event for which your script is being registered.

Cipscis
User avatar
Amanda savory
 
Posts: 3332
Joined: Mon Nov 27, 2006 10:37 am

Post » Wed Jun 20, 2012 8:40 am

Note that http://www.creationkit.com/OnUpdate_-_Form and http://www.creationkit.com/OnUpdateGameTime_-_Form are two separate native events. You need to make sure you're defining the event for which your script is being registered.

Cipscis

Thanks Cipscis, how is this? Will the 0.1 work to test with its a [censored] to sit here for an hour?

Scriptname BalokMQ101ChechSCRIPT extends QuestQuest property MQ101 autoQuest Property BalokCourierTimer  AutoQuest Property BalokMQ101Check  AutoEvent OnInit()		 RegisterForSingleUpdateGameTime(0.1)EndEventEvent OnUpdateGameTime()	if (MQ101.IsCompleted())			BalokCourierTimer.Start()			Debug.Notification("Courier Timer has started")			BalokMQ101Check.Stop()				  	else			RegisterForSingleUpdateGameTime(0.1)			Debug.Notification("MQ101 is not completed")			Return		endifEndEvent
User avatar
remi lasisi
 
Posts: 3307
Joined: Sun Jul 02, 2006 2:26 pm

Post » Wed Jun 20, 2012 11:30 am

That looks like it should work, yeah. I'd generally stick with regular (i.e. not game time) updates unless you specifically need to wait a certain amount of game time before doing something, like with what you mentioned about setting a stage in your quest after 3 or 4 days.

If you're just checking a value continually, I think regular updates would be more suitable. There isn't really a reason to let the frequency of these checks be dependent on timescale, after all.

Cipscis
User avatar
Etta Hargrave
 
Posts: 3452
Joined: Fri Sep 01, 2006 1:27 am

Post » Wed Jun 20, 2012 2:15 pm

If you're just checking a value continually, I think regular updates would be more suitable. There isn't really a reason to let the frequency of these checks be dependent on timescale, after all.

Cipscis

So would that look like this:

Scriptname BalokMQ101ChechSCRIPT extends QuestQuest property MQ101 autoQuest Property BalokCourierTimer  AutoQuest Property BalokMQ101Check  AutoEvent OnInit()		  RegisterForUpdate()EndEventEvent OnUpdate()		if (MQ101.IsCompleted())			    BalokCourierTimer.Start()			    Debug.Notification("Courier Timer has started")			    BalokMQ101Check.Stop()									else			    RegisterForUpdate()			    Debug.Notification("MQ101 is not completed")			    Return  		endifEndEvent
User avatar
Angela Woods
 
Posts: 3336
Joined: Fri Feb 09, 2007 2:15 pm

Post » Wed Jun 20, 2012 9:51 am

No, the sole parameter of http://www.creationkit.com/RegisterForUpdate_-_Form is not optional so I don't expect that would compile.

Also, I generally recommend using a chain of single updates, i.e. only using http://www.creationkit.com/RegisterForSingleUpdate_-_Form and calling it again at the end of your http://www.creationkit.com/OnUpdate_-_Form event, so long as you want to keep receiving updates.

The advantage of this method is that it prevents multiple OnUpdate events becoming queued, particularly when using short intervals for heavier events, which can cause save bloat and, I believe, cause other scripts to slow down.

Cipscis
User avatar
MR.BIGG
 
Posts: 3373
Joined: Sat Sep 08, 2007 7:51 am

Post » Wed Jun 20, 2012 2:21 pm

No, the sole parameter of http://www.creationkit.com/RegisterForUpdate_-_Form is not optional so I don't expect that would compile.

Also, I generally recommend using a chain of single updates, i.e. only using http://www.creationkit.com/RegisterForSingleUpdate_-_Form and calling it again at the end of your http://www.creationkit.com/OnUpdate_-_Form event, so long as you want to keep receiving updates.

The advantage of this method is that it prevents multiple OnUpdate events becoming queued, particularly when using short intervals for heavier events, which can cause save bloat and, I believe, cause other scripts to slow down.

Cipscis

OK, like this?

Scriptname BalokMQ101ChechSCRIPT extends QuestQuest property MQ101 autoQuest Property BalokCourierTimer  AutoQuest Property BalokMQ101Check  AutoEvent OnInit()	    RegisterForSingleUpdate(60)EndEventEvent OnUpdate()	    if (MQ101.IsCompleted())		    BalokCourierTimer.Start()		    Debug.Notification("Courier Timer has started")		    BalokMQ101Check.Stop()													  	    else		    RegisterForSingleUpdate(60)		    Debug.Notification("MQ101 is not completed")		    Return  	    endifEndEvent
User avatar
Darian Ennels
 
Posts: 3406
Joined: Mon Aug 20, 2007 2:00 pm

Post » Wed Jun 20, 2012 11:50 am

That looks good to me :)

Cipscis
User avatar
Tracey Duncan
 
Posts: 3299
Joined: Wed Apr 18, 2007 9:32 am

Post » Wed Jun 20, 2012 1:59 pm

So, just for the sake of education, what are the differences between using RegisterForSingleUpdate(60) and RegisterForSingleUpdateGameTime(0.1) ? What are the advantages or disadvantages of one over the other, and potential problems of one over the other? (It seems to me they work pretty much the same? I was using the GameTime one because RandomNoob mentioned it above.)
User avatar
Benji
 
Posts: 3447
Joined: Tue May 15, 2007 11:58 pm

Post » Wed Jun 20, 2012 1:37 pm

The first difference is that http://www.creationkit.com/RegisterForSingleUpdateGameTime_-_Form will trigger a call to http://www.creationkit.com/OnUpdateGameTime_-_Form event, whereas http://www.creationkit.com/RegisterForSingleUpdate_-_Form will trigger a call to http://www.creationkit.com/OnUpdate_-_Form.

Aside from that, the only difference is a matter of units. http://www.creationkit.com/RegisterForSingleUpdate_-_Form uses real time - if I put in 60, an update will be triggered in 60 seconds. http://www.creationkit.com/RegisterForSingleUpdateGameTime_-_Form uses game time - if I put in 60, a game time update will be triggered in 60 in-game hours.

So basically http://www.creationkit.com/RegisterForSingleUpdateGameTime_-_Form is useful when you need something to happen after a certain amount of game time specifically. It's also sensitive to timescale, so if I have a non-default timescale then game time updates might happen more or less frequently after the same call to http://www.creationkit.com/RegisterForSingleUpdateGameTime_-_Form.

This extra functionality adds an extra dimension to your scripts, though, and one that's not necessarily wanted. Unless you have something that should specifically rely on game time (for example, setting a quest stage after 3 or 4 days as you mentioned in this thread's opening post) it's better to use http://www.creationkit.com/RegisterForSingleUpdate_-_Form so you have more control over when the update happens, and to help prevent and potential bugs from things like resting and non-standard timescales.

I hope that clears things up a bit for you.

Cipscis
User avatar
Scott
 
Posts: 3385
Joined: Fri Nov 30, 2007 2:59 am

Post » Wed Jun 20, 2012 3:21 pm

Unless you have something that should specifically rely on game time (for example, setting a quest stage after 3 or 4 days as you mentioned in this thread's opening post) it's better to use http://www.creationkit.com/RegisterForSingleUpdate_-_Form so you have more control over when the update happens, and to help prevent and potential bugs from things like resting and non-standard timescales.

Cipscis

Thanks again Cipscis. Since this timer only checks to see of MQ101 is completed and starts another quest I think RegisterforSingleUpdate is good, but I probably need to use the GameTime one on my actual courier since he's based on 4 or so days passing. That clears it up beautifully!

:foodndrink:
User avatar
Kirsty Wood
 
Posts: 3461
Joined: Tue Aug 15, 2006 10:41 am


Return to V - Skyrim