Elevators, multi-floor: Difference between revisions
No edit summary |
|||
Line 1: | Line 1: | ||
= Two stage elevator using sliding door entity = | = Two stage elevator using sliding door entity = | ||
A quick and simple way to make a two-floor elevator is just to use the sliding door entity. This is now superseded by a custom Dark Mod elevator entity but for interest, see for details. | A quick and simple way to make a two-floor elevator is just to use the sliding door entity. This is now superseded by a custom Dark Mod elevator entity but for interest, see A_-_Z_Beginner_Full_Guide_Page_5#Elevators for details. | ||
= Multi stage elevator using custom Dark Mod entities = | = Multi stage elevator using custom Dark Mod entities = |
Revision as of 18:48, 22 April 2008
Two stage elevator using sliding door entity
A quick and simple way to make a two-floor elevator is just to use the sliding door entity. This is now superseded by a custom Dark Mod elevator entity but for interest, see A_-_Z_Beginner_Full_Guide_Page_5#Elevators for details.
Multi stage elevator using custom Dark Mod entities
written by Fidcal
Three stage elevator using a script
Originally written by Dram on http://forums.thedarkmod.com/topic/3865 Ok, assumed knowledge is:
- how to make a platform move
- how to make it triggered by buttons
- how to do basic scripting
These are covered in the how to make a platform move tutorial, so do that one first and everything here will be simpler to understand.
This elevator basically is like the ones in thief, in that you press a button to go up or down rather then a button to select which floor to go to.
Start
Ok, to start, make 3 floors, each with a panel that has buttons, and the elevator itself. The bottom floor needs one button, the middle floor needs two, and the top needs one. Make all the buttons into func_darkmod_button. For the bottom floor button we have these attributes:
Those attributes are for the bottom button. For the other buttons the only difference is what script function it calls vie the "state_change_callback" attribute. The following pic shows the name of each script function in relation to the buttons. Remember that these script function names can be changed to whatever you wish.
Names of script functions relative to buttons
Also make sure your elevator is at the bottom level. For this purpose anyway. Once you understand how the scripts work you'll be able to change where it starts yourself. Now change the elevator into a func_mover, if you have'nt already.
These are the settings on the elevator in this tute:
To explain the settings:
- name elevator - Name of the entity. Can be whatever you want, just remember the name.
- accel_time 0.4 - Time it takes to accelerate to full speed. ).4 seconds for this one to tune in with the sound.
- decel_time 0.4 - As above except for deceleration.
- move_speed 30 - The speed at which the elevator travels in Doom units/second. Make sure you calculate how long it takes to get to each floor otherwise pressing the button when it has'nt completed it's movement will restart it and cause problems. Basically calculate it for the delay that will be mentioned later on.
- dmg 1000 - Does 1000 damage to anything that obstructs it - DON'T STAND UNDER IT MWAHAHAHA.
- snd_move test_elevator_loop - The sound to make while moving. Put your own sound here. The sound has to be a looping sound otherwise it'll play only once.
- snd_accel test_elevator_stop - The sound to make when accelerating. Does not need to loop.
- snd_decel test_elevator_stop - As above but for deceleration.
The Script
Now to make the script for it. Remember that you can have many script functions in one map script, just they all have to be unique.
Paste the following code into your map script:
float elevator_moving = 0; float elevator_state = 0; // 0 is bottom, 1 is middle, 2 is top void main() { } // The Elevator void elevator_bottom(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 248 ); sys.wait(9); elevator_state = 0; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 472 ); sys.wait(19); elevator_state = 0; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 248 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } } } } void elevator_middle_a(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 248 ); sys.wait(9); elevator_state = 0; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 224 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 248 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } } } } void elevator_middle_b(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 224 ); sys.wait(9); elevator_state = 2; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 224 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 248 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } } } } void elevator_top(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 224 ); sys.wait(9); elevator_state = 2; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 224 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 472 ); sys.wait(19); elevator_state = 2; elevator_moving = 0; } } } }
Notice that there are four functions - elevator_top, elevator_middle_a, elevator_middle_b, and elevator_bottom.
These are the functions called on by the state_change_callback mentioned earlier.
Now to look at the code in a bit more detail. Things in bold are comments to help you understand wtf it is.
The Code
float elevator_moving = 0; // this variable is at 0 if the elevator is NOT moving float elevator_state = 0; // 0 is bottom, 1 is middle, 2 is top //this variable is used to show which floor the elevator is currently on
void main() as mentioned in the platform tute, this has to be in a map script, but does'nt need to do anything { }
The Elevator
Bottom Floor Button.
When the elevator is on this floor and you press this button, the elevator goes up one floor
void elevator_bottom(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) // do the following if the button is open (pressed) { door.Close(1); // close the button (push it back out). This makes it act like a button if (elevator_moving == 0) // if the elevator is NOT moving" { if (elevator_state == 1) // if the variable is on 1 then the elevator is on the middle floor (0 is bottom floor) { elevator_moving = 1; // set this variable to 1 so that the code knows that the elevator is moving and not to restart the sequence sys.wait(2); // 2 second delay before movement to give the user time to get on the elevator $elevator.move ( DOWN, 248 ); // where it says elevator in $elevator.move is the name of your elevator entity.
So if yours is called func_mover_1 then put that in there instead of elevator. As for the movement, this was described in the platform tute, but to summarise, the DOWN is the direction to move, and the 248 is the distance to move in Doom Units. The platform tute explains how to find this distance etc.
sys.wait(9);
this delay is here because for this particular elevator it takes 9 seconds to move from the middle floor to the bottom floor. Set this to how long your one takes to reach the bottom floor.
elevator_state = 0; // after the elevator reaches the bottom floor set this variable to reflect that elevator_moving = 0; // our elevator has stopped moving, so set this variable to reflect that } else if (elevator_state == 2) // if the variable is on 2 then the elevator is on the top floor
I think you can figure the rest out for yourself from here. It's all the same pretty much except the variables change for each floor and the distance to move does too
{ elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 472 ); // distance to move from top floor to bottom floor sys.wait(19); // the time it takes for the elevator to reach the bottom floor from the top floor elevator_state = 0; elevator_moving = 0; } else if (elevator_state == 0) // if the variable is on 0 then the elevator is on the bottom floor" { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 248 );
we're at the bottom floor so make the elevator go up one floor instead of further down. The distance here is from bottom floor to middle floor
sys.wait(9); // time it takes to get from bottom to middle floor elevator_state = 1; elevator_moving = 0; } } } }
The rest of these functions are like the above one, except they're relevant to each floor
Middle Floor Button
The bottom one in this case. When the elevator is on this floor and you press this button, the elevator goes down one floor
void elevator_middle_a(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 248 ); sys.wait(9); elevator_state = 0; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 224 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 248 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } } } }
Middle Floor Button. The top one in this case.
When the elevator is on this floor and you press this button, the elevator goes up one floor. Note that the code is very similar to the other button on this floor, except that this one makes the elevator go up rather then down, hence the need for two buttons on the middle floor
void elevator_middle_b(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 224 ); sys.wait(9); elevator_state = 2; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 224 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 248 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } } } }
Top Floor Button
When the elevator is on this floor and you press this button, the elevator goes down one floor
void elevator_top(entity door, boolean bOpen, boolean bLocked, boolean bInterrupted) { if(bOpen) { door.Close(1); if (elevator_moving == 0) { if (elevator_state == 1) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 224 ); sys.wait(9); elevator_state = 2; elevator_moving = 0; } else if (elevator_state == 2) { elevator_moving = 1; sys.wait(2); $elevator.move ( DOWN, 224 ); sys.wait(9); elevator_state = 1; elevator_moving = 0; } else if (elevator_state == 0) { elevator_moving = 1; sys.wait(2); $elevator.move ( UP, 472 ); sys.wait(19); elevator_state = 2; elevator_moving = 0; } } } }
If you've done the platform tute then you'll understand that code a bit better, so you should be able to tell what to change and where.
That covers elevators. If you understand this code now then you'll see where you need to add what sop that you can have an elevator that goes to multiple floors, not just three. Basically you'd need to add more functions. 2 functions per floor except the top and bottom floor, which have one.