Game Development Community

Door Object Resource Method

by Treyd · in Technical Issues · 07/13/2007 (8:17 am) · 7 replies

Hi,

I'm trying to get this resource working:

http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=10200

Can someone help me figure out how to use the console method the author speaks of:

%obj.toggle();

I tried placing this in my player.cs onCollision() as %this.toggle(); just to see if I collided with the door if it would open. I didn't work...
What I'd really like to do with this is get it set up for key press just like every game does where if I walk up to the door and press say "e" the door opens. Not sure if this resource will allow me to do this. I'm thinking I might have to use this resource instead or some hybrid of the two.

http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=4004

Any help would be greatly appreciated.

#1
07/14/2007 (11:52 am)
Ok bumping my own post...

I'm an idiot...
I opened the map editor and got the exact ID of the door and ran it in the console 1541.toggle(); does work. The door works great! Note 1541 ID# is specific to my editor, yours will more than likely be something different. Now I can set up my key press shyte. As soon as I have it I'll post it here for anyone who likes. Also I realized %this.toggle() in the onCollision is totally wrong. It should be %col.toggle(); Don't know how the hell I screwed that up. Don't get up extra early and try to code before work...ahhhh F-that code whenever you have a free nanosecond! Be back with keypress before the end of the weekend.

Later
#2
07/14/2007 (11:54 am)
Just keep in mind it's very bad practice to use actual object ID numbers in your scripts :)

Glad to hear you have it working a bit.
#3
07/14/2007 (12:08 pm)
Thanks Stephen,

Good to know you guys are actively scouting the forums.
I'm thinking about going this route with the Interact command I saw it in this resource here:

http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=6780

It gets saved as interact.cs and exec'd at startup

function serverCmdinteract(%client)
{

// get the player object
%player = %client.player;

// with %distance set to 4, we can activate things that are 4m away.
%distance = 4;

// determine where the player is looking, and scale it out by a factor
// of %distance. By default, this gives us a 4m long vector
%eye = %player.getEyeVector();
%vec = vectorScale(%eye, %distance);

// define the start and end coordinates of the ray
%startPoint = %player.getEyeTransform();
%endPoint = VectorAdd(%startPoint,%vec);

// set the mask to only return a hit on ShapeBase objects
%searchMasks = $TypeMasks::StaticObjectType;

// cast ray starting at startPoint ending at endPoint with mask, ignoring %player
%scanTarg = ContainerRayCast (%startPoint, %endPoint, %searchMasks, %player);

// call the interact function on the object's datablock
if(%scanTarg)
%scanTarg.getDataBlock().interact(%scanTarg,%client);

}

And placing this in the datablock of the door:

function Door::onInteract (%this, %obj)
{
%obj.toggle();
%this.schedule(5000, "toggle", %obj)
}

I'm really take a wild guess at this point just saw you responded and wanted to get something up quickly. I really need to get my hands dirty with it since I'm not very good at code I learn by making it not work 20 different ways then finally after there's no more ways for it to be broke I find how it works. Ok later I'll give it shot.
#4
07/14/2007 (12:42 pm)
One thing that is important in learning TorqueScript (and it's event based nature) is to carefully track parameters that get passed along an execution stack. For example, the interaction of the ::onInteract code is actually pretty complex, and the way you have it listed above is probably causing you some issues:

// call the interact function on the object's datablock
if(%scanTarg)
  %scanTarg.getDataBlock().interact(%scanTarg,%client);

and

function Door::onInteract (%this, %obj)
{
  %obj.toggle();
  %this.schedule(5000, "toggle", %obj)
}

can be very confusing if you aren't aware of how things work in the TorqueScript parsing.

Let's sit down and define some of the variables we are using, based on how the code reads:

%client: This is the objectID of the GameConnection object that indicates which network connection is being used for this particular call.
%scanTarg : based on how the containerRayCast is defined, this variable should contain a server side ObjectID of the object that is first to be hit with the ray being cast

%scanTarg.getDataBlock() : this method call returns the objectID of the datablock assigned to the %scanTarg.
%scanTarg.getDataBlock().interact(%scantarg, %client) : this call happens on the namespace list associated with the datablock of the object that the ray hits. Normally, a good naming convention would mean this datablock is named "DoorData", instead of "Door", since "Door" implies an actual object in the game world, where "DoorData" is more obviously not a specific game object, but data about a game object type.

Now, something very important to note in your code above:

the namespace method call
%scanTarg.getDataBlock().interact(%scanTarg,%client);

does not call the code
function Door::onInteract (%this, %obj)

If you look carefully, you are trying to call Door::interact, but you've written a method called Door::onInteract().

In addition, it's very important to know and understand that when you make a namespace method call, the TorqueScript parser will automatically put the objectID of the object the call is being made upon as the first argument. User supplied arguments (your %scanTarg, and %client) are going to be placed after the object ID of the object that the method is being called upon, which actually means that the namespace method needs to accept three arguments, not just the two you send.

so, end result, if you want things to be working properly given your code above, you should make the following changes:

%scanTarg.getDataBlock().interact(%scanTarg,%client);

should be

%scanTarg.getDataBlock().onInteract(%scanTarg, %client);

and the method declaration should go from:

function Door::onInteract (%this, %obj)

to

function Door::onInteract(%this, %obj, %client)

which would give your ::onInteract method the following three arguments:

%this: the object id of a datablock that is assigned to %obj
%obj: the actual in game objectID of the "thing" being interacted with
%client: the object ID of the GameConnection object associated with the client that is interacting with the door. Note: %client is not used in your method, which is why this wasn't obvious to you.
#5
07/14/2007 (5:30 pm)
Stephen you are the man!

Thanks for clearing some things up that were a little foggy for me. Everything works as you've suggested. I got it bound to the "j" key and it works fine. Now the problem lies in the original resource.... sigh whenever the casting is called it sometimes finds the door and sometimes doesn't. Upon further testing at times after a few toggle() calls I can run through the door. Its like the collision mesh is changing shape and location or not appearing right away.

I just swapped out the author's model for a different door and it seems to be working fine now.

Also its possible my %distance in the casting was set too high so I lowered that. And I also tightened up the field in the authors datablock for the door that searches for a player blocking the door. I was thinking it was to large in scale and I had to be far away from the door to open it.

Thanks for help, encouragement, and support through this.

Best,

Trey

If someone really wants the bind code I'll post it but I just followed the examples from this resource on weapon reloading to get it working. I've got notify on for the thread.

http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=2286
#6
07/14/2007 (8:47 pm)
Well i have not bound the door object resource to a kb key yet, but for me it worked without any problems whatso ever. i simpley used the included door.cs file, execed it. then dropped that into my mission and presto a working door (although like i said i did not bind the open to a kb key yet, simpled used collision to do that for th etime being)
#7
07/30/2007 (1:28 pm)
My my, it took me a while to get this going. The door would never come back down again.

I finally found, that this isn't quite correct:

function Door::onInteract (%this, %obj)
{
%obj.toggle();
%this.schedule(5000, "toggle", %obj)
}

Instead it should be:

function Door::onInteract (%this, %obj, %client)
{
%obj.toggle();
%obj.schedule(5000, "toggle")
}

Using TGE 1.5.2