Jump to content

Timed Light Switch


pepperman35

Recommended Posts

Background: I desire to have a set of static street lamps turn on and off depending on the hour of the day. I am using DLC04_StreetLampTilingRemap01 for the ones that are off during the day; and DLC04_StreetLampTilingRemap01On is combined with defaultLightWarm01SpotNS, LightBeamThin01, and DefaultLightCoolFLNS for the ones that are ON during the night. All of these components are parented to a EnableMarker which has the reference ID of FO4_StreetLampEnabler01. I have placed a script on the EnableMarker (i.e., FO4_StreetLampEnabler01) which should control the enabling and disabling the various streetlamps and lights. The script originated from here and was modified by DieFeM in response to Citizenbari’s post.


Questions:

1. Is there a way to test the state of the EnableMarker? I am trying to troubleshoot the script and it doesn’t seem that the states (enabled, disabled) are changing.

2. Should the script be placed on the EnableMarker or should I create a default dummy (activator)?




ScriptName TimedLightSwitch extends ObjectReference
{Controls a set of lights with a master enable parent marker with this
script attached to turn on and off at the times of the day specified
by the properties LightsOffTime and LightsOnTime}

;
;-- Properties --------------------------------------
;
float Property LightsOffTime = 7.0 auto
{The time at which lights should be turned off}
float Property LightsOnTime = 18.0 auto
{The time at which lights should be turned on}

ObjectReference Property FO4_StreetLampEnabler01 Auto Const Mandatory

;
;-- Initialization Event --------------------------------------
;
Event OnInit()
; Is the enabler disabled or enable?
If (FO4_StreetLampEnabler01.IsDisabled())
Debug.Trace("TimedLightSwitchScript: OnInit event. The FO4_StreetLampEnabler01 is disabled!")
Else
Debug.Trace("TimedLightSwitchScript: OnInit event. The FO4_StreetLampEnabler01 is enabled!")
endIf
If (ShouldLightsBeOff())
Debug.Trace("TimedLightSwitchScript:Initialization event = " + " Lights should be OFF")
GoToState("LightsOff")
Else
Debug.Trace("TimedLightSwitchScript:Initialization event = " + " Lights should be ON")
GoToState("LightsOn")
EndIf

EndEvent
;
;-- States --------------------------------------
;
State LightsOff

Event OnBeginState(string asOldState)
Debug.Trace("TimedLightSwitchScript:State LightsOff called! Ready to disable = " + " FO4_StreetLampEnabler01")
FO4_StreetLampEnabler01.Disable()
; Is the enabler disabled?
If (FO4_StreetLampEnabler01.IsDisabled())
Debug.Trace("TimedLightSwitchScript: State LightsOff - The FO4_StreetLampEnabler01 is disabled!")
Else
Debug.Trace("TimedLightSwitchScript: State LightsOff - The FO4_StreetLampEnabler01 is enables!")
endIf
RegisterForSingleUpdateGameTimeAt(LightsOnTime)
EndEvent

Event OnTimerGameTime(int aiTimerID)
If (ShouldLightsBeOff())
RegisterForSingleUpdateGameTimeAt(LightsOnTime)
Else
GoToState("LightsOn")
EndIf
EndEvent

EndState

State LightsOn

Event OnBeginState(string asOldState)
Debug.Trace("TimedLightSwitchScript:State LightsOn called! Ready to enable = " + " FO4_StreetLampEnabler01")
FO4_StreetLampEnabler01.Enable()
; Is the enabler disabled?
If (FO4_StreetLampEnabler01.IsDisabled())
Debug.Trace("TimedLightSwitchScript: State LightsOn - The FO4_StreetLampEnabler01 is disabled!")
Else
Debug.Trace("TimedLightSwitchScript: State LightsOn - The FO4_StreetLampEnabler01 is enables!")
endIf
RegisterForSingleUpdateGameTimeAt(LightsOffTime)
EndEvent

