T3D 1.1 Preview - Armor Impact Body Locations Always Hit Head - LOGGED (THREED-1803)
by Steve Acaster · in Torque 3D Professional · 05/08/2011 (6:08 pm) · 10 replies
T3D 1.1 Preview
win7 32bit
target:
player/armor hit locations reports, porjectile impacts on players
Issue
Impact locations and bodyparts always seem to score a hit to the head regardless of where they have actually been shot.
Repeat
Edit Armor::damage function and add this code snippet in scripts/server/player.cs.
Nowe spawn in-game with an Ai and shoot them in the feet/legs. Check the console and see that bodypart/location always seem to be recorded as "head".
Suggest:
Make bodypart locations correspond to the settings in art/datablocks/player.cs -
Only an issue in Preview, fine before.
win7 32bit
target:
player/armor hit locations reports, porjectile impacts on players
Issue
Impact locations and bodyparts always seem to score a hit to the head regardless of where they have actually been shot.
Repeat
Edit Armor::damage function and add this code snippet in scripts/server/player.cs.
function Armor::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{
if (!isObject(%obj) || %obj.getState() $= "Dead")
return;
//yorks test new!
%location = %obj.getDamageLocation(%position);
%bodyPart = getWord(%location, 0);
%region = getWord(%location, 1);
echo("c4DAMAGELOCATION: bodyPart = "@ %bodyPart @" || REGION = "@ %region);
// BODYPARTS: HEAD | TORSO | LEGS
// REGION (legs/Torso): front_left | front_right | back_left | back_right
// REGION (head): left_back | left_middle | left front
// middle_back | middle_middle | middle_front
// right_back | right_middle | right_front
//yorks test end new!
%obj.applyDamage(%damage);
// Deal with client callbacks here because we don't have this
// information in the onDamage or onDisable methods
%client = %obj.client;
%sourceClient = %sourceObject ? %sourceObject.client : 0;
if (%obj.getState() $= "Dead" && isObject(%client))
%client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
// Update the numerical Health HUD
%obj.updateHealth();
}Nowe spawn in-game with an Ai and shoot them in the feet/legs. Check the console and see that bodypart/location always seem to be recorded as "head".
Suggest:
Make bodypart locations correspond to the settings in art/datablocks/player.cs -
// Damage location details boxNormalHeadPercentage = 0.83; boxNormalTorsoPercentage = 0.49; boxHeadLeftPercentage = 0; boxHeadRightPercentage = 1; boxHeadBackPercentage = 0; boxHeadFrontPercentage = 1;
Only an issue in Preview, fine before.
About the author
One Bloke ... In His Bedroom ... Making Indie Games ...
#2
Headshot everytime with your script - I'm using stock code, stock rocketlauncher (just no blast on the projectile)
05/09/2011 (9:32 am)
@RichardHeadshot everytime with your script - I'm using stock code, stock rocketlauncher (just no blast on the projectile)
#3
You're right, when I'm using projectiles I hit always the same spot, no matter at what angle I am with the target, although it's not the head but the legs front any time. I don't have this with my melee weapons (sword, dagger), with these weapons I get the right location (hit-location determined with a raycast), so I think it must have something to do with projectiles, but to be sure I have to investigate further.
05/09/2011 (10:06 am)
@Steve:You're right, when I'm using projectiles I hit always the same spot, no matter at what angle I am with the target, although it's not the head but the legs front any time. I don't have this with my melee weapons (sword, dagger), with these weapons I get the right location (hit-location determined with a raycast), so I think it must have something to do with projectiles, but to be sure I have to investigate further.
#4
05/09/2011 (10:31 am)
Logged as THREED-1803.
#5
It seems that the projectile onCollision callback returns the hit normal twice to script. Don't know why this happens, cause the code seems to be right.
Just added the printf in projectile.cpp and add a echo of the position and normal in the projectiledata::onCollision in script to compare the results.
Update 2:
Yes, this is definately the problem. Somehow the hitPosition value gets lost when sending it to script. In the projectileData::onCollision script you get the hitNormal value where you should get the hitPosition value.
05/09/2011 (10:45 am)
Update:It seems that the projectile onCollision callback returns the hit normal twice to script. Don't know why this happens, cause the code seems to be right.
void Projectile::onCollision(const Point3F& hitPosition, const Point3F& hitNormal, SceneObject* hitObject)
{
// No client specific code should be placed or branched from this function
if(isClientObject())
return;
if (hitObject != NULL && isServerObject())
{
// ME Collision test hit location Yorksh Rifles
Con::printf("Projectile_hit_location: %f %f %f",hitPosition.x,hitPosition.y,hitPosition.z);
mDataBlock->onCollision_callback( this, hitObject, mFadeValue, hitPosition, hitNormal );
}
}Just added the printf in projectile.cpp and add a echo of the position and normal in the projectiledata::onCollision in script to compare the results.
Update 2:
Yes, this is definately the problem. Somehow the hitPosition value gets lost when sending it to script. In the projectileData::onCollision script you get the hitNormal value where you should get the hitPosition value.
#6
In projectile.cpp find the Projectile::onCollision function somewhere around line 1132 and replace:
with this
Rebuild the engine and the Projectile onCollision script should give you the right hit position and normal.
05/15/2011 (12:47 pm)
Ugly Fix:In projectile.cpp find the Projectile::onCollision function somewhere around line 1132 and replace:
...
if (hitObject != NULL && isServerObject())
{
mDataBlock->onCollision_callback( this, hitObject, mFadeValue, hitPosition, hitNormal );
}
...with this
...
if (hitObject != NULL && isServerObject())
{
char b1[100];
char b2[100];
char b3[100];
dSprintf(b1,sizeof(b1),"%f",mFadeValue);
dSprintf(b2,sizeof(b2),"%f %f %f",hitPosition.x, hitPosition.y, hitPosition.z);
dSprintf(b3,sizeof(b3),"%f %f %f",hitNormal.x, hitNormal.y, hitNormal.z);
Con::executef(getDataBlock(), "onCollision", Con::getIntArg(getId()), Con::getIntArg(hitObject->getId()), b1, b2, b3);
}
...Rebuild the engine and the Projectile onCollision script should give you the right hit position and normal.
#7
05/16/2011 (7:05 pm)
Ugly fix is better than no fix at all. :)
#8
you effectivly removed the callback?
or does the
Con::executef(getDataBlock(), "onCollision", Con::getIntArg(getId.....
replace that?
I also noticed that if the player "bumps his foot" its called a headshot....no projectiles involved...
try replacing
dunno where boxNormalTorsoPercentage and boxNormalTorsoPercentage come from...
mark as fixed?
05/16/2011 (8:14 pm)
but what if we rely on the projectiles mDataBlock->onCollision_callback to do things from script?you effectivly removed the callback?
or does the
Con::executef(getDataBlock(), "onCollision", Con::getIntArg(getId.....
replace that?
I also noticed that if the player "bumps his foot" its called a headshot....no projectiles involved...
try replacing
boxNormalHeadPercentage = 0.83; boxNormalTorsoPercentage = 0.49;with
boxHeadPercentage = 0.83; boxTorsoPercentage = 0.49;works because those are the actual field names that are exposed to script..
dunno where boxNormalTorsoPercentage and boxNormalTorsoPercentage come from...
mark as fixed?
#9
And to think that particular typo/error goes all the way back to TGE! Somebody probably copied a Tribes 2 player datablock way back in the beginning and never corrected field misnames after all this time. That certainly explains the error prone results of getDamageLocation() over the years and why "body" was hardcoded in the scripts.
Oh, and conexecutef() is actually the old way of declaring a callback.
05/16/2011 (9:01 pm)
Nice catch deepscratch :)And to think that particular typo/error goes all the way back to TGE! Somebody probably copied a Tribes 2 player datablock way back in the beginning and never corrected field misnames after all this time. That certainly explains the error prone results of getDamageLocation() over the years and why "body" was hardcoded in the scripts.
Oh, and conexecutef() is actually the old way of declaring a callback.
#10
Yes, this executes the onCollision callback in script, as Michael stated, it is the old way.
05/17/2011 (1:49 am)
@deepscratch:Quote:or does the
Con::executef(getDataBlock(), "onCollision", Con::getIntArg(getId.....
replace that?
Yes, this executes the onCollision callback in script, as Michael stated, it is the old way.
Richard Marrevee
R.G.S - Richards Game Studio
Can you try the next piece of code, because I'm not seeing this effect.
function Armor::damage(%this, %obj, %sourceObject, %position, %damage, %damageType) { if (!isObject(%obj) || %obj.getState() $= "Dead") return; %obj.applyDamage(%damage); %location = "Body"; if(getWordCount(%position)>1) %location = %obj.getDamageLocation(%position); else %location = %position; echo("Hit at " @ %location); ... sourceClient=%client;I get hits all over the body, depending on my anim (melee type) and pose.
It is known that for some reason the head get hit the most of the time, at least in my case.