Doors: Difference between revisions
Springheel (talk | contribs) |
|||
(66 intermediate revisions by 8 users not shown) | |||
Line 25: | Line 25: | ||
Additionally: | Additionally: | ||
* Up, down, | * Up, down, right, and left in Dark Radiant's ''top'' orthoview are regarded here as the standard map directions of North, South, East, and West where useful for clarity. | ||
* Where the term ''brush'' is used with a door it mostly also applies to a door made up of a group of brushes and/or patches. | * Where the term ''brush'' is used with a door it mostly also applies to a door made up of a group of brushes and/or patches. | ||
* Where the term ''door'' is used it often will also apply to any object you wish to rotate when frobbed, for instance an openable window, box lid, or even more exotic objects that the imaginative mapper might conceive like a signal, engine part, toy, or whatever. So long as it needs to turn or slide just a fixed amount when frobbed then return when frobbed again then the following applies. | * Where the term ''door'' is used it often will also apply to any object you wish to rotate when frobbed, for instance an openable window, box lid, or even more exotic objects that the imaginative mapper might conceive like a signal, engine part, toy, or whatever. So long as it needs to turn or slide just a fixed amount when frobbed then return when frobbed again then the following applies. | ||
Line 40: | Line 40: | ||
*Entity List: most of the door models can be found here. These doors have properties already assigned so they are ready to be used. Only one base door of each type is listed, create the size/hinge count door you want (2 hinge doors have a 'no hinge' skin). You can choose a skin for the door once it has been created in the editor with the "skin" spawnarg (use the model name of the door you want, taken from the model list, as its value). This is the easiest way to create a door. The same goes for door handles. | *Entity List: most of the door models can be found here. These doors have properties already assigned so they are ready to be used. Only one base door of each type is listed, create the size/hinge count door you want (2 hinge doors have a 'no hinge' skin). You can choose a skin for the door once it has been created in the editor with the "skin" spawnarg (use the model name of the door you want, taken from the model list, as its value). This is the easiest way to create a door. The same goes for door handles. | ||
Remember also that door functions may be applied to objects other than doors | Remember also that door functions may be applied to objects other than doors, such as openable windows, drawbridges, gates, etc. In fact, anything that needs a partial rotation or slide when frobbed then return when frobbed again, such as a signal device. Lockboxes and chests use similar properties. | ||
You can create one door/handle set and copy/paste it, but you need to take great care that all the name props are changed to match in each clone. Otherwise you get handles that fly off when a distant door moves, and handles that don't move. | |||
==Creating a Door== | ==Creating a Door== | ||
Line 100: | Line 100: | ||
* Give it a door texture from the texture browser (or wall texture for a secret door) | * Give it a door texture from the texture browser (or wall texture for a secret door) | ||
* Right click in orthoview and select ''Create Entity'' then <code>atdm:mover_door</code> | * Right click in orthoview and select ''Create Entity'' then <code>atdm:mover_door</code> | ||
To move the rotation point to the door | You now have a working door but it will rotate around its center. To move the rotation point to where you want the door hinges to be: | ||
* Select the door and press 'v' or the ''Select Vertices'' button to enter vertex editing mode. The door's origin will show up as a small green square in the middle of the brush. | |||
* In top-down orthoview, move the origin from the center to the corner of the brush. This is easiest in drag mode ('q' or the ''Resize'' button), although you can use translate mode ('w' or the ''Translate'' button) by manually selecting the vertex first. | |||
==== Multi-brush doors: ==== | ==== Multi-brush doors: ==== | ||
Line 125: | Line 126: | ||
===Door handles and other door attachments=== | ===Door handles and other door attachments=== | ||
'''Summary: just add the property ''bind'' with the door's name to the attachment and position it where you want it on the door. If it's a ''atdm:mover_door_handle'' then it automatically will work as a handle but you can bind virtually anything.''' | |||
You can add handles and other items to doors such that they move correctly with the door whether rotating, sliding, or both and even if the door is not vertical such as a skylight or trapdoor. | You can add handles and other items to doors such that they move correctly with the door whether rotating, sliding, or both and even if the door is not vertical such as a skylight or trapdoor. | ||
Handle models come in two types, ''single handles'' and ''double handles''. A single handle is one sided, this means the handle will be inside the door or outside the door, but not both. A double handle has a lever on the inside of the door and a handle on the outside of the door. Each has benefits. | Handle models come in two types, ''single handles'' and ''double handles''. A single handle is one sided, this means the handle will be inside the door or outside the door, but not both. A double handle has a lever on the inside of the door and a handle on the outside of the door. Each has benefits. | ||
*'''''Single door handles''''': | *'''''Single door handles''''': | ||
Single door handles can be used on a static door, a door that's just for show that no AI's or the player can use. In this case you should just create a door handle from the model viewer, it will be static and have no properties such as scripts. It is for looks only. | Single door handles can be used on a static door, a door that's just for show that no AI's or the player can use. In this case you should just create a door handle from the model viewer, it will be static and have no properties such as scripts. It is for looks only. Note that TDM is trying to establish the expectation that decorative doors that cannot be opened do not have handles (though not all maps follow this). | ||
I will call this ''multiple handles'', see more below. | I will call this ''multiple handles'', see more below. | ||
Line 244: | Line 244: | ||
"used_by1" "doorkey_2 | "used_by1" "doorkey_2 | ||
==== Keys | ==== Keys Carried by AI ==== | ||
So you have a door and you have a guard AI and you want the guard to be able to open/close/lock the door, but you also want the player to be able to pickpocket the key. Keys can be attached to AI in two ways. | |||
''The Def_Attach Method''. This method is the best one for doors that you expect the AI to operate. It uses spawnargs to spawn the key at game start. | |||
*"def_attach6" "atdm:prop_silverkey" // the entity to spawn - in this case a key. | |||
*"pos_attach6" "belt_back_right" // where the key will spawn on the Ai. | |||
*"name_attach6" "door_key" // this gives 'attach6' arg the name "door_key" and is the name the arg "used_by" will need, eg: "used_by" "door_key" | |||
*"set inv_name on door_key" "Door key" // The name the key get when the play adds it to their inventory. | |||
*"set name on door_key" "door_key" // here it gets a name to be used in the map in general. | |||
For more info on this method, see [[Attaching Props to AI]]. | |||
''The Bind Method''. This lacks the animation finesse of def_attach, but does let you see the key in DR. The method is particularly helpful in, say, adding a second key to an AI in the back middle of a belt. The AI cannot use a bound key to open a locked door; the workaround is to fake it with "can_unlock" as discussed further below. Or to use bound keys mainly for items the AI will not attempt to open, such as hatches, duct covers, or chests. | |||
* Load a key entity | |||
* Position where you want it in relation to the AI, and bind it to them (i.e., "bind" "<AIname>") | |||
* Add the spawnarg "bindToJoint" "Hips" (or another location like LeftHips_Dummy; see AI for list) | |||
* Adjust existing spawnargs accordingly (that is, be sure the name and door's/chest's "used_by" match, if you aren't using a prefab chest with key). This is for the benefit of the player after pickpocketing the key; as stated above, the AI itself can't use it for unlocking. | |||
For more info on this method, see [[Attaching_Items]] and [[BindToJoint]]. | |||
====Keys Carried by Player==== | |||
With a door's key selected in your inventory and the door highlighted, you can... | |||
* unlock it (which will also auto-open if enabled) by either frobbing it or hitting the Use key (typically U or Enter). | |||
* lock (or relock) it via the Use key. Why do this? To avoid pursuit, or to lure guards into a room, and then lock them in (if they don't have a key or specific can_unlock powers). | |||
====Master Key for Testing==== | ====Master Key for Testing==== | ||
Line 409: | Line 424: | ||
=== Doors Collision/Push Behaviour === | === Doors Collision/Push Behaviour === | ||
Doors | Doors push all entities by default, except for the player. Doors will also stop moving when anything blocks their movement. However, this default behaviour can be changed by setting appropriate spawnargs: | ||
Set '''push_player''' to '''1''' to let the player be pushed by this door: | Set '''push_player''' to '''1''' to let the player be pushed by this door: | ||
"push_player" "1" // Push the player too (default is off) | "push_player" "1" // Push the player too (default is off) | ||
By default '''stop_when_blocked''' is set to 1 and if a door is blocked by an entity then even if the entity is removed afterwards, the door stays | By default '''stop_when_blocked''' is set to 1 and if a door is blocked by an entity then even if the entity is removed afterwards, the door stays where it is. The next frob will close the door. | ||
Set '''stop_when_blocked''' to '''0''' to prevent the door from ending the opening sequence when anything blocks its way. It will still pause - but continue to open if the block is removed. | Set '''stop_when_blocked''' to '''0''' to prevent the door from ending the opening sequence when anything blocks its way. It will still pause - but continue to open if the block is removed. | ||
"stop_when_blocked" "0" // door keeps moving after being blocked (default is off) | "stop_when_blocked" "0" // door keeps moving after being blocked (default is off) | ||
With this setting, doors will still stop at blocking entities (the player, for instance), but will continue to move when the entity | With this setting, doors will still stop at blocking entities (the player, for instance), but will continue to move when the entity moves out of the way. | ||
There is another spawnarg which stops a door pushing a moveable. Apply this to the ''moveable'' not the door... | There is another spawnarg which stops a door pushing a moveable. Apply this to the ''moveable'', not the door... | ||
"notPushable" "1" | "notPushable" "1" | ||
Line 426: | Line 441: | ||
===Door Sounds=== | ===Door Sounds=== | ||
There are multiple ways to put sounds on doors. | |||
''snd_open'' <br> | |||
Sound is triggered as the door begins to open. | |||
''snd_opened'' <br> | |||
Sound is triggered when the door finishes opening. Defaults to "nosound". | |||
The | ''snd_move''<br> | ||
The sound plays while the door moves. Defaults to "nosound". | |||
'' | ''snd_close'' <br> | ||
Sound is triggered as the door finishes closing. | |||
The following sounds should be left on the default sound in most cases so players clearly know what is going on: | |||
''snd_locked''<br> | ''snd_locked''<br> | ||
The sound played when a player tries to open a locked door. | The sound played when a player or an AI tries to open a locked door. | ||
''snd_unlock string''<br> | ''snd_unlock string''<br> | ||
The sound played when | The sound played when a door is unlocked. | ||
You can silence any of these sounds by setting the following properties as shown: | |||
''snd_open nosound''<br> | |||
''snd_close nosound'' | |||
Don't just use a dash - as it seems to cause a sound of its own. | |||
===Sound Propagation through Doors and Doorways=== | ===Sound Propagation through Doors and Doorways=== | ||
Line 470: | Line 497: | ||
There are also various sound properties for lockpicking:<br> | There are also various sound properties for lockpicking:<br> | ||
''snd_lockpick_pin_1 through 14'' and ''snd_lockpick_pin_success'' | ''snd_lockpick_pin_1 through 14'' and ''snd_lockpick_pin_success'' | ||
===Allowing the Player to Interrupt Door Motion=== | |||
The door property ''interruptable'' determines whether a door can be stopped by frobbing while it is opening or closing. It is enabled (i.e., set to 1) by default. Then the player, by frobbing to start the normal opening, then frobbing again to interrupt, can open a door to any position, e.g., slightly ajar to peek through. Another frob will begin closing, and so on with any additional frobs to stop/reverse-direction. | |||
Be aware that an rotating-style door, when left ajar, will subsequently open or close more slowly than normal in an angular-velocity sense. It instead takes the same time as a full (uninterrupted) opening or closing would take in seconds, as given by ''move_time'' discussed next. | |||
===Speed of Door Opening and Closing=== | ===Speed of Door Opening and Closing=== | ||
Rotating Door Speed:<br> | Rotating Door Speed:<br> | ||
The time a rotating door takes to open or close is set in the ''move_time'' property, no matter what its maximum open angle may be. So with rotation set at, say, 150 degrees the door just opens faster than at, say, 80 degrees. To change this value, make sure the door is selected then... | |||
To change | |||
* Right click the entity inspector and check ''show inherited properties'' | * Right click the entity inspector and check ''show inherited properties'' | ||
* Scroll down, select ''move_time'' | * Scroll down, select ''move_time'' | ||
* Edit the second line of the input box ''below'' the properties window to the time you want. | * Edit the second line of the input box ''below'' the properties window to the time you want. | ||
* The time is in seconds and decimal fractions can be used. | * The time is in seconds and decimal fractions can be used. The default is currently 1.75 seconds. | ||
Sliding Door Speed:<br> | Sliding Door Speed:<br> | ||
Line 493: | Line 522: | ||
* The speed is in Dark Radiant grid units per second. | * The speed is in Dark Radiant grid units per second. | ||
* The default is 0 and if set to this then the door slides open in one second whatever the distance, great or small. | * The default is 0 and if set to this then the door slides open in one second whatever the distance, great or small. | ||
* CAUTION: | * CAUTION: It is assumed ''translate'' has been changed from its default value of 0 0 0. If not, a non-zero ''translate_speed'' may cause problems. | ||
===Visportals and Doors=== | ===Visportals and Doors=== | ||
A visportal face surrounded by solid at its edges and in contact with a door is closed when the door is closed and enabled when the door is open. In most cases you will place a visportal in contact with a working door unless you can see through the door (such as a true glass door or barred gate.) For full details see [[Visportals]]. | A visportal face surrounded by solid at its edges and in contact with a door is closed when the door is closed and enabled when the door is open. In most cases you will place a visportal in contact with a working door unless you can see through the door (such as a true glass door or barred gate*.) For full details see [[Visportals]]. | ||
''*As of 2.0 it is possible to make visportals that remain transparent when closed for gates and windows. See'' [[Controlling Sound Loss Across Portals]] | |||
==Auto-Closing/Opening Doors== | ==Auto-Closing/Opening Doors== | ||
Line 505: | Line 536: | ||
;"auto_open_time":"Set this to something >= 0 to let the mover automatically open (again) after this time when being fully closed (measured in seconds). Defaults to -1, which means 'do not autoopen'. The event is also activated when the mover starts at the closed position at map start. | ;"auto_open_time":"Set this to something >= 0 to let the mover automatically open (again) after this time when being fully closed (measured in seconds). Defaults to -1, which means 'do not autoopen'. The event is also activated when the mover starts at the closed position at map start. | ||
<div class="toccolours mw-collapsible mw-collapsed"> | |||
Before auto_close_time and the AI Door Management spawnargs next were provided, a more laborious method was used to auto-close doors as if AI were closing doors behind them. Hit "Expand" to review it. | |||
<div class="mw-collapsible-content">I have one door that I particularly want the AI to close as there is a bit of frame lag inside if not. So I set this up and it works good as an auto-closing door - not as good as a true AI closing door as it will auto close when the player goes through as well but it does look very effective to see AI going through and closing the door behind them. Not tested exhaustively so I don't know if there could be any downside. Here's what to do.... | |||
I have one door that I particularly want the AI to close as there is a bit of frame lag inside if not. So I set this up and it works good as an auto-closing door - not as good as a true AI closing door as it will auto close when the player goes through as well but it does look very effective to see AI going through and closing the door behind them. Not tested exhaustively so I don't know if there could be any downside. Here's what to do.... | |||
First a quick summary to make it more clear: | First a quick summary to make it more clear: | ||
Line 568: | Line 597: | ||
* Click {{apply}} and then {{ok}} on the main S & R panel bottom right. | * Click {{apply}} and then {{ok}} on the main S & R panel bottom right. | ||
It should now work. No need to wait for an AI, just frob the door and watch it close itself. If not, check the position of the stim brush is close to where the door stops when open. | It should now work. No need to wait for an AI, just frob the door and watch it close itself. If not, check the position of the stim brush is close to where the door stops when open.</div> | ||
</div> | |||
==AI Door management== | ==AI Door management== | ||
By default AI will open doors and close them behind them. Here are some spawnargs '''on the door''' the mapper can use to modify that behaviour: | |||
;"ai_should_not_handle" :If set to 1, AI will not attempt to handle it and add it to the forbidden areas (so that it doesn't try to path through). They might still walk through the door when it is open though. Useful if you have some special use door that you don't want the AI to operate. | |||
;"ai_should_not_close" :If set to 1, AI will not close the door behind them unless it obstructs them. | |||
;"canRemainOpen" :If set to 1, it's the same as "ai_should_not_close, with the added behavior that this is ignored if the door needs to be relocked, or the door is marked "shouldBeClosed". '''(This spawnarg is available starting in TDM 2.02.)''' | |||
Spawnargs '''on the AI''' that the mapper can use: | |||
;"canCloseDoors" :Added in 2.12. Defaults to 1. If set to 0, the AI will not close doors after passing through them. | |||
To get AI to unlock/relock specific doors there are two methods: | |||
1. Provide the AI with the key, as detailed in the def_attach method in [[#Keys_carried_by_AI]] above. | |||
2. Add the following spawnarg/value to the AI: | |||
;"can_unlock" ''<doorname>'' | |||
For additional doors on the same AI use ''can_unlock1 doorname', `can_unlock2 doorname' etc. '''Do NOT use can_unlock_1.''' | |||
If both (1) and (2) are used, then the AI can still go through the door after the player pickpockets the key. Otherwise, unless someone else opens the door for the AI, a typical sequence is that the AI checks their pockets for the missing key, stalls a bit at the locked door, and then (with now-better pathing algorithms) the AI uses an alternate route to the next path_corner, or "mentally" skips ahead in the route to next reachable node and goes there. | |||
===Door Handling Positions=== | |||
It is also possible to set custom door handling positions for the AI. This is especially useful when the standard routine that lets the AI choose their standing positions while opening and closing the door fails, leaving them standing still, or circling around in front of the door helplessly. | |||
Place a movers > ''atdm:door_handling_position'' entity where you want the AI to stand while opening/closing the door from this side. | |||
On the door, you need to set the spawnarg "door_handle_position" "name_of_door_handling_position". You can also place a ''door_handling_position'' on each side of the door, and the AI will automatically choose the right one. In this case, you need to set spawnargs with "door_handle_position_1" etc., and the corresponding names of the ''door_handling_position'' entities on the door. | |||
The ''door_handling_position'' entities can also carry spawnargs that define the behaviour of the AI, which are useful for example for doors that can only be opened or locked from one side: | |||
'''"ai_no_open"''' If set to "1", the AI will not try to open the door from this side (but will still walk through when the door is already open). | |||
'''"ai_no_close"''' If set to "1", the AI will not attempt to close the door from this side. | |||
'''"ai_no_unlock"''' If set "1", the AI will not be able to unlock the door from this side, but still use it when it is not locked. | |||
'''"ai_no_lock"''' If this is set "1", the AI will not lock the door from this side. | |||
===Door Controllers=== | |||
'''Available in TDM 2.02+''' | |||
''' | You can design a door so it's operated by buttons or levers or switches (aka ''controllers''). | ||
A controller is simply an entity that targets the door. Typical examples of entities that can be used are: | |||
* Buttons: atdm:mover_button | |||
* Levers: atdm:switch_rotate_lever | |||
* Switch: atdm:mover_lever | |||
* Lock: atdm:froblock. (See also next section) | |||
1. Set up the door in the normal manner. It can be a rotating door, a sliding door, a locked door, etc. | |||
2. Turn off the "frobable" spawnarg on the door. ("frobable" "0") | |||
3. Create a controller entity on each side of the door. If you're setting up a locked door using atdm:froblock, there's no need to put any locking information on the controllers. When the game starts, it will transfer any locking information from the door to the controllers. | |||
4. Give each controller the door as a target. | |||
Both the player and any AI that wants to use the door will use the controllers to operate it. Any key, "can_unlock", or lockpick settings you would normally use at the door are now used at the controllers. | |||
Controllers and ''door_handling_position'' entities can be used on the same door, but in that situation the ''door_handling_position'' entities don't define where the AI stands to operate the door. They simply provide the "ai_no_*" spawnargs that define AI behavior on each side of the door. | |||
If you wish, you could provide a controller on only one side of the door instead of both sides. Note that, since the door is not frobable, the player won't be able to operate the door from the non-controller side. | |||
====More about Using a Separate "Froblock" Lock Plate==== | |||
''by Geep, 2021-22'' | |||
Froblock, just discussed as a controller method, actually predated the controller concept in TDM. Here we recap that earlier context, with an alternative treatment of highlighting, and thoughts on texturing and usage. | |||
'''" | Suppose you want to have a lock plate (typically mounted on a door frame or wall) that opens a nearby door, where the door and lock plate highlight separately. A traditional way is to adapt the ''froblock'' method described under the "Making your own" section of [[Containers, Chests, etc.]] | ||
Basically, your door is the "chest lid" (of class atdm:mover_door) and your lock is the "chest body" (of class atdm:froblock). Set the properties as described in the wiki. There is a stock texture (darkmod/door/keyhole_metal_001) you can use to decorate a surface of your lock plate, or a patch on it. This method is probably most apt for small hatches and grates designed for the player alone, and with no handles, or non-turning handles attached with "bind". | |||
''' | ===AI and 'non-frobable' Doors=== | ||
Be aware that the 'frobable' spawnarg only applies to the player, not AI. If you set a door to be non-frobable (i.e. 'frobable' '0'), AI can still operate it by interacting directly with it, even if it has a controller. For example they will do this if: | |||
* they are fleeing or chasing the player | |||
* the door has a controller but the AI can't reach it (for example the controller is on the other side of the door) | |||
The best way to mitigate this is to use Door Handling Position entities (see above) with the 'ai_no_open' spawnarg set on them. | |||
===AI locking doors behind them=== | ===AI locking doors behind them=== | ||
Line 626: | Line 699: | ||
In the rare case where a door is set up to use door-handling position entities (necessary for AI to use sliding doors), either or both of those entities can have the "ai_no_lock" spawnarg, which means AI aren't allowed to lock the door from that side. | In the rare case where a door is set up to use door-handling position entities (necessary for AI to use sliding doors), either or both of those entities can have the "ai_no_lock" spawnarg, which means AI aren't allowed to lock the door from that side. | ||
==Initially Blocking a Door - Partially or Fully== | |||
''by Geep 2021'' | |||
Suppose you have a door that you want to start out either as unopenable, or able to open just a crack, then later, after something happens, be fully openable and operational. One method known to work: | |||
* Create a moveable object that the opening door runs into and tries to push. | |||
* Arrange that the far side of the moveable object is jammed against some immovable worldspawn. | |||
Here's two specific examples that use a wooden plank moveable: | |||
* In "Perilous Refuge", a plank blocks the door leading out of the player's starting location, until the player carries it away. | |||
* At the end of "Away0" (WIP 2021), the player tries to open a door. But if preconditions aren't met, the occupant seems to let the door open only a crack and complains. Blockage is done by an unseen plank resting on the floor hitting a knob of worldspawn. Preconditions met causes a "$plank.remove()" script call. | |||
Other methods that you might think would work but don’t: | |||
* Block with a func_static object, or an unjammed moveable with "notpushable 1" set. In both cases, the door travels through the object. | |||
* In advance, "grab" an unjammed moveable to make it appear "solid" to the physics engine. (This was tested by having the player manipulate it; if it had worked, a “grabber” script call might suffice.) | |||
* Dynamically change the door’s "rotate" limit from script using "setSpawnArg"; this function would only work before you spawn the door, not afterwards. | |||
(Others possibilities not yet tested: | |||
* Change "rotate" using the "setKey" script function; for some spawnargs this works even after spawn. | |||
* Create a moveable and bind it to the world entity. | |||
* If you are mainly interested in initially blocking an AI from using a door: it's possible that the AI re-reads the spawnargs for what doors it's allowed to open. Try adding a frob Response to the key (Entity -> Stim/Response... -> Response) with an effect that sets the “can_unlock" spawnarg on that AI to "-".) | |||
==Controlling a Door by Scripting== | |||
''by Geep 2021'' | |||
===If Unlocked=== | |||
Simply use, for example with a door named ''door1'': | |||
$door1.Open(); | |||
... | |||
$door1.Close(); | |||
Alternatively, toggle it open or closed with: | |||
$door1.frob(); | |||
If the door has "interruptable 1" (which is the default with atdm:mover_door), you can also frob() it twice to leave it ajar. Interpose and adjust a sys.wait(...) to tune it. | |||
===If Locked=== | |||
You need to unlock it first. Changing the door's "locked" spawnarg value won't work. Instead you will use: | |||
$door1.Unlock(); | |||
But there are complications. By default, the door has spawnarg "open_on_unlock 1". So, assuming you didn't change that, you'd think unlocking the door would open it. But this spawnarg will be ignored if the gamer has global menu option "Open Doors on Unlock" set to Off. Assuming you want to reliably have the door open, do this: | |||
$door1.Unlock(); // MAYBE will open door too. | |||
sys.wait(3); // If so, wait for door to fully open. Value may need adjusting based on door's speed | |||
$door1.Open(); // Otherwise, open it now. | |||
The wait is added, because otherwise, the opening begun by Unlock may be stopped by Open with the door only partially open. (Probably an alternative to using sys.wait here is to zero the door's "interruptable" spawnarg.) | |||
==Doors as Triggers== | ==Doors as Triggers== | ||
Line 631: | Line 758: | ||
''by Ishtvan & greebo'' | ''by Ishtvan & greebo'' | ||
Doors (or any binary frob mover, buttons, levers, etc) now have the option to trigger their target on closing or opening. (For definition purposes, a button is defined as "closed" in the state when it starts out and "open" in the state you press it down to. I know that's a little non-intuitive, but it came from deriving from doors). | Doors (or any binary frob mover, buttons, levers, etc) now have the option to [[Triggers|trigger]] their target on closing or opening. (For definition purposes, a button is defined as "closed" in the state when it starts out and "open" in the state you press it down to. I know that's a little non-intuitive, but it came from deriving from doors). | ||
New spawnargs on frob movers: | New spawnargs on frob movers: | ||
Line 638: | Line 765: | ||
;"trigger_on_close":If set to 1, this binary mover will trigger its targets when it completely closes after being open. | ;"trigger_on_close":If set to 1, this binary mover will trigger its targets when it completely closes after being open. | ||
== Suspicious Doors == | |||
If you give a door the spawnarg '''"shouldBeClosed" "1"''', then AI will treat it as suspicious if they find the door open. | |||
Doors with that spawnarg should work like this: | |||
- an AI opening the door knows he's not to become suspicious if he opened the door | |||
- nearby AI alerted by the open door will also not react if they can see the door, and can see the AI that opened it | |||
- AI who come upon the open door later probably won't be able to see the AI that opened it, so they'll treat it as suspicious | |||
- if the AI who opened the door comes upon the door later, and it's still open, and no one's touched it since he opened it, he'll see his name on the door and won't become suspicious. "Oh, crap. I forgot to close it earlier." | |||
- If an AI comes upon an open door that should be closed, he should close it whether he becomes suspicious or not. | |||
'''Post TDM 2.00:''' | |||
- AI turn to look at a door they see opening. The player can crack open a suspicious door to peek out w/o grabbing the attention of a nearby AI. After 5s, the AI will notice the cracked open door. Non-suspicious doors can be cracked open indefinitely w/o nearby AI noticing. | |||
==Slanted or Tilted Doors== | |||
Slanted or tilted doors can be made as follows: | |||
1) Place your door, preferrably one of the prefab doors, which have a model door and model handle and all the rotation spawnargs pre-set. | |||
2) rotate and place the door+handle model into place you want it to be. Now, if you use the door in the game, the door will rotate around the world z-axis, and not the door model z-axis (which is rotated). | |||
3) to get the door to rotate around the door model z-axis, you must place a model (any model will do, and it can be placed anywhere in the map). Rotate the new model into the same orientation your door model was rotated, i.e. if you door is rotated 45 degrees around the x-axis, do the same rotation on the new model. | |||
4) bind the doors on the new model. This makes the doors start rotating along the new model origin (which is rotated the same way as the doors). | |||
5) working slanted door. | |||
Do note, that all the rotated objects need to be models (suspicion, not tested). You can export DR built stuff into a model using the DR ase exporter script. For custom doors, remember that the exporter places the model origin at the map origin if you do not choose the "place origin in the middle of the object" option. | |||
Also note that the AI probably cannot use slanted doors and might get stuck (suspicion, not tested). | |||
There is a link to a test map here: | |||
http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/?p=395486 | |||
==Skins: A Wide Variety of Door Textures== | ==Skins: A Wide Variety of Door Textures== | ||
This is to remind you that as with many Dark Mod models, there is a wide range of extras skins (textures) available for door models. There are now several basic door entities of different sizes so choose your size first. Then enter the spawnarg: skin with any temporary value. Now select it and click the skin button at the bottom of Dark Radiant's Entity Inspector and you will find a large of range of skin textures from which to select to give you a choice of appearances for your door. | This is to remind you that as with many Dark Mod models, there is a wide range of extras skins (textures) available for door models. There are now several basic door entities of different sizes so choose your size first. Then enter the spawnarg: skin with any temporary value. Now select it and click the skin button at the bottom of Dark Radiant's Entity Inspector and you will find a large of range of skin textures from which to select to give you a choice of appearances for your door. | ||
==Extra Notes== | ==Extra Notes== | ||
''func_darkmod_door'' is no longer used (just in case you come across it in the Dark Mod forums or wiki.) '''<code>atdm:mover_door</code>''' is the entity to use. | ''func_darkmod_door'' is no longer used (just in case you come across it in the Dark Mod forums or wiki.) '''<code>atdm:mover_door</code>''' is the entity to use. | ||
{{tutorial-editing}} | {{tutorial-editing}} |
Latest revision as of 20:12, 30 January 2024
Written by Fidcal edit Baddcog
Quick Summary
Quick way to get an unlocked door in your map:
- Insert one of the prefab doors complete with handles and select its skin property and click the button to change its skin appearance to whatever you want. Set any other properties you need.
Alternatively,
- Create a door from the entity list
- Use the "skin" spawnarg on the door to change its appearance.
- Create a handle from the entity list
- Add the door_handle property to the door and give it the name of the handle
- To the door handle add the value frob_peer and use the name of the door.
- To open clockwise, change the rotate property from
0 90 0
to0 -90 0
Introduction
This tutorial explains how to put doors into your map using Dark Radiant, as well as adjust them and their properties.
The rest of this tutorial assumes that you have a basic understanding of using DarkRadiant. If you haven't done so, please go read the Dark Radiant Must Know Basic Intro article first.
Additionally:
- Up, down, right, and left in Dark Radiant's top orthoview are regarded here as the standard map directions of North, South, East, and West where useful for clarity.
- Where the term brush is used with a door it mostly also applies to a door made up of a group of brushes and/or patches.
- Where the term door is used it often will also apply to any object you wish to rotate when frobbed, for instance an openable window, box lid, or even more exotic objects that the imaginative mapper might conceive like a signal, engine part, toy, or whatever. So long as it needs to turn or slide just a fixed amount when frobbed then return when frobbed again then the following applies.
Door types
All tangible objects in Dark Mod are entities, having either a pre-made model shape or else brush/patch(es). So there are two ways to create a door in Dark Radiant: as a model door or a textured brush door (or a hybrid of the two).
Models are ready made door objects but cannot within Dark Radiant (at the time of writing) be resized, rescaled, cropped or clipped whereas brushes are very flexible in that respect and can be worked into custom shapes for your map, including secret doors that blend into walls and other surfaces.
Most of the current door models are found in two places along with the door handles.
- Model Viewer: doors created from here will be static in the world and have no props other than material type.
You can add any props to them to make them working doors. If nothing else it is a good place to view the different size and skin options for the doors.
- Entity List: most of the door models can be found here. These doors have properties already assigned so they are ready to be used. Only one base door of each type is listed, create the size/hinge count door you want (2 hinge doors have a 'no hinge' skin). You can choose a skin for the door once it has been created in the editor with the "skin" spawnarg (use the model name of the door you want, taken from the model list, as its value). This is the easiest way to create a door. The same goes for door handles.
Remember also that door functions may be applied to objects other than doors, such as openable windows, drawbridges, gates, etc. In fact, anything that needs a partial rotation or slide when frobbed then return when frobbed again, such as a signal device. Lockboxes and chests use similar properties.
You can create one door/handle set and copy/paste it, but you need to take great care that all the name props are changed to match in each clone. Otherwise you get handles that fly off when a distant door moves, and handles that don't move.
Creating a Door
Put simply, to make a door you will be creating an 'entity with model' or 'entity with brush' or some variation thereof.
Creating a Model Door
There are several approaches to making a model door; the simplest is to create a door from the entity list; or create a door from the model viewer (good for static unusable prop doors).
Entity List:
- Deselect everything in editor by hitting the Esc button
- Right-click an ortho view and select Create Entity
- Navigate to darkmod/movers/atdm:door_..., choose the door you want
- Click Add
- To change its appearance, add a "skin" spawnarg to the door, with the value being the model name of the door you want.
You now have a workable door in your level.
Model Viewer:
- Right click in the orthoview, select Create Model then
darkmod
and select a door. - Note that you can left drag the image in the Choose Model dialog to rotate it around.
- Click
and you have a static door.
- If you want to make it work (openable, frobbable) then:
Alternatively you can do it the old way:
- Create any temporary brush
- Right click in orthoview and select
Create Entity
thenatdm:mover_door
. - Left lick the model name line in the entity inspector.
- Below it on the Entity Inspector panel you should now see a button 'Choose Model'
- Left click it, select a door model from the darkmod group.
- Note that you can left drag the image in the Choose Model dialog to rotate it around.
- The temporary brush was deleted.
In all three instances, you now have a working door with default properties.
Name your door by adding the prop (or modifing it) to name My_Door_1. You can use any name that you feel is appropriate but all doors with handles attached must have their own specific name. Use the name My_Door_1 for your first attempt as it will be referenced when you get around to attaching handles (see below).
To add a handle and other adjustments, see #Customising and Adjusting Door Properties below.
Creating a Textured Brush Door
Tip: If unsure of size then you might insert a temporary human AI first to get a sense of height.
The simplest brush door:
- Drag out a new brush to the size required, eg, a seven foot high door is 84" x 1.1 = about 90 units in Dark Radiant.
- Give it a door texture from the texture browser (or wall texture for a secret door)
- Right click in orthoview and select Create Entity then
atdm:mover_door
You now have a working door but it will rotate around its center. To move the rotation point to where you want the door hinges to be:
- Select the door and press 'v' or the Select Vertices button to enter vertex editing mode. The door's origin will show up as a small green square in the middle of the brush.
- In top-down orthoview, move the origin from the center to the corner of the brush. This is easiest in drag mode ('q' or the Resize button), although you can use translate mode ('w' or the Translate button) by manually selecting the vertex first.
Multi-brush doors:
More complex multi-brush doors can be created using the Clipper tool, CSG, etc. - this is not covered in this tutorial. Then assign atdm:mover_door
for that whole brush structure. Also you can collect various brushes positioned together in relation to one another as needed, select them all, then assign atdm:mover_door
for the group. All the brushes will be children of the atdm:mover_door
entity and will rotate and be frobbable, etc. as one unit, as one door. To add further brushes or even model shapes later see the section on #Adding handles and other items to doors.
Name your door by adding the prop (or modifing it) to name My_Door_1. You can use any name that you feel is appropriate but all doors with handles attached must have their own specific name. Use the name My_Door_1 for your first attempt as it will be referenced when you get around to attaching handles (see below). (repeated from above in case you didn't choose to create a model door)
Double Doors
Double doors are automatically recognised by the code when the doors are spawned. The prerequisite is that both doors are sharing/touching the same visportal. The spawnarg auto_setup_double_door (which defaults to "1") will take care of setting up the open/lock peer relationship between the two doors. The doors will open/close and lock/unlock along with each other as a result.
What happens behind the scenes: the doors are adding each other to their internal open_peer and lock_peer list, which causes the double doors to perform the same action when frobbed or used.
Note that auto_setup_double_door will not set the frob_peer relationship, i.e. each door will frob-highlight on its own without highlighting the other door. You'll need to add that spawnarg manually if you want to highlight the entire double door as one.
Customising and Adjusting Door Properties
Handles, lockplates, etc. can be added to doors and door properties can be adjusted for rotation, sliding, locking, and more.
Some of the door models have hinge plates and lockboxes that are reskinnable with a good variety of skins.
Door handles and other door attachments
Summary: just add the property bind with the door's name to the attachment and position it where you want it on the door. If it's a atdm:mover_door_handle then it automatically will work as a handle but you can bind virtually anything. You can add handles and other items to doors such that they move correctly with the door whether rotating, sliding, or both and even if the door is not vertical such as a skylight or trapdoor. Handle models come in two types, single handles and double handles. A single handle is one sided, this means the handle will be inside the door or outside the door, but not both. A double handle has a lever on the inside of the door and a handle on the outside of the door. Each has benefits.
- Single door handles:
Single door handles can be used on a static door, a door that's just for show that no AI's or the player can use. In this case you should just create a door handle from the model viewer, it will be static and have no properties such as scripts. It is for looks only. Note that TDM is trying to establish the expectation that decorative doors that cannot be opened do not have handles (though not all maps follow this).
I will call this multiple handles, see more below.
These can also be useful on brush doors created in the editor that may be very thin or very wide.
- Double door handles:
These are models have have a handle inside and outside. The bonus is that they only use one entity. Maps are limited to about 4,000 entities but when you count lights, AI, sound speakers, ect... you can run out of entities quickly on a large map. If you plan on building a large map this is the way to go, even in a small map they have benefits, namely that you only have to attach one handle per door.
Whether you decide to use a single handle or a double handle you must first follow the instructions below and attach one handle first. If you choose a double handle, follow the instructions below and you are done. If you choose a single handle type follow the instructions then also follow the multiple handle instructions for the second handle.
Both single and double handle types can be found in two places. The model viewer which will create a static model good for show, you can manually add props to make them work OR you can look in the entity browser. Using a handle from the entity browser saves you a little bit of time as some props are already added, you just need to add the frob_peer names for the doors/handles and the door_handle name to the door.
Adding a working model door handle
Quick summary:
- Create a model or brush handle and make it an atdm:mover_door_handle entity.
- Position it on your door. Use the opposite side from the door's multicolor X-Y-Z indicator (highlight the door to see it) if it's not obvious which side it goes on.
- Bind the handle to the door (bind <doorname>)
- It should now be a working handle though may need adjustments of rotation etc. see later.
Important: read preceding section on door handle types and performance issues first.
This works with both a model door and a brush door:
Rotation:
- By default the door handle entity rotates anti-clockwise (looked at from the front) then springs back. A double handle model is OK but two singles (see Multiple door handles below) need more care as only one is the functioning entity and the other is just attached to it. So anti-clockwise is fine for a door with its hinge on the left and the handle on the right - the handle will rotate down then spring back. If you put the functioning door handle on the other side you will have to change the default rotate property from -45 0 0 to 45 0 0. Therefore it is easier to generally put this handle on the side of the door where the hinge is on the left and the non-functioning attachment handle on the other side.
- If your door only needs one handle, eg, a cupboard door, and from outside its hinge is on the right then you will need to change the rotate property of the handle as described above.
The functioning handle entity:
- Create an entity door handle (movers folder) or create a brush or model handle and assign it the entity atdm:mover_door_handle.
- Position it where you wish on your door.
- Bind the handle to the door, by adding the "bind" spawnarg to the handle.
You now have a working door handle with default properties.
- Multiple door handles:
Now that you've got a handle attached to one side of the door it is time to add one to the other side (unless you used a double handle).
- Create the new handle. The single handles come in left and right persuasions. A door needs a left facing handle on one side and a right facing handle on the other, so if you have already added the left handle create a right handle and line it up on the other side of the door.
- Name this handle. I prefer to keep a naming convention for each door and it's respective handles, it makes things alot easier. The door is named My_Door_1, the first handle is named My_Handle_1 so name the second handle My_Handle_1_1. This will make it stay with the first handle in the entity list. This is important to keep organized. If you name it My_Handle_2 then when you get to another door named My_Door_2 you'll be confused.
- Place and bind that handle to your door.
You now have two single door handles on either side of the door that rotate together as if they were physically attached.
To add a brush to a brush door:
- Select the new brush and the brush door all together; the entity must be selected last.
- Use Edit -> Reparent primitives. This ensures the parent entity adopts the new item(s).
- If you have trouble selecting them in the orthoview because other brushes, etc. get selected then try in the camera view or as a last resort move them temporarily to an open area (but keep them in the same positions relative to each other.) Use SHIFT+
on new item(s) then SHIFT+
on main entity. Once they are all selected, use the Edit -> Reparent primitives.
To add model static items: knockers, hinges, static handles etc. to a Model Door:
- Select item
- Right click in orthoview and select Create Entity then
entity func_static
- Position it where you wish on your door.
- To synchronize this with your particular door you need to add the property bind and the individual door name to the brush entity. To do this...
- Select the model door.
- In the entity inspector, select the name line
- Select the bottom line in the input box below the properties window.
- Copy the name
- Deselect the door with ESC
- Select the brush entity
- Add a property "bind" to it.
- Change the value of the property by pasting in the door name
- Click
or press ENTER
To add brush static items: knockers, hinges, static handles to a Model Door:
- This method is not ideal but it seems to work OK.
- Select the brush.
- Right click in orthoview and select Create Entity then atdm:mover_door_handle
- Position it where you wish on your door.
To synchronize this with your particular door you need to add the property door_handle on the door, and give as the value the name of the brush you just created.
This brush turns like a handle. To stop it:
- Adding rotate 0 0 0 or disabling the handle script won't help.
- Add a real working handle (as in the section above To add a working model door handle... and it must be added LAST.)
If you don't want too see a real working handle added maybe try another tiny brush with the handle function and hide it inside the door?
Locking Doors
To lock a door check the show inherited properties in the entity inspector for a atdm:mover_door entity and you should see the locked property. Select it and in the input box below the properties you can change its value:
- 0 = unlocked (default)
- 1 = locked
If locked it will require an entity that is associated with it to be able to act as a key to unlock it.
Currently door handles on locked doors will rotate when frobbed, they will bounce back though and the door will stay locked until unlocked.
Keys
Assigning specific keys to specific doors is simple.
- It is recommended that you create an existing key entity. These keys have all required props, they just need to be named.
Alternatively you can create a key from the Model Viewer and want it to be useable
- Make sure it has the properties:
useable 1 [so it can be used by the door] frobable 1 inv_name <unique name> inv_category Keys inv_target player1 inv_icon guis/assets/hud/inventory_icons/<icon name> inv_stackable 0 or 1 where 1 can be used on all copies of the same key so they show as one entry in the inventory with a total.
Add to the door the property used_by
with the name of the key as the value. Multiple keys can open the same door by using several used_by spawnargs:
"used_by" "doorkey_1" "used_by1" "doorkey_2
Keys Carried by AI
So you have a door and you have a guard AI and you want the guard to be able to open/close/lock the door, but you also want the player to be able to pickpocket the key. Keys can be attached to AI in two ways.
The Def_Attach Method. This method is the best one for doors that you expect the AI to operate. It uses spawnargs to spawn the key at game start.
- "def_attach6" "atdm:prop_silverkey" // the entity to spawn - in this case a key.
- "pos_attach6" "belt_back_right" // where the key will spawn on the Ai.
- "name_attach6" "door_key" // this gives 'attach6' arg the name "door_key" and is the name the arg "used_by" will need, eg: "used_by" "door_key"
- "set inv_name on door_key" "Door key" // The name the key get when the play adds it to their inventory.
- "set name on door_key" "door_key" // here it gets a name to be used in the map in general.
For more info on this method, see Attaching Props to AI.
The Bind Method. This lacks the animation finesse of def_attach, but does let you see the key in DR. The method is particularly helpful in, say, adding a second key to an AI in the back middle of a belt. The AI cannot use a bound key to open a locked door; the workaround is to fake it with "can_unlock" as discussed further below. Or to use bound keys mainly for items the AI will not attempt to open, such as hatches, duct covers, or chests.
- Load a key entity
- Position where you want it in relation to the AI, and bind it to them (i.e., "bind" "<AIname>")
- Add the spawnarg "bindToJoint" "Hips" (or another location like LeftHips_Dummy; see AI for list)
- Adjust existing spawnargs accordingly (that is, be sure the name and door's/chest's "used_by" match, if you aren't using a prefab chest with key). This is for the benefit of the player after pickpocketing the key; as stated above, the AI itself can't use it for unlocking.
For more info on this method, see Attaching_Items and BindToJoint.
Keys Carried by Player
With a door's key selected in your inventory and the door highlighted, you can...
- unlock it (which will also auto-open if enabled) by either frobbing it or hitting the Use key (typically U or Enter).
- lock (or relock) it via the Use key. Why do this? To avoid pursuit, or to lure guards into a room, and then lock them in (if they don't have a key or specific can_unlock powers).
Master Key for Testing
By default, ALL locks can be opened by any key named key_master. Just create a key in your map, name it key_master and it becomes a master key for use while testing. Add inv_map_start 1 to it so it is in the player inventory at game start. Remember to delete it when your mission is finished.
Lockpicks
by Baddcog
There are two lock pick types.
- s=snake
- t=triangular
A lock can be set with many pins. Each pin has a click sequence and each needs a designated lockpick type (see above). Keep in mind that the lockpicking in The Darkmod is much more involved than in T2 or T3. The player has to listen to sounds or watch a handle or lockbar to know when a lock is pin is picked.
This means that authors can be very evil and really frustrate the player, in which case their missions will probably not be played. So be nice to the player and don't waste your time. Use simple locks for the most part and save complicated locks for important sections and to build tension. Don't make the player have 20 pins to pick all with different lockpicks. In most cases 1 or 2 pins will suffice and it isn't necessary to use both lockpicks on every lock. Also try to include a lock lever on lockboxes or chests, door handles will rotate as the pins are being picked. This gives the player visual clues to help with the picking (and essential in noisy environments where you can't hear the clicks.) IMO this system is a huge leap foward for lockpicking but also has the ability to completely frustrate the player as stated above. Keep this in mind when designing your lockpick systems.
These props go on the door itself, or the lid of a chest, eg,
- lock_pins 1327
- lock_picktype stts
The lock_pins property specifies how many pins each lockpicktype has. The lockpick_type property specifies how many times the player has to switch picks and which pick they have to use. You can see there must always be an equal number of lock_pins and lock_picktypes specified
So looking at the example above we have lockpick_type s(snake), t(triangular), t(triangular), and s(snake). The player will have to use these lockpicks in this order. Once the snake lockpick's pins are open the player can advance to the triangular pick and so forth. 5 is added to every click sequence so 5 is the minimum click pattern even if you set it to 0. In the example above the lockpins specify in order which pick types have how many pins, so the s pick has 1 + 5 = 6 clicks, the t pick has 8 and so on. The above is a difficult lock and to avoid annoying the player it is best only used rarely on a special lock like an important big vault door. Ordinary footlockers and common doors can be just 1 or 2 click sequences, eg, lock_pins 2 and lock_picktype t means the player uses one pick and listens for the end of one sequence of 7 clicks.
lockpick_rotate - is placed on the door. It is the amount the visible rotating handle or pin rotates while picking. For a rotating handle or lockbar normally ignore this and leave the default. During lockpicking it oscillates and progresses to the normal full turn of the handle. Example 0 45 0.
lockpick_translate - is placed on the door. It is the amount the visible handle or pin moves in a straight line while picking. Use this if you have eg, a lockbar that you want to move in a straight line and not rotate, eg sliding catch. Example 0 -5 0
By default, doors are pickable. If you don't set up the above lockpick spawnargs then it can't be picked. So there is normally no need to enable lockpicking - just set up the above spawnargs. There is a pickable spawnarg set to 1 by default. If set to 0 then the door becomes unpickable. But hard to think of an application except in testing or perhaps a special custom situation where it is switched by script perhaps.
Open, Partially Open, or Closed Door at Game Start
By default, doors are closed at game start. If you want a door to be already open or partially open then do the following.
Note well: Create all doors in their closed position. Adjust as follows and they will automatically be at the open position when game starts.
Already Open Rotating Door:
- Select the door.
- Select the entity inspector
- Check show inherited properties
- Select the open property
- Edit the value to 1 in the input box below and tick the check button
- The door will now be fully open at game start.
- If you want it only partly open:
- Make sure its open property is set to 1 as above.
- Right click the entity inspector and select add property
- Click the + sign on the left of the top line where atdm:mover_door is listed to open the folder. (if atdm:mover_door is not listed then the entity was likely changed from eg, func_static. If so, save the map and reload to update the add property list)
- scroll down, select start_rotate then click
- This adds it to the property list.
- Now select start_rotate in the property list.
- Edit the bottom line of the input box below the properties window to the angle you want in the same form as described in the Rotate Direction and Open Angle section. So for example, to have a door that has a fully open default rotate value of 0 90 0 to start only half open you would give it a start_rotate value of 0 45 0.
- In a similar way add the property first_frob_open".
- Set it to 1 and a partly open door should then open fully on the first frob.
- Set it to 0 and a partly open door should close on the first frob.
Already Open Sliding Door:
- Select the door.
- Select the entity inspector
- Check show inherited properties
- Select the open property
- Edit the value to 1 in the input box below and click
or press ENTER
- The door will now be fully open at game start.
- If you want it only partly open:
- Right click the entity inspector and select add property
- Make sure its open property is set to 1
- Click the + sign on the left of the top line where atdm:mover_door is listed to open the folder.
- scroll down, select start_position then click OK. (if atdm:mover_door is not listed then the entity was likely changed from eg, func_static. If so, save the map and reload to update the add property list)
- This adds it to the property list.
- Now select start_position in the property list.
- Edit the bottom line of the input box below the properties window to the position you want in the same form as described in the Sliding (Translation) Amount and Direction section. So for example, to have a door that has a fully open default translate value of 0 50 0 to start only half open you would give it a start_position value of 0 25 0.
- In a similar way add the property first_frob_open".
- Set it to 1 and a partly open door should then open fully on the first frob.
- Set it to 0 and a partly open door should close on the first frob.
Rotation Centre, Pivot, Hinge point
The centre of rotation of a door is at the origin point of its entity and the door rotates with reference to the orientation of that origin point, not the world map. See Rotate Direction... for more about that. This section only deals with the position of the rotation centre in the door.
Model Door Centre of Rotation:
The centre of rotation of a model door cannot be changed within Dark Radiant. Because a model door rotates around the centre 'spine' of its back edge this will cause clipping (penetration into solid) as in this example (where the door is set to open to 89 degrees for clarity):
So care is needed with placement. You will not normally position a door right next to a wall as in the example but against a shallow frame so clipping will barely be noticeable but either way it can be fixed. You can correct it by adding a translation (see Sliding (Translation) Directions) value of half the door width in the direction of the door handle. This will gently move the door out as it rotates to clear any solid on that side as in this diagram:
Half a door width will typically be about 2. Any 'attachments' such as door handles will still synchronize with the door movement whether the door is rotating, sliding, or both.
Brush Door Centre of Rotation:
The centre of rotation of a brush door can be changed. The default origin point of a brush is at its centre. Therefore a default rotating brush door will rotate around its centre when you first create it. So, mappers will commonly need to move that rotation point to a corner or even to some other offset position for example, for an openable window using the door function.
Put simply, to move the rotation point of a brush door you need to move the entity origin relative to the brush(es.)
Moving the entity origin (centre of rotation) relative to a brush door:
- Select the brush door
- Select Vertices mode (default shortcut key is V or button on top toolbar 'Select Vertices')
- Drag the door's entity origin to the point where you want the door to rotate. This should be on the corner on the leading edge side (the side to where the door is opening.) to avoid clipping as in this diagram....
- You should now find that door rotates around that point.
Rotate Direction and Open Angle
By default, rotating doors open anti-clockwise (viewed from above) by 90 degrees from the start orientation. If you want to change this edit the rotate property in the entity inspector. Don't confuse this rotate property with the rotation property. In the entity inspector remember that to see the inherited rotate property you must check the box 'Show inherited properties'.
The three values shown in the rotate property are degrees from the closed position around Y Z X (absolute map axes Front, Top, Side views in DR's ortho view.)
- Positive Y = Open clockwise (Dark Radiant grid front view, looking north)
- Negative Y = Open anti-clockwise (Dark Radiant grid front view, looking north)
- Positive Z = Open anti-clockwise (Dark Radiant grid top view, looking down)
- Negative Z = Open clockwise (Dark Radiant grid top view, looking down)
- Positive X = Open anti-clockwise (Dark Radiant grid side view, looking west)
- Negative X = Open clockwise (Dark Radiant grid side view, looking west)
There is a problem when you come to rotations that are not around the main Y Z X axes of the map, for instance a drawbridge that lowers down to the south east. You might think you can combine Y Z X values to get the result you want - and this can be done (for south east use 45 45 90) but it is a bit of a kludge and the drawbridge twists eccentrically as it lowers (though it arrives correctly!)
The values are in the range -179 to +180. Positive values give an anti-clockwise opening rotation (looking down from above) and negative values give a clockwise opening rotation. The value 180 is unique in that it continues in an anti-clockwise rotation when closing rather than returning clockwise so might be used if you can think of some object that might need such a motion when frobbed!
Edit the rotate value by selecting it and using the input box at the bottom and clicking the check(tick) button. That will change the angle the door will open to. Note that the line with the original default of 0 90 0 will still be there but your new entry will be added on a separate line and that is the one that will work in the game. CAUTION: when adjusting later make sure you have your new line selected and not the original! If you do it will appear to change but your first setting will remain unaltered.
Examples:
- 0 90 0 = Opens anti-clockwise round the entity's 'vertical' to 90 degrees - typical default vertical door.
- 0 0 90 = Lowers a drawbridge from the entity 'vertical' to horizontal.
- 0 0 -45 = Opens clockwise by 45 degrees viewed from the east side. This might suit a skylight in a sloping roof.
'rotate' cannot be combined with translate motions (see #Sliding (Translation) Amount and Direction) in one door; you need to bind one door to another and link they by targetting one to the other. By that means you can produce exotic and useful motions. A door opening against an upward-sloping floor can thus have a lifting hinge and raise up slightly to clear the floor; a door can rotate towards you and slide back to one side very effectively.
Sliding (Translation) Amount and Direction
By default a Dark Mod door will rotate open. For most sliding doors you want to stop them rotating as well as make them slide. You cannot delete (remove) the rotate property - you have to set the rotate property to 0 0 0 to stop a door rotating (see Rotate Direction and Open Angle.)
Now edit the translate property value by selecting it (remember to have inherited properties box checked) and using the input box at the bottom and clicking the check(tick) button. That will change the distance the door will slide to. Note that the line with the original default of 0 0 0 will still be there but your new entry will be added on a separate line and that is the one that will work in the game. CAUTION: when adjusting later make sure you have your new line selected and not the original! If you do it will appear to change but your first setting will remain unaltered.
Typically (but not always) you will want your sliding door to slide the width of the door. The three values in the translate property by default are 0 0 0 and are X Y Z absolute map values (irrespective of door orientation) where:
- Positive X = Slide East (Right side of Dark Radiant grid in top view)
- Negative X = Slide West (Left side of Dark Radiant grid in top view)
- Positive Y = Slide North (top of Dark Radiant grid in top view)
- Negative Y = Slide South (bottom of Dark Radiant grid in top view)
- Positive Z = Slide Up (Top of Dark Radiant grid in side views)
- Negative Z = Slide Down (Bottom of Dark Radiant grid in side views)
So for a 50 unit wide door you want to slide fully to the east you would use 50 0 0 for the translate property values. A 100 unit portcullis sliding vertically up would need 0 0 100 to be fully raised.
Doors Collision/Push Behaviour
Doors push all entities by default, except for the player. Doors will also stop moving when anything blocks their movement. However, this default behaviour can be changed by setting appropriate spawnargs:
Set push_player to 1 to let the player be pushed by this door:
"push_player" "1" // Push the player too (default is off)
By default stop_when_blocked is set to 1 and if a door is blocked by an entity then even if the entity is removed afterwards, the door stays where it is. The next frob will close the door.
Set stop_when_blocked to 0 to prevent the door from ending the opening sequence when anything blocks its way. It will still pause - but continue to open if the block is removed.
"stop_when_blocked" "0" // door keeps moving after being blocked (default is off)
With this setting, doors will still stop at blocking entities (the player, for instance), but will continue to move when the entity moves out of the way.
There is another spawnarg which stops a door pushing a moveable. Apply this to the moveable, not the door...
"notPushable" "1"
Door Sounds
There are multiple ways to put sounds on doors.
snd_open
Sound is triggered as the door begins to open.
snd_opened
Sound is triggered when the door finishes opening. Defaults to "nosound".
snd_move
The sound plays while the door moves. Defaults to "nosound".
snd_close
Sound is triggered as the door finishes closing.
The following sounds should be left on the default sound in most cases so players clearly know what is going on:
snd_locked
The sound played when a player or an AI tries to open a locked door.
snd_unlock string
The sound played when a door is unlocked.
You can silence any of these sounds by setting the following properties as shown:
snd_open nosound
snd_close nosound
Don't just use a dash - as it seems to cause a sound of its own.
Sound Propagation through Doors and Doorways
This information will change significantly with the release of 2.0. See Controlling Sound Loss Across Portals
The sound volume reduction to the player (ie, the sound the player hears) is fixed and constant in a cvar which adds a distance factor to the original sound. It is recommended that you do not change that because it will affect other FMs. Currently there is no way to change the way that sound to the player is reduced through doors and doorways.
Sound propagation to AI, eg, impact sounds or guard yells is treated separately:
Sound propagation to AI relies on visportals. For details study Sound Propagation: Part 1 and Sound Propagation: Part 2 as well as Visportals This tutorial will just cover the relevant sound and sound propagation properties of doors. If you set the show inherited properties box in the entity inspector you can see them as described here.
Remember, the following have no effect on what the player hears through a door or doorway.
loss_open
Drop in sound volume in dB propagated to AI (not player) when going through an open door. (default 1dB)
loss_closed
Drop in sound volume in dB propagated to AI (not player) when going through a closed door. (default 15dB) You would want to set this very high to block all sound with a thick door but very low for a barred gate for example.
loss_double_open
Drop in sound volume in dB propagated to AI (not player) when going through double doors when only one is open. (default 1dB)
There are also various sound properties for lockpicking:
snd_lockpick_pin_1 through 14 and snd_lockpick_pin_success
Allowing the Player to Interrupt Door Motion
The door property interruptable determines whether a door can be stopped by frobbing while it is opening or closing. It is enabled (i.e., set to 1) by default. Then the player, by frobbing to start the normal opening, then frobbing again to interrupt, can open a door to any position, e.g., slightly ajar to peek through. Another frob will begin closing, and so on with any additional frobs to stop/reverse-direction.
Be aware that an rotating-style door, when left ajar, will subsequently open or close more slowly than normal in an angular-velocity sense. It instead takes the same time as a full (uninterrupted) opening or closing would take in seconds, as given by move_time discussed next.
Speed of Door Opening and Closing
Rotating Door Speed:
The time a rotating door takes to open or close is set in the move_time property, no matter what its maximum open angle may be. So with rotation set at, say, 150 degrees the door just opens faster than at, say, 80 degrees. To change this value, make sure the door is selected then...
- Right click the entity inspector and check show inherited properties
- Scroll down, select move_time
- Edit the second line of the input box below the properties window to the time you want.
- The time is in seconds and decimal fractions can be used. The default is currently 1.75 seconds.
Sliding Door Speed:
The speed of a sliding door is set in the translate_speed property. To add this, make sure the door is selected then...
- Right click the entity inspector and check show inherited properties
- Scroll down, select translate_speed
- Edit the second line of the input box below the properties window to the speed you want.
- The speed is in Dark Radiant grid units per second.
- The default is 0 and if set to this then the door slides open in one second whatever the distance, great or small.
- CAUTION: It is assumed translate has been changed from its default value of 0 0 0. If not, a non-zero translate_speed may cause problems.
Visportals and Doors
A visportal face surrounded by solid at its edges and in contact with a door is closed when the door is closed and enabled when the door is open. In most cases you will place a visportal in contact with a working door unless you can see through the door (such as a true glass door or barred gate*.) For full details see Visportals.
*As of 2.0 it is possible to make visportals that remain transparent when closed for gates and windows. See Controlling Sound Loss Across Portals
Auto-Closing/Opening Doors
Doors that automatically close after being open for some time are easy to setup: Each frobmover entity supports these spawnargs:
- "auto_close_time"
- Set this to something >= 0 to let the mover automatically close (again) after this time when being fully opened (measured in seconds). Defaults to -1, which means 'do not autoclose'. The event is also activated when the mover starts at the open position at map start.
- "auto_open_time"
- "Set this to something >= 0 to let the mover automatically open (again) after this time when being fully closed (measured in seconds). Defaults to -1, which means 'do not autoopen'. The event is also activated when the mover starts at the closed position at map start.
Before auto_close_time and the AI Door Management spawnargs next were provided, a more laborious method was used to auto-close doors as if AI were closing doors behind them. Hit "Expand" to review it.
First a quick summary to make it more clear:
A trigger_relay is used both as a relay AND carries a stim. We put the trigger_relay with its stim in the path of the open door. The door has a response property. When it opens and contacts the stim its response is to send a signal back to the relay. The relay pauses then closes the door...
- First, optionally give your door a suitable name like autodoor1, whatever.
- Copy that name to the clipboard.
Next we need a relay with a delay:
- Create entity > darkmod > trigger_relay
- Place it roughly at the position the door will be at when open and to be on the safe side 3/4th of the way to the far end of the door (not the hinge end) to give max distance from the close door.
- Add the property 'target' and paste in the door name you just copied.
- Give the relay itself a name, eg, autoDoor_relay_1, and copy that name to the clipboard, you'll need that too in a bit.
- Add the property delay and the value 3 - this is the delay in seconds before the door will close; 3 seems about right but 2 might be worth a try because to that 3 is added a random value between 0 to 0.5 seconds from the Time Interval we entered for the stim firings.
- Add the property 'wait' and the value 3. This is the time before it can work again in seconds. If you set it too low then in theory the door might trigger again but in this situation I don't think it's possible. Too long, eg, one minute, and it won't work if the AI goes back through the door before then. If this value is -1 then the whole thing will only work ONCE so might be used for an AI who goes through once, closes it behind him, but you don't want it to be an autodoor thereafter.
That's the relay, now we add a stim to it:
- Still with the trigger relay selected, go to Entity -> Stim/Response
- Custom stim tab.
- Click Add stim type, select the new custom stim type you just made at the bottom of the list and type in eg, autoDoorStim at top right in the input box.
- Click the stim tab and the little drop down arrow against the 'type' selector at bottom left and you should see your new custom stim name. Select it.
- Select the new autoDoorStim in the list and on the right you need only type in the radius box 15.0 There is quite a lot of room for error. I had it working on 10 and also on 25. The value should be less than the distance to the closed door else it will trigger open! But no so small that the door might not reach it.
- Select the check box for Time Interval and enter 500 (millisecs.) This is so it doesn't keep firing more frequently than is necessary. This stim will be firing all through your mission whether the door is used or not so if you had dozens of these then maybe it would affect performance. Too big a number and there may be a long delay before the door shuts - but it will be random depending on the next time the stim happens to fire. We'll control the delay we want more precisely later.
That's the stim set up, now for the response to it which is put on the door....
- Select the doorm, then use Entity -> Stim/response and select the response tab.
- Click the little drop down arrow against the 'type' selector at bottom left and you should see your new custom stim name. Select it.
- Right click in the big Response Effects box on the bottom right of the panel.
- Add New Effect and you should get a default 'Activate Response' response added to the list. Double click it.
- In the Effect selector at the stop select 'Trigger'
- in the Target box, paste in the name of the relay you copied or you can select it from the list at the little arrow.
- Leave the Activator box empty.
AI Door management
By default AI will open doors and close them behind them. Here are some spawnargs on the door the mapper can use to modify that behaviour:
- "ai_should_not_handle"
- If set to 1, AI will not attempt to handle it and add it to the forbidden areas (so that it doesn't try to path through). They might still walk through the door when it is open though. Useful if you have some special use door that you don't want the AI to operate.
- "ai_should_not_close"
- If set to 1, AI will not close the door behind them unless it obstructs them.
- "canRemainOpen"
- If set to 1, it's the same as "ai_should_not_close, with the added behavior that this is ignored if the door needs to be relocked, or the door is marked "shouldBeClosed". (This spawnarg is available starting in TDM 2.02.)
Spawnargs on the AI that the mapper can use:
- "canCloseDoors"
- Added in 2.12. Defaults to 1. If set to 0, the AI will not close doors after passing through them.
To get AI to unlock/relock specific doors there are two methods:
1. Provide the AI with the key, as detailed in the def_attach method in #Keys_carried_by_AI above.
2. Add the following spawnarg/value to the AI:
- "can_unlock" <doorname>
For additional doors on the same AI use can_unlock1 doorname', `can_unlock2 doorname' etc. Do NOT use can_unlock_1.
If both (1) and (2) are used, then the AI can still go through the door after the player pickpockets the key. Otherwise, unless someone else opens the door for the AI, a typical sequence is that the AI checks their pockets for the missing key, stalls a bit at the locked door, and then (with now-better pathing algorithms) the AI uses an alternate route to the next path_corner, or "mentally" skips ahead in the route to next reachable node and goes there.
Door Handling Positions
It is also possible to set custom door handling positions for the AI. This is especially useful when the standard routine that lets the AI choose their standing positions while opening and closing the door fails, leaving them standing still, or circling around in front of the door helplessly.
Place a movers > atdm:door_handling_position entity where you want the AI to stand while opening/closing the door from this side.
On the door, you need to set the spawnarg "door_handle_position" "name_of_door_handling_position". You can also place a door_handling_position on each side of the door, and the AI will automatically choose the right one. In this case, you need to set spawnargs with "door_handle_position_1" etc., and the corresponding names of the door_handling_position entities on the door.
The door_handling_position entities can also carry spawnargs that define the behaviour of the AI, which are useful for example for doors that can only be opened or locked from one side:
"ai_no_open" If set to "1", the AI will not try to open the door from this side (but will still walk through when the door is already open).
"ai_no_close" If set to "1", the AI will not attempt to close the door from this side.
"ai_no_unlock" If set "1", the AI will not be able to unlock the door from this side, but still use it when it is not locked.
"ai_no_lock" If this is set "1", the AI will not lock the door from this side.
Door Controllers
Available in TDM 2.02+
You can design a door so it's operated by buttons or levers or switches (aka controllers).
A controller is simply an entity that targets the door. Typical examples of entities that can be used are:
- Buttons: atdm:mover_button
- Levers: atdm:switch_rotate_lever
- Switch: atdm:mover_lever
- Lock: atdm:froblock. (See also next section)
1. Set up the door in the normal manner. It can be a rotating door, a sliding door, a locked door, etc.
2. Turn off the "frobable" spawnarg on the door. ("frobable" "0")
3. Create a controller entity on each side of the door. If you're setting up a locked door using atdm:froblock, there's no need to put any locking information on the controllers. When the game starts, it will transfer any locking information from the door to the controllers.
4. Give each controller the door as a target.
Both the player and any AI that wants to use the door will use the controllers to operate it. Any key, "can_unlock", or lockpick settings you would normally use at the door are now used at the controllers.
Controllers and door_handling_position entities can be used on the same door, but in that situation the door_handling_position entities don't define where the AI stands to operate the door. They simply provide the "ai_no_*" spawnargs that define AI behavior on each side of the door.
If you wish, you could provide a controller on only one side of the door instead of both sides. Note that, since the door is not frobable, the player won't be able to operate the door from the non-controller side.
More about Using a Separate "Froblock" Lock Plate
by Geep, 2021-22
Froblock, just discussed as a controller method, actually predated the controller concept in TDM. Here we recap that earlier context, with an alternative treatment of highlighting, and thoughts on texturing and usage.
Suppose you want to have a lock plate (typically mounted on a door frame or wall) that opens a nearby door, where the door and lock plate highlight separately. A traditional way is to adapt the froblock method described under the "Making your own" section of Containers, Chests, etc.
Basically, your door is the "chest lid" (of class atdm:mover_door) and your lock is the "chest body" (of class atdm:froblock). Set the properties as described in the wiki. There is a stock texture (darkmod/door/keyhole_metal_001) you can use to decorate a surface of your lock plate, or a patch on it. This method is probably most apt for small hatches and grates designed for the player alone, and with no handles, or non-turning handles attached with "bind".
AI and 'non-frobable' Doors
Be aware that the 'frobable' spawnarg only applies to the player, not AI. If you set a door to be non-frobable (i.e. 'frobable' '0'), AI can still operate it by interacting directly with it, even if it has a controller. For example they will do this if:
- they are fleeing or chasing the player
- the door has a controller but the AI can't reach it (for example the controller is on the other side of the door)
The best way to mitigate this is to use Door Handling Position entities (see above) with the 'ai_no_open' spawnarg set on them.
AI locking doors behind them
If one AI is involved (no one else is in the queue), he'll lock it behind him if he had to unlock it in the first place.
Prior to TDM 1.08, if more than one AI is using the door at the same time (there's a queue), the first AI unlocks the door, and the last AI through will only lock it if it's marked "should_always_be_locked" AND they have a "can_unlock" for that door or they have a key for that door. The last AI to use the door doesn't know that the first AI found it locked, because that info is kept per AI, and not per door.
Starting in TDM 1.08, if the first AI in a door queue found the door locked, that information is remembered by the door and the last AI through uses it to relock the door, as long as they have a "can_unlock" for that door or they have a key for that door.
In the rare case where a door is set up to use door-handling position entities (necessary for AI to use sliding doors), either or both of those entities can have the "ai_no_lock" spawnarg, which means AI aren't allowed to lock the door from that side.
Initially Blocking a Door - Partially or Fully
by Geep 2021
Suppose you have a door that you want to start out either as unopenable, or able to open just a crack, then later, after something happens, be fully openable and operational. One method known to work:
- Create a moveable object that the opening door runs into and tries to push.
- Arrange that the far side of the moveable object is jammed against some immovable worldspawn.
Here's two specific examples that use a wooden plank moveable:
- In "Perilous Refuge", a plank blocks the door leading out of the player's starting location, until the player carries it away.
- At the end of "Away0" (WIP 2021), the player tries to open a door. But if preconditions aren't met, the occupant seems to let the door open only a crack and complains. Blockage is done by an unseen plank resting on the floor hitting a knob of worldspawn. Preconditions met causes a "$plank.remove()" script call.
Other methods that you might think would work but don’t:
- Block with a func_static object, or an unjammed moveable with "notpushable 1" set. In both cases, the door travels through the object.
- In advance, "grab" an unjammed moveable to make it appear "solid" to the physics engine. (This was tested by having the player manipulate it; if it had worked, a “grabber” script call might suffice.)
- Dynamically change the door’s "rotate" limit from script using "setSpawnArg"; this function would only work before you spawn the door, not afterwards.
(Others possibilities not yet tested:
- Change "rotate" using the "setKey" script function; for some spawnargs this works even after spawn.
- Create a moveable and bind it to the world entity.
- If you are mainly interested in initially blocking an AI from using a door: it's possible that the AI re-reads the spawnargs for what doors it's allowed to open. Try adding a frob Response to the key (Entity -> Stim/Response... -> Response) with an effect that sets the “can_unlock" spawnarg on that AI to "-".)
Controlling a Door by Scripting
by Geep 2021
If Unlocked
Simply use, for example with a door named door1:
$door1.Open(); ... $door1.Close();
Alternatively, toggle it open or closed with:
$door1.frob();
If the door has "interruptable 1" (which is the default with atdm:mover_door), you can also frob() it twice to leave it ajar. Interpose and adjust a sys.wait(...) to tune it.
If Locked
You need to unlock it first. Changing the door's "locked" spawnarg value won't work. Instead you will use:
$door1.Unlock();
But there are complications. By default, the door has spawnarg "open_on_unlock 1". So, assuming you didn't change that, you'd think unlocking the door would open it. But this spawnarg will be ignored if the gamer has global menu option "Open Doors on Unlock" set to Off. Assuming you want to reliably have the door open, do this:
$door1.Unlock(); // MAYBE will open door too. sys.wait(3); // If so, wait for door to fully open. Value may need adjusting based on door's speed $door1.Open(); // Otherwise, open it now.
The wait is added, because otherwise, the opening begun by Unlock may be stopped by Open with the door only partially open. (Probably an alternative to using sys.wait here is to zero the door's "interruptable" spawnarg.)
Doors as Triggers
by Ishtvan & greebo
Doors (or any binary frob mover, buttons, levers, etc) now have the option to trigger their target on closing or opening. (For definition purposes, a button is defined as "closed" in the state when it starts out and "open" in the state you press it down to. I know that's a little non-intuitive, but it came from deriving from doors).
New spawnargs on frob movers:
- "trigger_on_open"
- If set to 1, this binary mover will trigger its targets when it starts out completely closed and is opened.
- "trigger_when_opened"
- If set to 1, this binary mover will trigger its targets when it is completely opened. Code defaults to 0.
- "trigger_on_close"
- If set to 1, this binary mover will trigger its targets when it completely closes after being open.
Suspicious Doors
If you give a door the spawnarg "shouldBeClosed" "1", then AI will treat it as suspicious if they find the door open.
Doors with that spawnarg should work like this:
- an AI opening the door knows he's not to become suspicious if he opened the door
- nearby AI alerted by the open door will also not react if they can see the door, and can see the AI that opened it
- AI who come upon the open door later probably won't be able to see the AI that opened it, so they'll treat it as suspicious
- if the AI who opened the door comes upon the door later, and it's still open, and no one's touched it since he opened it, he'll see his name on the door and won't become suspicious. "Oh, crap. I forgot to close it earlier."
- If an AI comes upon an open door that should be closed, he should close it whether he becomes suspicious or not.
Post TDM 2.00: - AI turn to look at a door they see opening. The player can crack open a suspicious door to peek out w/o grabbing the attention of a nearby AI. After 5s, the AI will notice the cracked open door. Non-suspicious doors can be cracked open indefinitely w/o nearby AI noticing.
Slanted or Tilted Doors
Slanted or tilted doors can be made as follows:
1) Place your door, preferrably one of the prefab doors, which have a model door and model handle and all the rotation spawnargs pre-set.
2) rotate and place the door+handle model into place you want it to be. Now, if you use the door in the game, the door will rotate around the world z-axis, and not the door model z-axis (which is rotated).
3) to get the door to rotate around the door model z-axis, you must place a model (any model will do, and it can be placed anywhere in the map). Rotate the new model into the same orientation your door model was rotated, i.e. if you door is rotated 45 degrees around the x-axis, do the same rotation on the new model.
4) bind the doors on the new model. This makes the doors start rotating along the new model origin (which is rotated the same way as the doors).
5) working slanted door.
Do note, that all the rotated objects need to be models (suspicion, not tested). You can export DR built stuff into a model using the DR ase exporter script. For custom doors, remember that the exporter places the model origin at the map origin if you do not choose the "place origin in the middle of the object" option.
Also note that the AI probably cannot use slanted doors and might get stuck (suspicion, not tested).
There is a link to a test map here: http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/?p=395486
Skins: A Wide Variety of Door Textures
This is to remind you that as with many Dark Mod models, there is a wide range of extras skins (textures) available for door models. There are now several basic door entities of different sizes so choose your size first. Then enter the spawnarg: skin with any temporary value. Now select it and click the skin button at the bottom of Dark Radiant's Entity Inspector and you will find a large of range of skin textures from which to select to give you a choice of appearances for your door.
Extra Notes
func_darkmod_door is no longer used (just in case you come across it in the Dark Mod forums or wiki.) atdm:mover_door
is the entity to use.