Atan wrote most of this tutorial in response to a question by Nightmare, find the thread here:
Descent Forum Topic: script help, in the English Embassy section.
Thanks Atan, and Nightmare, for shedding some light on this subject!
Note: If you haven't used Quicktest you may want to read Setting up D3 Edit and Quicktest first. If you do not have DALLAS up and running, read Papacat's 'Get DALLAS Working' Tutorial. You might also want to read this thread on Planet Descent, 'DALLAS still won't compile'.
Make a simple test level, two small rooms separated by a door. Insert a switch anywhere, in the first room, the one with the player start in it. One of type 'Handleswitch' would be best. Name it 'MySwitch'. Verify your level, name it "switchtest" (note: if you already have a level with this name, select another name) and save it. Test fly your level and look for your Handleswitch. Shooting it will do nothing; this is just to see if your level is ok. Make sure the door works, too. Load your level into the editor, select worldview. Start Dallas.
Once you have DALLAS open, make a script as follows:
Press 'Save'
Dallas will work until 'done' and produce a file named: switchtest.dll and switchtest.msg (if you named your level switchtest)(Osiris Folder, in the SDK folder.) if all went well.
If you don't see them: Did you set your path? Follow DOS rules for the path. If the path is too long, it won't work, or you may just need to make system files visible in windows.
Open Quicktest and insert the two files into your hog now. Save your level. Start the level and fly against the switch now or shoot it. You should hear the sound. This must work before we proceed! Next we'll animate the switch. We will proceed with a few steps now, but I strongly suggest that you test-fly each step. Working? Good! Let's go!
Now we will animate the switch by collide:
Don't forget to save the script. Use Quicktest to test fly, no need to reinsert your new dll, Quicktest will do that for you.
A hit will produce switch movement and sound. Don't forget to save the script first. Note: The animation 'speed' in: 'Play object Sound animation from frame 0 to 20, cycle time = 1.00, looping=FALSE' is set by the 'cycle time' it is set to 1.00 here, just increase to, for instance, 5.0 and see how it looks.
Save, then test fly.
Open Dallas, generate a new message, and name it: ShowHitText. Write "Switch is Activated!" into the window below ChangeNameID.
Now when you test fly your level, you should hear a sound and see the switch move when you shoot the switch. You should also see the HUD message; "Switch is Activated!".
Now our switch has a purpose!
Please remove the 'Auto close' Flag for this door in D3Edit (DoorwayBar) if it is set.
See the difference between the last two examples? First should Open/Close the door, second should open it only.
How can we prevent opening the door by direct hit, so that the switch can open it only? Any ideas? Hint: we must do something at Event Levelstart.
Activate should Open the door which closes automatically if the Flag 'AutoClose' in DoorwayBar is set for this door. (note: do not use a blastable door here.) Set position to 100% means that the door should open only. Flag 'AutoClose' must be cleared for this; otherwise it will close again without a new event.
OK, we must first test fly to see if this will work for you now, if not compare your script to above and make adjustments as needed.
At Levelstart we can set the Door behavior, so please remove the 'Lock' flag in the Doorway bar.
This should lock the door for you by script. Test it out. Try to open the door without hitting the switch. It should be locked. Hit the switch. In addition to sound, movement and the HUD message, the door will open all the way and stay there. If not, find and fix the problem before proceeding.
Now we will close the door by a timer event. Open Dallas, -> Open the user type workshop -> Timer Id -> Add a new value, name it 'CloseDoor'.
Ok, this script will look for the level timer event CloseDoor and then set the door animation to 0.0 (Close the door). But before it will work, what must we do? Right, we must start a level timer first.
To start the timer, we will change our well-known Script000 like this:
Try it out, it should work. The door opens and after a 10-sec delay it will close again. Does this work for you?
So, what about multiple hitting the switch with i.e. vauss, laser? Could this be dangerous for our idea? Hmm, what idea? Ok, goal is upon shooting the switch; it should open only one time, and close again. Next hits should not open the door again; you had your chance to reach a goody. (or perhaps get trapped in the second room;). Any idea how to accomplish that? Now this time we will try that using two different methods. Is that timer working for you now as described? If so, we can go ahead to the 'limit an action'.
Easy way first. Right click on:
This will do what we need. Where should we insert this? Remember that the goal was to open the door one time only.
Second method, with a little more output this time, look carefully!
Important: Remove the line 'Select max times' by changing it back to 'Run Infinitely'
Generate a new message with the following text:
Name this message: 'TellMe'. Use the UserTypeWorkshop to generate a new UserVar, name it: 'Count'. Add a line in Level Start Script: Set user var count to 5.0. Now Script 001 looks like this:
Changes in Script000:
Ok, this is a little complicated, so I'll try to tell you what should happen: At level start we preset a variable with 5. If we hit the switch the script looks if it is a player weapon and if our variable is >0. If this conditions are ok, the script starts our known actions and decrement the variable (now 4), then shows the text '4 chances left' ( %d is like a placeholder. %f would show floating point value) This is a great way to show count actions in D3! If our variable reaches 0 the script will show '0 chances left' but each following hit will be ignored by this script now. (because the condition is not true...)
Try it out until it works for you like described. Be careful to hit the switch only once to trigger it, i.e. use a flare. Then try out what will happen if you shoot the switch rapidly with your lasers. What trouble occurs in this case? How can we fix this?
![]()
Well, that was the end of the thread. But we are left with a question. When we test fly, if we shoot with one flare at a time, our script works perfectly. But if we shoot with lasers, we use up all our chances in a quick burst of laser fire. The HUD message reports 0 chances and after 10 seconds, the door is locked. Why does it do this? Lets look at our script for the answer.
In Script000, we perform a couple of checks, then proceed with a list of tasks. The script starts and runs every time a collision with a player weapon occurs, until 'Count' reaches 0. So if we shoot quickly, the script will run five times in rapid succession. Thus, our cache of chances is quickly depleted. Is that the desired effect? Not likely! We have a little more work to do. Let's refine our goal: The door will stay open for ten seconds per chance. In Script000 we can check that the door is closed before we allow the script to run. Under 'If the following condition is met:' right click on 'AND' and add a new condition, to check that the position of the door is 0% (closed).
Now, test fly. We can see that we hit the switch once the door will open. If the door is open, shooting the switch will do nothing. But if you hit the switch with both lasers at the same time, the script will run twice before the door opens. So we lose one of our chances. The script is running in two instances, so close in time that before the first instance starts to open the door, the second one is past the point where it checks to see if the door has started to open. So we need to set a condition in the first instance that will block execution of the second. Let's add a user flag. Go to the user types workshop and create a user flag called 'flagit'. In Script001, add the condition (User Flag flagit) = (FALSE). Now script 000 will not run unless 'flagit' is false. This new line should be last under AND. Now add a new action under 'Then perform...', still in script000. Can you guess what this action is? We need to make flagit TRUE here: 'Set user flag flagit to TRUE'. Drag it to the top of
the list.
Next go to Script002 and add, under 'Then perform...' a new action: 'Set user flag flagit to FALSE'. Also, I moved the lines 'Decrement user var Count' and 'Show HUD message TellMe' to Script002. And I added the action 'Show Timer CloseDoor on HUD' to Script000. So now Script000 looks like this:
Script001 hasn't changed from above, but here it is anyway:
And Script002:
Check your scripts carefully!
Test fly. Our script works perfectly this time. 'Show Timer' shows us the time until the door closes... we would not want to get trapped in the second room. I will leave it up to you to provide a reason why!
However, if DALLAS is working but you are still having trouble with your scripts, please go through the steps above one more time. Any variations could produce unexpected results. After you get it working, then you can go back in DALLAS and have some fun with this.
I suggest this should be a last resort only, as you will not learn by copying a script. But if you cannot get this to work by any other means, here's a screenshot of the script:

Comments? Click here to discuss issues related to this tutorial.