Difference between revisions of "Light Switch"

From the CreationKit Wiki
Jump to navigation Jump to search
imported>Cipscis
(Added to "Solutions" category)
imported>Tunaisafish
m (→‎Manual Light Switch: fix enablemarker ref)
Line 127: Line 127:


Event OnBeginState()
Event OnBeginState()
Disable()
EnableMarker.Disable()
EndEvent
EndEvent


Line 139: Line 139:


Event OnBeginState()
Event OnBeginState()
Enable()
EnableMarker.Enable()
EndEvent
EndEvent



Revision as of 04:05, 13 April 2012


Setup

The script on this page can be used to automatically turn a set of lights on or off depending on the time of day. It contains 2 properties, which have default values but are configurable in the Creation Kit

  1. LightsOffTime
    • The time at which lights should be turned off. Set to 7:00 am by default.
  2. LightsOnTime
    • The time at which lights should be turned on. Set to 6:00 pm by default.

In order to set this script up to be used, you'll need to either create a marker or select one of the lights to be the "master", and set it to be the enable parent of all the other lights. Then, just attach the script below to that marker or master light. If you don't want to use the default values, then either alter them in the script or override them in the Creation Kit.

Script

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}

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}

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

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

	RegisterForSingleUpdateGameTime(GameTime - CurrentTime)

EndFunction

Event OnInit()

	If (GetCurrentHourOfDay() > LightsOffTime)
		GoToState("LightsOff")
	Else
		GoToState("LightsOn")
	EndIf

EndEvent

State LightsOff

	Event OnBeginState()
		Disable()
		RegisterForSingleUpdateGameTimeAt(LightsOnTime)
	EndEvent

	Event OnUpdateGameTime()
		GoToState("LightsOn")
	EndEvent

EndState

State LightsOn

	Event OnBeginState()
		Enable()
		RegisterForSingleUpdateGameTimeAt(LightsOffTime)
	EndEvent

	Event OnUpdateGameTime()
		GoToState("LightsOff")
	EndEvent

EndState

Script Explanation

This script consists of 2 custom functions, one OnInit event, and two states, each with their own OnBeginState and OnUpdateGameTime events.

The functions are documented within the script, but just in case they're not clear:

GetCurrentHourOfDay

This function uses the Utility script's global function, GetCurrentGameTime, and some mathematical manipulation, to get the current time of the current day as a number between 0.0 and 24.0

RegisterForSingleUpdateGameTimeAt

This function works as a variation of RegisterForSingleUpdateGameTime. The twist is that, while RegisterForSingleUpdateGameTime takes a duration as its parameter, this custom function takes the time at which the update should take place as its parameter.

So, for example, if I were to pass 7.0 as its parameter, then the next time it's 7:00 am in Skyrim, this object will have the native event OnUpdateGameTime called on it.

OnInit

This event should pretty much always be used to set up your script in whatever ways are required that cannot be done when initialising properties or variables. All that's required here is that the correct state is selected depending on the current time in-game when this event runs.

If the lights should be off, then the script enters the "LightsOff" state, whereas if they should be on, then the script enters the "LightsOn" state.

States

The two states are nearly identical, and work sort of like mirror images of one another. Each state, when it begins, changes the enable state of the marker or master light (and therefore all other lights), and registers for a single update in game time at the time at which the state needs to change, as set by the two properties of this script.

When that time is reached, the OnUpdateGameTime event is called, which switches the script to the other state, and its OnBeginState event will run.

Extending This Script

The key functionality in this script is in the states. Specifically, that they both use the OnBeginState native event to set everything that needs to be set, so that the lights can be turned on or off simply by changing the state of the script. By taking advantage of this, it wouldn't be particularly difficult to, say, change the script so that the lights' state is toggled when the scripted object is activated:

Manual Light Switch

ScriptName ManualLightSwitch extends ObjectReference
{Controls a set of lights with a master enable parent
marker (EnableMarker) and a switch with this script
attached to turn on and off when the switch is activated}

ObjectReference Property EnableMarker auto
{The marker set as the enable parent of all the lights}

Event OnInit()

	If (EnableMarker.IsDisabled())
		GoToState("LightsOff")
	Else
		GoToState("LightsOn")
	EndIf

EndEvent

State LightsOff

	Event OnBeginState()
		EnableMarker.Disable()
	EndEvent

	Event OnActivate(ObjectReference akActionRef)
		GoToState("LightsOn")
	EndEvent

EndState

State LightsOn

	Event OnBeginState()
		EnableMarker.Enable()
	EndEvent

	Event OnActivate(ObjectReference akActionRef)
		GoToState("LightsOff")
	EndEvent

EndState