Difference between revisions of "Scripting tutorial lever"

175 bytes added ,  22:57, 15 March 2012
no edit summary
imported>Fg109
imported>Fg109
Line 1: Line 1:
[[Category:Tutorials]]
[[Category:Community Tutorials]]
[[Category:Scripting]]
[[Category:Papyrus]]
=Lever Scripting Tutorial=
=Lever Scripting Tutorial=


Line 26: Line 31:


Now that we know how the animation for a lever works, we can begin writing a script for it.
Now that we know how the animation for a lever works, we can begin writing a script for it.


===Starting Your Script===
===Starting Your Script===
Line 34: Line 40:


<source lang="Papyrus">Scriptname fg109TutorialLeverScript extends ObjectReference</source>
<source lang="Papyrus">Scriptname fg109TutorialLeverScript extends ObjectReference</source>


I put my name in there, because it makes it easier to filter through all the scripts in the scripts folder in order to find my own.  I suggest you do the same.
I put my name in there, because it makes it easier to filter through all the scripts in the scripts folder in order to find my own.  I suggest you do the same.
Line 41: Line 48:
<source lang="Papyrus">Scriptname fg109TutorialLeverScript extends ObjectReference
<source lang="Papyrus">Scriptname fg109TutorialLeverScript extends ObjectReference
{A script that will activate one of three doors, depending on the position of the lever.}</source>
{A script that will activate one of three doors, depending on the position of the lever.}</source>


===Properties and Variables===
===Properties and Variables===
Line 58: Line 66:
ObjectReference property Door03 auto
ObjectReference property Door03 auto
{The last of the doors we can activate.}</source>
{The last of the doors we can activate.}</source>


Obviously, the properties here are to reference the doors that we want to be able to open.  The reason we declared these as properties is because in Papyrus, we aren't allowed to reference anything directly.  Instead, we use properties as placeholders for the things that we actually want to manipulate, and then afterwards we set the values of these properties outside of the script.  This is to make it possible to reuse the same script for multiple items and purposes.
Obviously, the properties here are to reference the doors that we want to be able to open.  The reason we declared these as properties is because in Papyrus, we aren't allowed to reference anything directly.  Instead, we use properties as placeholders for the things that we actually want to manipulate, and then afterwards we set the values of these properties outside of the script.  This is to make it possible to reuse the same script for multiple items and purposes.
Line 71: Line 80:
;The previous position of the lever.</source>
;The previous position of the lever.</source>


Note that comments in curly braces are only allowed for properties and the first line of the script.  For comments in the rest of a script, you need to use semicolons.  We will be using these variables to keep track of the position of the lever.  You might notice that the declaration for the variable "LeverPosition" is different than for "LeverPositionOld".
 
We will be using these variables to keep track of the position of the lever.  You might notice that the declaration for the variable "LeverPosition" is different than for "LeverPositionOld".


What we have done is assign a default value to "LeverPosition".  This means that even before anything has happened, the value of "LeverPosition" has already been changed to 1, instead of the default of 0.  The reason for this is because of what I said in the previous section on levers.
What we have done is assign a default value to "LeverPosition".  This means that even before anything has happened, the value of "LeverPosition" has already been changed to 1, instead of the default of 0.  The reason for this is because of what I said in the previous section on levers.
Line 78: Line 88:


That is it for the properties and variables.  Now we move onto the actual work of the script.
That is it for the properties and variables.  Now we move onto the actual work of the script.
{{WarningBox|Comments in curly braces are only allowed for properties and the first line of the script.  For comments in the rest of a script, you need to use semicolons.}}


===Events and Functions===
===Events and Functions===
Line 86: Line 100:


Let's start by defining our functions.  Our events are going to be calling on our functions, so I feel it's a better idea to put these first.
Let's start by defining our functions.  Our events are going to be calling on our functions, so I feel it's a better idea to put these first.


<source lang="Papyrus">Function SetDefaultState()
<source lang="Papyrus">Function SetDefaultState()
Line 115: Line 130:
endif</source>
endif</source>


