Jump to content

[Scripting Help] - Generator System Bug - Lights In Other Cells Will Not Turn Off


Recommended Posts

I started look at Skyrim modding again, and got back to my Soul Cairn house mod additions that I was 80% done with. Bear with me as this is a complex system.

 

Individual Light Switches

In this, I created light switches in several cells, each containing ObjectReferences to the individual light objects. When the switches are used it will turn off/on the lights based on the current global storing their light state. A global is in use since the state is referred to by multiple scripts, as there can be more than one light switch for a given set of lights.

 

Below is an example of the scripts I am using for the individual light switches:

Entrance:

 

 

Scriptname AJDSCHEntranceLightSwitchScript extends ObjectReference  

GlobalVariable Property AJDSCHEntranceLightSwitchState  Auto  

ObjectReference Property AJDSCHEntranceLight1  Auto  
ObjectReference Property AJDSCHEntranceLight2  Auto  
ObjectReference Property AJDSCHEntranceLight3  Auto  
ObjectReference Property AJDSCHEntranceLight4  Auto  
ObjectReference Property AJDSCHEntranceLight5  Auto  
ObjectReference Property AJDSCHEntranceLight6  Auto  
ObjectReference Property AJDSCHEntranceLight7  Auto  
ObjectReference Property AJDSCHEntranceLight8  Auto  
ObjectReference Property AJDSCHEntranceLight9  Auto  
ObjectReference Property AJDSCHEntranceLight10  Auto  
ObjectReference Property AJDSCHEntranceLight11  Auto  
ObjectReference Property AJDSCHEntranceLight12  Auto  

GlobalVariable Property AJDSCHGeneratorState Auto

;Light Switch State is default to off

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Inputs: None
;
;The purpose of this function is to be called from an external script to retoggle the lights
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function ToggleLights()
	;Checks to see if the light switch state is set to On 
	If(((AJDSCHEntranceLightSwitchState.GetValue() as Int) == 1) && ((AJDSCHGeneratorState.GetValue() as Int) < 1))
		TurnLightsOn()
	Else
		TurnLightsOff()
	EndIf
EndFunction

Function TurnLightsOn()
	AJDSCHEntranceLight1.Enable()  
	AJDSCHEntranceLight2.Enable()  
	AJDSCHEntranceLight3.Enable()  
	AJDSCHEntranceLight4.Enable()  
	AJDSCHEntranceLight5.Enable()  
	AJDSCHEntranceLight6.Enable()  
	AJDSCHEntranceLight7.Enable()  
	AJDSCHEntranceLight8.Enable()  
	AJDSCHEntranceLight9.Enable()  
	AJDSCHEntranceLight10.Enable()  
	AJDSCHEntranceLight11.Enable()  
	AJDSCHEntranceLight12.Enable() 
EndFunction

Function TurnLightsOff()
	AJDSCHEntranceLight1.Disable()  
	AJDSCHEntranceLight2.Disable()  
	AJDSCHEntranceLight3.Disable()  
	AJDSCHEntranceLight4.Disable()  
	AJDSCHEntranceLight5.Disable()  
	AJDSCHEntranceLight6.Disable()  
	AJDSCHEntranceLight7.Disable()  
	AJDSCHEntranceLight8.Disable()  
	AJDSCHEntranceLight9.Disable()  
	AJDSCHEntranceLight10.Disable()  
	AJDSCHEntranceLight11.Disable()  
	AJDSCHEntranceLight12.Disable()  
EndFunction

Event OnActivate(ObjectReference akActivator)
	int temp = 0
	temp = (AJDSCHEntranceLightSwitchState.GetValue() as int)
	;Performs check if lights are off first
	if (temp == 0 && ((AJDSCHGeneratorState.GetValue() as int) < 1))
		;Turn on the lights
		TurnLightsOn()
		;Set the light switch state to on
		AJDSCHEntranceLightSwitchState.SetValue(1)
	elseif(temp == 0 && ((AJDSCHGeneratorState.GetValue() as int) > 0))	
		AJDSCHEntranceLightSwitchState.SetValue(1)
	else
		;Turn off the lights
		TurnLightsOff()
		;Set the light switch state to off
		AJDSCHEntranceLightSwitchState.SetValue(0)
	endif
