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

98 lines
3.4 KiB
Ucode

class ScrnM99Bullet extends M99Bullet;
var protected actor LastHitWall;
var float HitVelocityReduction;
var float HitDamageReduction;
var int MinDamage;
simulated function ProcessTouch (Actor Other, vector HitLocation)
{
local vector X;
local Vector TempHitLocation, HitNormal;
local array<int> HitPoints;
local KFPawn HitPawn;
local bool bHeadshot;
if ( Other == none || Other == Instigator || Other.Base == Instigator || !Other.bBlockHitPointTraces || Other==IgnoreImpactPawn )
return;
X = Vector(Rotation);
if( ROBulletWhipAttachment(Other) != none ) {
if( Other.Base == none || Other.Base.bDeleteMe)
return;
Other = Instigator.HitPointTrace(TempHitLocation, HitNormal, HitLocation + (65535 * X), HitPoints, HitLocation,, 1);
if( Other == none || Other == IgnoreImpactPawn || HitPoints.Length == 0 )
return;
HitPawn = KFPawn(Other);
if (Role == ROLE_Authority) {
if ( HitPawn != none ) {
if( !HitPawn.bDeleteMe )
HitPawn.ProcessLocationalDamage(Damage, Instigator, TempHitLocation, MomentumTransfer * X, MyDamageType,HitPoints);
IgnoreImpactPawn = HitPawn;
}
}
}
else {
if ( ExtendedZCollision(Other) != none)
Other = Other.Owner; // ExtendedZCollision is attached to KFMonster
if ( Other == IgnoreImpactPawn )
return; // avoid double hitting the same target
if ( Pawn(Other) != none )
IgnoreImpactPawn = Pawn(Other);
bHeadshot = IgnoreImpactPawn != none && IgnoreImpactPawn.IsHeadShot(HitLocation, X, 1.0);
if ( KFMonster(IgnoreImpactPawn) != none )
Damage = AdjustZedDamage(Damage, KFMonster(IgnoreImpactPawn), bHeadshot);
if ( bHeadshot )
IgnoreImpactPawn.TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, MomentumTransfer * X, DamageTypeHeadShot);
else
Other.TakeDamage(Damage, Instigator, HitLocation, MomentumTransfer * X, MyDamageType);
}
if( Level.NetMode!=NM_Client )
PlayhitNoise(Pawn(Other)!=none && Pawn(Other).ShieldStrength>0);
Velocity *= HitVelocityReduction;
Damage *= HitDamageReduction;
if ( Damage < MinDamage )
Destroy();
}
simulated function int AdjustZedDamage( int Damage, KFMonster Victim, bool bHeadshot )
{
if ( ZombieFleshpound(Victim) != none )
Damage *= 0.7; // It will be multiplied by 0.5 in ZombieFleshpound.TakeDamage(), ending up with 0.35
else if (ZombieBoss(Victim) != none )
Damage *= 0.8; // 20% resistance to Pat
else if ( Level.Game.GameDifficulty >= 5.0 && ZombieScrake(Victim) != none )
Damage *= 0.5;
return Damage;
}
simulated function HitWall( vector HitNormal, actor Wall )
{
if ( LastHitWall != none && LastHitWall == Wall )
Destroy(); // stuck in door
LastHitWall = Wall;
super.HitWall(HitNormal, Wall);
}
defaultproperties
{
HitVelocityReduction=0.850000
HitDamageReduction=0.800000
MinDamage=30
DamageTypeHeadShot=Class'ScrnBalanceSrv.ScrnDamTypeM99HeadShot'
HeadShotDamageMult=3.000000
Damage=800.000000
DamageRadius=0.000000
MyDamageType=Class'ScrnBalanceSrv.ScrnDamTypeM99SniperRifle'
}