Fast Forwarding time?

Post » Wed Jun 20, 2012 5:35 pm

I'm looking to fast forward time in my mod. I've asked a question about this before, and the response I got was to use TimeScale to achieve my goal. I could probably do this, but I don't know how the game would act if I adjusted timescale in a way that multiple days passed by over the course of a second or two (which I'd want to do...). My solution was to merely set the GameDaysPassed global variable directly.

I've made a script that displays a series of menus to the player. After he chooses how much time he wants to pass, the GameDaysPassed variable is modified by the appropriate amount.

Scriptname LichSoulHibernationActivatorScript extends ObjectReference  Actor Property Player Auto            ; It is preferred to have a direct reference to the player at all times for optimization purposes.GlobalVariable Property GameDaysPassed AutoMessage Property Lich02HibernationOptionsMainMenu AutoMessage Property Lich02HibernationOptionsDays AutoMessage Property Lich02HibernationOptionsWeeks AutoMessage Property Lich02HibernationOptionsMonths AutoMessage Property Lich02HibernationOptionsYears AutoState Activated    ; NO CODE DESIRED.EndStateAuto State NotActivated        Event OnActivate(ObjectReference akActionRef)                ; Prevent further activations, just in case        GoToState("Activated")        ; Set value of gamedayspassed to a local variable for optimization purposes        float gdpLocalVar = GameDaysPassed.GetValue()        ; Loop the main menu until told to quit        Bool ExitMenu = False        While ExitMenu != True            ; We only want to loop if told to by the player, so flip the flag automatically after each loop            ExitMenu = True            ; Display the Main Menu            int MainMenuButton = Lich02HibernationOptionsMainMenu.Show()            if MainMenuButton == 0                ; Player has selected days                ; Get the number of days to advance from the Player                int SubMenuButton = Lich02HibernationOptionsDays.Show()                ; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to their current date based on the button pressed                if SubMenuButton != 7 || SubMenuButton != 8                    ; Add gamedays to the current date                    Debug.MessageBox("GDP: " + GameDaysPassed.GetValue() + ". gdpLocalVar: " + gdpLocalVar + ". New GDP:" + (gdpLocalVar + (SubMenuButton+1)))                    GameDaysPassed.SetValue(gdpLocalVar + (SubMenuButton + 1))                ElseIf SubMenuButton == 7                    ; Loop and show the menu once more                    ExitMenu = False                EndIf            ElseIf MainMenuButton == 1                ; Player has selected weeks                ; Get the number of weeks to advance from the Player                int SubMenuButton = Lich02HibernationOptionsWeeks.Show()                ; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to their current date based on the button pressed                if SubMenuButton != 5 || SubMenuButton != 6                    ; Add gamedays to the current date                    GameDaysPassed.SetValue(gdpLocalVar + ((SubMenuButton + 1) * 7))                ElseIf SubMenuButton == 5                    ; Loop and show the menu once more                    ExitMenu = False                EndIf            ElseIf MainMenuButton == 2                ; Player has selected months                ; Get the number of months to advance from the Player                int SubMenuButton = Lich02HibernationOptionsMonths.Show()                ; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to their current date based on the button pressed                if SubMenuButton != 5 || SubMenuButton != 6                    ; Add gamedays to the current date                    GameDaysPassed.SetValue(gdpLocalVar + (((SubMenuButton + 1) * 7) * 4.2))                ElseIf SubMenuButton == 5                        ; Loop and show the menu once more                    ExitMenu = False                EndIf            ElseIf MainMenuButton == 3                ; Player has selected years                ; Get the number of years to advance from the Player                int SubMenuButton = Lich02HibernationOptionsYears.Show()                ; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to their current date based on the button pressed                if SubMenuButton != 5 || SubMenuButton != 6                    ; Add gamedays to the current date                    GameDaysPassed.SetValue(gdpLocalVar + (((SubMenuButton + 1) * 7) * 52))                ElseIf SubMenuButton == 5                    ; Loop and show the menu once more                    ExitMenu = False                EndIf            EndIf        EndWhile        ; Return state to normal        GoToState("NotActivated")    EndEventEndState

However, it does not work. The menus all work fine, but GameDaysPassed is never modified/

If you noticed, in the middle of one of the menus, I use this code:
Debug.MessageBox("GDP: " + GameDaysPassed.GetValue() + ". gdpLocalVar: " + gdpLocalVar + ". New GDP:" + (gdpLocalVar + (SubMenuButton+1)))

That line, when shown in game, prints the correct value. The calculation is correct, however, it is not actually applied to the global variable. GameDaysPassed always remains the same. I checked in the editor to make sure it wasn't constant, which it isn't, so I'm not entirely sure what is wrong.

Anyone have any ideas or possible alternatives?
User avatar
Rachel Hall
 
Posts: 3396
Joined: Thu Jun 22, 2006 3:41 pm

