Jump to content

DOWNLOAD MODS

Are you looking for something shiny for your load order? We have many exclusive mods and resources you won't find anywhere else. Start your search now...

LEARN MODDING

Ready to try your hand at making your own mod creations? Visit the Enclave, the original ES/FO modding school, and learn the tricks of the trade from veteran modders...

JOIN THE ALLIANCE

Membership is free and registering unlocks image galleries, project hosting, live chat, unlimited downloads, & more...

3 state Light Switch script? please.


js100serch
 Share

Recommended Posts

Hi everyone.

Well I don't know nothing about scripting. What I want to do is to have a switch that cycles through 3 different lights. "Red, Green, Blue, Red, Green, Blue and so on...". I already have the regular light switch that turns on and off a light I can use that to have two lights Red and Green but I need to ad the Blue one but I have no idea of how to do it.

Can you help me?. Thanks =D

Link to comment
Share on other sites

This is the script I'm using to basically just turn a light on/off or simply change the color from Red to Green.
 

ScriptName LightSwitch 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

 

ScreenShot12.bmp

Edited by js100serch
Link to comment
Share on other sites

Hello, and huge apologies if I am not supposed to be posting here! The rules said that one shall not interfere with a scholar's classroom or something like that, but I am still not quite sure whether this is still a part of the classroom. The scripting classroom, that is. But there would appear to be others replying to posts placed here, too. Which makes me uncertain. So any moderators are free to remove this! And also let me know if this is a part of the classroom, that I should not be posting in. I am still relatively new here (as in, not having posted a lot)! :blush:

You have the idea there: only the one light that currently should be visible needs to be enabled, others need to be disabled. So when you have the first light on, you will need to have the other two lights off. When the second one is on, the other two ones off, etc. So if you use individual lights, and add all three as separate properties, it might look something like that:

ScriptName LightSwitch Extends ObjectReference

ObjectReference Property rLight1 Auto	; light one
ObjectReference Property rLight2 Auto	; light two
ObjectReference Property rLight3 Auto	; light three

Event OnInit()
    GoToState("Light3")	; go to the state before 1 (so when activated, state goes to 1)
    rLight3.Disable()	; so that 3 (enabled in state 3) should not be enabled
EndEvent

State Light1
    Event OnBeginState()
        rLight1.Enable()
        rLight2.Disable()
        rLight3.Disable()
    EndEvent
    Event OnActivate(ObjectReference akActionRef)
        GoToState("Light2")	; go to next state
    EndEvent
EndState

State Light2
    Event OnBeginState()
        rLight1.Disable()
        rLight2.Enable()
        rLight3.Disable()
    EndEvent
    Event OnActivate(ObjectReference akActionRef)
        GoToState("Light3")	; go to next state
    EndEvent
EndState

State Light3
    Event OnBeginState()
        rLight1.Disable()
        rLight2.Disable()
        rLight3.Enable()
    EndEvent
    Event OnActivate(ObjectReference akActionRef)
        GoToState("Light1")	; return to state 1
    EndEvent
EndState

And I think it should be perfectly fine. At least it compiled just fine.

However, adding more lights might be tricky with that method, and there is a lot of code in that for something that could be done in a more flexible manner with less code (in my opinion, at least). So I cannot resist trying to maybe explain how that could work! If you do not get it straight away, it is fine! But in case you are planning to one day move on to things like looping through stuff, this might be one chance to switch from the current hardcoded set of three or two to a more flexible manner using a list one can easily add a hundred lights in! Makes my inner nerd excited! :woohoo:

Also, a huge disclaimer: I have not tested that script in-game! The idea should be there, and it compiles just fine. If the ObjectReference array/list works the way I think it should, then it should work.

So, assuming you just want to cycle through a number of lights, you could, instead of manually adding a new state for each light, have a list of lights. One list to hold all lights! It would both cut down property count and code length! Also manual labour in writing the code! And a list would not be limited to three, you could have a hundred lights! In addition to a list, one would need a variable to store the currently active index. When the list does not change constantly, the index could show the currently active light's position on that list. So a list and an integer variable. After that, the list of an arbitrary length needs to be handled somehow. This is what While is for. A while loop runs as long as the condition it is given evaluates to false. One can use it to travel along the list all the way to the end, no matter how long the list. It proceeds one step at a time. When the list is there, and the active index, all we need to do is, upon activating, increment the current index by one (to move it to the next one) or set it to 0 (to return to the end if the list end is reached). When the new active light index is available, all there remains is to disable all other lights in the list, and enable the one at the current active index.

As in, the script would be attached to your button, and after attaching it to that button, you would need to fill the two properties in the CK. The rLightList is an array/list of ObjectReferences, and that would hold all your light references (in a single property! yay!). The iCurrentLight would be the index of the currently active light (from the rLightList property), or -1 if you want to have all lights disabled initially and only turn on the first one upon first activation. Because one needs to keep track of the current active light somehow! When the button would be activated, the index of the current light would be either incremented by 1 or set to 0 (if at the end of list, as the index of the last item in an array/list is actually the length - 1). The script should then cycle through the list of ObjectReferences (in reverse order), and disable all but the current light.

Like I said, I have not tested it, but I think something like that should work (if it does not work "out of the box"). If there is something unclear, I can see about trying to explain it - but I am extremely bad at explainign things, mind you! Also, if that works, it should work with any number of lights to cycle, not just three.

ScriptName LightSwitch Extends ObjectReference

