Help with timer script and GameDaysPassed.Value

Post » Thu Jun 21, 2012 11:52 am

Ok so I'm trying to track how long its been since my nasty bloodsvcker has napped in his coffin. Granted all the details are not in there yet, but I want to get the timer working first, then I'll add in the detrimental effects for not spending time in your coffin, and bonuses for doing so, etc etc.

Right now I'm trying to set my float CurrentGameTime to GameDaysPassed.Value, yet it keeps returning 0.0. Shouldn't it be a game time or something, like how many days I've been playing this character?

Ultimately I want to set the time I went to sleep in that event onSleepStart in my float LastCoffinSleepTime, and then in my OnUpdate event, add how much time has passed since that time. Obviously I don't have that logic in there yet, as I'm still trying to grasp how to do a timer properly in Skyrim.

Scriptname PlayerVampireNeedsQuestScript  extends QuestGlobalVariable Property GameDaysPassed AutoFloat Property LastCoffinSleepTime AutoFloat Property HowLongWithoutCoffinSleep AutoFloat Property CurrentGameTime Auto;prolly need vampire quest extends hereEvent OnInit()RegisterForSingleUpdate(0.1)RegisterForSleep()EndEventEvent OnUpdate()RegisterForSingleUpdate(15);this is definitely secondsCurrentGameTime = GameDaysPassed.Valuedebug.notification("current game time is" +CurrentGameTime)EndEventEvent OnSleepStop(bool abInterrupted)if abInterrupted	 Debug.Trace("Player was woken by something!")  LastCoffinSleepTime =  GameDaysPassed.Valueelse	 Debug.Trace("Player woke up naturally")  LastCoffinSleepTime =  GameDaysPassed.ValueendIfendEvent
User avatar
Tanya
 
Posts: 3358
Joined: Fri Feb 16, 2007 6:01 am

Post » Thu Jun 21, 2012 2:34 pm

Why not use the http://www.creationkit.com/GetCurrentGameTime_-_Utility function? It does exactly the same thing as that Global, and saves you a property declaration.
User avatar
Krystal Wilson
 
Posts: 3450
Joined: Wed Jan 17, 2007 9:40 am

Post » Thu Jun 21, 2012 6:39 pm

Why not use the http://www.creationkit.com/GetCurrentGameTime_-_Utility function? It does exactly the same thing as that Global, and saves you a property declaration.
While aiIteration < 1000	aiIteration += 1	fTimePassed = Utility.GetCurrentGameTime() ; Time Elapsed: 14.569000EndWhile
...takes approximately 1,000 times longer than...
While aiIteration < 1000	aiIteration += 1	fTimePassed = GameDaysPassed.GetValue() ; Time Elapsed: 0.014999 (GameDaysPassed.Value fared just as well)EndWhile


ScriptName PlayerVampireNeedsQuestScript extends QuestFloat Property fLastCoffinSleepTime AutoFloat Property fHowLongWithoutCoffinSleep AutoFloat Property fCurrentGameTime AutoGlobalVariable Property GameDaysPassed AutoEvent OnInit()	RegisterForSingleUpdate(0.1)	RegisterForSleep()EndEventEvent OnUpdate()	RegisterForSingleUpdate(15)	fCurrentGameTime = GameDaysPassed.GetValue()	Debug.Notification("current game time is" + fCurrentGameTime)EndEventEvent OnSleepStop(Bool abInterrupted)	If abInterrupted		Debug.Trace("Player was woken by something!")		fLastCoffinSleepTime = GameDaysPassed.GetValue()	Else		Debug.Trace("Player woke up naturally")		fLastCoffinSleepTime = GameDaysPassed.GetValue()	EndIfEndEvent
User avatar
Sheeva
 
Posts: 3353
Joined: Sat Nov 11, 2006 2:46 am

Post » Thu Jun 21, 2012 7:35 pm

And does that really matter when you are only calling that once per update?

The difference between 0.014999 and 0.000014999 is indiscernible to the human brain.

That sounds more like a nitpick to me.

But, in any case...

