rott/kf_sources/KFMod/Classes/ZEDMKIISecondaryProjectile.uc
2026-07-14 20:27:09 +07:00

354 lines
10 KiB
Ucode

//=============================================================================
// ZEDMKIIPrimaryProjectile
//=============================================================================
// Energy ball projectile for the ZEDGun MKII
//=============================================================================
// Killing Floor Source
// Copyright (C) 2013 Tripwire Interactive LLC
// John "Ramm-Jaeger" Gibson
//=============================================================================
class ZEDMKIISecondaryProjectile extends LAWProj;
var Emitter FlameTrail;
var class<Emitter> ExplosionEmitter;
var class<Emitter> FlameTrailEmitterClass;
var float ExplosionSoundVolume;
var() float ZapAmount; // Amount of zap to apply to zeds when this projectile explodes near them
//-----------------------------------------------------------------------------
// PostBeginPlay
//-----------------------------------------------------------------------------
simulated function PostBeginPlay()
{
if ( Level.NetMode != NM_DedicatedServer )
{
if ( !PhysicsVolume.bWaterVolume )
{
FlameTrail = Spawn(FlameTrailEmitterClass,self);
}
}
OrigLoc = Location;
if( !bDud )
{
Dir = vector(Rotation);
Velocity = speed * Dir;
}
super(ROBallisticProjectile).PostBeginPlay();
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
local Controller C;
local PlayerController LocalPlayer;
local float ShakeScale;
local ZEDMKIISecondaryProjectileExplosion Explosion;
bHasExploded = True;
// Don't explode if this is a dud
if( bDud )
{
Velocity = vect(0,0,0);
LifeSpan=1.0;
SetPhysics(PHYS_Falling);
}
PlaySound(ExplosionSound,,ExplosionSoundVolume);
if ( EffectIsRelevant(Location,false) )
{
if( class'ROEngine.ROLevelInfo'.static.RODebugMode() )
{
Explosion = ZEDMKIISecondaryProjectileExplosion(Spawn(ExplosionEmitter,,,HitLocation + HitNormal*20,rotator(HitNormal)));
Explosion.ExplosionRadius = DamageRadius;
}
else
{
Spawn(ExplosionEmitter,,,HitLocation + HitNormal*20,rotator(HitNormal));
}
Spawn(ExplosionDecal,self,,HitLocation, rotator(-HitNormal));
}
BlowUp(HitLocation);
Destroy();
// Shake nearby players screens
LocalPlayer = Level.GetLocalPlayerController();
if ( LocalPlayer != none )
{
ShakeScale = GetShakeScale(Location, LocalPlayer.ViewTarget.Location);
if( ShakeScale > 0 )
{
LocalPlayer.ShakeView(RotMag * ShakeScale, RotRate, RotTime, OffsetMag * ShakeScale, OffsetRate, OffsetTime);
}
}
for ( C=Level.ControllerList; C!=None; C=C.NextController )
{
if ( PlayerController(C) != None && C != LocalPlayer )
{
ShakeScale = GetShakeScale(Location, PlayerController(C).ViewTarget.Location);
if( ShakeScale > 0 )
{
C.ShakeView(RotMag * ShakeScale, RotRate, RotTime, OffsetMag * ShakeScale, OffsetRate, OffsetTime);
}
}
}
}
// Get the shake amount for when this projectile explodes
simulated function float GetShakeScale(vector ViewLocation, vector EventLocation)
{
local float Dist;
local float scale;
Dist = VSize(ViewLocation - EventLocation);
if (Dist < DamageRadius * 2.0 )
{
scale = (DamageRadius*2.0 - Dist) / (DamageRadius*2.0);
}
return scale;
}
// Overridden to not do explosive damage
//simulated function BlowUp(vector HitLocation)
//{
// if ( Role == ROLE_Authority )
// MakeNoise(1.0);
//}
//
//simulated function ProcessTouch(Actor Other, Vector HitLocation)
//{
// local vector X;
// local Vector TempHitLocation, HitNormal;
// local array<int> HitPoints;
// local KFPawn HitPawn;
//
// // Don't let it hit this player, or blow up on another player
// if ( Other == none || Other == Instigator || Other.Base == Instigator )
// return;
//
// // Don't collide with bullet whip attachments
// if( KFBulletWhipAttachment(Other) != none )
// {
// return;
// }
//
// // Don't allow hits on poeple on the same team
// if( KFHumanPawn(Other) != none && Instigator != none
// && KFHumanPawn(Other).PlayerReplicationInfo.Team.TeamIndex == Instigator.PlayerReplicationInfo.Team.TeamIndex )
// {
// return;
// }
//
// // Use the instigator's location if it exists. This fixes issues with
// // the original location of the projectile being really far away from
// // the real Origloc due to it taking a couple of milliseconds to
// // replicate the location to the client and the first replicated location has
// // already moved quite a bit.
// if( Instigator != none )
// {
// OrigLoc = Instigator.Location;
// }
//
// X = Vector(Rotation);
//
// if( Role == ROLE_Authority )
// {
// if( ROBulletWhipAttachment(Other) != none )
// {
// if(!Other.Base.bDeleteMe)
// {
// Other = Instigator.HitPointTrace(TempHitLocation, HitNormal, HitLocation + (200 * X), HitPoints, HitLocation,, 1);
//
// if( Other == none || HitPoints.Length == 0 )
// return;
//
// HitPawn = KFPawn(Other);
//
// if (Role == ROLE_Authority)
// {
// if ( HitPawn != none )
// {
// // Hit detection debugging
// /*log("Bullet hit "$HitPawn.PlayerReplicationInfo.PlayerName);
// HitPawn.HitStart = HitLocation;
// HitPawn.HitEnd = HitLocation + (65535 * X);*/
//
// if( !HitPawn.bDeleteMe )
// HitPawn.ProcessLocationalDamage(Damage, Instigator, TempHitLocation, MomentumTransfer * Normal(Velocity), MyDamageType,HitPoints);
//
//
// // Hit detection debugging
// //if( Level.NetMode == NM_Standalone)
// // HitPawn.DrawBoneLocation();
// }
// }
// }
// }
// else
// {
// if (Pawn(Other) != none && Pawn(Other).IsHeadShot(HitLocation, X, 1.0))
// {
// Pawn(Other).TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, MomentumTransfer * Normal(Velocity), MyDamageType);
// }
// else
// {
// Other.TakeDamage(Damage, Instigator, HitLocation, MomentumTransfer * Normal(Velocity), MyDamageType);
// }
// }
// }
//
// if( !bDud )
// {
// Explode(HitLocation,Normal(HitLocation-Other.Location));
// }
//}
/* HurtRadius()
Hurt locally authoritative actors within the radius.
// Overriden to zap zeds instead of hurting them
*/
simulated function HurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
local actor Victims;
local int NumKilled;
local KFMonster KFMonsterVictim;
local Pawn P;
local array<Pawn> CheckedPawns;
local int i;
local bool bAlreadyChecked;
if ( bHurtEntry )
return;
bHurtEntry = true;
ClearStayingDebugLines();
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) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo')
&& ExtendedZCollision(Victims)==None )
{
if ( Instigator == None || Instigator.Controller == None )
Victims.SetDelayedDamageInstigatorController( InstigatorController );
if ( Victims == LastTouched )
LastTouched = None;
P = Pawn(Victims);
if( P != none )
{
for (i = 0; i < CheckedPawns.Length; i++)
{
if (CheckedPawns[i] == P)
{
bAlreadyChecked = true;
break;
}
}
if( bAlreadyChecked )
{
bAlreadyChecked = false;
P = none;
continue;
}
KFMonsterVictim = KFMonster(Victims);
if( KFMonsterVictim != none && KFMonsterVictim.Health <= 0 )
{
KFMonsterVictim = none;
}
CheckedPawns[CheckedPawns.Length] = P;
if( KFMonsterVictim == none )
{
P = none;
continue;
}
else
{
// Zap zeds only
if( Role == ROLE_Authority )
{
KFMonsterVictim.SetZapped(ZapAmount, Instigator);
NumKilled++;
}
//DrawStayingDebugLine( Location, P.Location,255, 255, 0);
}
P = none;
}
}
}
if( Role == ROLE_Authority )
{
if( NumKilled >= 4 )
{
KFGameType(Level.Game).DramaticEvent(0.05);
}
else if( NumKilled >= 2 )
{
KFGameType(Level.Game).DramaticEvent(0.03);
}
}
bHurtEntry = false;
}
simulated function Destroyed()
{
if ( FlameTrail != none )
{
FlameTrail.Kill();
FlameTrail.SetPhysics(PHYS_None);
}
Super.Destroyed();
}
defaultproperties
{
Speed=1000.000000
MaxSpeed=1000.000000
Damage=0.000000
DamageRadius=300.000000
ArmDistSquared=0
StaticMeshRef="ZED_FX_SM.Energy.ZED_FX_Energy_Card"
DrawScale=4.000000
MyDamageType=Class'KFMod.DamTypeZEDGunMKII'
ExplosionSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Secondary_Explode"
AmbientSoundRef="KF_FY_ZEDV2SND.WEP_ZEDV2_Secondary_Projectile_LP"
ExplosionDecal=Class'KFMod.FlameThrowerBurnMark_Medium'
ExplosionEmitter=Class'KFMod.ZEDMKIISecondaryProjectileExplosion'
ExplosionSoundVolume=1.650000
FlameTrailEmitterClass=Class'KFMod.ZEDMKIISecondaryProjectileTrail'
LightType=LT_Steady
LightBrightness=255
LightRadius=8.000000
LightHue=128
LightSaturation=64
LightCone=16
bDynamicLight=True
bUnlit=True
AmbientGlow=254
AmbientVolumeScale=2.5
ZapAmount=1.5
}