Another light switch question, this time multiple switches f

Post » Mon Dec 05, 2011 7:24 pm

back again with another newby question.

I have a large room with a few lights sources. I am able to get them all to work together as one (through the helpful advice of using an xMarker to connect them all). This time, however, I'd like to have a few switches in this room to control the lighting.

I'd like the switches to not only all control the xMarker, but also effect eachother. Using the generic switch with the red and green light, I'd like it when one switch turns the light on, they all turn to green, setting themselves to an on state, so if I go to the other end of the room and hit the switch there, it turns off the xMarker

This is how far I've gotten with this script. This is what is in switch box 1
ScriptName VDMainHallLightSwitchScript01short OnBegin OnActivate	if(On == 0)		if IsActionRef player == 1			VDMainHallLightSwitch02Box.Activate			VDMainHallLightSwitch03Box.Activate			VDMainHallLightSwitch04Box.Activate			VDMainHallLightMarker01.Enable		endif		Activate		set On to 1	else		if IsActionRef player == 1			VDMainHallLightSwitch02Box.Activate			VDMainHallLightSwitch03Box.Activate			VDMainHallLightSwitch04Box.Activate			VDMainHallLightMarker01.Disable		endif		Activate		set On to 0	endifEnd


the other boxes have a similar script, but change out the VDMainHallLightSwitch#Box.Activate for whatever it isn't. When I hit the first switch, it turns on the marker and lights as expected, and seems to sometimes effect the other switches, but not always, and I seem to have to toggle a switch on and off to get the xMarker to react.
User avatar
Darlene Delk
 
Posts: 3413
Joined: Mon Aug 27, 2007 3:48 am

Post » Mon Dec 05, 2011 2:48 pm

I think you could accomplish this by making all of your switches persistent and giving them an Editor ID. Then use the GetOpenState command on all of them to determine which light is lit and flip them using SetOpenState as necessary.
User avatar
Emily Jeffs
 
Posts: 3335
Joined: Thu Nov 02, 2006 10:27 pm

Post » Mon Dec 05, 2011 2:00 pm

thanks a ton for the lead. I followed what you said and came up with this, which works exactly how I want it to :) even better, I can cram the same script into all 4 switches, instead of messing around with 4 different scripts.
I guess I want to try to fill in the gaps in my understanding this all and wonder, since they are all the same model, doing the same animation, using the same script, do they all need to be individual Persistent Reference? could I just make a unique Base Object ref and have as many switches for this set of lights without needing a persistent Reference Editor ID? This wouldn't that streamline the code a lot? could it self reference it's base ID and trigger all others the same?

posting it here incase someone else is looking for the same thing:

ScriptName VDMainHallLightSwitchScriptBegin OnActivate	if IsActionRef player == 1		if GetOpenState == 3				VDMainHallLightSwitch01Box.SetOpenState 1				VDMainHallLightSwitch02Box.SetOpenState 1				VDMainHallLightSwitch03Box.SetOpenState 1				VDMainHallLightSwitch04Box.SetOpenState 1				VDMainHallLightMarker01.Enable		else				VDMainHallLightSwitch01Box.SetOpenState 0				VDMainHallLightSwitch02Box.SetOpenState 0				VDMainHallLightSwitch03Box.SetOpenState 0				VDMainHallLightSwitch04Box.SetOpenState 0				VDMainHallLightMarker01.Disable		endif	endifEnd

User avatar
+++CAZZY
 
Posts: 3403
Joined: Wed Sep 13, 2006 1:04 pm

Post » Mon Dec 05, 2011 9:22 pm

I don't think it will work that way as even though each switch runs the same script, they are not running them at the same time. There may be one base object, but there are still four distinct references to that base object. In other words, each switch will runs its own version of the switch script when its activated. So running the script on one switch will not make the other switches run their script. Its not really a big deal to have all the switches be persistent anyway. I have levels that have maybe 100 or more persistent refs. Remember that all actors and Xmarkers are persistent by default. Its just that to use a ref in a script, it must be persistent. Think about how many Actors, xmarkers and other patrol refs are in the Fallout.esm. It must be thousands of persistent refs.

By the way this:


Begin onactivate	if IsActionRef player == 1


is the same as this:

Begin OnActivate Player

User avatar
Richard Dixon
 
Posts: 3461
Joined: Thu Jun 07, 2007 1:29 pm

Post » Tue Dec 06, 2011 3:32 am

Actually, in this case I'd recommend using http://geck.gamesas.com/index.php/IsActionRef, although without the useless "== 1", instead of "http://geck.gamesas.com/index.php/OnActivate player". Although, in both cases, the code will only run when the player activates the scripted reference, when http://geck.gamesas.com/index.php/IsActionRef is used to check for the player instead of http://geck.gamesas.com/index.php/OnActivate, any activation will trigger the http://geck.gamesas.com/index.php/OnActivate block, so if another actor activates the reference for any reason, its open state will not change because http://geck.gamesas.com/index.php/Activate was not called within the http://geck.gamesas.com/index.php/OnActivate block.

