/** * 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 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 }