ArronDominion Posted July 25, 2015 Share Posted July 25, 2015 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 SwitchesIn 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 GeneratorThere 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 More sharing options...
sLoPpYdOtBiGhOlE Posted July 25, 2015 Share Posted July 25, 2015 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 More sharing options...
ArronDominion Posted July 25, 2015 Author Share Posted July 25, 2015 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 More sharing options...
sLoPpYdOtBiGhOlE Posted July 25, 2015 Share Posted July 25, 2015 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 EndFunctionGenerator 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 EndFunctionI did test compile both scripts and they compile, but don't mean they'll work..lolIt 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 More sharing options...
ArronDominion Posted July 25, 2015 Author Share Posted July 25, 2015 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 More sharing options...
Recommended Posts