If you want to use the same script for each switch but think you might add more switches later, you could use a circular set of linked references to activate them each in turn. If I remember correctly, and http://geck.gamesas.com/index.php/SetOpenState instantly changes a reference's open state such that http://geck.gamesas.com/index.php/GetOpenState returns the updated value, then something like this should do the trick:
Spoiler
ref rLinkedRefBegin OnActivate	if IsActionRef player		if rLinkedRef == 0			set rLinkedRef to GetLinkedRef		endif		if GetOpenState == 3 ; Closed			SetOpenState 1 ; Open			if rLinkedRef.GetOpenState == 3 ; Closed				rLinkedRef.Activate player 1			endif		elseif GetOpenState == 1 ; Open			SetOpenState 0 ; Close			if rLinkedRef.GetOpenState == 1 ; Open				rLinkedRef.Activate player 1			endif		endif	endifEnd

Cipscis
User avatar
Blaine
 
Posts: 3456
Joined: Wed May 16, 2007 4:24 pm

Post » Tue Dec 06, 2011 12:14 am

*snip* and http://geck.gamesas.com/index.php/SetOpenState instantly changes a reference's open state such that http://geck.gamesas.com/index.php/GetOpenState returns the updated value *snip*


Actually, I think according to the TesWiki SetOpenState does not change the variable returned by GetOpenState, unless I am interpreting it wrong or it is incorrect/updated in Fo3.

Note that the value passed to SetOpenState does NOT correspond to the values returned by GetOpenState.

User avatar
Chloe Botham
 
Posts: 3537
Joined: Wed Aug 30, 2006 12:11 am

Post » Mon Dec 05, 2011 5:26 pm

That's because http://geck.gamesas.com/index.php/GetOpenState can return 5 different values, depending on the calling reference's open state, but http://geck.gamesas.com/index.php/SetOpenState only distinguishes between 0 and non-0 values. What it means is that how the two functions interpret values is unrelated - "3" for http://geck.gamesas.com/index.php/GetOpenState means "Closed", but for http://geck.gamesas.com/index.php/SetOpenState it means "Open".

Cipscis
User avatar
Dean Brown
 
Posts: 3472
Joined: Fri Aug 31, 2007 10:17 pm

Post » Mon Dec 05, 2011 5:33 pm

When I setup multiple light-switches for a dozen or more lights in an area (imagine light switches at both ends near the doors), Its enough to simply link each switch to the master xMarkerRef that controls all the lights. Then when any switch linked to that xMarkerRef is turned on/off, the script works on the master xMarkerRef and all of the lights follow suite. The setup is like this:

1. Setup one xMarkerRef as the master ref.

2. Each light is linked as to the master xMarkerRef as an Enable Parent (not a linked ref).

3. Setup each light switch as an Activator, and link each to the master xMarkerRef as a Linked Reference (not an enable parent).

I use the following script on the light switches:

scn LightSwitch02SCRIPTref rXmarkerRefbegin onActivate	set rXmarkerRef to GetLinkedRef	if rXmarkerRef		if rXmarkerRef.GetDisabled			rXmarkerRef.Enable 0		else			rXmarkerRef.Disable		endif	        Activate	else		PlaySound OBJSwitchButtonBFail	endifEnd


The Enable/Disable will trigger the state of the xMarkerRef, which will hit all the rest of the lights too. There may be much easier ways to handle this, but it works well for me. I've even applied this to a regular box light-switch (the kind you see in many office / hotel room spaces on the walls, I stripped one off the model and made it a real switch). The Activate in the script forces the switch to toggle, play a sound and whatnot.

Cheers,

Miax
User avatar
BEl J
 
Posts: 3397
Joined: Tue Feb 13, 2007 8:12 am

Post » Mon Dec 05, 2011 5:15 pm

I have one minor comment on that code. Change this:
if rXmarkerRef.GetDisabled	rXmarkerRef.Enable 0	Activateelse	rXmarkerRef.Disable	Activateendif
To this:
if rXmarkerRef.GetDisabled	rXmarkerRef.Enable 0else	rXmarkerRef.DisableendifActivate

If code should be run no matter the outcome of a conditional statement, then don't include it in the conditional block.

Cipscis
User avatar
Dezzeh
 
Posts: 3414
Joined: Sat Jun 16, 2007 2:49 am

Post » Tue Dec 06, 2011 12:53 am

Good point Cipscis! I corrected my post. :)

Cheers,

Miax
User avatar
Amanda savory
 
Posts: 3332
Joined: Mon Nov 27, 2006 10:37 am

Post » Tue Dec 06, 2011 3:06 am

That's because http://geck.gamesas.com/index.php/GetOpenState can return 5 different values, depending on the calling reference's open state, but http://geck.gamesas.com/index.php/SetOpenState only distinguishes between 0 and non-0 values. What it means is that how the two functions interpret values is unrelated - "3" for http://geck.gamesas.com/index.php/GetOpenState means "Closed", but for http://geck.gamesas.com/index.php/SetOpenState it means "Open".

Cipscis

Ohhh ok that makes sense! Thanks for explaining. :)
User avatar
Juan Cerda
 
Posts: 3426
Joined: Thu Jul 12, 2007 8:49 pm


Return to Fallout 3