Scripted Doors
by Mark Holcomb · 12/01/2004 (4:00 pm) · 22 comments
Download Code File
Installing doors allows the user to have scripted doors that will lift up or down
The door has two valid directions that can be assigned as dynamic variables
inside the map editor. The variable should be named 'dir' and the values it
can take are 'up', 'down', 'left', 'right' 'forward' or 'back'. If you do not assign a 'dir' variable the door will default to open upwards.
The door will slide appropriately along it's X,Y or Z axis for each of these commands relative to it's orientation in the world.
Each door has a default height to raise or lower, but you can change the height
each door raises by changing the dynamic variable 'liftheight' in the map editor
- or permanently change the default in the code in the datablock section for the
door.
I have defined three different keys that can be assigned as well.
To use the keys, you need to create a dynamic variable for the door called 'key',
then assign a key name to the value. The default keys are RedKey, BlueKey, and
Yellowkey.
The keys are items that can be placed in the game. They are picked up and added to
the players inventory. You can actually assign any inventory item as a 'key' the
code checks to see if the player has that item on them to see if they can open
the door. - So you're not limited to just the keys - you could restrict people from
entering the door if they weren't carrying a particular weapon that you know they
need to find before proceeding.
Some of you might try to use the doors as a lift. Don't bother unless you only want to
go down on the lift. The collision detection in Torque does not check for when a static
object moves into a player - rather it checks the players and projectiles when they
move. This means that if you stand on top of a door/lift and raise it, you will get stuck
inside the object because the static object moved up past you - and since it moved, there would be no collision detection. However if you use the door/lift to go down, it will
work because as the object drops, the player lands on top of it, which causes the
collision detection to work. I tried using an applyimpulse from the door that would bounce the player upward, causing the collision detection to kick in and keep the player on top of the lift, but it was quirky and did not always work.
I mentioned getting stuck inside the object. It is possible for a door to close on top of you. For the above mentioned reasons. To prevent a player from getting stuck in the door object, I have placed a small routine in the doors oncollision that applies a small impulse to the player object that pushes them back a little bit. That motion of course triggers the on collision again - which will push you out of the door object. (I chose backwards rather than forward to keep people from being able to force their way through doors.)
To make the doors interactive I followed the steps from the Torque Documentation to create an 'interact' key. If you have already implemented this into your code, then skip down to section #2.
Section #1 - Creating an interact key.
The interact key will assign a key that will attempt to 'interact' with any staticobject
that is within a set distance (4units) in front of you. To do this you have to assign a key
to the function that calls the interaction, you need to copy the file interact.cs into your
script directory, and then you need to make sure you load it in game.cs.
I'm going to give you the short version of this, for full details read the online docs from
garagegames at www.garagegames.com/docs/torque/general/ch06s04.php.
1. Back up \client\scripts\default.bind.cs and client\config.cs
2. In \client\scripts\default.bind.cs look for the section labelled: Misc. Player stuff
3. At the end of that section add this line.
(You can change the "w" to a different key if you want, but be sure that it is not already
assigned to a different task. - The torque tutorial uses "t" - I chose "w")
4. Save your file and open up client\config.cs
5. Go down to the bottom of it and add
(Remember to change your key to match the one in the steps above if necessary.)
6. Save the file.
7. Copy the file 'interact.cs' from the zip file into your \server\scripts\ directory.
(The code for the file is commented, and comes straight from the above mentioned tutorial.)
8. Open game.cs and add the following line in the onServerCreated function
9. Save game.cs
That almost concludes Section #1. I recommend reading the tutorial - it explains in detail what this code does and it helps expand the horizon of what you can do with StaticObjects. You can use them to regen health ala Halflife, spit out cokes ala MaxPayne. There are limitless things, but to use it all you have to do is create a datablock for your item, and add an ::onInteract function to it to do whatever you want the item to do.
Pretty sweet.
(Plus you never have to do this part again, the key and functionality is always there.)
Section #2 - Installing the doors.
1. In your /data/shapes directory create a new directory called door.
2. Copy the following files into the new door directory
bluekey.dts
bluekey.ms3d
bluekeyskin.png
door.dts
door.ms3d
door.mtl
door.obj
doormap.bmp
doorskin.jpg
key.ms3d
key.mtl
key.obj
key.qc
keymap.bmp
redkey.dts
redkey.ms3d
redkeyskin.png
yellowkey.dts
yellowkeyskin.png
The list is kind of long, but I've included the Milkshape files, as well as the .dts files.
3. Copy the following two files into your data\sound directory
door_locked.ogg
door1.ogg
4. Copy the door.cs file into \server\scripts
5. Open \server\script\game.cs and add the line
to the onServerCreatedFunction
6. Open up player.cs and find the function - datablock PlayerData(PlayerBody)
7. Scroll down to the bottom of it and add the lines:
Section #3 - Creating and using the doors.
1. To add a door, load up your map of choice.
2. Go into the map editor (F11) and go into the World Editor Creator (F4)
3. Look under Shapes and you should see two new entries 'Keys' and 'Door'
4. Expand Door and you'll see the door shape that can be insered into the map
5. Insert the door and position it where you would like.
6. Press F11 - walk up to your door, press your use key and the door should open.
Section #4 - Customizing your door.
I. - Locking the door.
To make the door locked, go back into the map editor, select your door, then hit F3.
Expand the dynamic variable section. Click the add button and create a new variable
called 'key'. Set the value to key to be 'Redkey'. Click the APPLY button for the
change to take effect.
Add a redkey to the map in the same manner as adding the door.
Go back into the game and try opening the door. Now go pick up the key and try
again.
II - Up and down.
To have your door slide down rather than go up, go into the map editor, select
the door, and press (F3). Expand the dynamic variable section and find the
variable named 'dir'. Change the value of 'dir' to 'down' (w/o the quotes).
Click APPLY, then exit the game editor (F11).
III - Open the door higher.
To have your door open further or less, go into the map editor, select
the door, and press (F3). Expand the dynamic variable section and find the
variable named 'liftheight'. Change the value of 'liftheight' to a different
number, such as 15 or such.
Click APPLY, then exit the game editor (F11).
That pretty much sums it all up. I included all the skins, and the simple shapes that
I used for the doors and keys. I know the art could be better, but I'm a programmer
not an artist. Hopefully this will help some of you who are more artist than programmer
get some doors in your games.
As alway, many thanks to the garagegames community whose bits and pieces of code and wisdom helped me put this together for others. Special thanks to Robert Brower whose resource:
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4004
gave me the info to get moving in the right direction with this.
*** 12/21/04 - Updated the code to handle left, right, forward, and back directions.
Note: If a door is opening towards the player, the door will pass through the player. This is due to the game engines collision detection scheme as discussed above.
Installing doors allows the user to have scripted doors that will lift up or down
The door has two valid directions that can be assigned as dynamic variables
inside the map editor. The variable should be named 'dir' and the values it
can take are 'up', 'down', 'left', 'right' 'forward' or 'back'. If you do not assign a 'dir' variable the door will default to open upwards.
The door will slide appropriately along it's X,Y or Z axis for each of these commands relative to it's orientation in the world.
Each door has a default height to raise or lower, but you can change the height
each door raises by changing the dynamic variable 'liftheight' in the map editor
- or permanently change the default in the code in the datablock section for the
door.
I have defined three different keys that can be assigned as well.
To use the keys, you need to create a dynamic variable for the door called 'key',
then assign a key name to the value. The default keys are RedKey, BlueKey, and
Yellowkey.
The keys are items that can be placed in the game. They are picked up and added to
the players inventory. You can actually assign any inventory item as a 'key' the
code checks to see if the player has that item on them to see if they can open
the door. - So you're not limited to just the keys - you could restrict people from
entering the door if they weren't carrying a particular weapon that you know they
need to find before proceeding.
Some of you might try to use the doors as a lift. Don't bother unless you only want to
go down on the lift. The collision detection in Torque does not check for when a static
object moves into a player - rather it checks the players and projectiles when they
move. This means that if you stand on top of a door/lift and raise it, you will get stuck
inside the object because the static object moved up past you - and since it moved, there would be no collision detection. However if you use the door/lift to go down, it will
work because as the object drops, the player lands on top of it, which causes the
collision detection to work. I tried using an applyimpulse from the door that would bounce the player upward, causing the collision detection to kick in and keep the player on top of the lift, but it was quirky and did not always work.
I mentioned getting stuck inside the object. It is possible for a door to close on top of you. For the above mentioned reasons. To prevent a player from getting stuck in the door object, I have placed a small routine in the doors oncollision that applies a small impulse to the player object that pushes them back a little bit. That motion of course triggers the on collision again - which will push you out of the door object. (I chose backwards rather than forward to keep people from being able to force their way through doors.)
To make the doors interactive I followed the steps from the Torque Documentation to create an 'interact' key. If you have already implemented this into your code, then skip down to section #2.
Section #1 - Creating an interact key.
The interact key will assign a key that will attempt to 'interact' with any staticobject
that is within a set distance (4units) in front of you. To do this you have to assign a key
to the function that calls the interaction, you need to copy the file interact.cs into your
script directory, and then you need to make sure you load it in game.cs.
I'm going to give you the short version of this, for full details read the online docs from
garagegames at www.garagegames.com/docs/torque/general/ch06s04.php.
1. Back up \client\scripts\default.bind.cs and client\config.cs
2. In \client\scripts\default.bind.cs look for the section labelled: Misc. Player stuff
3. At the end of that section add this line.
moveMap.bindCmd(keyboard, "w", "commandToServer('Interact');", "");(You can change the "w" to a different key if you want, but be sure that it is not already
assigned to a different task. - The torque tutorial uses "t" - I chose "w")
4. Save your file and open up client\config.cs
5. Go down to the bottom of it and add
moveMap.bindCmd(keyboard, "w", "commandToServer('Interact');", "");(Remember to change your key to match the one in the steps above if necessary.)
6. Save the file.
7. Copy the file 'interact.cs' from the zip file into your \server\scripts\ directory.
(The code for the file is commented, and comes straight from the above mentioned tutorial.)
8. Open game.cs and add the following line in the onServerCreated function
exec("./interact.cs"); 9. Save game.cs
That almost concludes Section #1. I recommend reading the tutorial - it explains in detail what this code does and it helps expand the horizon of what you can do with StaticObjects. You can use them to regen health ala Halflife, spit out cokes ala MaxPayne. There are limitless things, but to use it all you have to do is create a datablock for your item, and add an ::onInteract function to it to do whatever you want the item to do.
Pretty sweet.
(Plus you never have to do this part again, the key and functionality is always there.)
Section #2 - Installing the doors.
1. In your /data/shapes directory create a new directory called door.
2. Copy the following files into the new door directory
bluekey.dts
bluekey.ms3d
bluekeyskin.png
door.dts
door.ms3d
door.mtl
door.obj
doormap.bmp
doorskin.jpg
key.ms3d
key.mtl
key.obj
key.qc
keymap.bmp
redkey.dts
redkey.ms3d
redkeyskin.png
yellowkey.dts
yellowkeyskin.png
The list is kind of long, but I've included the Milkshape files, as well as the .dts files.
3. Copy the following two files into your data\sound directory
door_locked.ogg
door1.ogg
4. Copy the door.cs file into \server\scripts
5. Open \server\script\game.cs and add the line
exec("./door.cs"); to the onServerCreatedFunction
6. Open up player.cs and find the function - datablock PlayerData(PlayerBody)
7. Scroll down to the bottom of it and add the lines:
maxinv[RedKey] =1; maxinv[BlueKey] =1; maxinv[YellowKey] =1;
Section #3 - Creating and using the doors.
1. To add a door, load up your map of choice.
2. Go into the map editor (F11) and go into the World Editor Creator (F4)
3. Look under Shapes and you should see two new entries 'Keys' and 'Door'
4. Expand Door and you'll see the door shape that can be insered into the map
5. Insert the door and position it where you would like.
6. Press F11 - walk up to your door, press your use key and the door should open.
Section #4 - Customizing your door.
I. - Locking the door.
To make the door locked, go back into the map editor, select your door, then hit F3.
Expand the dynamic variable section. Click the add button and create a new variable
called 'key'. Set the value to key to be 'Redkey'. Click the APPLY button for the
change to take effect.
Add a redkey to the map in the same manner as adding the door.
Go back into the game and try opening the door. Now go pick up the key and try
again.
II - Up and down.
To have your door slide down rather than go up, go into the map editor, select
the door, and press (F3). Expand the dynamic variable section and find the
variable named 'dir'. Change the value of 'dir' to 'down' (w/o the quotes).
Click APPLY, then exit the game editor (F11).
III - Open the door higher.
To have your door open further or less, go into the map editor, select
the door, and press (F3). Expand the dynamic variable section and find the
variable named 'liftheight'. Change the value of 'liftheight' to a different
number, such as 15 or such.
Click APPLY, then exit the game editor (F11).
That pretty much sums it all up. I included all the skins, and the simple shapes that
I used for the doors and keys. I know the art could be better, but I'm a programmer
not an artist. Hopefully this will help some of you who are more artist than programmer
get some doors in your games.
As alway, many thanks to the garagegames community whose bits and pieces of code and wisdom helped me put this together for others. Special thanks to Robert Brower whose resource:
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4004
gave me the info to get moving in the right direction with this.
*** 12/21/04 - Updated the code to handle left, right, forward, and back directions.
Note: If a door is opening towards the player, the door will pass through the player. This is due to the game engines collision detection scheme as discussed above.
#2
Just create a copy of that called Door::Swing
and edit the part under :
//Set our new position to that of our current position modified in a small
//increment of the direction of travel
%newLoc = setWord(%newLoc, 2, (getWord(%newLoc, 2) +(0.05*%door.movemod)));
//Move the door to the updated position
%door.settransform(%newLoc);
and change it to rotate along the objects z axis.. (of course you will need to set your object's axis in the right place so it doesnt rotate from the middle)
Look at the original resource for details on this - it implements swinging type doors.
Great resource!
12/02/2004 (6:21 am)
yah.. look at his Door::OpenDoor function.. There is a switch that calls the door type.. see Door::RaiseDoor.Just create a copy of that called Door::Swing
and edit the part under :
//Set our new position to that of our current position modified in a small
//increment of the direction of travel
%newLoc = setWord(%newLoc, 2, (getWord(%newLoc, 2) +(0.05*%door.movemod)));
//Move the door to the updated position
%door.settransform(%newLoc);
and change it to rotate along the objects z axis.. (of course you will need to set your object's axis in the right place so it doesnt rotate from the middle)
Look at the original resource for details on this - it implements swinging type doors.
Great resource!
#4
With a little more modification the doors can be made to open left, right, forward and back.
(Just have to be sure to push the doors along the proper vectors - can't just shift the values the same as up and down, since the doors left and right vectors won't always be at right angles.)
I tried using an animated dts file to make doors that open and close like real doors. But ran into the problem of the collision boxes not animating. So the door would open, and wham you'd walk right into an invisible wall - that of the collision box of the closed door.
There's a resource that allows you to select collision boxes in code to swap between collision boxes, but it's a major undertaking and I just don't need the functionality that bad yet. But it can be done.
12/02/2004 (8:05 pm)
Kevin's correct, in how to make the door rotate. I haven't gotten to the point of doing that yet.With a little more modification the doors can be made to open left, right, forward and back.
(Just have to be sure to push the doors along the proper vectors - can't just shift the values the same as up and down, since the doors left and right vectors won't always be at right angles.)
I tried using an animated dts file to make doors that open and close like real doors. But ran into the problem of the collision boxes not animating. So the door would open, and wham you'd walk right into an invisible wall - that of the collision box of the closed door.
There's a resource that allows you to select collision boxes in code to swap between collision boxes, but it's a major undertaking and I just don't need the functionality that bad yet. But it can be done.
#5
I do have a problem though with the end of section 3: following the instructions, I dropped a door somewhere and should be able to open it, but I can't. I tracked down the problem to the fact that liftheight is uninitialized, so that the door never opens.
On further inspection, it seems that the problem is: once I place the door, no dynamic variables are to be seen (F3). When I get near the door and activate it, the following dynamic variables are suddenly there: dir, movemod, isDoorOpen and baselevel - but still no liftheight. When I add liftheight the door works. Any idea on why that is?
I used starter.fps of the downloadable SDK, not HEAD.
12/04/2004 (9:13 am)
Great ressource!!I do have a problem though with the end of section 3: following the instructions, I dropped a door somewhere and should be able to open it, but I can't. I tracked down the problem to the fact that liftheight is uninitialized, so that the door never opens.
On further inspection, it seems that the problem is: once I place the door, no dynamic variables are to be seen (F3). When I get near the door and activate it, the following dynamic variables are suddenly there: dir, movemod, isDoorOpen and baselevel - but still no liftheight. When I add liftheight the door works. Any idea on why that is?
I used starter.fps of the downloadable SDK, not HEAD.
#6
You're right. I ran into the same strangeness...
Here's a quick fix for the doors to work without having to set liftheight first.
add the line:
at the very top of the door.cs file.
Then drop down to Doors::Interact and change
to read:
That will at least allow the door to open without setting the dynamic variable by hand.
The dynamic variable problem - I'm not sure why the editor is behaving that way. I'll see if I can find out why.
12/04/2004 (10:35 am)
Dirk,You're right. I ran into the same strangeness...
Here's a quick fix for the doors to work without having to set liftheight first.
add the line:
$DOOR_DEFAULT_HEIGHT = 5;
at the very top of the door.cs file.
Then drop down to Doors::Interact and change
function Door::interact(%this, %obj, %client)
{
//If the door is open we will not call the door open
//function
if (!%obj.isDoorOpen)
{
//Checks to see if the door has a dynamic variable called 'key' set to anything
if(%obj.key !$="")to read:
function Door::interact(%this, %obj, %client)
{
//If the door is open we will not call the door open
//function
if (!%obj.isDoorOpen)
{
if(!%obj.liftheight) %obj.liftheight=$DOOR_DEFAULT_HEIGHT;
//Checks to see if the door has a dynamic variable called 'key' set to anything
if(%obj.key !$="")That will at least allow the door to open without setting the dynamic variable by hand.
The dynamic variable problem - I'm not sure why the editor is behaving that way. I'll see if I can find out why.
#7
12/07/2004 (10:47 am)
on this resource can I don't wont the dor to open I wont it to explode, is it posible?
#8
Here's a forum thread that might help point you in the right direction though.
www.garagegames.com/mg/forums/result.thread.php?qt=21018
Also search the forums for 'exploding objects'
12/07/2004 (11:00 am)
Anything's possible. But it's not coded to take damage or explode.Here's a forum thread that might help point you in the right direction though.
www.garagegames.com/mg/forums/result.thread.php?qt=21018
Also search the forums for 'exploding objects'
#9
This allows for more flexibility in using doors rather than the straight up/down.
The updated file is in the .zip file with the resource.
12/21/2004 (8:14 pm)
Just an update. I went back and recoded the door.cs file. It will now handle 'up', 'down', 'left', 'right', 'forward' and 'back' as directions to move the doors along.This allows for more flexibility in using doors rather than the straight up/down.
The updated file is in the .zip file with the resource.
#10
I tried as Kevin suggested but can't get it to swing.
02/13/2005 (6:39 am)
Can someone post the code to make the door swing?I tried as Kevin suggested but can't get it to swing.
#11
03/13/2005 (10:02 pm)
The only problem I have with this script is that I cannot seem to find a way to function it to commands.cs for server players to use whatever button is assigned to open the door. Any suggestions?
#12
03/14/2005 (5:40 am)
Not sure what you mean Chris. The resource has the U key bound to "Use" the door and command to server to activate it. Which part are you having problem with?
#13
04/19/2005 (6:10 pm)
I did everything and I got up placing the door and then trying it out. Everything is executed exactly. I used "o" as my interact key. I walk up to the door with one of the keys or even all three of them and press "o" and the whole game always crashes. I am not sure what to do. Any suggestions?
#14
04/20/2005 (4:32 am)
Rob, put alot of echo statement in the scripts and try to determine exactly what part causes the crash. The other thing you might try is run the debug version of the game and see if you can trap the event in the engine.
#15
04/25/2005 (1:54 pm)
will doors be included into the torque constructor? will be a bit fiddly to put all the doors in on the world editor
#16
04/29/2005 (5:57 am)
Here is a good one for ya. I put in the door and my testers tell me they can back thru the door without having a key. Seems the onCollision function that does the push back to prevent player trapped in the doorway also provides a cheat. So no keys are required.
#17
Get a friend to open the door quickly and get you unstuck or die.
There is also a way to do the doors with interiors, but Quark scares me a little, so I'm glad this resource was here.
Ari Rule
06/29/2005 (5:42 am)
I had the same problem so I just changed the onCollision to do damage instead of push the player back.Get a friend to open the door quickly and get you unstuck or die.
There is also a way to do the doors with interiors, but Quark scares me a little, so I'm glad this resource was here.
Ari Rule
#18
Also, I thought you might like to know that "moveMap.bindCmd(keyboard, "w", "commandToServer('Interact');", "");" doesn't have to be put in those files. Instead, just paste it into interact.cs or any other file in the server/scripts directory. It doesn't really matter where you put it as long as it's in a file that will be executed during gameplay. It's the same for all movemap.bind commands.
And, I'll be working on a door that explodes soon. It'll take a little while, but I'll figure it out. I also want to make one that blasts open when you run into it with a car or something.
08/02/2005 (4:31 pm)
It's a good resource. I looks kinda funky when it moves in the editor though. Very odd.Also, I thought you might like to know that "moveMap.bindCmd(keyboard, "w", "commandToServer('Interact');", "");" doesn't have to be put in those files. Instead, just paste it into interact.cs or any other file in the server/scripts directory. It doesn't really matter where you put it as long as it's in a file that will be executed during gameplay. It's the same for all movemap.bind commands.
And, I'll be working on a door that explodes soon. It'll take a little while, but I'll figure it out. I also want to make one that blasts open when you run into it with a car or something.
#19
So that players can't get stuck in them.
Ari Rule
08/30/2005 (11:21 pm)
Pretty soon I'll have the doors open on collision (if they have the key, if one is required).So that players can't get stuck in them.
Ari Rule
#20
08/31/2005 (5:07 am)
Can you make them swing as well? 
Torque Owner Jen Garcia
Otherwise, it's a great code snippet... very complete!