Note: This is an old page that has been updated/formatted, you can view the original here.
Rotating Doors: 2nd Edition
Author: Heinz Högel
This is the second edition of the Rotating Doors Tutorial, Part I. It was revised to support MotS levels too and contains some improved control scripts.
Without doors every level would be extremely boring. They add a good amount of uncertainty to a Jedi Knight's playground (who knows what is waiting behind them). But their appearance lacks a specific element of realism: they're always sliding up or aside and don't swing open like real-life doors. Well, in a high-tech environment like a spaceship or a station that makes sense, it's just the appropriate design for the Star Wars universe. But what about normal houses and low-tech areas? Ask an engineer or a carpenter how easy a swinging door is to be made compared with those sliding closings. No need for hollow spaces behind the walls, just a plain opening with a door in it.
If you look around in the original JK levels you won't find any exemplars of these real-life type doors. At first glance the reason for it seems to be: the JK engine can only move things along a linear path without changing it's orientation. But wait, there are definitely a lot of rotating things (ships, actors, fans etc.) — so how is that done? The answer depends on the type of thing. I.e. a fan has a rotational velocity (and according flags) given to it in it's template and it rotates constantly (stopping a fan by damaging it is done by replacing the rotating fan with a static one). An actor or ship is animated by so-called keyframes (.KEY files), that are much to difficult to make for most of us amateur level designers (at least until a 3DO editor appears with animating features for KEY files).
However, there are rare examples of rotating doors in the original game:
level 9 (the ramps opening to Fuel Station's big pipes area, the giant
semicircle doors in the pipe area itself and some concave doors in the
inner pipe walls) and 10 (the large cargo doors in the ship's exterior
area). Investigating more deeply into these levels you will find the cog
scripts used to control these special doors: 09_tilting_floor.cog*,
**09_pipedoorxx.cog (xx* stands for variations) and
10_cargodoors.cog. Besides the level specific extra code these
scripts are very similar to normal door scripts. Their "secret" is the
use of the function RotatePivot() instead of the usual
MoveToFrame(). Because this function isn't documented in the Jedi
Knight Unofficial Specs (version 0.3) yet, I did this little tutorial
to give you an idea on how to use it for swinging doors.
Swinging doors in JK Basic levels
What I have in mind is a double wing door swinging open to both sides of the door frame. I assume that you're pretty experienced in making standard doors, so I will only discuss steps in detail that are different or new for rotating doors. The following descriptions will work for JK Basic levels only - rotating doors in MotS levels need special care, so there is an extra section for them at the and of this tutorial (but please read on, 'cause I won't repeat all the basics).
First, we need a room with an adjoined corridor. The corridor should be twice as wide as a single door wing and exactly as high. Also, you can cleave a sector at the entrance to the corridor that is as deep as the door wings are (this is not a must with the cog script I will present later). And of course the corridor can be a very small sector just to connect two separate rooms.
Next, we insert the door wings themselves into the beginning of the
corridor. I used 3x3door_2a and 3x3door_2b for this example
(each wing: height 3 m, width 1.5 m, depth 0.25 m).
As usual with normal doors each door thing needs four additional entries in the thing editor: THINGFLAGS (0x400448), NUMFRAMES (2) and two FRAME entries. The value of the first frame should be the position of the door itself (simply click on the "Copy as Frame" button and paste it (Ctrl+V) as the value of the first FRAME entry.
The second frame makes the difference: It's not a positional frame like those used with normal doors (that is: it's not the end position of the door). Instead it's something the JK programmers call a "rotational axis frame" (according to some rare comments in JK cog scripts). The X, Y and Z values of such a frame define a center point (pivot) around which the door (or other thing) shall rotate. The values of PCH, YAW and ROL define the amount (angle) and direction of rotation.
You can define the second frame this way: Insert temporarily a (ghost)
thing and move it to the position of a (nonexistent) hinge of the door.
The Z coordinate doesn't matter here, so you can do this all in top
view. Then copy the coordinates of that auxiliary thing to the second
frame of the door (again with the the "Copy as Frame" button and
Ctrl+V). Set the PCH and ROL parts of that frame (first and third value
behind the colon) to 0.00000, if they aren't already. Insert as YAW
value (second part behind the colon) the opening angle (that is: how far
the door will swing open) - angles between 90.00000 and 180.00000
degrees would be appropriate for a realistic door (depends on the
architectural details around that door). In top view a positive angle
goes counter-clockwise. Of course, for a two wing door you have to go
through that procedure twice.
Finally you have to link a control cog script to the doors. Unfortunately you can't use one of the predefined scripts from the game, because there is no standard script for swinging doors like 00_door.cog for sliding doors. Therefore I present kind of a standard script for our purpose here. It's not as sophisticated as the JK scripts tend to be (no special treatment of the door sector for example) but basically it's doing the job it was crafted for: h0_swingdoors5.cog.
Place it in your level directory and add it to the placed cogs list. Six
parameters have to be filled in:
|Door1, Door2||The thing numbers of the two door wings.|
|Switch0||The surface ID of a switch I added to a wall near the doors. By activating this switch you can open or close the doors. The switch is displayed in activated state as long as the doors are moving.|
|Switch1||Same function as Switch0. Not used in this example, therefore set to —1.|
|Time||This time (in seconds) determines the duration of open/close actions.|
|AutoCloseDelay||Normally you have to activate one of the switches once more to close the doors again after they were opened. Setting AutoCloseDelay to a positive value causes the doors to be closed automatically after the specified time (in seconds).|
|TouchOpening||You can also open/close the doors by "touching" them (hitting the spacebar), if this parameter is set to 1. To disable this feature just set it to 0.|
That's all, folks! Save the level and start it in JK. Activate the
switch or just "touch" the doors and voilá — they swing open.
Heard the noise? It comes from the same source as with normal doors, and that is the SND file specified in the template of the doors. In this particular case it's med_door.snd linked to the 3x3door_2a thing:
# Foley description for medium doors startmove df_door2-1.wav 0x0 0.1 1.0 stopmove df_door2-3.wav 0x0 0.1 1.0 moving df_door2-2.wav 0x0001 0.1 1.0 0.5
The flag value 0x0001 in the "moving" action class causes the sound to be repeated until the move stops. If you would like to hear different sounds or even none of them at all, you can add a template to the JED master list, based on the door you've chosen and overloading the soundclass adjective with the name of a self supplied SND file that contains the sounds you want. Done in this way you can use a SND file without the action classes startmove, stopmove and moving to make your door silent. Also notice that, in our little example, only the 3x3door_2a thing has a SND file associated. The second door wing is "silent by nature" — otherwise every sound would be played twice!
One more annotation: Rotating doors (or similar things) ignore the
sector geometry around them. Therefore you don't have to worry about
little edges or ledges hindering the door from moving along the planned
path. But look out for other things with move class "physics" (i.e.
actors of all kind, displaceable crates, debris etc.) - they will block
the rotation! Doors with vertical rotation axes will push away such
obstacles in many cases, however there is no guarantee for that!
You find the described door example as a (very small) demonstration level here (containing both JK and MotS versions): rotdoor1.zip
The technical aspect
For those of you who want to take advantage of the RotatePivot()
function in their own cog scripts, here is the formal syntax of that
verb (in JK, not in MotS) in the Jedi Knight Unofficial Specs
Rotates the thing specified by RotThing in a time (in seconds) given in RotTime. The center of rotation is specified by the X/Y/Z part of the frame with number RotFrame of the thing. The PCH/YAW/ROL part of that frame defines direction and angle of rotation. A negative value in RotTime inverses the direction of rotation.
Use: RotatePivot(thing RotThing, int RotFrame, flex RotTime);
The MotS Disaster (and a solution for it)
Soon after the first edition of this tutorial was published, I received some alarming feedback from JK designers who tried to implement swinging doors in their new MotS levels: It simply didn't work! My naive thinking that all cog verbs in MotS would function the same way than in JK prevented me from testing it - directly leading to that disaster. So here are the facts on the irritating behavior of RotatePivot() in MotS:
First it sets the thing (that is: it's center) to the position given in RotFrame (similar to the function JumpToFrame()), ignoring the PCH/YAW/ROL part of RotFrame and setting the orientation simply to 0/0/0. Then it rotates the relocated thing around it's center by the angle(s) given in the PCH/YAW/ROL part of RotFrame. This behavior doesn't seem to fullfill any practical purpose (the verb isn't used in any MotS level!). It's most probably an ordinary program bug (blame LEC for that).
But in spite of that faulty RotatePivot() function there is a way to build rotating doors in MotS. However, you have to take an approach a little different to the one described above. First of all, the hinge thing is no longer only an auxiliary object for calculating the door frames. Every door needs a separate hinge thing (but still a ghost) permanently located at the actual hinge position. Like the doors in JK Basic the hinge needs certain attributes: THINGFLAGS (0x400448), NUMFRAMES (2) and two FRAMEs. The first frame must be set to the initial position of the hinge (PCH/YAW/ROL all zero!!!). The second one alike, but with YAW set to the opening angle of the door. The door itself needs only one FRAME set to the start position of it.
Prepared this way you can use the cog script h0_swingdoors4.cog similar to the one for JK Basic levels. Of course, to make this possible, there is a rather complicated workaround for the RotatePivot() fault in the code: It attaches the door to the hinge (this is done first in the startup section), rotates the hinge (swinging the door with it in the correct way), detaches the two things, sets the hinge thing back to its initial orientation and reattaches door and hinge for the next rotation.
So the hinge rotates and not the door itself. Remember what I wrote about the sounds of the doors? Well, to make the swinging doors in MotS sound like their sisters in JK another trick is needed: You have to provide new ghost type things with associated SND files (taken from typical door things) and use one of them for a hinge. Simply add the following lines to the MOTS.TPL file in the JEDDATA folder:
# DESC: # BBOX: 0 0 0 0 0 0 ghost_hinge_sm none orient=(0/0/0) type=ghost move=path soundclass=sm_door.snd # DESC: # BBOX: 0 0 0 0 0 0 ghost_hinge_med none orient=(0/0/0) type=ghost move=path soundclass=med_door.snd # DESC: # BBOX: 0 0 0 0 0 0 ghost_hinge_lg none orient=(0/0/0) type=ghost move=path soundclass=lg_door.snd
The very indirect way to rotate doors in MotS produces another little
disadvantage: If you (the walkplayer) are pushing a door while it's in
the process of opening, you can dislocate it a little (try it)! As a
small solution to that problem the script relocates each door to its
initial location after it's closed again (that's why the frame for the
door itself is needed). Maybe one of the readers of this tutorial will
find a better solution - let the Massassi Temple know!
Part II of the Rotating Doors Tutorial (if ever published) will feature some "iris doors", build of wedge style segments (6 or 8), which are opened by rotating them back into the wall.