rendered paste bodyclass DAProjectile extends AdvancedProjectile;
//var Actor Ignore;
var float ImpactSoundVolume;
simulated function PostBeginPlay() {
super.PostBeginPlay();
if(ForceRadius == 0) ForceRadius = CollisionRadius;
Velocity = GetTossVelocity(Instigator, Instigator.Controller.GetViewRotation());
}
simulated function Destroyed () {
Super.Destroyed ();
if ( trail != None ) {
trail.Kill();
}
}
// Hopefully this will solve that super bizarre thing that projectiles don't do damage, only
// their explosion does.
simulated function Touch(Actor Other) {
local actor HitActor;
local vector HitLocation, HitNormal, VelDir, AdjustedLocation;
local bool bBeyondOther;
local float BackDist, DirZ;
if (Other.IsA('Pawn') == true && Instigator != Pawn(Other) && Level.NetMode != NM_DedicatedServer){
Spawn(BloodEmitter,,,location);
}
if ( Other == None ) // Other just got destroyed in its touch?
return;
if ( Other.bProjTarget || (Other.bBlockActors && Other.bBlockPlayers) )
{
if ( Velocity == vect(0,0,0) || Other.IsA('Mover') )
{
ProcessTouch(Other,Location);
return;
}
//get exact hitlocation - trace back along velocity vector
bBeyondOther = ( (Velocity Dot (Location - Other.Location)) > 0 );
VelDir = Normal(Velocity);
DirZ = sqrt(abs(VelDir.Z));
BackDist = Other.CollisionRadius * (1 - DirZ) + Other.CollisionHeight * DirZ;
if ( bBeyondOther )
BackDist += VSize(Location - Other.Location);
else
BackDist -= VSize(Location - Other.Location);
HitActor = Trace(HitLocation, HitNormal, Location, Location - 1.1 * BackDist * VelDir, true);
if (HitActor == Other)
AdjustedLocation = HitLocation;
else if ( bBeyondOther )
AdjustedLocation = Other.Location - Other.CollisionRadius * VelDir;
else
AdjustedLocation = Location;
ProcessTouch(Other, AdjustedLocation);
//if ( (Role < ROLE_Authority) && (Other.Role == ROLE_Authority) )
ClientSideTouch(Other, AdjustedLocation);
}
}
simulated function ProcessTouch(Actor Other, Vector HitLocation) {
super.ProcessTouch(Other, HitLocation);
}
simulated function ClientSideTouch(Actor Other, Vector HitLocation) {
if(Other == Instigator) return; // you can't SHOOT YOURSELF with a projectile, but it's explosion could get you
log(self@"ClientSideTouch"@Other);
super.ClientSideTouch(Other, HitLocation);
// YAY! THIS FIXES THE FUCKING ANIMATION PROBLEM!
// we only should need to do it for zombies that are not our own
if(AdvancedPawn(Other) != None && Pawn(Other).Health < 0) {
if(!Other.IsA('DAZombieBase') && !Other.IsA('DAPawn')) {
log(self@"Running special death code..");
AdvancedPawn(Other).FocusedAnimEnd();
Other.StopAnimating();
AdvancedPawn(Other).PlayDying(myDamageType, HitLocation);
}
}
}
simulated function PostNetBeginPlay() {
if(Level.NetMode != NM_DedicatedServer && TrailEmitter != None) {
trail = Spawn( TrailEmitter, self );
trail.SetPhysics(PHYS_TRAILER);
trail.LifeSpan = 5.0;
trail.SetBase( self );
}
super(Projectile).PostNetBeginPlay();
}
// We do a new ver of the Actor function HurtRadius so we can apply Karma.
simulated function DAHurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
local actor Victims;
local float damageScale, dist;
local vector dir;
if( bHurtEntry || DamageRadius == 0)
return;
bHurtEntry = true;
log(self@"DAHurtRadius");
foreach CollidingActors(class'Actor', Victims, DamageRadius, 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')) &&
(Victims.Region.Zone == Region.Zone)
) {
if(Victims.IsA('Pawn') && Instigator != Pawn(Victims) && Level.NetMode != NM_DedicatedServer) {
Spawn(BloodEmitter,,,Victims.location);
}
dir = Victims.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
Victims.KAddImpulse(dir * (class<DADamage>(myDamageType).default.KDamageImpulse), Hitlocation);
Victims.TakeDamage
(
damageScale * DamageAmount,
Instigator,
Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,
(damageScale * Momentum * dir),
myDamageType
);
}
}
bHurtEntry = false;
}
simulated function BlowUp(vector HitLocation)
{
DAHurtRadius(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation );
if ( Role == ROLE_Authority )
MakeNoise(1.0);
}
simulated function Explode(vector HitLocation, vector HitNormal) {
//Ignore = None;
if(Level.NetMode != NM_DedicatedServer) {
Spawn(ExplosionEmitter,,, location);
PlaySound(ImpactSound,SLOT_NONE,ImpactSoundVolume,,1000);
}
/*if(Level.NetMode == NM_Client || Level.NetMode == NM_StandAlone) {
Spawn(ExplosionEmitter,,, location);
}*/
//if(Role == Role_Authority) {
//if(Level.NetMode == NM_DedicatedServer) {
// PlaySound(ImpactSound);
//}
BlowUp(HitLocation);
Destroy();
}
// Taken from the DOTZShotgunProjectile .. not sure if it's ever used, but it might be nice to have.
simulated function Landed( vector HitNormal ){
HitWall( HitNormal, None );
}
DefaultProperties
{
Acceleration=(X=0,Y=0,Z=-10)
ForceType=FT_DragAlong
}