EndEvent

 

 

 

Generator

There is a room which houses a Geothermal generator. The default Generator state is On. At some point the generator is flipped to off. The goal is for the generator state to control the lights in all cells.

 

Below is the generator script:

Generator:

 

 

Scriptname AJDSCHGeneratorOperationsScript extends ObjectReference  

Message Property AJDSCHGeneratorCheckIndicator  Auto  
Message Property AJDSCHGeneratorCheckManual  Auto  
Message Property AJDSCHGeneratorOnline  Auto  
{Messages displayed throughout the process.  CheckIndicator is used when some indicators are on and some are off.  CheckManual is used when all indicators are off.  Online is when it is turned on.}

GlobalVariable Property AJDSCHGeneratorFlowState  Auto  
GlobalVariable Property AJDSCHGeneratorPowerStation01State  Auto  
GlobalVariable Property AJDSCHGeneratorPowerStation02State  Auto  
GlobalVariable Property AJDSCHGeneratorState  Auto  
GlobalVariable Property AJDSCHGeneratorTurbine01State  Auto  
GlobalVariable Property AJDSCHGeneratorTurbine02State  Auto  
{Variables that are linked to the overall state of the generator.}

ObjectReference Property GeneratorGemOff  Auto  
ObjectReference Property GeneratorGemOn  Auto  
{The physical core gems.}

ObjectReference[] Property AJDSCHDwemerLightButtonsArray  Auto  
{The array storing all of the lights}

;;;;;;;;;;;;;;;;;;
;Generator state is set to offline when it is 1, and 0 means it is online
;;;;;;;;;;;;;;;;;;

Event OnActivate(ObjectReference akActivator)
	;Assigns the globals to temporary variables for ease of access
	int flowState = (AJDSCHGeneratorFlowState.GetValue() as int)
	int power01State = (AJDSCHGeneratorPowerStation01State.GetValue() as int)
	int power02State = (AJDSCHGeneratorPowerStation02State.GetValue() as int)
	int turbine01State = (AJDSCHGeneratorTurbine01State.GetValue() as int)
	int turbine02State = (AJDSCHGeneratorTurbine02State.GetValue() as int)
	int generatorState = (AJDSCHGeneratorState.GetValue() as int)
	
	;Assigns a total to all non-overall states.  If all are on, should add up to 5
	int total = flowState + power01State + power02State + turbine01State + turbine02State
	
	;For the gem rotation
	float neutralPosition = 0.0
	float neutralAngle = 0.0
	float rotationAngle = GeneratorGemOff.GetAngleZ() + 45.0
	float speed = 30.0
	
	float PosX = GeneratorGemOff.GetPositionX()
	float PosY = GeneratorGemOff.GetPositionY()
	float PosZ = GeneratorGemOff.GetPositionZ()
	float AngleX = GeneratorGemOff.GetAngleX()
	float AngleY = GeneratorGemOff.GetAngleY()
	
	;Checks to see if none of them are online
	if (total < 1)
		;Shows the message when no indicators are on
		AJDSCHGeneratorCheckManual.Show()
	;Checks to see if some of the non-overall states are set to online	
	elseif (total < 5)
		;Shows the message when some indicators need to be set to online
		AJDSCHGeneratorCheckIndicator.Show()
	;Everything is good to go and the generator is offline	
	elseif (generatorState == 1)
		;Change the Generator State
		AJDSCHGeneratorState.SetValue(0)
		;Change the power gems
		GeneratorGemOff.Disable()
		GeneratorGemOn.Enable()
		;Starts the rotation of the gems
	GeneratorGemOff.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
	GeneratorGemOn.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
		;Turn on the lights
		DealWithTheLights()
		;Calls for future gem rotations
		RegisterForUpdate(1.0)
		;Shows the generator online message
		
	;In the event someone wants to turn off the generator
	else
		;Change the Generator State
		AJDSCHGeneratorState.SetValue(1)
		;Change the power gems
		GeneratorGemOn.Disable()
		GeneratorGemOff.Enable()
		;Disables gem rotation
		UnregisterForUpdate()
		;Turn off the lights
		DealWithTheLights()
	endif
