All pastes #73579 Raw Edit

Anonymous

public text v1 · immutable
#73579 ·published 2006-06-28 00:40 UTC
rendered paste body
class 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
}