Another light switch question, this time multiple switches f

Post » Fri May 13, 2011 12:22 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
Ana
 
Posts: 3445
Joined: Sat Jul 01, 2006 4:29 am

Post » Fri May 13, 2011 6:26 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
Javier Borjas
 
Posts: 3392
Joined: Tue Nov 13, 2007 6:34 pm

Post » Fri May 13, 2011 5:58 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
Ryan Lutz
 
Posts: 3465
Joined: Sun Sep 09, 2007 12:39 pm

Post » Fri May 13, 2011 2:35 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
Emmie Cate
 
Posts: 3372
Joined: Sun Mar 11, 2007 12:01 am

Post » Fri May 13, 2011 8:18 pm

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
Alyce Argabright
 
Posts: 3403
Joined: Mon Aug 20, 2007 8:11 pm

Post » Fri May 13, 2011 5:24 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
Mark
 
Posts: 3341
Joined: Wed May 23, 2007 11:59 am

Post » Fri May 13, 2011 3:13 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
Aliish Sheldonn
 
Posts: 3487
Joined: Fri Feb 16, 2007 3:19 am

Post » Fri May 13, 2011 8:03 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
Kahli St Dennis
 
Posts: 3517
Joined: Tue Jun 13, 2006 1:57 am

Post » Fri May 13, 2011 3:13 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
Alexx Peace
 
Posts: 3432
Joined: Thu Jul 20, 2006 5:55 pm

Post » Fri May 13, 2011 9:01 pm

Good point Cipscis! I corrected my post. :)

Cheers,

Miax
User avatar
Lizzie
 
Posts: 3476
Joined: Sun Nov 19, 2006 5:51 am

Post » Fri May 13, 2011 4:07 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

Ohhh ok that makes sense! Thanks for explaining. :)
User avatar
daniel royle
 
Posts: 3439
Joined: Thu May 17, 2007 8:44 am


Return to Fallout 3