EndEvent

Event OnUpdate()
	;variables for rotation
	float neutralPosition = 0.0
	float neutralAngle = 0.0
	float rotationAngle = GeneratorGemOff.GetAngleZ() + 45.0
	float speed = 30.0
	
	float PosX = GeneratorGemOff.GetPositionX()
	float PosY = GeneratorGemOff.GetPositionY()
	float PosZ = GeneratorGemOff.GetPositionZ()
	float AngleX = GeneratorGemOff.GetAngleX()
	float AngleY = GeneratorGemOff.GetAngleY()
	
	;Checks to see if rotation angle is above 360.0
	if (rotationAngle > 360.0)
		rotationAngle = 0+45.0
	endif

	;Does the rotation
	GeneratorGemOff.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
	GeneratorGemOn.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
EndEvent

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Inputs: None
;
;The purpose of this function is to go through and either turn off or turn on the lights
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function DealWithTheLights()

	;Goes through each element of the array and calls a different script based off of the 
	(AJDSCHDweCaveLightSwitchButton as AJDSCHCaveLightSwitchScript).ToggleLights()
	(AJDSCHDweEntranceLightSwitchButton as AJDSCHEntranceLightSwitchScript).ToggleLights()
	(AJDSCHDweGroundFloorLightSwitchButton as AJDSCHGroundFloorLightSwitch).ToggleLights()
	(AJDSCHDweHerbalistLightSwitchButton as AJDSCHHerbalistLightSwitch).ToggleLights()
	(AJDSCHDweIgorLightSwitchButton as AJDSCHIgorLightSwitchScript).ToggleLights()
	(AJDSCHDweIgorOffLightSwitchButton as AJDSCHIgorOfficeLightSwitchScript).ToggleLights()
	(AJDSCHDweLibraryLightSwitchButton as AJDSCHLibraryLightSwitchScript).ToggleLights()
	(AJDSCHDweSecretTortureLightSwitchButton as AJDSCHSecretTortureLightSwitchScript).ToggleLights()
	(AJDSCHDweUselessLightSwitchButton as AJDSCHUselessLightSwitchScript).ToggleLights()

EndFunction


Function UselessMaybe()
	int index = 0
	int DwemerLightButtonsArrayLength = AJDSCHDwemerLightButtonsArray.Length
	ObjectReference CurrentLightButton

	While Index < DwemerLightButtonsArrayLength
		CurrentLightButton = AJDSCHDwemerLightButtonsArray[index]
	
		;Checks to see if we are at the Cave Light
		if (index == 0)
			;Turn off/on the light
			(CurrentLightButton as AJDSCHCaveLightSwitchScript).ToggleLights()
		;Checks to see if we are at the Entrance Light	
		ElseIf (index == 1)
			;Turn off/on the light
			(CurrentLightButton as AJDSCHEntranceLightSwitchScript).ToggleLights()
		;Checks to see if we are at the Ground Floor Light
		ElseIf (index == 2)
			;Turn off/on the light
			(CurrentLightButton as AJDSCHGroundFloorLightSwitch).ToggleLights()
		;Checks to see if we are at the Herbalist Light
		ElseIf (index == 3)
			;Turn of/on the light
			(CurrentLightButton as AJDSCHHerbalistLightSwitch).ToggleLights()
		;Checks to see if we are at the Igor Home Light
		ElseIf (index == 4)
			;Turn off/on the light
			(CurrentLightButton as AJDSCHIgorLightSwitchScript).ToggleLights()
		;Checks to see if we are at the Igor Office Light
		ElseIf (index == 5)
			;Turn off/on the light
			(CurrentLightButton as AJDSCHIgorOfficeLightSwitchScript).ToggleLights()
		;Checks to see if we are at the Library Light Switch
		ElseIf (index == 6)
			;Turn off/on the light
			(CurrentLightButton as AJDSCHLibraryLightSwitchScript).ToggleLights()
		;Checks to see if we are at the Secret Torture (or bedroom) Light Switch
		ElseIf (index == 7)
			;Turns off/on the light
			(CurrentLightButton as AJDSCHSecretTortureLightSwitchScript).ToggleLights()
		;Checks to see if we are at the Useless Light Switch	
		ElseIf (index == 8)
			;Turns off/on the light
			(CurrentLightButton as AJDSCHUselessLightSwitchScript).ToggleLights()
		;Current End of Switches
		Else
			;never will reach here
		EndIf

		;Increment our index
		index += 1
	EndWhile
