Game Development Community

Player Identities not staying constant?

by Jerane Alleyne · in Torque Game Engine · 08/27/2002 (7:17 pm) · 3 replies

I'm having a series of very puzzling bugs that I was hoping I could get some help with and that all seem to be interconnected.

First off, I have a homing missile, the method by which I obtain the "ID" of the targetted player in my cross hairs is:

if (gClientContainer.castRay(camPos, endPos, ObjectMask, &info)) {
if (ShapeBase* obj = dynamic_cast(info.object))
{
// We obtained the player info from castRay, casted it into a
// SceneObject type, and stored it in the Projectile
// datablock for further use.

mTargetObjectID = obj;

Obviously that's not the entire code section, but what it does is gets the ShapeBase instance of the player in my crosshairs and assigns it to mTargetObjectID (defined as ShapeBase*).

Then, we get in game, just two players.

If I have the player in my crosshairs (and he does NOT have me in his crosshairs) and I fire, the missile tracks him like normal.

However, if we BOTH have each other in our crosshairs, and I fire, the missile hits ME instead.

That's not the only bug that seems to be connected - in our game, we have the muzzle flash on for certain weapons, so that when the player fires the weapon a small burst of light accompanies the weapon fire.

However, currently when the player fires the weapon, the burst of light does not appear around the player firing the weapon, but instead around *every other player*. Again, this is confusing but it seems that it might have something in common.

Anyone have any ideas, or do you guys need more information from me?

#1
08/27/2002 (9:21 pm)
Dunno if that helps, but you can check if the object isn't the client itself with:
GameConnection* conn = GameConnection::getServerConnection();
ShapeBase* control = conn->getControlObject();
if (obj != control && obj->getShapeName())
...
That should prevent you from "shooting yourself" at least...
#2
08/27/2002 (10:01 pm)
Well without seeing the entire code I'm pretty sure no one will be able to pin down the exact problem. But from the description I can guess at what the problem is.

You're using a target scanning function to decide if you have a "lockable" target before firing your missile. The problem is, it sound like, you are using a shared function, so all the clients are calling the same function at the same time, last client in the list will have his target set to the default target.

Each client should have their own targetID and lock status.
#3
08/28/2002 (10:13 am)
Alright, here's all the relevant code:

In Projectile.cc in the onAdd() method I call getPlayer(), because when a projectile is added it means that the crosshairs are potentially on the target.

void Projectile::getPlayer()
{
// Must have a connection and player control object
GameConnection* conn = GameConnection::getServerConnection();
if (!conn)
return;
ShapeBase* control = conn->getControlObject();
if (!control || !(control->getType() & ObjectMask) || !conn->isFirstPerson())
return;

// Get control camera info
MatrixF cam;
Point3F camPos;
conn->getControlCameraTransform(0,&cam);
cam.getColumn(3, &camPos);

// Extend the camera vector to create an endpoint for our ray
Point3F endPos;
cam.getColumn(1, &endPos);
endPos *= gClientSceneGraph->getVisibleDistance();
endPos += camPos;

control->disableCollision();

RayInfo info;
if (gClientContainer.castRay(camPos, endPos, ObjectMask, &info)) {
// Hit something... but we'll only display health for named
// ShapeBase objects. Could mask against the object type here
// and do a static cast if it's a ShapeBaseObjectType, but this
// isn't a performance situation, so I'll just use dynamic_cast.
if (SceneObject* obj = dynamic_cast(info.object))
{
// We obtained the player info from castRay, casted it into a
// SceneObject type, and stored it in the Projectile
// datablock for further use.

mTargetObjectID = obj;
goodTarget = true;
}
}

else
goodTarget = false;
control->enableCollision();
}

Then, I use that SceneObject instance I obtained in getPlayer and call getTransform to get the position of the targetted player. onAdd() is only called once, when the projectile is added to the game, but since this code is placed inside the processTick function of Projectile.cc, it is called every tick.

// If we are homing AND we have a good target
if(mDataBlock->isHoming && goodTarget)
{
// Create a matrix, get the data for it from the target's ID
const MatrixF& mat = mTargetObjectID->getTransform();

// Turn it into usable XYZ data
mat.getColumn(3,&pos);
}

That help any?