Game Development Community

Head, body and leg shots.

by BrokeAss Games · in Torque Game Engine · 12/20/2005 (8:09 am) · 11 replies

This is quick location damage modifier.
It was inspired by the Tribes 2 sniper rifle.
Season to taste.

function CrossbowProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
   // Apply damage to the object all shape base objects
   if (%col.getType() & $TypeMasks::ShapeBaseObjectType)
   {
     %damLoc = firstWord(%col.getDamageLocation(%pos));
     //echo("Target Hit: " @ %damLoc);
     if(%damLoc $= "head")
     {
        %modifier = 2;
     }
     if(%damLoc $= "torso")
     {
        %modifier = 1;
     }
     if(%damLoc $= "legs")
     {
        %modifier = 0.5;
     }
     %col.damage(%obj,%pos,%modifier * %this.directDamage,"CrossbowBolt");
   }
}

Else if? Select case? Nothing worse than a tired newb.
Hope this is useful, it does work.

Ari

#1
01/02/2006 (2:02 am)
You are a genius! And it only took me 10 days to find it...you should put this on TDN and/or make a resource (as simple as this is, I was never sure where to use getDamageLocation from) I've been searching for ages for just this small bit of information.
#2
01/02/2006 (4:37 am)
@Midhir
Nope, I'm still a nub, I just do great research. ;)
I'll try and get it on TDN.

Ari
#3
01/02/2006 (7:42 am)
This is what ive done:

function SoldierBase::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{
if (%obj.getState() $= "Dead")
return;

%location = %obj.getdamagelocation(%position);
%region = getword(%location,0);
%part = getword(%location,1);

switch$(%region)
   {
   case "head":
   %percentage = %obj.HeadPercentage;
   case "Legs":
   %percentage = %obj.LegsPercentage;
   case "Torso":
   %percentage = %obj.TorsoPercentage;
   case "Heart":
   %percentage = %obj.HeartPercentage;
   default:
   %percentage = 1;
   echo("Damage Location not found on" @ %obj;
   }

%damage = %damage*%Percentage;

// apply damage
 %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")
      %client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
}
I havent tried it yet,

I havent seen the getdamagelocation function on any documentation but thats how it was used somewhere else i dont know what the second word or %part is

I just added the heart case because i plan on adding it, it wont give that callback :P

crossed fingers it is like that for 1.4
and mines inside the damage function
#4
01/03/2006 (6:41 am)
Having the damage dealt in the player makes it more universal and doesn't require each weapon to be re-worked.
For the standard torque player you would use John's method in function Armor::damage in starter.fps/server/scripts/player.cs.

@John
I know you said you hadn't tried this, but I have a few questions.
I'm not finding the damage percentages, just location.
// Damage location details
   boxNormalHeadPercentage       = 0.83;
   boxNormalTorsoPercentage      = 0.49;
   boxHeadLeftPercentage         = 0;
   boxHeadRightPercentage        = 1;
   boxHeadBackPercentage         = 0;
   boxHeadFrontPercentage        = 1;
Is percentages (added to player datablock?) custom or something in 1.4?
Just wondering if I'm missing something.
A heart shot would be great!

Ari
*Didn't read the post all the way through and went looking for the "heart", LOL. A tired coder can be dangerous. Double check all this, I could be "sleep posting". ;)
#5
01/03/2006 (6:54 am)
You inspired me to change the function this what ive done with it now

and no there isnt anything in the engine for a heart shot, but I plan on adding it
if i can ever get vc 2005 to compile :P

function PlayerShape::damage(%this, %obj, %sourceObject, %position, %damage, %damageType)
{

if (%obj.getState() $= "Dead")
return;


%location = %obj.getdamagelocation(%position);
%region = getword(%location,0);
%part = getword(%location,1);

switch$($sourceobject.damagetype = "Explosion")
{
case  "Direct":
switch$(%region)
   {
   case "head":
   %percentage = %obj.HeadPercentage;
   case "Legs":
   %percentage = %obj.LegsPercentage;
   case "Torso":
   %percentage = %obj.TorsoPercentage;
   case "Heart":
   %percentage = %obj.HeartPercentage;
   default:
   %percentage = 1;
   echo("Damage Location not found on" @ %obj);
   }

case "Explosion":
switch$(%region)
   {
   case "head":
   %percentage = %obj.HeadPercentage;
   case "Legs":
   %percentage = %obj.LegsPercentage;
   case "Torso":
   %percentage = %obj.TorsoPercentage;
   default:
   %percentage = 1;
   echo("Damage Location not found on" @ %obj);
   }
default:
switch$(%region)
   {
   case "head":
   %percentage = %obj.HeadPercentage;
   case "Legs":
   %percentage = %obj.LegsPercentage;
   case "Torso":
   %percentage = %obj.TorsoPercentage;
   case "Heart":
   %percentage = %obj.HeartPercentage;
   default:
   %percentage = 1;
   echo("Damage Location not found on" @ %obj);
   }
}

%damage = %damage*%Percentage;

// Apply damage to the object all shape base objects
if (%col.getType() & $TypeMasks::ShapeBaseObjectType)  
{

// apply damage
 %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")
      %client.onDeath(%sourceObject, %sourceClient, %damageType, %location);
}

ive never tried nesting switch statments before

the projectile has a variable damagetype

the player has variables:
HeadPercentage
LegsPercentage
TorsoPercentage
HeartPercentage

[Edit] Fixed bugs
#6
08/31/2006 (8:01 am)
So how does this work?

my character looks unconventional, and the head is more to the side and lower, (sort of like a hunchback)

how do the percentages apply here?

or can i use a second collision box that only acts with this?
#7
09/08/2006 (11:26 am)
How do you define the regions on the model? are there seperate collision boxes for each of the regions? could this be adapted to offer location damage forvehicles?, along the lines of a shot in a critical spot blows the vehicle up.

THanks
#8
09/08/2006 (11:39 am)
Quote:
How do you define the regions on the model?
You don't.
Quote:
are there seperate collision boxes for each of the regions?
No.
Quote:
could this be adapted to offer location damage forvehicles?
Probably but I doubt it would work very well.

Torque just determines which section / percentage of the bounding box was hit. It is split into three sections. Head, torso and legs. So the top 15% would be classified as the head, the middle the torso and the bottom section the legs. Not very accurate but doesn't take much to compute and good enough for most fps games.
#9
09/09/2006 (7:09 am)
Do you have any idea how the region damage for vehicles works? or is there just a single region?
thanks
#10
09/09/2006 (8:40 am)
I'm not sure to be honest with you. I don't really use the vehicles in Torque all that much. I would imagine there is just a single region, i.e. any hit to the bounding box and that's all you get.

I believe others have implemented 'zoned' vehicle damage, not sure how difficult it was or how well it worked.

Quote:
along the lines of a shot in a critical spot blows the vehicle up.

Is this all you're after? If so, there may be easier ways to go about it. If you don't mind being hacky, maybe you could mount an image to the critical spot and when that is hit trigger the vehicle to reach the destroyed state.
#11
09/09/2006 (8:43 am)
Just a quick suggestion, if you want to find out for yourself...

In your vehicle script you should have a function similar to this:
function heliVehicleData::damage(%data, %obj, %sourceObj, %position, %amount, %damageType, %momentum)
{
  %obj.applyDamage(%amount);
}

Just place an echo on %position and see what you get.