EndFunction

ObjectReference Property AJDSCHDweCaveLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweEntranceLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweGroundFloorLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweHerbalistLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweIgorLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweIgorOffLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweLibraryLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweSecretTortureLightSwitchButton  Auto  
ObjectReference Property AJDSCHDweUselessLightSwitchButton  Auto  

 

 

 

As you can see I have tried a few options, none of which are currently successful. Anyone have any ideas on what I am missing, or if what I am attempting is not possible?

Link to comment
Share on other sites

I can probably offer some help to resolve it and simplify your Light and Generator scripts.

What other scripts are setting those GlobalVariables?
So you have more then 1 switch controlling one set of lights, what's the expected behavior when one switch is on on the other off, etc?
(Be quite easy if there was only 1 switch per set of lights.)
What's actually happening and failing?
I can see what your trying to do, but there is some missing information as to what is failing and apart from trying to get it to work.

Link to comment
Share on other sites

So each set of lights have their own global variable representing a switch state. With multiple switches, they don't care what the other one's pushed state is as it only checks what the global has been set to at the current time. After the fact I added a global for the generator state and integrated it into the light switches. Current behavior for the switches is that they turn on/off when expected regardless which particular switch was used.

 

The point of failure is when the switch for the generator, the 2nd script, is fired, the lights that are currently set to on will not shut off due to the generator state. The generator switch is in a cell called AJDSCHSoulCairnHomeHiddenGenerator while the light switches are in AJDSCHSoulCairnHomeHiddenCave and AJDSCHSoulCairnHomeHiddenFarm.

 

The reason for the complexity in the generator activation script is that there is a quest (not implemented, but the mechanics are there) where the player will have to go through the process of trouble shooting the generator and reactivate it. The components for this reactivation is turning on the flow, turning on the substations, and turning on the flow (hence the total of 5 mentioned in the activation portion).

 

The goal of that generator switch is to change it's active state, and remotely toggle a LightSwitch that will call ToggleLights in some shape or form, and turn on/off remotely based on the generator state and what the global for the light activation state for the particular set of lights is set.

Link to comment
Share on other sites

Here's an example script pretty much the same thing as you have but made to work on any switch with any amount of lights can be added to the script.

(one script will work for any any group of lights, you only have to edit the properties in ck after adding it to a switch, no need to edit the actual script and recompile it, just fill properties.)

Also made it so you can add any other switches that control the same group of lights.

This way when you toggle a light switch it sets the state in any other attached switches to the group (not dependent on GlobalVariable).

Light Script:

Scriptname LightSwitchScript extends ObjectReference

ObjectReference[] Property Lights Auto
{Add as many lights references as you like in CK, your switch will enable/disable them as needed}

ObjectReference[] Property OtherSwitches Auto
{If there is more then this switch controlling this group off lights, then add the other switch references here}

