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

290 lines
9.6 KiB
Ucode

class ScrnM79IncGrenadeProjectile extends M79GrenadeProjectile;
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
//overrided to change smoke emiter
simulated function PostBeginPlay()
{
local rotator SmokeRotation;
BCInverse = 1 / BallisticCoefficient;
if ( Level.NetMode != NM_DedicatedServer)
{
SmokeTrail = Spawn(class'ScrnBalanceSrv.ScrnFlameNadeTrail',self);
SmokeTrail.SetBase(self);
SmokeRotation.Pitch = 32768;
SmokeTrail.SetRelativeRotation(SmokeRotation);
//Corona = Spawn(class'KFMod.KFLAWCorona',self);
}
OrigLoc = Location;
if( !bDud )
{
Dir = vector(Rotation);
Velocity = speed * Dir;
}
if (PhysicsVolume.bWaterVolume)
{
bHitWater = True;
Velocity=0.6*Velocity;
}
super(Projectile).PostBeginPlay();
}
//copied from flame nade
simulated function Explode(vector HitLocation, vector HitNormal)
{
local PlayerController LocalPlayer;
bHasExploded = True;
// Don't explode if this is a dud
if( bDud )
{
Velocity = vect(0,0,0);
LifeSpan=1.0;
SetPhysics(PHYS_Falling);
}
// Incendiary Effects..
PlaySound(sound'KF_GrenadeSnd.FlameNade_Explode',,100.5*TransientSoundVolume);
if ( EffectIsRelevant(Location,false) )
{
Spawn(Class'KFIncendiaryExplosion',,, HitLocation, rotator(vect(0,0,1)));
Spawn(ExplosionDecal,self,,HitLocation, rotator(-HitNormal));
}
BlowUp(HitLocation);
Destroy();
// Shake nearby players screens
LocalPlayer = Level.GetLocalPlayerController();
if ( (LocalPlayer != None) && (VSize(Location - LocalPlayer.ViewTarget.Location) < (DamageRadius * 1.5)) )
LocalPlayer.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
}
simulated function HurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
local actor Victims;
local float damageScale, dist;
local vector dirs;
local int NumKilled;
local KFMonster KFMonsterVictim;
local Pawn P;
local KFPawn KFP;
local array<Pawn> CheckedPawns;
local int i;
local bool bAlreadyChecked;
if ( bHurtEntry )
return;
bHurtEntry = true;
foreach CollidingActors (class 'Actor', Victims, DamageRadius, HitLocation)
{
// null pawn variables here just to be sure they didn't left from previous iteration
// and waste another day of my life to looking for this fucking bug -- PooSH /totallyPissedOff!!!
P = none;
KFMonsterVictim = none;
KFP = none;
// 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 )
{
dirs = Victims.Location - HitLocation;
dist = FMax(1,VSize(dirs));
dirs = dirs/dist;
damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
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; // and if you forget to re-null it somewhere?!! and then look for a bug during 2 days?!! Damned Tripwire, I hate you so much
continue;
}
KFMonsterVictim = KFMonster(Victims);
if( KFMonsterVictim != none && KFMonsterVictim.Health <= 0 )
{
KFMonsterVictim = none;
}
KFP = KFPawn(Victims);
if( KFMonsterVictim != none )
{
damageScale *= KFMonsterVictim.GetExposureTo(HitLocation/*Location + 15 * -Normal(PhysicsVolume.Gravity)*/);
}
else if( KFP != none )
{
damageScale *= KFP.GetExposureTo(HitLocation/*Location + 15 * -Normal(PhysicsVolume.Gravity)*/);
}
CheckedPawns[CheckedPawns.Length] = P;
if ( damageScale <= 0)
{
P = none;
continue;
}
else
{
//Victims = P;
P = none;
}
}
if ( KFMonsterVictim != none && class'ScrnBalance'.default.Mut.BurnMech != none) {
class'ScrnBalance'.default.Mut.BurnMech.MakeBurnDamage(
KFMonsterVictim,
damageScale * DamageAmount,
Instigator,
Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dirs,
(damageScale * Momentum * dirs),
DamageType
);
}
else {
Victims.TakeDamage
(
damageScale * DamageAmount,
Instigator,
Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dirs,
(damageScale * Momentum * dirs),
DamageType
);
}
if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);
if( Role == ROLE_Authority && KFMonsterVictim != none && KFMonsterVictim.Health <= 0 )
{
NumKilled++;
}
}
}
/*
if ( (LastTouched != None) && (LastTouched != self) && (LastTouched.Role == ROLE_Authority) && !LastTouched.IsA('FluidSurfaceInfo') )
{
Victims = LastTouched;
LastTouched = None;
dirs = Victims.Location - HitLocation;
dist = FMax(1,VSize(dirs));
dirs = dirs/dist;
damageScale = FMax(Victims.CollisionRadius/(Victims.CollisionRadius + Victims.CollisionHeight),1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius));
if ( Instigator == None || Instigator.Controller == None )
Victims.SetDelayedDamageInstigatorController(InstigatorController);
Victims.TakeDamage
(
damageScale * DamageAmount,
Instigator,
Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dirs,
(damageScale * Momentum * dirs),
DamageType
);
if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0)
Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation);
}
*/
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 ProcessTouch(Actor Other, Vector HitLocation)
{
// Don't let it hit this player, or blow up on another player
if ( Other == none || Other == Instigator || Other.Base == Instigator || !Other.bBlockHitPointTraces )
return;
// Don't collide with bullet whip attachments
if( KFBulletWhipAttachment(Other) != none )
{
return;
}
// Don't allow hits on people on the same team - except hardcore mode
if( !class'ScrnBalance'.default.Mut.bHardcore && KFPawn(Other) != none && Instigator != none
&& KFPawn(Other).GetTeamNum() == Instigator.GetTeamNum() )
{
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;
}
if( !bDud && ((VSizeSquared(Location - OrigLoc) < ArmDistSquared) || OrigLoc == vect(0,0,0)) )
{
if( Role == ROLE_Authority )
{
AmbientSound=none;
PlaySound(Sound'ProjectileSounds.PTRD_deflect04',,2.0);
Other.TakeDamage( ImpactDamage, Instigator, HitLocation, Normal(Velocity), ImpactDamageType );
}
bDud = true;
Velocity = vect(0,0,0);
LifeSpan=1.0;
SetPhysics(PHYS_Falling);
}
if( !bDud )
{
Explode(HitLocation,Normal(HitLocation-Other.Location));
}
}
defaultproperties
{
ArmDistSquared=2500.000000
ImpactDamage=50
ExplosionSoundRef="KF_GrenadeSnd.FlameNade_Explode"
Damage=60.000000
MyDamageType=Class'KFMod.DamTypeFlameNade'
}