This may be a dumb question, but did you set the property to point to the Global in the Creation Kit? I forget to do this all the time. And my tests show that GameDaysPassed does return a proper value, so that's about the only reason I can think of for your attempt not working.
User avatar
~Amy~
 
Posts: 3478
Joined: Sat Aug 12, 2006 5:38 am

Post » Thu Jun 21, 2012 5:00 pm

And does that really matter when you are only calling that once per update?
Yes it does, particularly when tons of other stuff is going on.
The difference between 0.014999 and 0.000014999 is indiscernible to the human brain.

That sounds more like a nitpick to me.
Why would one spend $1,000 when they can get the same thing for $1? Cumulatively, little optimizations like this can make a huge difference, particularly when one has gobs of mods loaded. Leaving that $999 in the pool speeds everything else up at the expense of a mere property declaration.
User avatar
Joe Bonney
 
Posts: 3466
Joined: Tue Jul 17, 2007 12:00 pm

Post » Thu Jun 21, 2012 11:01 pm

Fair enough. By my tests, using GameDaysPassed should work, because it worked in my test (I used to use GetCurrentGameTime() in one of my in-dev scripts, but switched to using GameDaysPassed on reading this thread, and it changed nothing save speeding up the amount of time it takes to get that value). The only reason I could see it not working is because the property isn't pointing to anything in the plugin, so the game is filling it in with NONE at run-time.
User avatar
Robert DeLarosa
 
Posts: 3415
Joined: Tue Sep 04, 2007 3:43 pm

Post » Thu Jun 21, 2012 12:23 pm

On my timer script (which was admittedly for vastly different purposes) I used RegisterForSingleUpdateGameTime, which doesn't need a global at all.

Then again, I'm really new at this and might not be able to give the best advice. JustinOther knows what he's talking about.
User avatar
Nicola
 
Posts: 3365
Joined: Wed Jul 19, 2006 7:57 am

Post » Thu Jun 21, 2012 10:07 pm

On my timer script (which was admittedly for vastly different purposes) I used RegisterForSingleUpdateGameTime, which doesn't need a global at all.

Then again, I'm really new at this and might not be able to give the best advice. JustinOther knows what he's talking about.
Great catch. That function is perfect for all sorts of timer events (assuming that you can cancel and/or reset the timer) that depend on tracking game time rather than real-time. The only problem is that you would still want to check the actual time because none of Skyrim's Update events are guaranteed to trigger at exactly the right time. (Sleeping or fast-travel can fast-forward time past the target you set for example.)

But that just goes to show that being new might actually be helpful with Papyrus. We old-timers have gotten so used to working with the many quirks of the old scripting system that we aren't even thinking about things like this in the new Papyrus way. People found the OnUpdate event and have been using it as a replacement for our old "beloved" fQuestDelayTime for quest scripts. But an entirely new strategy is more appropriate in many cases.
User avatar
Donatus Uwasomba
 
Posts: 3361
Joined: Sun May 27, 2007 7:22 pm

Post » Thu Jun 21, 2012 6:49 pm

Haha, I wish I could take credit! But, it really has to go to DreamKing; he used that function when helping Bolak come up with a timer script in a thread not too long ago.
User avatar
Becky Cox
 
Posts: 3389
Joined: Thu Jun 22, 2006 8:38 am

Post » Thu Jun 21, 2012 7:02 pm

On my timer script (which was admittedly for vastly different purposes) I used RegisterForSingleUpdateGameTime, which doesn't need a global at all.

Then again, I'm really new at this and might not be able to give the best advice. JustinOther knows what he's talking about.

Good for broad-scale calculations, but not really for minute timing. My latest mod actually requires both, and after looking at a couple people's Source scripts, I came up with this:

Float Function GetTimeDelta()	Int TimeDeltaReal = (((gameHour.GetValue() - TimeLast) * 3600) / Timescale.GetValue()) as Int	Float TimeDeltaGame = gameHour.GetValue() - TimeLast	TimeLast = GameHour.GetValue()		If TimeDeltaGame < 0		TimeDeltaGame = TimeDeltaGame + 24	EndIf	;Sanity check.		If TimeDeltaReal <= 0		TimeDeltaReal = 1	EndIf	;Sanity check.		If(TimeDeltaGame >= 1) || (HasTraveled())		CalcRealTime = False		Return TimeDeltaGame	Else		CalcRealTime = True		Return TimeDeltaReal as Float	EndIfEndFunction