Post » Thu Jun 21, 2012 1:37 am

It's probably nothing to do with your code and everything to do with the variable itself. The GameDaysPassed global is always updating itself since time is always passing, after all.

What happens if you use a custom global variable? Does it work correctly then? If it does, then that means you'll have to think of some other way to fast forward time (like using the Timescale variable as you said earlier).
User avatar
Kate Schofield
 
Posts: 3556
Joined: Mon Sep 18, 2006 11:58 am

Post » Wed Jun 20, 2012 6:46 pm

It's probably nothing to do with your code and everything to do with the variable itself. The GameDaysPassed global is always updating itself since time is always passing, after all.

What happens if you use a custom global variable? Does it work correctly then? If it does, then that means you'll have to think of some other way to fast forward time (like using the Timescale variable as you said earlier).
Yeah, I figured that was probably it, but I posted the whole code just in case. I created a new variable as you suggested and it worked properly. I don't really know of an alternative though, and I don't want to use timescale for the reasons I posted above.
User avatar
Oscar Vazquez
 
Posts: 3418
Joined: Sun Sep 30, 2007 12:08 pm

Post » Wed Jun 20, 2012 12:22 pm

What about using the GameHour global? I just tested it with the console and it seemed to work properly. I changed GameHour to 23.99, waited until the day changed, changed GameHour to 23.99 again, waited for the day to change again, and when I checked GameDaysPassed, two days had passed.
User avatar
steve brewin
 
Posts: 3411
Joined: Thu Jun 21, 2007 7:17 am

Post » Wed Jun 20, 2012 1:08 pm

What about using the GameHour global? I just tested it with the console and it seemed to work properly. I changed GameHour to 23.99, waited until the day changed, changed GameHour to 23.99 again, waited for the day to change again, and when I checked GameDaysPassed, two days had passed.
Hm. Well, It's not as though that wouldn't work, but the real issue lies here:

ElseIf MainMenuButton == 3	; Player has selected years	; Get the number of years to advance from the Player	int SubMenuButton = Lich02HibernationOptionsYears.Show()	; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to the current date based on the button pressed	if SubMenuButton != 5 || SubMenuButton != 6		; Add gamedays to the current date		; Here I would have to add a loop that runs hundreds of times (365 per year) using the system you mention	ElseIf SubMenuButton == 5		; Loop and show the menu once more		ExitMenu = False	EndIfEndIf

Using that system for a couple days is no big deal, a couple of weeks is OK, a month is a little iffy, but a year, let alone multiple years, is completely out of the question--and people will use the years function. Users within my thread have stated their desire to be able to do this, so I'd like to have the functionality working just as well for it as everything else.

Looping hundreds of times per game day is just simply not practical, unfortunately. This is of course, the same reason I'm not using timescale.

EDIT: Oh, there are variables for days/months/years as well. I'll see if I can work something up with using those.
User avatar
luke trodden
 
Posts: 3445
Joined: Sun Jun 24, 2007 12:48 am

Post » Wed Jun 20, 2012 10:57 am

Hmm, I'm not too sure about this. When using the above method (changing GameDay, GameMonth, or GameYear), I am able to properly "change the day", however, this doesn't affect the actual days that have passed.

The calendar updates, but the actual "GameDaysPassed" (which many scripts, and likely the actual game, use for time tracking) does not update.
User avatar
Eddie Howe
 
Posts: 3448
Joined: Sat Jun 30, 2007 6:06 am

Post » Wed Jun 20, 2012 6:06 pm

