Multistate elevator
The intention of this article is to describe an EASY way of setting up a multistate elevator. This means an elevator that is able to stop on multiple floors. There are other ways to set this up and one is described in another wiki article (here), but as this method here is a bit easier, especially when it comes to coding, you may want to try this approach.
Requirements
Obviously you need an elevator. Use a model or create one using brushes and patches. If your done, make an entity func_mover out of it. A func_mover entity is one that is controlled via a script. This provides a much deeper possibility of controlling it.
The basic setup
Place the elevator where you want it to be upon map start. Also create some buttons you want for controlling the elevator. The last thing we need is a couple of path_corner entities. Place one at each location you want the elevator to be able to stop at.
Hint: The elevator will stop at the path_corner entities. This will happen so that the origin of the elevator will be at the center of the button of the cuboid representing the path_corner entity in the editor.
I may note that it is not really needed to use path_corner entities for the purpose her. If you like you may use something else.
Getting the elevator to work
The first thing you need to do is to let the elevator target the path_corner entities. Use "target0", "target1" and so one starting from the lowest path_corner upwards. Then give the buttons a spawnarg "moveDir" "N", where N represents the number of the path_corner you want the button to let the elevator move to.
Example: If you want the button to move the elevator to the path_corner that is targeted via the spawnarg "target1", N would be "1". So you would set "moveDir" "1" one the button.
The next step is to let EVERY button target the platform. Then add the spawnarg "state_change_callback" "movePlat" on EVERY button. The latter holds the name of the function to call when the button is used.
That's all you need to do in DarkRadiant.
The last step: a pinch of coding
The last step is to set up the script function that is called by the buttons. If not already done you have to create a file mymapname.script in your maps folder where mymapname.map is the map file your working with. Both files should be in the same directory. If you've gone the latter way you have to include the following lines:
void movePlat(entity button,boolean bOpen,boolean bLocked,boolean bInterrupted) { entity mover = button.getEntityKey("target"); entity target = mover.getEntityKey("target"+button.getKey("moveDir")); mover.moveTo(target); } void main() { }
The main routine is called upon map start. We don't need it here, but it has to be in the script file. The first routine is the one important for us. The function receives four arguments, of which only the first one is important to us. This is the button entity that called the script (the one you've pushed in game). The first step is to find out which elevator should be moved. As the elevator was targeted by all the buttons, the first line handles this for us. So mover is our elevator now.
Then we need to find out where our elevator should move to, what is handled by the second code line. There is also a method getTarget(n) that should be capable of doing the same thing as getEntityKey("target"+button.getKey("moveDir")), but I didn't tested it, so it's up to you if you want to use it (This information was provided by demagogue).
The last line of the function tells the mover (our platform) to move to the specific target.
Some last notes
As you can easely see one tiny function handles all the elevators in you map. This is a nice advantage in opposition to the method mentioned in the other wiki article(again, here), . But you may also notice that this setup does not support AI using them and I'm not sure it is possible to achieve this, as I didn't tested it. It is up to you to decide if you want to have this functionality.
Another thing is that movement speed can be controlled in to ways: the actual speed or the movement time. The latter would mean that the elevator needs the same time for two stages as for one, what is not suitable here. A simple way to setup the movement speed is to add the line mover.speed(V) at the beginning of the function, where V is the speed in Doom units per second. Another way is to set the spawnarg "translate_speed" "V" on the entity.
If you want to hear a sound while the elevator move add the spawnarg "snd_move" "someAwesomeMovementSound" on the elevator. Something that starts with machine may fit here.
Multistate includes two (obviously).