Calculates the difference in time passed in-game twice. The first calculation converts to real-time in seconds passed (as an Int because I don't need Float-point precision), and the second calculates game time in hours passed (I do need Float-point precision here to accommodate partial hours passing). Then, depending on the conditions, returns one value or the other and tells the script which.

I was having a lot of trouble with getting timers set up, but once I got the above written, all my problems were solved. The above is good for both minute timing accurate to one second and broad-scale timing. Depending on which you want.
User avatar
Sudah mati ini Keparat
 
Posts: 3605
Joined: Mon Jul 23, 2007 6:14 pm

Post » Thu Jun 21, 2012 10:11 am

This may be a dumb question, but did you set the property to point to the Global in the Creation Kit? I forget to do this all the time. And my tests show that GameDaysPassed does return a proper value, so that's about the only reason I can think of for your attempt not working.
ARGH!!! No I forgot to auto-full my properties. I didn't know globals had to be filled too. At any rate, I'll try it out now... and there seems to be plenty of timer methods to work with here now :)
User avatar
zoe
 
Posts: 3298
Joined: Sun Nov 12, 2006 1:09 pm

Post » Thu Jun 21, 2012 5:37 pm

While aiIteration < 1000	aiIteration += 1	fTimePassed = Utility.GetCurrentGameTime() ; Time Elapsed: 14.569000EndWhile
...takes approximately 1,000 times longer than...
While aiIteration < 1000	aiIteration += 1	fTimePassed = GameDaysPassed.GetValue() ; Time Elapsed: 0.014999 (GameDaysPassed.Value fared just as well)EndWhile


ScriptName PlayerVampireNeedsQuestScript extends QuestFloat Property fLastCoffinSleepTime AutoFloat Property fHowLongWithoutCoffinSleep AutoFloat Property fCurrentGameTime AutoGlobalVariable Property GameDaysPassed AutoEvent OnInit()	RegisterForSingleUpdate(0.1)	RegisterForSleep()EndEventEvent OnUpdate()	RegisterForSingleUpdate(15)	fCurrentGameTime = GameDaysPassed.GetValue()	Debug.Notification("current game time is" + fCurrentGameTime)EndEventEvent OnSleepStop(Bool abInterrupted)	If abInterrupted		Debug.Trace("Player was woken by something!")		fLastCoffinSleepTime = GameDaysPassed.GetValue()	Else		Debug.Trace("Player woke up naturally")		fLastCoffinSleepTime = GameDaysPassed.GetValue()	EndIfEndEvent
Well I tried this, filled my properties and it still reports back 0.0000 as my current game time. Is there something wrong with the logic? Shouldn't it report a number between 0 and 24 based on the current hour? And is the f in front of all my variable names just a nice way to track which variables are floats? Should I name my INTs something like iMyInt instead of MyInt ?
User avatar
Jani Eayon
 
Posts: 3435
Joined: Sun Mar 25, 2007 12:19 pm

Post » Thu Jun 21, 2012 11:19 pm

Yes. You don't need to put the fs or is in your variables.

GameDaysPassed does not report a value between 0 and 24. It is a constantly increasing variable, which goes up by 1 for every game day that passes. If you want a 0-24 readout, use GameHour instead.
User avatar
Emily Jeffs
 
Posts: 3335
Joined: Thu Nov 02, 2006 10:27 pm

Post » Thu Jun 21, 2012 9:42 am

Ok so part of it is working now. The problem is the onSleepStop doesn't seem to be doing anything. Is there a trick to getting that to work? That code is more or less from the wiki, I've never used OnSleepStop before.

Also with my timer code, I'm no math genius but what will happen when the next day comes around and CurrentGameTime becomes 0? Seems to me my formula will mess up.

