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

138 lines
5.1 KiB
Ucode

/**
* Base class for all ScrN shotgun bulelts.
* Adjusted MaxPenetrations to be really max penetration count (off-perk)
* Added feature to make additional penetration damage reduction when hitting specific zeds
*
* @author PooSH, 2012
*/
class ScrnCustomShotgunBullet extends ShotgunBullet
abstract;
var() float BigZedPenDmgReduction; // Additional penetration damage reduction after hitting big zeds. 0.5 = 50% dmg. red.
var() int BigZedMinHealth; // If zed's base Health >= this value, zed counts as Big
var() float MediumZedPenDmgReduction; // Additional penetration damage reduction after hitting medium-size zeds. 0.5 = 50% dmg. red.
var() int MediumZedMinHealth; // If zed's base Health >= this value, zed counts as Medium-size
var String StaticMeshRef;
var String AmbientSoundRef;
static function PreloadAssets()
{
if ( default.AmbientSoundRef != "" )
default.AmbientSound = sound(DynamicLoadObject(default.AmbientSoundRef, class'Sound', true));
if ( default.StaticMeshRef != "" )
UpdateDefaultStaticMesh(StaticMesh(DynamicLoadObject(default.StaticMeshRef, class'StaticMesh', true)));
}
static function bool UnloadAssets()
{
if ( default.AmbientSoundRef != "" )
default.AmbientSound = none;
if ( default.StaticMeshRef != "" )
UpdateDefaultStaticMesh(none);
return true;
}
simulated function ProcessTouch (Actor Other, vector HitLocation)
{
local vector X;
local Vector TempHitLocation, HitNormal;
local array<int> HitPoints;
local KFPlayerReplicationInfo KFPRI;
local KFPawn HitPawn;
local Pawn Victim;
local KFMonster KFM;
if ( Other == none || Other == Instigator || Other.Base == Instigator || !Other.bBlockHitPointTraces )
return;
X = Vector(Rotation);
if( Instigator != none && ROBulletWhipAttachment(Other) != none ) {
// we touched player's auxilary collision cylinder, not let's trace to the player himself
// Other.Base = KFPawn
if( Other.Base == none || Other.Base.bDeleteMe )
return;
Other = Instigator.HitPointTrace(TempHitLocation, HitNormal, HitLocation + (200 * X), HitPoints, HitLocation,, 1);
if( Other == none || HitPoints.Length == 0 || Other.bDeleteMe )
return; // bullet didn't hit a pawn
HitPawn = KFPawn(Other);
if ( HitPawn != none ) {
HitPawn.ProcessLocationalDamage(Damage, Instigator, TempHitLocation, MomentumTransfer * Normal(Velocity), MyDamageType,HitPoints);
}
}
else {
if ( ExtendedZCollision(Other) != none)
Victim = Pawn(Other.Owner); // ExtendedZCollision is attached to KFMonster
else if ( Pawn(Other) != none )
Victim = Pawn(Other);
KFM = KFMonster(Victim);
if ( Victim != none && Victim.IsHeadShot(HitLocation, X, 1.0))
Victim.TakeDamage(Damage * HeadShotDamageMult, Instigator, HitLocation, MomentumTransfer * Normal(Velocity), MyDamageType);
else
Other.TakeDamage(Damage, Instigator, HitLocation, MomentumTransfer * Normal(Velocity), MyDamageType);
}
if ( Instigator != none )
KFPRI = KFPlayerReplicationInfo(Instigator.PlayerReplicationInfo);
if ( KFPRI != none && KFPRI.ClientVeteranSkill != none )
PenDamageReduction = KFPRI.ClientVeteranSkill.static.GetShotgunPenetrationDamageMulti(KFPRI,default.PenDamageReduction);
else
PenDamageReduction = default.PenDamageReduction;
// loose penetrational damage after hitting specific zeds -- PooSH
if ( KFM != none)
PenDamageReduction *= ZedPenDamageReduction(KFM);
Damage *= PenDamageReduction; // Keep going, but lose effectiveness each time.
// if we've struck through more than the max number of foes, destroy.
// MaxPenetrations now really means number of max penetration off-perk -- PooSH
if ( Damage / default.Damage < (default.PenDamageReduction ** MaxPenetrations) + 0.0001 )
Destroy();
else {
speed = VSize(Velocity);
if( Speed < (default.Speed * 0.25) )
Destroy();
}
}
/**
* Further damage reduction after hitting a specific zed
* @param Monster Zed that took damage
* @return Further penetration damage reduction. Doesn't affect current Monster!
* 1.0 - no additional penetration damage reduction
* 0.75 - 25% additional penetration damage reduction
*/
simulated function float ZedPenDamageReduction(KFMonster Monster)
{
if ( Monster == none )
return 1.0;
if ( Monster.default.Health >= BigZedMinHealth )
return BigZedPenDmgReduction;
else if ( Monster.default.Health >= MediumZedMinHealth )
return MediumZedPenDmgReduction;
return 1.0;
}
defaultproperties
{
BigZedPenDmgReduction=0.500000
BigZedMinHealth=1000
MediumZedPenDmgReduction=0.750000
MediumZedMinHealth=500
MaxPenetrations=3
PenDamageReduction=0.700000
}