GlobalVariable Property AJDSCHGeneratorState Auto
{Generator State so you can access the state of the generator}

Bool Property SwitchState = False Auto Hidden
{Your light switch state, no need to set this in CK, the switch will set this as needed}

Message Property NoJuiceMsg Auto
{Optionally point this to a message that tells the user the generator is off if they flick the switch}

Event OnActivate(ObjectReference akActivator)

    ;Set the switch state even if the generator is turned off
    SwitchState = !SwitchState

    ; If there are other switches we set their state to match this switch.
    Int i = OtherSwitches.Length
    While i
        i -= 1
        (OtherSwitches[i] As LightSwitchScript).SwitchState = SwitchState
    EndWhile

    ;If the generator is on toggle the lights using the switch state, if it's off give the user a message and don't turn the lights on or off.
    If !AJDSCHGeneratorState.GetValue() ;Gather 0 means the generator is On?
        TurnLightsOn(SwitchState)
    Else
        ;No juice, generator is turned off.
        If NoJuiceMsg
            NoJuiceMsg.Show()
        EndIf
    EndIf
EndEvent

;True Turns lights on, false turns lights off.
Function TurnLightsOn(Bool bTurnOn)
    Int i = Lights.Length
    While i
        i -= 1
        If bTurnOn
            If Lights[i].IsDisabled()
                Lights[i].Enable()
            EndIf
        Else
            If Lights[i].IsEnabled()
                Lights[i].Disable()
            EndIf
        EndIf
    EndWhile
EndFunction

Generator script I didn't edit anything to do with the flow or generator state, I assumed the 0 state of the generator means it's on.

Just removed the UselessMaybe() function and Redid the the DealWithTheLights() function.

Add your light switch references to the LightSwitches property array, left a note about adding your switches.

Scriptname AJDSCHGeneratorOperationsScript extends ObjectReference

ObjectReference[] Property LightSwitches Auto
{Fill this with as many light switch references as you like, the generator will check them and do it's thing.
Note: only need 1 switch for each group of lights added, not multiple switches for 1 group of lights}

Message Property AJDSCHGeneratorCheckIndicator  Auto
Message Property AJDSCHGeneratorCheckManual  Auto
Message Property AJDSCHGeneratorOnline  Auto
{Messages displayed throughout the process.  CheckIndicator is used when some indicators are on and some are off.  CheckManual is used when all indicators are off.  Online is when it is turned on.}

GlobalVariable Property AJDSCHGeneratorFlowState  Auto
GlobalVariable Property AJDSCHGeneratorPowerStation01State  Auto
GlobalVariable Property AJDSCHGeneratorPowerStation02State  Auto
GlobalVariable Property AJDSCHGeneratorState  Auto
GlobalVariable Property AJDSCHGeneratorTurbine01State  Auto
GlobalVariable Property AJDSCHGeneratorTurbine02State  Auto
{Variables that are linked to the overall state of the generator.}

ObjectReference Property GeneratorGemOff  Auto
ObjectReference Property GeneratorGemOn  Auto
{The physical core gems.}

ObjectReference[] Property AJDSCHDwemerLightButtonsArray  Auto
{The array storing all of the lights}

;;;;;;;;;;;;;;;;;;
;Generator state is set to offline when it is 1, and 0 means it is online
;;;;;;;;;;;;;;;;;;