I ended up biting the bullet on this one. If the player uses any mods that have poorly written functions involving OnUpdateGameTime then man oh man is the player going to get a fistfull of bugs/crashes when this bad boy runs. (I was using quite a few mods while I tested it and it seemed OK, but well, I don't trust it to be honest.

Scriptname LichSoulHibernationActivatorScript extends ObjectReference  Actor Property Player Auto			; It is preferred to have a direct reference to the player at all times for optimization purposes.GlobalVariable Property TimeScale AutoMessage Property Lich02HibernationOptionsMainMenu AutoMessage Property Lich02HibernationOptionsDays AutoMessage Property Lich02HibernationOptionsWeeks AutoMessage Property Lich02HibernationOptionsMonths AutoMessage Property Lich02HibernationOptionsYears AutoPlayerLich02QuestScript Property PlayerLich02Quest AutoState Activated	; NO CODE DESIRED.EndStateAuto State NotActivated		Event OnActivate(ObjectReference akActionRef)		; Prevent further activations, just in case		GoToState("Activated")		; Loop the main menu until told to quit		Bool ExitMenu = False		While ExitMenu != True		; WTB Do While Loop			; Menu returns true if told to exit			ExitMenu = ShowMainMenu()		EndWhile				; Return state to normal		GoToState("NotActivated")	EndEventEndState; Display the Main Menubool Function ShowMainMenu()	; Show the main menu	int MainMenuButton = Lich02HibernationOptionsMainMenu.Show()	; Continue based on menu choice	bool ExitMenu = True	if MainMenuButton == 0		ExitMenu = ShowDaysMenu()	ElseIf MainMenuButton == 1		ExitMenu = ShowWeeksMenu()	ElseIf MainMenuButton == 2		ExitMenu = ShowMonthsMenu()	ElseIf MainMenuButton == 3		ExitMenu = ShowYearsMenu()	EndIf	Return ExitMenuEndFunction; Player has selected daysbool Function ShowDaysMenu()	; Get the number of days to advance from the Player		 	int SubMenuButton = Lich02HibernationOptionsDays.Show()			; SortMenuButton becomes the number of days chosen - 1.	; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to the current date based on the button pressed	if SubMenuButton != 7 && SubMenuButton != 8		; Add gamedays to the current date		FastForward(NumDays=SubMenuButton + 1)	ElseIf SubMenuButton == 7		; Return False if user wants to show main menu again		Return False	EndIf	; Always exit menu afterwards unless told to return to the main menu	; Return true to do this	Return TrueEndFunction; Player has selected weeksbool Function ShowWeeksMenu()	; Get the number of weeks to advance from the Player	int SubMenuButton = Lich02HibernationOptionsWeeks.Show()			; SortMenuButton becomes the number of weeks chosen - 1.	; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to the current date based on the button pressed	if SubMenuButton != 5 && SubMenuButton != 6		; Add gamedays to the current date		FastForward(NumDays=((SubMenuButton+1) * 7) )	ElseIf SubMenuButton == 5		; Return False if user wants to show main menu again		Return False	EndIf	; Always exit menu afterwards unless told to return to the main menu	; Return true to do this	Return TrueEndFunction; Player has selected monthsbool Function ShowMonthsMenu()	; Get the number of months to advance from the Player	int SubMenuButton = Lich02HibernationOptionsMonths.Show()			; SortMenuButton becomes the number of months chosen - 1.	; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to the current date based on the button pressed	if SubMenuButton != 5 && SubMenuButton != 6		; Add gamedays to the current date		FastForward(NumDays=((SubMenuButton+1) * 30.4166) )	ElseIf SubMenuButton == 5		; Return False if user wants to show main menu again		Return False	EndIf	; Always exit menu afterwards unless told to return to the main menu	; Return true to do this	Return TrueEndFunction; Player has selected yearsbool Function ShowYearsMenu()	; Get the number of years to advance from the Player	int SubMenuButton = Lich02HibernationOptionsYears.Show()			; SortMenuButton becomes the number of years chosen - 1.	; As long as the Player has not chosen to cancel or return to the main menu, we add gamedays to the current date based on the button pressed	if SubMenuButton != 5 && SubMenuButton != 6		; Add gamedays to the current date		FastForward(NumDays=((SubMenuButton+1) * 365) )	ElseIf SubMenuButton == 5		; Return False if user wants to show main menu again		Return False	EndIf	; Always exit menu afterwards unless told to return to the main menu	; Return true to do this	Return TrueEndFunction; Fast forward by the specified number of daysFunction FastForward(float NumDays)	;Debug.MessageBox("GD: " + GameDay.GetValue() + ". GM: " + GameMonth.GetValue() + ". GY: " + GameYear.GetValue() + ". GDP: " + GameDaysPassed.GetValue() + ".")	;Debug.MessageBox("Current Game Time: " + Utility.GetCurrentGameTime())	; Store the current TimeScale Value so we can change it back to normal afterwards.	float origTimeScaleVal = TimeScale.GetValue()	; Fade the screen to black and disable player controls	Game.DisablePlayerControls()	PlayerLich02Quest.FadeToBlack()	; Make the specified number of days pass by over 5 seconds. (Due to script threading this may overshoot a bit...)	TimeScale.SetValue( 17280 * NumDays )	; Wait for the time to pass, and then reset timescale back to its original value	Utility.Wait(5)	TimeScale.SetValue(origTimeScaleVal)	; Return vision to normal and restore player controls	Game.EnablePlayerControls()	PlayerLich02Quest.FadeToNormal()	;Debug.MessageBox("Current Game Time: " + Utility.GetCurrentGameTime())	;Debug.MessageBox("GD: " + GameDay.GetValue() + ". GM: " + GameMonth.GetValue() + ". GY: " + GameYear.GetValue() + ". GDP: " + GameDaysPassed.GetValue() + ".")	;Debug.MessageBox("GDP: " + GameDaysPassed.GetValue() + ". Current Game Time: " + Utility.GetCurrentGameTime() + ". As String: " + Utility.GameTimeToString(Utility.GetCurrentGameTime()) + ".")EndFunction
User avatar
Matt Gammond
 
Posts: 3410
Joined: Mon Jul 02, 2007 2:38 pm


Return to V - Skyrim