ObjectReference[] Property aLightList Auto  ; this is a list, add all your lights here
Int Property iCurrentLight Auto             ; currently active light's index, remember to fill it!

Event OnActivate(ObjectReference akActionRef)
    Int iTemp = aLightList.Length  ; how many items are there in the light list?
    ObjectReference rTemp          ; this is a temporary ObjectReference
    If(iCurrentLight > iTemp - 2)  ; have we reached the end of the list?
        iCurrentLight = 0
    Else
        iCurrentLight += 1
    EndIf
    While(iTemp > 0)               ; travels list in reverse order, from end to start
        iTemp -= 1                 ; to make the while loop move along the list
        rTemp = aLightList[iTemp]  ; get the light ObjectReference at current index
        If(iTemp != iCurrentLight) ; if it's not the current one, disable it
            rTemp.Disable()
        Else                       ; the current light needs to be enabled
            rTemp.Enable()
        EndIf
    EndWhile
EndEvent

Hopefully that helps a little! And please, moderators and/or scholars remove this if the classroom extends all the way here. :sour:

Edited by Contrathetix
minor changes
  • Upvote 1
Link to comment
Share on other sites

Hi and huge thanks for the help both of you ladyonthemoon and Contrathetix

What is that "class room" all about? isn't this a regular forum? O.o

Contrathetix  It works like a charm. But is it possible to add some a delay to the lights, they activate instantly O.o

Look my mod is not kind of a big deal but I would like to credit you once I launch it. You are the 3rd person who helps me with scripting stuff. Let me know if you want credit for this.

Edited by js100serch
  • Upvote 1
Link to comment
Share on other sites

Sure, delay is always possible! The first step to take is to Google for Skyrim ini Papyrus section tweaks and copypaste the first 1000x default values to the ini. That should help everyone achieve some delays eventually.  :thumbup: Sorry, could not resist. Do not do that. :blush:

Yes, there is the Utility.Wait command (http://www.creationkit.com/index.php?title=Wait_-_Utility) for that purpose. But, as I think you might already know, Papyrus can have some script latency depending on the current workload. So depending on the user's script latency (or whatever the official term may be), the Utility.Wait command can either wait just the amount of time it was told to, or it can wait twice that, ten times, or even an eternity, if the user has serious issues. Ehm. The user's setup has serious issues. You can use it just fine, but if you use it on something that requires precise timing, then there might be issues.

Utility.Wait(0.5)  ; script stops here, continues after ~0.5 seconds gamemode

If you add an intentional delay to the script, there is a greater chance of a restless user spamming the button over and over again because it did not work instantly (maybe he/she also suffers from a modest amount of self-induced script lag). So a state could be added, to account for the "busy" state, when the work is being done. This is something I forgot from that last version. Also, this one has not been tested, either (just compiled, which it did just fine), but to give you an idea of how to add the delay (with length determined as property, but you could also type it straight into the script if you want, making it potentially less modular):

 

 


ScriptName Lightswitch Extends ObjectReference

ObjectReference[] Property aLightList Auto
Int Property iCurrentLight Auto
Float Property fUpdateDelay Auto

Function LightCycle()
	Int iTemp = aLightList.Length
	ObjectReference rTemp
	If(iCurrentLight > iTemp - 2)
		iCurrentLight = 0
	Else
		iCurrentLight += 1
	EndIf
	If(fUpdateDelay > 0)
		Utility.Wait(fUpdateDelay)
	EndIf
	While(iTemp > 0)
		iTemp -= 1
		rTemp = aLightList[iTemp]
		If(iTemp != iCurrentLight)
			rTemp.Disable()
		Else
			rTemp.Enable()
		EndIf
	EndWhile
EndFunction

State Busy
	Event OnBeginState()
		LightCycle()
		GoToState("Free")
	EndEvent
	Event OnActivate(ObjectReference akActionRef)		
	EndEvent
EndState

State Free
	Event OnActivate(ObjectReference akActionRef)
		GoToState("Busy")
	EndEvent
EndState

 

The Wait command is outside the While loop, and it should, upon pressing the button, first wait for a certain amount of time, then go through the loop to disable/enable lights.

And no need to give any credit for me, this is not really that much work. I like scripting, and it is great to be able to help others. Also, it seemed you were actually invested in the project, considering how there was also a smilar thread with similar contents on The Nexus Forums (that got buried by other threads pretty quickly). But anyway, no need to credit me.

And indeed! I have only really done worldbuilding with Oblivion, not so much with Skyrim. Someone did actually mention issues with too many lights. Thank you for reminding me! I like scripting more, and like to focus on that. But in theory (*ahem*), that second script suggestion could handle lots of lights with no issues. :P

From what I have noticed, the classroom thing is the idea behind this "modding school" here: each classroom is dedicated to a specific aspect of modding, and each classroom has a scholar assigned, and that scholar is in charge of the classroom. People can carry out the excercises described in the "lessons", and the scholar can assist them should any issues arise. Others should not interfere, to keep the scholar in charge of the whole process and to prevent "students" getting confused. Or that is how I have perceived it. I am not sure where the classroom boundaries go. Maybe this is a casual forum. Looks like Hanaisse moved this from somewhere else, and I am not sure where from. But there is also the "Study Hall" forum, for example. But if you posted this there first, and then Hanaisse moved it here, that could mean that he/she intended that you be instructed by a scholar - something I am definitely not. :blush:

Hopefully that helps a little.

Edited by Contrathetix
typos... arrrrrrrrrgh
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...