Event OnActivate(ObjectReference akActivator)
    ;Assigns the globals to temporary variables for ease of access
    int flowState = (AJDSCHGeneratorFlowState.GetValue() as int)
    int power01State = (AJDSCHGeneratorPowerStation01State.GetValue() as int)
    int power02State = (AJDSCHGeneratorPowerStation02State.GetValue() as int)
    int turbine01State = (AJDSCHGeneratorTurbine01State.GetValue() as int)
    int turbine02State = (AJDSCHGeneratorTurbine02State.GetValue() as int)
    int generatorState = (AJDSCHGeneratorState.GetValue() as int)

    ;Assigns a total to all non-overall states.  If all are on, should add up to 5
    int total = flowState + power01State + power02State + turbine01State + turbine02State

    ;For the gem rotation
    float neutralPosition = 0.0
    float neutralAngle = 0.0
    float rotationAngle = GeneratorGemOff.GetAngleZ() + 45.0
    float speed = 30.0

    float PosX = GeneratorGemOff.GetPositionX()
    float PosY = GeneratorGemOff.GetPositionY()
    float PosZ = GeneratorGemOff.GetPositionZ()
    float AngleX = GeneratorGemOff.GetAngleX()
    float AngleY = GeneratorGemOff.GetAngleY()

    ;Checks to see if none of them are online
    if (total < 1)
        ;Shows the message when no indicators are on
        AJDSCHGeneratorCheckManual.Show()
    ;Checks to see if some of the non-overall states are set to online
    elseif (total < 5)
        ;Shows the message when some indicators need to be set to online
        AJDSCHGeneratorCheckIndicator.Show()
    ;Everything is good to go and the generator is offline
    elseif (generatorState == 1)
        ;Change the Generator State
        AJDSCHGeneratorState.SetValue(0)
        ;Change the power gems
        GeneratorGemOff.Disable()
        GeneratorGemOn.Enable()
        ;Starts the rotation of the gems
        GeneratorGemOff.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
        GeneratorGemOn.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
        ;Turn on the lights
        DealWithTheLights(True)
        ;Calls for future gem rotations
        RegisterForUpdate(1.0)
        ;Shows the generator online message

    ;In the event someone wants to turn off the generator
    else
        ;Change the Generator State
        AJDSCHGeneratorState.SetValue(1)
        ;Change the power gems
        GeneratorGemOn.Disable()
        GeneratorGemOff.Enable()
        ;Disables gem rotation
        UnregisterForUpdate()
        ;Turn off the lights
        DealWithTheLights(False)
    endif
EndEvent

Event OnUpdate()
    ;variables for rotation
    float neutralPosition = 0.0
    float neutralAngle = 0.0
    float rotationAngle = GeneratorGemOff.GetAngleZ() + 45.0
    float speed = 30.0

    float PosX = GeneratorGemOff.GetPositionX()
    float PosY = GeneratorGemOff.GetPositionY()
    float PosZ = GeneratorGemOff.GetPositionZ()
    float AngleX = GeneratorGemOff.GetAngleX()
    float AngleY = GeneratorGemOff.GetAngleY()

    ;Checks to see if rotation angle is above 360.0
    if (rotationAngle > 360.0)
        rotationAngle = 0+45.0
    endif

    ;Does the rotation
    GeneratorGemOff.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
    GeneratorGemOn.TranslateTo(PosX, PosY, PosZ, AngleX, AngleY, rotationAngle, speed)
EndEvent

; UseSwitchState True means use the light switch last state (after turning the generator on), False turning the generator off (turn the lights off).
Function DealWithTheLights(Bool UseSwitchState)
    LightSwitchScript CurSwitch
    Int i = LightSwitches.Length
    While i
        i -= 1
        CurSwitch = LightSwitches[i] As LightSwitchScript
        If !UseSwitchState
            CurSwitch.TurnLightsOn(UseSwitchState)
        Else
            CurSwitch.TurnLightsOn(CurSwitch.SwitchState)
        EndIf
    EndWhile
EndFunction

I did test compile both scripts and they compile, but don't mean they'll work..lol

It makes it pretty hard to test when i don't have what they'll be attached to and set up as.

 

Edited: generator script as I didn't allow for turning off the generator..doh.

Link to comment
Share on other sites

I figured out what was going on in the original scripts. The scripts themselves were setup properly. My problem stemmed from the Property for the GeneratorState not being set on the Light Switch scripts. The lights are now having correct behavior when the generator is on compared to when it is off. Thanks for the help though, I will keep that in mind when I do a similar setup in the future.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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