Thread: UE2 - UT2kX The Explosive bullet.(U-04)
View Single Post
Old 15th Feb 2008, 03:39 AM   #2
Wormbo
Wormlike
 
Wormbo's Avatar
 
Join Date: Jun. 4th, 2001
Location: Quedlinburg, Germany
Posts: 4,310
The problem with the HurtRadius function is the poor support for small radii. To overcome this problem, I wrote a function that checks against the actual collision cylinder:
Code:
function ExtendedHurtRadius(vector HitLocation, vector AimDir, Actor HitActor)
{
  local Actor Victims;
  local float damageScale, dist, damageAmount;
  local vector dir;
  
  DamageAmount = RandRange(DamageMin, DamageMax) * DamageAtten;
  foreach Weapon.VisibleCollidingActors(class'Actor', Victims, DamageRadius + 200, HitLocation) {
    // don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag
    if (Victims != self && Victims.Role == ROLE_Authority && !Victims.IsA('FluidSurfaceInfo')) {
      dist = DistToCylinder(Victims.Location - HitLocation, Victims.CollisionHeight, Victims.CollisionRadius);
      if ( dist > DamageRadius )
        continue;
      dir = Normal(Victims.Location - HitLocation);
      if (Victims == HitActor)
        dir = Normal(dir + AimDir);
      damageScale = 1 - FMax(0, dist / DamageRadius);
      Victims.TakeDamage(damageScale * DamageAmount, Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir, damageScale * Momentum * dir, DamageType);
      if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
        Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, Instigator.Controller, DamageType, Momentum, HitLocation);
    }
  }
}

/**
Calculates a point's distance to a cylinder.
*/
static final function float DistToCylinder(vector CenterDist, float HalfHeight, float Radius)
{
  CenterDist.X = VSize(vect(1,1,0) * CenterDist) - Radius;
  if (CenterDist.X < 0)
    CenterDist.X = 0;
  
  CenterDist.Y = 0;
  
  if (CenterDist.Z < 0)
    CenterDist.Z *= -1;
  
  CenterDist.Z -= HalfHeight;
  if (CenterDist.Z < 0)
    CenterDist.Z = 0;
  
  return VSize(CenterDist);
}
This roughly works as follows: ExtendedHurtRadius picks out all actors within the desired radius as well as actors that are relatively close to the outer bounds of the "damage sphere". It then uses DistToCylinder to calculate the actual distance from the center to the outer bounds of each actor's collision cylinder.

For obvious reasons this code only works with target actors that use cylinder collision. Static mesh collision will break this code because those actors' collision cylinder size might not be related to the actual collision shape.
__________________
Wormbo's UT/UT2004/UT3 mods | PlanetJailbreak | Unreal Wiki | Liandri Archives

<elmuerte> you shouldn't do all-nighters, it's a waste of time and effort
<TNSe> nono
<TNSe> its always funny to find code a week later you dont even remember writing
<Pfhoenix> what's worse is when you have a Star Wars moment
<Pfhoenix> "Luke! I am your code!" "No! Impossible! It can't be!"
Wormbo is online now   Reply With Quote