Introduction
This tutorial describes the process of making an elevator that can move between more than two floors. It is a platform elevator, not a normal enclosed elevator. To keep things as simple as possible, I didn't make it with
buttons that move with the elevator, although that could easily be incorporated as well.
There are two parts to this tutorial -
- The elevator construction - this is the easy part.
- The button "state checking" - this is the more complicated part. This is where you give your elevator "rules".
For this tutorial, the rules will be:
- The elevator "call" button can only be activated if the elevator is on another level.
- The elevator movement buttons can only be activated if the elevator is on the current level.
- If the elevator is between levels, none of the buttons can be activated.
Prepare for a bit of head spinning!
Setup - Elevator Construction
The construction of the elevator is the easy part. Below is a cut-away view showing the first stage of the construction.
The setup and configuration of a
func_train and its
path_corners is explained in the func_train entity description. Only the entity properties outlined below should be set.
func_train (elev1)
This is the elevator. It should be built in a location that will give it even lighting, as it will automatically move to the first stop target when the level loads, but it will retain its lighting from where it was originally built. By starting the elevator on the second level, I was able to give it even lighting without having to build it at a separate location.
- Name (targetname) - This elevator must be triggered each time it is moved, so you need to specify a name here. For the tutorial, I've used
elev1
. - First stop target (target) - Set this to the path_corner you want the train to start on. For this tutorial, I've set it to path_corner
p2
.
The above properties are the only essential ones. You might also want to modify the speed and sounds, as you see fit.
path_corner (p1, p2, and p3)
These are the path points the elevator will move to. The main difference between these and a normal set of path_corners is that these only have a Name, no "next stop target". This will be explained more below.
- Name (targetname) - the path_corners need a Name so they can be referred to by other entities. In the tutorial, starting at the lowest path_corner and working upward, I've named them
p1
, p2
, and p3
.
In addition to the Name setting, each path_corner must have its
Wait for retrigger flag checked. This causes the elevator to stop and wait at each level.
"Call" buttons
In the next step, we'll setup the "call" buttons. These will be used to call the elevator to your level if it isn't there. Useful, no?
Below is the same cut-away view as above with the "call" buttons and their associated entities. (They would, of course, be set on a wall).
func_button ("call" buttons, #1, #2, and #3)
These are the buttons that you'll press to call the elevator. They're setup is pretty straightforward.
- Targeted object (target) - Each "call" button targets a multi_manager. Starting from the lowest button and working upward, they target
mm_button1
, mm_button2
, and mm_button3
.
Each func_button should also have its
Don't Move flag checked. This is for esthetic reasons and avoids the delay of the button pressing.
multi_manager (mm_button1, mm_button2, and mm_button3)
These multi_managers coordinate the events that occur when the "call" button is pressed. The use of multi_managers is outlined in the multi_manager entity description.
- Name (targetname) - this is the name the func_buttons use to refer to the multi_managers. From the lowest and working upward, the multi_managers should be named mm_button1, mm_button2, and mm_button3.
to_l1, 0
or to_l2, 0
or to_l3, 0
- these are the Names of trigger_changetargets, and they are activated immediately when the multi_manager is activated. The lowest multi_manager will have the to_l1
key, the middle the to_l2
key, and the top the to_l3
key.elev1, 0.1
- this is the Name of the elevator, and it is activated 0.1 seconds after the multi_manager is activated (to give time for the trigger_changetargets to set the path of the elevator).
trigger_changetarget (to_l1, to_l2, and to_l3)
When activated, these set the target of the elevator to the level of the "call" button that was pressed. The use of the trigger_changetarget entity is outlined in the trigger_changetarget entity description.
- Name (targetname) - This is the name that will be refered to by the preceeding multi_managers. Starting at the bottom and working upward, they are named
to_l1
, to_l2
, and to_l3
. - Target (target) - The target of these will always be the elevator, so it should be set to
elev1
. - New Target (m_iszNewTarget) - This is the Name of the new path_corner that the elevator will target. Starting from the lowest trigger_changetarget and working upward, this value should be set to
p1
, p2
, and p3
.
Elevator Movement buttons
Now we'll add some buttons to move the elevator between the levels. Below is another picture of the same cut-away view. The buttons, multi_managers, and trigger_changetargets added in the previous step have been hidden to avoid a cluttered look.
func_button ("move" button #1, #2, #3, and #4)
These buttons act exactly like the "call" buttons, except that they cause the elevator to move up or down a level (depending on which button is pressed) and the player is generally assumed to be on the elevator when a button is pushed. Note that, whereas everything previous to this step involved multiples of 3, this has 4 buttons because the middle level has a button for both up (#2) and down (#3).
- Targeted object (target) - Each button targets a multi_manager.
- targets mm_l1_l2
- targets mm_l2_l3
- targets mm_l2_l1
- targets mm_l3_l2
Each func_button should also have its
Don't Move flag checked.
multi_manager
These multi_managers coordinate the events that occur when the "move" button is pressed. The use of multi_managers is outlined in the multi_manager entity description.
- Name (targetname) - this is the name the func_buttons use to refer to the multi_managers. From #1 to #4, the multi_managers should be named
mm_l1_l21
, mm_l2_l3
, mm_l2_l1
, and mm_l3_l2
l1_l2, 0
or l2_l3, 0
or l2_l1, 0
or l3_l2, 0
- these are the Names of trigger_changetargets, and they are activated immediately when the multi_manager is activated. They are listed in order from #1 to #4.elev1, 0.1
- this is the Name of the elevator, and it is activated 0.1 seconds after the multi_manager is activated (to give time for the trigger_changetargets to set the path of the elevator).
trigger_changetarget (l1_l2, l2_l3, l2_l1, and l3_l2)
When activated, these set the target of the elevator to the appropriate level depending on which "move" button was pressed. The use of the trigger_changetarget entity is outlined in the trigger_changetarget entity description.
- Name (targetname) - This is the name that will be refered to by the preceeding multi_managers. From #1 to #4, they are named
l1_l2
, l2_l3
, l2_l1
, and l3_l2
. - Target (target) - The target of these will always be the elevator, so it should be set to elev1.
- New Target (m_iszNewTarget) - This is the Name of the new path_corner that the elevator will target. Going from #1 to #4, the value of this should be set to
p2
, p3
, p1
, and p2
.
Stretch!
Ok, that's that part. That was the easy part?! Well, not really. It's a little head spinning, no? That is the straightforward part though. You'll have something that looks similar to the picture below (again, this is a cut-away... you should have walls and stuff too.
You might note that the colors of the entities are different. This is because i've turned them into VisGroups so I could easily hide them.
You can now run and test your level. The buttons should all work - if you press a "call" button, the elevator will move to the appropriate level. If you press a "move" button, the elevator will take you to the appropriate level. But wait, if you press a "move" button when the elevator is not at your level, the elevator will move as if it was. This just isn't right!
In the next section, we'll setup the state-checking entities that will prevent this.
Setup - Button State Checking
In this section, we're going to impose a few rules on the use of the buttons.
- The elevator "call" button can only be activated if the elevator is on another level.
- The elevator movement buttons can only be activated if the elevator is on the current level.
- If the elevator is between levels, none of the buttons can be activated.
Below is a cut-away picture showing all of the entities that you'll be placing/modifying/using for setting up the first level's state checking.
Is your head spinning?
Keepers of the State
Ok, we'll start with the group of 7 entities that are responsible for tracking the state of the elevator and controlling what buttons are active when. Only 6 of the entities are used to keep track of the states. The sixth, the
all_off
multi_manager, is there for ease of use only. Activating it will turn all of the buttons off.
multi_manager (all_off)
This entity isn't entirely necessary, but it simplifies things greatly.
As mentioned above, activating this turns off all of the "call" and "move" buttons.
- Name (targetname) - Set this to all_off.
eg_call1_off, 0
- turns off the level 1 call button multisource (by way of an env_global)eg_call2_off, 0
- turns off the level 2 call button multisourceeg_call3_off, 0
- turns off the level 3 call button multisourceeg_elev1_off, 0
- turns off the level 1 move button multisourceeg_elev2_off, 0
- turns off the level 2 move buttons multisourceeg_elev3_off, 0
- turns off the level 3 move button multisource
Yes, yes, I know - none of the above entities (
eg_call*_off
,
eg_elev*_off
) have been defined yet. Patience, grasshopper.
multisource (ms_call1)
This is the multisource master for the level 1 "call" button. When it is "off", the button will be disabled.
- Name (targetname) - set this to
ms_call1
. - Global State Master (globalstate) - set this to
call1state
. This is the global state that is defined by the env_global entities, below. The state of call1state
(on or off) determines the state of the multisource.
Now that you've created this multisource, select the level 1 "call" button, and in its properties, set its
Master (
master) property to
ms_call1
.
env_global (eg_call1_on)
Activating this entity will set the
call1state
global state to "on", enabling the
ms_call1
multisource.
- Name (targetname) - set this to
eg_call1_on
. - Global State to Set (globalstate) - set this to
call1state
. - Trigger Mode (triggermode) - set this to
On (1)
. - Initial State (initialstate) - set this to
On (1)
.
The
Set Initial State flag should also be set. Now, when the level starts, this will immediately set the state of
call1state
global to "on". Each time this entity is triggered afterward, it will always set the state of
call1state
to on.
env_global (eg_call1_off)
Activating this entity will set the
call1state
global state to "off", disabling the
ms_call1
multisource.
- Name (targetname) - set this to
eg_call1_off
. - Global State to Set (globalstate) - set this to
call1state
. - Trigger Mode (triggermode) - set this to
Off (0)
. - Initial State (initialstate) - set this to
Off (0)
.
Do not check the
Set Initial State flag for this entity. Each time this entity is triggered, it will set the state of
call1state
to off.
multisource (ms_elev1)
This is the multisource master for the level 1 "move" button. When it is "off", the button will be disabled.
- Name (targetname) - set this to
ms_elev1
. - Global State Master (globalstate) - set this to
elev1state
. This is the global state that is defined by the env_global entities, below. The state of elev1state
(on or off) determines the state of the multisource.
Now that you've created this multisource, select the level 1 "move" button, and in its properties, set its
Master (
master) proper