ID's not matching (and changing)?
by James Laker (BurNinG) · in Torque Game Engine · 02/13/2007 (10:41 am) · 10 replies
Okay...
I've read the other posts about these not matching up, without a solution.
I've created a Targetting reticule that displays an bitmap above the player (or bot) that I have currently targetted.
In my guiTargetHud I have this piece of code:
Now Con::printf("Debug 2.2 (%d)", shape->getId()); does display the ID. My problem is that when the shape is out of my view and returns, the Id has changed... Why does this happen?
Then in my script I use this piece of code:
But these ID's don't match up. Now I think it's because it might be using ControlObject's ID.
Can anyone give me some insight, an exlpanation and/or a solution?
TIA
James
I've read the other posts about these not matching up, without a solution.
I've created a Targetting reticule that displays an bitmap above the player (or bot) that I have currently targetted.
In my guiTargetHud I have this piece of code:
...
// All ghosted objects are added to the server connection group,
// so we can find all the shape base objects by iterating through
// our current connection.
for (SimSetIterator itr(conn); *itr; ++itr) {
if ((*itr)->getType() & ShapeBaseObjectType) {
ShapeBase* shape = static_cast<ShapeBase*>(*itr);
if (shape != control && shape->getShapeName()) {
Con::printf("Debug 2.1 (%d)", LockedTargetID);
Con::printf("Debug 2.2 (%d)", shape->getId());
//Check to see if we are finding the correct Target
if (shape->getId() != LockedTargetID || LockedTargetID < 0)
return;
...Now Con::printf("Debug 2.2 (%d)", shape->getId()); does display the ID. My problem is that when the shape is out of my view and returns, the Id has changed... Why does this happen?
Then in my script I use this piece of code:
...
// Use the container system to iterate through all the objects
// within our scan radius. We'll only for ShapeBase objects.
InitContainerRadiusSearch(%position, %scanRadius, $TypeMasks::ShapeBaseObjectType);
while ((%targetObject = containerSearchNext()) != 0) {
// If its an player
if (%targetObject.player)
{
echo("%targetObject = " @ %targetObject);
echo("%targetObject name = " @ %targetObject.getshapename());
echo("Current Lock Target = " @ %this.lockedid);
// Only target this player if he is not already targetted
if (%targetObject != %this.lockedid)
{
//Target locked!!!
%this.lockedid = %targetObject;
...But these ID's don't match up. Now I think it's because it might be using ControlObject's ID.
Can anyone give me some insight, an exlpanation and/or a solution?
TIA
James
#2
It might be interesting to see if the value of shape->getGhostId() (or getNetIndex() in C++) changes during these periods.
That's about all I got on this one.
02/13/2007 (11:39 am)
If the client-side ID changes when it goes out of view, could that mean that it's going out of scope, hence no longer ghosted for a moment (maybe?), then when you view it again, you are looking at at different client-side instance? Not sure if that makes any sense, though. It might be interesting to see if the value of shape->getGhostId() (or getNetIndex() in C++) changes during these periods.
That's about all I got on this one.
#3
02/13/2007 (12:08 pm)
Yes, when the object goes out of view it is no longer ghosted. When it gets back, it is assigned a new ghost ID.
#4
EDIT:
This seems to work:
But is it the correct way of doing it?
02/13/2007 (12:33 pm)
Stefan: So what should I use, since Im in the dark here. plsEDIT:
This seems to work:
if (conn->getId()-1 != LockedTargetID || LockedTargetID < 0)
But is it the correct way of doing it?
#5
For some reason, that seems to work. So apparently, even though the client-side ID might change when it goes out of scope, pointers to the object stay valid. At least they do so far...it could be that this only works when I'm running it in single player mode. I'll check later if this is the case.
02/13/2007 (12:35 pm)
BTW, I am doing something similar, in that I have a gameTSCtrl that tracks a reference to a selected object, and instead of storing the ID, I store a pointer to the actual ShapeBase instance in a static variable in the ShapeBase class (I took much of the code from the object selection resource). Then inside the ShapeBase onRender method, I compare the (client-side) stored pointer with the address of the object being rendered, and decide whether to draw the selection graphic there.For some reason, that seems to work. So apparently, even though the client-side ID might change when it goes out of scope, pointers to the object stay valid. At least they do so far...it could be that this only works when I'm running it in single player mode. I'll check later if this is the case.
#7
WoW Player Control Emulation
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11152
But as I'm now concerned that this will have trouble working multiplayer (until I get home and test it), you might want to look at this one too, which handles storing the selected/targeted object a different way:
Updated Object Selection (with TLK bonus)
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=10359
02/13/2007 (12:48 pm)
Here's the resource I was working from most recently:WoW Player Control Emulation
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11152
But as I'm now concerned that this will have trouble working multiplayer (until I get home and test it), you might want to look at this one too, which handles storing the selected/targeted object a different way:
Updated Object Selection (with TLK bonus)
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=10359
#8
I'm guessing here that you are crossing the server-client memory boundary, and in fact are storing a pointer to the server's instantiation of the object. That is a very bad thing.
If you want to keep this type of information client side, you'll want to add a "uniqueID" field that is transmitted to the client from the server, and match against that. GhostID's are not expected to be consistent/persistent for this type of use.
02/13/2007 (1:15 pm)
Quote:
BTW, I am doing something similar, in that I have a gameTSCtrl that tracks a reference to a selected object, and instead of storing the ID, I store a pointer to the actual ShapeBase instance in a static variable in the ShapeBase class (I took much of the code from the object selection resource). Then inside the ShapeBase onRender method, I compare the (client-side) stored pointer with the address of the object being rendered, and decide whether to draw the selection graphic there.
For some reason, that seems to work. So apparently, even though the client-side ID might change when it goes out of scope, pointers to the object stay valid. At least they do so far...it could be that this only works when I'm running it in single player mode. I'll check later if this is the case.
I'm guessing here that you are crossing the server-client memory boundary, and in fact are storing a pointer to the server's instantiation of the object. That is a very bad thing.
If you want to keep this type of information client side, you'll want to add a "uniqueID" field that is transmitted to the client from the server, and match against that. GhostID's are not expected to be consistent/persistent for this type of use.
#9
Yeah, as I was writing out the explanation above for how I was doing this, it struck me that this was what I was actually doing. Time for a reimplementation (which I'd originally borrowed from this resource: http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11152 , so that's doing the same thing).
02/13/2007 (1:31 pm)
Quote:
I'm guessing here that you are crossing the server-client memory boundary, and in fact are storing a pointer to the server's instantiation of the object. That is a very bad thing.
Yeah, as I was writing out the explanation above for how I was doing this, it struck me that this was what I was actually doing. Time for a reimplementation (which I'd originally borrowed from this resource: http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=11152 , so that's doing the same thing).
#10
In the code I use this (Same as ShapeNameHud):
Then when I start iterating through the shapebaseobjects, they are only those for the server connection:
I think I'm just gonna target by ShapeBaseName, instead of ID. I think iterating through all the world objects can be a big performance hit.
If anyone knows of anything else I can do lemme know.
02/14/2007 (1:36 am)
I think I might have found the problem, not a solution though.In the code I use this (Same as ShapeNameHud):
// Must have a connection and control object GameConnection* [b]conn[/b] = GameConnection::getConnectionToServer(); if (!conn) return;
Then when I start iterating through the shapebaseobjects, they are only those for the server connection:
// All ghosted objects are added to the server connection group,
// so we can find all the shape base objects by iterating through
// our current connection.
for (SimSetIterator itr(conn); *itr; ++itr) {
if ((*itr)->getType() & ShapeBaseObjectType) {
ShapeBase* shape = static_cast<ShapeBase*>(*itr);
if (shape != control && shape->getShapeName()) {I think I'm just gonna target by ShapeBaseName, instead of ID. I think iterating through all the world objects can be a big performance hit.
If anyone knows of anything else I can do lemme know.
Torque Owner James Laker (BurNinG)
Con::printf("Debug 2.3 (%d)", control->getId());But no go... I don't know now :-/
Hehe, Would try EVERYTHING if I just knew what they were.
EDIT:
conn->getId() also doesnt work... But that seems like conn->getId() -1 works.
It's not right, I know.