All I want to do is count the hours that have passed continuously, until the player sleeps. Once the player wakes up, I want to set the time to 0 and start adding again.

Scriptname PlayerVampireNeedsQuestScript  extends QuestFloat Property LastCoffinSleepTime AutoFloat Property HowLongWithoutCoffinSleep AutoFloat Property CurrentGameTime AutoGlobalVariable Property GameHour Auto;prolly need vampire quest extends hereEvent OnInit()RegisterForSingleUpdate(0.1)RegisterForSleep()EndEventEvent OnUpdate()RegisterForSingleUpdate(15);this is definitely secondsCurrentGameTime = GameHour.GetValue();debug.notification("current game time is" +CurrentGameTime)HowLongWithoutCoffinSleep = LastCoffinSleepTime - CurrentGameTime * -1debug.notification("HowLongWIthoutCoffinSleep is " +HowLongWithoutCoffinSleep)EndEventEvent OnSleepStop(bool abInterrupted)if abInterrupted	 ;Debug.Trace("Player was woken by something!")  LastCoffinSleepTime =  GameHour.GetValue()  debug.notification("the player was woken abnormally, and LastCoffinSleepTime is " +LastCoffinSleepTime)else	 ;Debug.Trace("Player woke up naturally")  LastCoffinSleepTime =  GameHour.GetValue();todo add some kind of thing that makes you have to sleep to subtract coffin deprivation  debug.messagebox("the player woke normally, and LastCoffinSleepTime is " +LastCoffinSleepTime)endIfendEvent
User avatar
Poetic Vice
 
Posts: 3440
Joined: Wed Oct 31, 2007 8:19 pm

Post » Thu Jun 21, 2012 10:08 pm

Ok so part of it is working now. The problem is the onSleepStop doesn't seem to be doing anything. Is there a trick to getting that to work? That code is more or less from the wiki, I've never used OnSleepStop before.

Also with my timer code, I'm no math genius but what will happen when the next day comes around and CurrentGameTime becomes 0? Seems to me my formula will mess up.

All I want to do is count the hours that have passed continuously, until the player sleeps. Once the player wakes up, I want to set the time to 0 and start adding again.

Okay, I think I misunderstood what you wanted there. You really do want to use GameDaysPassed for your check, because it does not reset, it just keeps going. If you want to get GameHoursPassed, just multiply the value of the Global by 24. So...

(I also found an Order of Operations error which I commented.)

Scriptname PlayerVampireNeedsQuestScript  extends QuestFloat Property LastCoffinSleepTime AutoFloat Property HowLongWithoutCoffinSleep AutoFloat Property CurrentGameTime AutoGlobalVariable Property GameDaysPassed Auto;prolly need vampire quest extends hereEvent OnInit()RegisterForSingleUpdate(0.1)RegisterForSleep()EndEventEvent OnUpdate()RegisterForSingleUpdate(15);this is definitely secondsCurrentGameTime = (GameDaysPassed.GetValue() * 24) ;Convert Days into Hours.;debug.notification("current game time is" +CurrentGameTime)HowLongWithoutCoffinSleep = (LastCoffinSleepTime - CurrentGameTime) * -1 ;Order of Operations error here, corrected.debug.notification("HowLongWIthoutCoffinSleep is " +HowLongWithoutCoffinSleep)EndEventEvent OnSleepStop(bool abInterrupted)if abInterrupted		 ;Debug.Trace("Player was woken by something!")  LastCoffinSleepTime =  (GameDaysPassed.GetValue() * 24)  debug.notification("the player was woken abnormally, and LastCoffinSleepTime is " +LastCoffinSleepTime)else		 ;Debug.Trace("Player woke up naturally")  LastCoffinSleepTime =  (GameDaysPassed.GetValue() * 24)  debug.messagebox("the player woke normally, and LastCoffinSleepTime is " +LastCoffinSleepTime)endIfendEvent
User avatar
Vickytoria Vasquez
 
Posts: 3456
Joined: Thu Aug 31, 2006 7:06 pm


Return to V - Skyrim