Event OnTimerGameTime(int aiTimerID)
If (ShouldLightsBeOff())
GoToState("LightsOff")
Else
RegisterForSingleUpdateGameTimeAt(LightsOffTime)
EndIf
EndEvent

EndState

;
;-- Functions --------------------------------------
;
bool Function ShouldLightsBeOff()
{Validate the light state based on current time of day}

float CurrentTime = GetCurrentHourOfDay()
Debug.Trace("TimedLightSwitchScript:Function ShouldLightsBeOff called! CurrentTime = " + CurrentTime)
If (CurrentTime >= LightsOffTime) && (CurrentTime < LightsOnTime)
Debug.Trace("TimedLightSwitchScript:Function ShouldLightsBeOff called! ShouldLightsBeOff = " + " true")
return true
Else
Debug.Trace("TimedLightSwitchScript:Function ShouldLightsBeOff called! ShouldLightsBeOff = " + " true")
return false
EndIf
Debug.Trace("TimedLightSwitchScript:Function ShouldLightsBeOff called! CurrentTime = " + CurrentTime)
EndFunction

float Function GetCurrentHourOfDay() global
{Returns the current time of day in hours since midnight}
float Time = Utility.GetCurrentGameTime()
Debug.Trace("TimedLightSwitchScript:Function GetCurrentHourOfDay called! Time = " + Time)
Time -= Math.Floor(Time) ; Remove "previous in-game days passed" bit
Time *= 24 ; Convert from fraction of a day to number of hours
Return Time

EndFunction

Function RegisterForSingleUpdateGameTimeAt(float GameTime)
{Registers for a single UpdateGameTime event at the next occurrence
of the specified GameTime (in hours since midnight)}

float CurrentTime = GetCurrentHourOfDay()
If (GameTime < CurrentTime)
GameTime += 24
EndIf

StartTimerGameTime(GameTime - CurrentTime)
Debug.Trace("TimedLightSwitchScript:Function RegisterForSingleUpdateGameTimeAt called! CurrentTime = " + CurrentTime)
EndFunction

Edited by pepperman35
Link to comment
Share on other sites

I wonder if the script will still run when the enable marker is disabled, or if the events in that script would still run in the case that the reference containing this script is unloaded.

 

What happens if the enable marker reference is in the unloaded area? Will it just spit a "can not whatever on None object" in the log?

because if the reference is in an unloaded area, and not persistent, they'll return as a None I guess.

 

Taking all of that in to account, wouldn't it be appropriate handling the OnLoad and OnUnload events so that the timers are enabled or disabled? Or maybe attach it on a quest, which is always active, unlike a reference, and handle all enable parents from it.

 

Well, there's my two cents. I hope it helps.

Link to comment
Share on other sites

DieFeM, your two cents are always important and valued. The script seems to run when the enable marker is disables; however, the results are similar. I will investigate the log a bit closer as I seem to recall see something along the lines of "can not whatever on None object." I used a similar version of the script on a door (which was an animated window louver) but instead of enabling and disabling a marker it opened and closed the louvers. It seemed to work fine there. I will have to research OnLoad and OnUnload events a bit more as well as attaching this to a quest. You have given me a rudder steer so I will do a bit more sailing.

Link to comment
Share on other sites

Okay, haven't had a chance to look at niston F4MS but here is what I have done to date

 

1. Created a trigger volume around the settlement and added this script to control the activation of a master controller.

Scriptname FO4_StreetLampTriggerScript extends ObjectReference
{script that simply activates the master script when player enters the trigger}

Group Required_Properties
	ObjectReference property myMasterRef auto const
EndGroup


;************************************

auto State Active
	Event OnTriggerEnter(ObjectReference akActionRef)
		if(akActionRef == game.GetPlayer())
			myMasterRef.enable()
			myMasterRef.activate(myMasterRef)
			Debug.Notification("Hello, the player has entered the scene")
		endif
	EndEvent

	Event OnTriggerLeave(ObjectReference akActionRef)
		if(akActionRef == game.GetPlayer())
			myMasterRef.disable()
			Debug.Notification("Hello, the player has left the scene")
		endif
	EndEvent