check to see if the lever is in position -1 (pushed to the left) and returns it to the middle position if so.  The OpenDoor is calling a function that we're going to put into the script further down.
check to see if the lever is in position -1 (pushed to the left) and returns it to the middle position if so.  The OpenDoor line is calling a function that we're going to put into the script further down.
 
 
{{ProTip|If you want to learn scripting, you must understand the structure of if-elseif-endif statements.  Basically, you start with "if" to check if a condition is true.  If it is true, then every line after it is executed until you come to either an "elseif" or "endif".  The "elseif" conditional is optional.  It is useful if you want to check for a new condition when you know the previous condition(s) were not true.  Like "if", if the "elseif" condition is true, all the lines after it are executed until you come to another "elseif" or "endif".  The "endif" is used to wrap up all if-elseif-endif structures.  For every "if", you must have an "endif" or else the script won't compile.}}


If you want to learn scripting, you must understand the structure of if-elseif-endif statements.  Basically, you start with "if" to check if a condition is true.  If it is true, then every line after it is executed until you come to either an "elseif" or "endif".  The "elseif" conditional is optional.  It is useful if you want to check for a new condition when you know the previous condition(s) were not true.  Like "if", if the "elseif" condition is true, all the lines after it are executed until you come to another "elseif" or "endif".  The "endif" is used to wrap up all if-elseif-endif structures.  For every "if", you must have an "endif" or else the script won't compile.


This is our next function:
This is our next function:
Line 130: Line 147:


The DisableDoors function is used when we want to disable the doors from normal activation.  Using [[BlockActivation_-_ObjectReference|BlockActivation]] will stop you from opening the door, even though you will still see the open door prompt.  There are other commands we could have used to even disable the activation prompt, but we are trying to keep this as simple as possible.
The DisableDoors function is used when we want to disable the doors from normal activation.  Using [[BlockActivation_-_ObjectReference|BlockActivation]] will stop you from opening the door, even though you will still see the open door prompt.  There are other commands we could have used to even disable the activation prompt, but we are trying to keep this as simple as possible.


<source lang="Papyrus">Function CloseDoors()
<source lang="Papyrus">Function CloseDoors()
Line 154: Line 172:


we close the door by using [[SetOpen_-_ObjectReference|SetOpen]].  We do the same thing for the other two doors.
we close the door by using [[SetOpen_-_ObjectReference|SetOpen]].  We do the same thing for the other two doors.


<source lang="Papyrus">Function OpenDoor()
<source lang="Papyrus">Function OpenDoor()
Line 172: Line 191:


Events are things that happen in the game.  When an event occurs, the script will receive news of it, and if there is code written in the script dealing with the event, it will be carried out.
Events are things that happen in the game.  When an event occurs, the script will receive news of it, and if there is code written in the script dealing with the event, it will be carried out.


<source lang="Papyrus">Event OnReset()
<source lang="Papyrus">Event OnReset()
Line 179: Line 199:


Here we are seeing the code for an [[OnReset_-_Quest|OnReset]] event.  It is received when the object that the script is attached to, or the cell that said object is in, is reset.  When this event is received, the script executes two of the functions we created earlier, SetDefaultState and DisableDoors.
Here we are seeing the code for an [[OnReset_-_Quest|OnReset]] event.  It is received when the object that the script is attached to, or the cell that said object is in, is reset.  When this event is received, the script executes two of the functions we created earlier, SetDefaultState and DisableDoors.


<source lang="Papyrus">Event OnLoad()
<source lang="Papyrus">Event OnLoad()
Line 186: Line 207:


The next event we are looking out for is the [[OnLoad_-_ObjectReference|OnLoad]] event.  It is received when the 3D model of the object that the script is attached to gets redrawn in by the graphics engine.  We tell it to do the same thing as the OnReset event.
The next event we are looking out for is the [[OnLoad_-_ObjectReference|OnLoad]] event.  It is received when the 3D model of the object that the script is attached to gets redrawn in by the graphics engine.  We tell it to do the same thing as the OnReset event.


<source lang="Papyrus">Auto State Inactive
<source lang="Papyrus">Auto State Inactive
Line 216: Line 238:
State Active
State Active
EndState</source>
EndState</source>


And now we have come to the final part of our script, the [[OnActivate_-_ObjectReference|OnActivate]] event.  This event is received when someone tries to activate our lever.
And now we have come to the final part of our script, the [[OnActivate_-_ObjectReference|OnActivate]] event.  This event is received when someone tries to activate our lever.
Line 236: Line 259:


tells the lever that it is now in the "Active" state as soon as we activate it.  That doesn't mean that the script will stop processing the rest of the code in the "Inactive" state, it just means that subsequent activations don't trigger the code.
tells the lever that it is now in the "Active" state as soon as we activate it.  That doesn't mean that the script will stop processing the rest of the code in the "Inactive" state, it just means that subsequent activations don't trigger the code.


<source lang="Papyrus">CloseDoors()
<source lang="Papyrus">CloseDoors()
if (LeverPosition != 0)
if (LeverPosition != 0)
SetDefaultState()</source>
SetDefaultState()</source>


If you've followed what's been going on so far, this should be easy.  We call the CloseDoors function to make sure all the doors have closed.  If the lever is not in the middle position, we change it to the middle position.
If you've followed what's been going on so far, this should be easy.  We call the CloseDoors function to make sure all the doors have closed.  If the lever is not in the middle position, we change it to the middle position.


<source lang="Papyrus">else
<source lang="Papyrus">else
Line 255: Line 281:
endif</source>
endif</source>


Otherwise, the lever must have been in the middle position.  This is where we check our LeverPositionOld variable to figure out what was the previous position.  Obviously, we don't want to go from right, to middle, back to right.  So if the old lever position was 1 (right), then we now go to the left position.  If the old position was -1 (left), we now go to the right position.
 
If the previous condition wasn't true, then the lever must have been in the middle position.  This is where we check our LeverPositionOld variable to figure out what was the previous position.  Obviously, we don't want to go from right, to middle, back to right.  So if the old lever position was 1 (right), then we now go to the left position.  If the old position was -1 (left), we now go to the right position.


Then we set the value of LeverPositionOld to 0, and call the OpenDoor function.  We didn't have these two lines after
Then we set the value of LeverPositionOld to 0, and call the OpenDoor function.  We didn't have these two lines after
Line 261: Line 288:
<source lang="Papyrus">if (LeverPosition != 0)</source>
<source lang="Papyrus">if (LeverPosition != 0)</source>


because they're already part of the SetDefaultState function. And our final bit of code
because they're already part of the SetDefaultState function.
 
Our final bit of code


<source lang="Papyrus">Utility.Wait(1)
<source lang="Papyrus">Utility.Wait(1)
Line 268: Line 297:
is telling our script to stop processing anything for 1 second (in order to let the animations play out) and then go back to the "Inactive" state (so that activating the lever again will do something).
is telling our script to stop processing anything for 1 second (in order to let the animations play out) and then go back to the "Inactive" state (so that activating the lever again will do something).


===Conclusion===
 
===Wrapping Up===


So put all that together, and your script should look something like this:
So put all that together, and your script should look something like this:


<source lang="Papyrus">Scriptname fg109TutorialLeverScript extends ObjectReference
<source lang="Papyrus">Scriptname fg109TutorialLeverScript extends ObjectReference
Line 400: Line 431:
State Active
State Active
EndState</source>
EndState</source>


So save your script and it should compile successfully.  Then you can try it out by putting down a lever somewhere, double-clicking it to edit it, and go to its right-most tab.  You should remove the two scripts that are already on it and replace them with the script you just wrote.  It should look like this:
So save your script and it should compile successfully.  Then you can try it out by putting down a lever somewhere, double-clicking it to edit it, and go to its right-most tab.  You should remove the two scripts that are already on it and replace them with the script you just wrote.  It should look like this:
Anonymous user