Mounting, I beg of you, please help
by Charlie Higdon · in Torque Game Engine · 10/12/2008 (6:50 pm) · 9 replies
I'm having the worst time with mounting. This was my attempt at learning how to place an object on another object without any specific name. I figured I'd start slow.
There is a lot commented out, I left it there so I wouldn't try the same things again.
//===========================================
//$STICKAT::PLAYER_REACH = 4.5;
datablock ItemData(Test)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Test";
// Basic Item properties
shapeFile = "~/data/shapes/player/player.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "item to place or mount";
};
datablock StaticShapeData(ShapeA)
{
category = "Test";
shapeFile = "~/data/shapes/player/player.dts";
};
================================================
function Test::onUse(%obj,%this,%user,%player)
//On use, place this item at the location the player's crosshair is at
//according to specified mask.
{
%player = %this;
%eye = %player.getEyeVector();
//Get the starting position for the raycast
%startPoint = %player.getEyeTransform();
//This should be the ending position for the raycast
%endPoint = vectorScale(%eye, 4.5 );
%endPoint = vectorAdd(%startPoint,%endPoint);
//Echo out the positions
echo("StartPoint = " + %startpoint);
echo("EndPoint = " + %endpoint);
%found = ContainerRayCast (%startPoint, %endPoint, $TypeMasks::InteriorObjectType, %player);
if(%found)
//%found.getDataBlock().Operate(%found);
//%startPosition = %player.getWorldBoxCenter();
//%forwardVector = %player.getForwardVector();
//%endPosition = VectorScale( %forwardVector , 10 );
//%endPosition = VectorAdd( %startPosition, %endPosition );
//%info = ContainerRayCast(%startPosition, %endPosition, -1, %player);
new Staticshape(ShapeA) {
datablock = "ShapeA";
//position = FreshMeat.getTransform();
position = %endPoint;
//position = LocalClientConnection.camera.getTransform();
//position = LocalClientConnection.camera.getPosition();
//position = %endPosition();
};
%user.decInventory(%this,1);
if (%user.client)
messageClient(%user.client, 'Shape Used');
}
//=======================================================================
That allows me to pick up the crossbow and have it stick on an InteriorObjectType when I am within range, with one in inventory, and pressing the key I set to use it.
I chose player because I thought it had both types MountPoints and Mount nodes. What in the name of God could I change/add to have this object actually mount to a static shape.
Example: I pick up the twirling player item, walk within range of my raycast to a StaticShape of the player model, and press use. How do I tell it to mount the object to the object I am raycasting too? I know the basic
line.
%shapeA.mountObject( %shapeB, 10);
I am confused how to add this into my code. I'm surprised I got as far as I did. Please, someone help me this little bit.
I know I need to change the search mask to reflect static shapes, but other than that I am lost. I don't know how to specify for the item to mount to, and ONLY to a certain object, not every other staticshape with a mountpoint. Where would I specify the specific object to be mounted to? I have the feeling I need to declare the datablock for both the item being mounted as a static shape, and the datablock of the staticshape being mounted to.
There is a lot commented out, I left it there so I wouldn't try the same things again.
//===========================================
//$STICKAT::PLAYER_REACH = 4.5;
datablock ItemData(Test)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Test";
// Basic Item properties
shapeFile = "~/data/shapes/player/player.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "item to place or mount";
};
datablock StaticShapeData(ShapeA)
{
category = "Test";
shapeFile = "~/data/shapes/player/player.dts";
};
================================================
function Test::onUse(%obj,%this,%user,%player)
//On use, place this item at the location the player's crosshair is at
//according to specified mask.
{
%player = %this;
%eye = %player.getEyeVector();
//Get the starting position for the raycast
%startPoint = %player.getEyeTransform();
//This should be the ending position for the raycast
%endPoint = vectorScale(%eye, 4.5 );
%endPoint = vectorAdd(%startPoint,%endPoint);
//Echo out the positions
echo("StartPoint = " + %startpoint);
echo("EndPoint = " + %endpoint);
%found = ContainerRayCast (%startPoint, %endPoint, $TypeMasks::InteriorObjectType, %player);
if(%found)
//%found.getDataBlock().Operate(%found);
//%startPosition = %player.getWorldBoxCenter();
//%forwardVector = %player.getForwardVector();
//%endPosition = VectorScale( %forwardVector , 10 );
//%endPosition = VectorAdd( %startPosition, %endPosition );
//%info = ContainerRayCast(%startPosition, %endPosition, -1, %player);
new Staticshape(ShapeA) {
datablock = "ShapeA";
//position = FreshMeat.getTransform();
position = %endPoint;
//position = LocalClientConnection.camera.getTransform();
//position = LocalClientConnection.camera.getPosition();
//position = %endPosition();
};
%user.decInventory(%this,1);
if (%user.client)
messageClient(%user.client, 'Shape Used');
}
//=======================================================================
That allows me to pick up the crossbow and have it stick on an InteriorObjectType when I am within range, with one in inventory, and pressing the key I set to use it.
I chose player because I thought it had both types MountPoints and Mount nodes. What in the name of God could I change/add to have this object actually mount to a static shape.
Example: I pick up the twirling player item, walk within range of my raycast to a StaticShape of the player model, and press use. How do I tell it to mount the object to the object I am raycasting too? I know the basic
line.
%shapeA.mountObject( %shapeB, 10);
I am confused how to add this into my code. I'm surprised I got as far as I did. Please, someone help me this little bit.
I know I need to change the search mask to reflect static shapes, but other than that I am lost. I don't know how to specify for the item to mount to, and ONLY to a certain object, not every other staticshape with a mountpoint. Where would I specify the specific object to be mounted to? I have the feeling I need to declare the datablock for both the item being mounted as a static shape, and the datablock of the staticshape being mounted to.
About the author
#2
Can StaticShape and the datablock have the same name,
and shouldent one of the definitors have a % ?
Sorry for blurred eye ramblings -good luck!
10/13/2008 (2:52 pm)
Kneedeep in .asp all evening, and on my way to bed...Can StaticShape and the datablock have the same name,
and shouldent one of the definitors have a % ?
Sorry for blurred eye ramblings -good luck!
#3
I guess I'm just to stupid to do this.
I've spent 4 days, and I mean WHOLE days messing with this. I've tried using shapes from the game that I know have mount points and nodes, I've tried making my own. I was able to make a weapon and replace the crossbow, so I know I have at least one shape with mountpoints working.
This is the same thing that made me quit trying with it about 2 months ago.
It should be simple, but for the love of God I just don't see it.
Pick up item, ( a sign for example), walk over to a sign post, press the button I assigned for using the sign, and have it mount to the signpost.
Instead what I have is,
Pick up item ( a sign), walk over to ANY searchmask specified in script, press the button I assigned, and have it stick where the raycast is ending.
I do not know how to tell it to get the datablock of the item I am raycasting at, and mount the objects if the datablock matches.
10/13/2008 (3:15 pm)
I don't know anymore, not that I ever did. I've bought every torque book out there searched through all the resources on mounting and posts, I just don't know.I guess I'm just to stupid to do this.
I've spent 4 days, and I mean WHOLE days messing with this. I've tried using shapes from the game that I know have mount points and nodes, I've tried making my own. I was able to make a weapon and replace the crossbow, so I know I have at least one shape with mountpoints working.
This is the same thing that made me quit trying with it about 2 months ago.
It should be simple, but for the love of God I just don't see it.
Pick up item, ( a sign for example), walk over to a sign post, press the button I assigned for using the sign, and have it mount to the signpost.
Instead what I have is,
Pick up item ( a sign), walk over to ANY searchmask specified in script, press the button I assigned, and have it stick where the raycast is ending.
I do not know how to tell it to get the datablock of the item I am raycasting at, and mount the objects if the datablock matches.
#4
//Datablocks, both ItemData and StaticShape Data go here
//-----------------------------------------------------------------
datablock ItemData(Box)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt3.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "a test shape to mount";
};
datablock ItemData(boxmt2)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt2.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "a test shape to mount";
};
datablock StaticShapeData(boxmt5)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt3.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
};
datablock StaticShapeData(boxmt4)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt2.dts";
// Dynamic properties defined by the scripts
};
//-------------------------------------------------
//-----------End of Datablock Section--------------
//-------------------------------------------------
//-------------------------------------------------
//-------Raycast and Mounting Functions here-------
//-------------------------------------------------
function Box::onUse(%obj,%this,%user,%player)
//On use, have a raycast and upon striking a particular StaticShape,
//have an item be mounted on that specific shape and only that shape.
// We do not want it to mount on just any old thing.
//Example, sign mounts on sign post, not on refrigerator.
{
%player = %this;
%eye = %player.getEyeVector();
//Get the starting position for the raycast
%startPoint = %player.getEyeTransform();
//This should be the ending position for the raycast
%endPoint = vectorScale(%eye, 4.5 );
%endPoint = vectorAdd(%startPoint,%endPoint);
//Echo out the positions
echo("StartPoint = " + %startpoint);
echo("EndPoint = " + %endpoint);
%found = ContainerRayCast (%startPoint, %endPoint, $TypeMasks::StaticShapeObjectType, %player);
if(%found)
new Staticshape(Test)
{
datablock = "boxmt5";
boxmt5.mountObject(boxmt4, 0);
//position = %endPoint;
};
%user.decInventory(%this,1);
if (%user.client)
messageClient(%user.client, 'Box Used');
=====================================
That's where i'm at now, getting a syntax error on "boxmt5.mountObject(boxmt4, 0);"
I've tried it as
"boxmt5.mountObject(boxmt4, 0);"
"%boxmt5.mountObject(%boxmt4, 0);"
I reckon I still need to get the ID of the staticshape i'm raycasting and if the ID matches (where i specify that i have no idea) then I tell it to mount the two shapes....which I guess I'm no where near right either.
10/13/2008 (9:29 pm)
//-----------------------------------------------------------------//Datablocks, both ItemData and StaticShape Data go here
//-----------------------------------------------------------------
datablock ItemData(Box)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt3.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "a test shape to mount";
};
datablock ItemData(boxmt2)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt2.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "a test shape to mount";
};
datablock StaticShapeData(boxmt5)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt3.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
};
datablock StaticShapeData(boxmt4)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
// Basic Item properties
shapeFile = "~/data/shapes/mnt/boxmt2.dts";
// Dynamic properties defined by the scripts
};
//-------------------------------------------------
//-----------End of Datablock Section--------------
//-------------------------------------------------
//-------------------------------------------------
//-------Raycast and Mounting Functions here-------
//-------------------------------------------------
function Box::onUse(%obj,%this,%user,%player)
//On use, have a raycast and upon striking a particular StaticShape,
//have an item be mounted on that specific shape and only that shape.
// We do not want it to mount on just any old thing.
//Example, sign mounts on sign post, not on refrigerator.
{
%player = %this;
%eye = %player.getEyeVector();
//Get the starting position for the raycast
%startPoint = %player.getEyeTransform();
//This should be the ending position for the raycast
%endPoint = vectorScale(%eye, 4.5 );
%endPoint = vectorAdd(%startPoint,%endPoint);
//Echo out the positions
echo("StartPoint = " + %startpoint);
echo("EndPoint = " + %endpoint);
%found = ContainerRayCast (%startPoint, %endPoint, $TypeMasks::StaticShapeObjectType, %player);
if(%found)
new Staticshape(Test)
{
datablock = "boxmt5";
boxmt5.mountObject(boxmt4, 0);
//position = %endPoint;
};
%user.decInventory(%this,1);
if (%user.client)
messageClient(%user.client, 'Box Used');
=====================================
That's where i'm at now, getting a syntax error on "boxmt5.mountObject(boxmt4, 0);"
I've tried it as
"boxmt5.mountObject(boxmt4, 0);"
"%boxmt5.mountObject(%boxmt4, 0);"
I reckon I still need to get the ID of the staticshape i'm raycasting and if the ID matches (where i specify that i have no idea) then I tell it to mount the two shapes....which I guess I'm no where near right either.
#5
A datablock is an object, granted. A datablock is an object that stores information. The point of this is so that objects of the same type can share information that doesn't change in the course of a game. Take cars for an example.
Datablocks can also define slightly more specific properties:
So how do objects relate to this?
When you create a car object, you give it a datablock. You're not creating a copy of the datablock or anything; you're just pointing at the datablock object. So we want to create a red car.
Now, this actual object contains a reference to the RedCar datablock. It knows what sort of car it is because we told it 'you can look at RedCar to get all the information about yourself'.
The key thing is that the datablock is a separate object; don't confuse OurCar and RedCar. RedCar is an object that holds static information; OurCar is a Car object in the level.
In your script, %found gives you the ID of the world object (not the datablock) that was hit by the raycast (datablocks don't exist in the physical level, right?). So you want to mount a shape to %found. You created a new StaticShape called Test. You want to mount this to object %found. So you'd use:
And one more note: you're currently trying to mount within the Test object's definition. Don't do that. Your code should look like this:
I'm a little pressed for time, so I didn't go into too much depth, and there still may be problems in the code, but I think I've worked through the fundamentals :) Hope it helps.
10/14/2008 (7:52 am)
Quote:boxmt5.mountObject(boxmt4, 0);You're not mounting objects, you're mounting datablocks. This is the same problem I had when I was picking up TS, and it's a critical thing. I think you're mixing up datablock and objects.
A datablock is an object, granted. A datablock is an object that stores information. The point of this is so that objects of the same type can share information that doesn't change in the course of a game. Take cars for an example.
datablock CarData(BasicCar)
{
hasWheels = true;
numWheels = 4;
hasEngine = true;
canRunPeopleOver = true;
};This obviously isn't a real datablock, but pretend. This defined a datablock of class CarData. The datablock's name is BasicCar. It defines a number of properties that are true for all cars - all cars have 4 wheels, an engine, and can run people over.Datablocks can also define slightly more specific properties:
datablock CarData(RedCar: BasicCar)
{
colour = Red;
};
datablock CarData(BlueCar: BasicCar)
{
colour = Blue;
};Now we've defined datablocks named RedCar and BlueCar, still of type CarData. The ' : BasicCar' just means that the datablocks copy all the data from BasicCar, to avoid us writing out the same properties again. What we've added is a colour valueto these datablocks. All red cars are red, and all blue cars are blue.So how do objects relate to this?
When you create a car object, you give it a datablock. You're not creating a copy of the datablock or anything; you're just pointing at the datablock object. So we want to create a red car.
new Car(OurCar) {
dataBlock = RedCar;
position = "x y z";
};This creates an actual Car object, the physical car, at position xyz. We named the car 'OurCar' so we can call it by name if we want to.Now, this actual object contains a reference to the RedCar datablock. It knows what sort of car it is because we told it 'you can look at RedCar to get all the information about yourself'.
The key thing is that the datablock is a separate object; don't confuse OurCar and RedCar. RedCar is an object that holds static information; OurCar is a Car object in the level.
Quote:boxmt5.mountObject(boxmt4, 0);So again. Here, you are telling the boxmt4 datablock to mount itself to the boxmt5 datablock. Which is nonsensical, since datablocks aren't physical objects in the world. You have to tell the object instances to mount.
In your script, %found gives you the ID of the world object (not the datablock) that was hit by the raycast (datablocks don't exist in the physical level, right?). So you want to mount a shape to %found. You created a new StaticShape called Test. You want to mount this to object %found. So you'd use:
%found.mountObject(Test,0);
And one more note: you're currently trying to mount within the Test object's definition. Don't do that. Your code should look like this:
new StaticShape(Test) {
dataBlock = boxmt5;
};
%found.mountObject(Test,0);
//position = %endPoint;I'm a little pressed for time, so I didn't go into too much depth, and there still may be problems in the code, but I think I've worked through the fundamentals :) Hope it helps.
#7
I appreciate explaining about datablocks in the gameworld. I was thinking telling it to mount by datablock was the same as telling it to mount the object, since the object is defined in the datablock. You wouldn't believe how long I spent just getting a raycast to work =).
Thanks again. Works perfect now.
10/14/2008 (2:56 pm)
Thank you Daniel. I was finally able to get it working with that. I stuck several mountable items around as a test, and it would only mount to the one I wanted.I appreciate explaining about datablocks in the gameworld. I was thinking telling it to mount by datablock was the same as telling it to mount the object, since the object is defined in the datablock. You wouldn't believe how long I spent just getting a raycast to work =).
Thanks again. Works perfect now.
#8
10/15/2008 (6:57 am)
Daniel, that was an excellent writeup. Thumbs up!
#9
Glad I could help :)
10/16/2008 (7:52 am)
Quote:I was thinking telling it to mount by datablock was the same as telling it to mount the object, since the object is defined in the datablock.That's exactly what I ran into, though this was in the area of writing functions in datablocks' namespaces. The world objects just refer to the datablock object for information.
Glad I could help :)
Torque Owner Charlie Higdon
datablock ItemData(boxmt3)
{
// Mission editor category, this datablock will show up in the
// specified category under the "shapes" root category.
category = "Mounting";
// Basic Item properties
shapeFile = "~/data/shapes/things2mnt/boxmt3.dts";
mass = 2.0;
elasticity = 0.2;
// Dynamic properties defined by the scripts
pickUpName = "a test shape to mount";
};
datablock StaticShapeData(Test3)
{
category = "Mounting";
shapeFile = "~/data/shapes/things2mnt/boxmt3.dts";
};
datablock StaticShapeData(Test2)
{
category = "Mounting";
shapeFile = "~/data/shapes/things2mnt/boxmt2.dts";
};
//////////////////////////////////////////////////////////////////
function Boxmt::onUse(%obj,%this,%user,%player)
//On use, place this item at the location the player's crosshair is at
//as long as it is in range and not on a vehicle, another player, or water.
{
%player = %this;
%eye = %player.getEyeVector();
//Get the starting position for the raycast
%startPoint = %player.getEyeTransform();
//This should be the ending position for the raycast
%endPoint = vectorScale(%eye, 4.5 );
%endPoint = vectorAdd(%startPoint,%endPoint);
//Echo out the positions
echo("StartPoint = " + %startpoint);
echo("EndPoint = " + %endpoint);
%found = ContainerRayCast (%startPoint, %endPoint, $TypeMasks::StaticShapeObjectType, %player);
if(%found)
new Staticshape(Test3)
{
datablock = "Test3";
%Test2.mountObject(%Test3, 0);
};
%user.decInventory(%this,1);
if (%user.client)
messageClient(%user.client, 'Shape Used');
}
//====================================================================
I get the following message "Line 92 syntax error".
Line 92 for me is " %Test2.mountObject(%Test3, 0);"
I simply want to mount Test3 to Test2 if my raycast determines that it has struck a Test2 within range. The objects have mountpoints, nodes, collision, all that good stuff. Please someone help.