EndState

;************************************

State Done
	;do nothing
	Event OnTriggerEnter(ObjectReference akActionRef)
	    ;do nothing
	EndEvent

	Event OnTriggerLeave(ObjectReference akActionRef)
	    ;Disable the master activator
		myMasterRef.disable()
	EndEvent
EndState

2. I added an activated (FO4_StreetLampMaster01) which holds the TimedLightSwitch script.

ScriptName FO4_TimedLightSwitch extends ObjectReference
{Controls a set of lights with a master enable parent marker with this
script attached to turn on and off at the times of the day specified
by the properties LightsOffTime and LightsOnTime}

;
;-- Properties --------------------------------------
; 
float Property LightsOffTime = 7.0 auto
{The time at which lights should be turned off}
float Property LightsOnTime = 18.0 auto
{The time at which lights should be turned on}

ObjectReference Property FO4_StreetLampOnEnabler01 Auto Const Mandatory
ObjectReference Property FO4_StreetLampOffEnabler01 Auto Const Mandatory
;
; Event Handlers
;
Event OnLoad()
  If !IsDisabled()
    Debug.Notification("This object is loaded, playing animations should work now")
	If (ShouldLightsBeOff())
		GoToState("LightsOff")
	Else
        GoToState("LightsOn")
    EndIf
  Else
      Debug.Notification("This object is loaded but disabled - so it doesn't have 3D")
  Endif
EndEvent

Event OnUnload()
  CancelAllTimers()
endEvent
;
; States
;
State LightsOff
 
    Event OnBeginState(string asOldState)
        FO4_StreetLampOffEnabler01.Enable()
		FO4_StreetLampOnEnabler01.Disable()
        RegisterForSingleUpdateGameTimeAt(LightsOnTime)
    EndEvent
 
    Event OnTimerGameTime(int aiTimerID)
        If (ShouldLightsBeOff())
            RegisterForSingleUpdateGameTimeAt(LightsOnTime)
        Else
            GoToState("LightsOn")
        EndIf
    EndEvent
 
EndState
 
State LightsOn
    Event OnBeginState(string asOldState)
        FO4_StreetLampOnEnabler01.Enable()
		FO4_StreetLampOffEnabler01.Disable()
        RegisterForSingleUpdateGameTimeAt(LightsOffTime)
    EndEvent
 
    Event OnTimerGameTime(int aiTimerID)
        If (ShouldLightsBeOff())
            GoToState("LightsOff")
        Else
            RegisterForSingleUpdateGameTimeAt(LightsOffTime)
        EndIf
    EndEvent
 
EndState

;
; Functions
;
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" bit
    Time *= 24 ; Convert from fraction of a day to number of hours
    Return Time
EndFunction

bool Function ShouldLightsBeOff()
{Validate the light state based on current time of day}
        float CurrentTime = GetCurrentHourOfDay()
        If (CurrentTime >= LightsOffTime) && (CurrentTime < LightsOnTime)
            return true
        Else
            return false
        EndIf
EndFunction

Function RegisterForSingleUpdateGameTimeAt(float GameTime)
{Registers for a single UpdateGameTime event at the next occurrence
of the specified GameTime (in hours since midnight)}
    float CurrentTime = GetCurrentHourOfDay()
    If (GameTime < CurrentTime)
        GameTime += 24
    EndIf
    StartTimerGameTime(GameTime - CurrentTime)
EndFunction

Function CancelAllTimers()
	CancelTimerGameTime()
EndFunction

Initial testing looks promising. If anyone see any pitfalls with the approach or scripts, I am more than willing to listen and learn. I most certainly appreciated your insights, experience and help as I am but a novice when it comes to scripting.

Edited by pepperman35
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...