NexBeth Posted August 19, 2019 Share Posted August 19, 2019 I have a script below that works to enable and disable objects (such as fire lights and food plates) based on time of day set in properties. This works well as long as I don't use Wait or Fast. The process of speeding up game time interferes and items that should be shown at a given time, don't show up, or visa versa. I've actually tried a couple of different scripts but the problem occurs in both. I'm not a scripter at all so some help with this, if that is even possible, is appreciated. float Property ItemOffTime = 9.0 auto{The time at which item should be turned off}float Property ItemOnTime = 8.0 auto{The time at which item should be turned on}float Function GetCurrentHourOfDay() global{Returns the current time of day in hours since midnight}float Time = Utility.GetCurrentGameTime()Time -= Math.Floor(Time) ; Remove "previous in-game days passed" bitTime *= 24 ; Convert from fraction of a day to number of hoursReturn TimeEndFunctionFunction RegisterForSingleUpdateGameTimeAt(float GameTime){Registers for a single UpdateGameTime event at the next occurrenceof the specified GameTime (in hours since midnight)}float CurrentTime = GetCurrentHourOfDay()If (GameTime < CurrentTime)GameTime += 24EndIfRegisterForSingleUpdateGameTime(GameTime - CurrentTime)EndFunctionEvent OnInit()If (GetCurrentHourOfDay() > ItemOffTime)GoToState("ItemOff")ElseGoToState("ItemOn")EndIfEndEventState ItemOffEvent OnBeginState()Disable()RegisterForSingleUpdateGameTimeAt(ItemOnTime)EndEventEvent OnUpdateGameTime()GoToState("ItemOn")EndEventEndStateState ItemOnEvent OnBeginState()Enable()RegisterForSingleUpdateGameTimeAt(ItemOffTime)EndEventEvent OnUpdateGameTime()GoToState("ItemOff")EndEventEndState Link to comment Share on other sites More sharing options...
maxarturo Posted August 19, 2019 Share Posted August 19, 2019 (edited) This is an issue that i encountered in the past with a similar script, and the quick solution was to disable " Wait " and " Fast Travel " for the Player, but it was in an interior cell. At the end i remove this function and replaced it with another one ( making the Player to activate everything from inside the power plant and... well i don't want to bore you with this ). I didn't found a solution to this, since i didn't bother myself too much with it. The problem is that when the script executes, its start with an internal clock that differs from that of the Player when he enters " wait ". To resolve this the Script needs to detect when the Player enters " wait " and at the end retrive again the time to execute its functions, or " REFRESH ", or " Updating " every X seconds but this will result on putting too much presure on the system ( having a script that is always - continuously running ), the problem is that " Papyrus " and the " Game Engine " has limitations on what you + it can do. * Although, when i exited and re entered the cell everything was normal ( But this was in my case ). If anyone has found a solution to this, i'm also interested. Edited August 19, 2019 by maxarturo Link to comment Share on other sites More sharing options...
IsharaMeradin Posted August 20, 2019 Share Posted August 20, 2019 Taken from the OnUpdateGameTime wiki page: OnUpdateGameTime may come in much later then you expect if the player is sleeping, waiting, fast traveling, or serving jail time. The event will only be sent once, after the sleep/wait/travel/serve period is over, so you should be prepared to handle hours passing between updates.Thus if you want things to remain exact, then you need to grab the new current time and compare that to your old current time (i.e. when you started the last register for game time update). If the new is far enough that things should change, change them and then figure out the remainder of time so that the next register will happen when you want it to. in pseudo code extra time passed = (new current - old current) - original wait time While extra time passed > original wait time extra time passed -= original wait time EndWhile new wait time = original wait time - extra time passed Register for (new wait time) Change things as needed Link to comment Share on other sites More sharing options...
cdcooley Posted August 20, 2019 Share Posted August 20, 2019 Try this. I haven't tested it but it should work. ScriptName EnableDuringInterval extends ObjectReference { Script to enable an object only for a certain amount of time each day. } float Property DisableHour = 9.0 auto float Property EnableHour = 8.0 auto Event OnInit() OnUpdateGameTime() ; get things started EndEvent Event OnUpdateGameTime() ; get the current hour of the day float hour = Utility.GetCurrentGameTime() hour = (hour - Math.Floor(hour)) * 24.0 ; determine the proper state and when the next update should happen if EnableHour < DisableHour ; enable and disable are during the same day if hour < EnableHour RegisterForSingleUpdateGameTime(EnableHour - hour) elseif hour < DisableHour RegisterForSingleUpdateGameTime(DisableHour - hour) else ; need to register for enable hour tomorrow RegisterForSingleUpdateGameTime(EnableHour - hour + 24.0) endif if hour >= EnableHour && hour < DisableHour Enable() else Disable() endif else ; should be enabled across the midnight boundary if hour < DisableHour RegisterForSingleUpdateGameTime(DisableHour - hour) elseif hour < EnableHour RegisterForSingleUpdateGameTime(EnableHour - hour) else ; need to register for disable hour tommorrow RegisterForSingleUpdateGameTime(DisableHour - hour + 24.0) endif if hour >= EnableHour || hour < DisableHour Enable() else Disable() endif endif EndEvent Link to comment Share on other sites More sharing options...
NexBeth Posted August 20, 2019 Author Share Posted August 20, 2019 Thanks for the detailed replies folks. I'll test cdcooley's script right off and see if that does the trick. It sounds like this is somewhat of a complex problem. Will post back with results. Thank you all very much, and cdcooley for writing out a script for me. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted August 20, 2019 Share Posted August 20, 2019 There exist another approach like critter spawning, papyrus code as follow: xyzEDSampleObjectScript Scriptname xyzEDSampleObjectScript extends ObjectReference ; to enable and disable objects (such as fire lights and food plates) based on time of day ; https://forums.nexusmods.com/index.php?/topic/7917108-firing-enabledisable-script-interupted-by-wait-or-fast-travel/ GlobalVariable PROPERTY GameHour auto ; use autofill here Float PROPERTY fTimeOn = 8.0 auto ; {The time at which item should be turned on} Float PROPERTY fTimeOff = 9.0 auto ; {The time at which item should be turned off} Bool bRun ; [default=False] ; -- EVENTs -- ;========================== auto state Waiting ;================= EVENT OnCellAttach() ; player go inside the cell of this object bRun = TRUE myF_Action() ENDEVENT EVENT OnCellDetach() ; player leave the cell of this object IF ( bRun ) bRun = False UnRegisterForUpdateGameTime() myF_Disable() ENDIF ENDEVENT EVENT OnUpdateGameTime() Utility.Wait(0.25) ; wait a bit to give other scripts runtime myF_Action() ENDEVENT ;======= endState ;========================== state Done ; nothing here ;========= endState ; -- FUNCTIONs -- 2 ;--------------------- FUNCTION myF_Disable() ;--------------------- IF self.IsDisabled() ; self is already disabled ELSE self.Disable(False) ; no fade effect ENDIF ENDFUNCTION ;-------------------- FUNCTION myF_Action() ;-------------------- IF self.GetBaseObject() ELSE gotoState("Done") ; ### STATE ### RETURN ; - STOP - mod has been uninstalled or papyrus stack overflow ENDIF ;--------------------- bool bOK = (GameHour.GetValue() >= fTimeOn) ; 0.00 .. 12.00 .. 23.59 <-- our time range here IF (fTimeOn >= fTimeOff) ; from 19.00 to 5.00 at night bOK = bOK || (GameHour.GetValue() < fTimeOff) ELSE ; from 8.00 to 9.00 on days bOK = bOK && (GameHour.GetValue() < fTimeOff) ENDIF IF ( bOK ) IF self.IsDisabled() self.Enable(TRUE) ; fading in ENDIF ELSE IF self.IsDisabled() ELSE self.Disable(TRUE) ; fading out ENDIF ENDIF RegisterForSingleUpdateGameTime(1.0) ; wait for 1 hour and test again ENDFUNCTION Link to comment Share on other sites More sharing options...
NexBeth Posted August 20, 2019 Author Share Posted August 20, 2019 There exist another approach like critter spawning, papyrus code as follow: Will this work on interior as well as ext. cells? Also, you mention critter spawning which is rather random during the time allowed by the script. My applicaton would be precise--needs to come on and go off precisely at specified time. Thanks, ReDragon. Link to comment Share on other sites More sharing options...
maxarturo Posted August 21, 2019 Share Posted August 21, 2019 There exist another approach like critter spawning, papyrus code as follow: Will this work on interior as well as ext. cells? Also, you mention critter spawning which is rather random during the time allowed by the script. My applicaton would be precise--needs to come on and go off precisely at specified time. Thanks, ReDragon. Seeing ReDragon script, it serves your purpose.But i can't test it to see if it does the trick, i'm on vacations.Test it and see... Link to comment Share on other sites More sharing options...
cdcooley Posted August 22, 2019 Share Posted August 22, 2019 ReDragon's script is designed for making sure things happen only when the player is present. The item gets disabled when the player leaves the cell and the re-enable if the player enters at the right time. When entering the cell during the "on" time there will be a slight delay before the state change (which is meant to lighten the script load when a cell loads, but might be distracting if the player leaves while things are on and then returns almost immediately to find them off and just turning on). More importantly the use of a standard 1 hour re-check interval instead of calculating a new check for the appropriate time means it will both use more resources and not guarantee the switch at the right time if the player remains in the cell for multiple hours. (So basically it's a fine script, but the wrong one for this task.) Link to comment Share on other sites More sharing options...
NexBeth Posted August 22, 2019 Author Share Posted August 22, 2019 (edited) cdcooley, thanks very much for responses here especially for writing out that script for me. I've done some preliminary testing and have had no problems. Things go off and on as scheduled. (It's only been about 2 yrs that I've been looking for script that will do this!) I'll start a new game now and see how everything plays together for an in-game test run of my mod. On a personal note, I have spent some time and effort to learn scripting with not much luck. There are some guides and so-forth, but to me it is like a new language. Most of the guides I've seen seem to run through how to set up a specific script for a specific purpose, but they don't really explain the language nor the meaning of the symbols and how to place them. Without understanding that, for me at least I just can't get how to put together proper commands. Aside from that, I find this aspect of modding rather boring too so there is that too that impedes learning I suppose. Thanks all. Edited August 22, 2019 by NexBeth Link to comment Share on other sites More sharing options...
Recommended Posts