//============================================================================= // KFDT_Explosive //============================================================================= // Damage caused by air pressures normally associated with explosives //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC //============================================================================= class KFDT_Explosive extends KFDamageType abstract; `include(KFGameDialog.uci) /** * Modify the "amount of blood" for persistent blood splatters. For explosives, * we treat is as a critical hit no matter which hit zone it hit. */ static simulated function float GetBloodScale(float HitZoneDamageScale, bool bIsDismemberingHit, bool bWasObliterated) { return default.BloodScale * ((bIsDismemberingHit || bWasObliterated) ? 2.f : 1.f); } /** * Take the primary HitDirection and modify it to add more spread. * Additional hit directions are added per hit to create radial splats */ static simulated function AddBloodSpread(KFPawn_Monster InPawn, vector HitDirection, out array HitSpread, bool bIsDismeberingHit, bool bWasObliterated) { local float PolarAngle, AzimuthAngle; local float RandomizedPolarAngle, RandomizedAzimuthAngle; local vector SampleDir; // Sample uniformly distributed directions around the hemisphere for( PolarAngle = Pi/2.f; PolarAngle > 0; PolarAngle -= Pi/4.f) { // Apply small bias to account for FP inaccuracy for( AzimuthAngle = 0.f; AzimuthAngle < 2*Pi - 0.01; AzimuthAngle += Pi/4.f ) { // Apply small randomization (-15,15) degrees RandomizedPolarAngle = PolarAngle + (0.26 - RandRange(0,0.52)); RandomizedAzimuthAngle = AzimuthAngle + (0.26 - RandRange(0,0.52)); SampleDir.x = Sin(RandomizedPolarAngle)*Cos(RandomizedAzimuthAngle); SampleDir.y = Sin(RandomizedPolarAngle)*Sin(RandomizedAzimuthAngle); SampleDir.z = Cos(RandomizedPolarAngle); HitSpread.AddItem(SampleDir); } } // Add the vertically up direction. PolarAngle = 0 HitSpread.AddItem(vect(0,0,1)); // Trace down and apply blood on the ground if obliterated if( bWasObliterated ) { // Apply small bias to account for FP inaccuracy for( AzimuthAngle = 0.f; AzimuthAngle < 2*Pi - 0.01; AzimuthAngle += Pi/2.f ) { // Apply small randomization (-15,15) degrees RandomizedPolarAngle = 0.8 * Pi + (0.26 - RandRange(0,0.52)); RandomizedAzimuthAngle = AzimuthAngle + (0.26 - RandRange(0,0.52)); SampleDir.x = Sin(RandomizedPolarAngle)*Cos(RandomizedAzimuthAngle); SampleDir.y = Sin(RandomizedPolarAngle)*Sin(RandomizedAzimuthAngle); SampleDir.z = Cos(RandomizedPolarAngle); HitSpread.AddItem(SampleDir); } // Add the vertically down direction. PolarAngle = Pi HitSpread.AddItem(vect(0,0,-1)); } } /** Returns ID of dialog event for killer to speak after killing a zed using this damage type */ static function int GetKillerDialogID() { return `KILL_Explosive; } /** Allows the damage type to map a hit zone to a different bone for dismemberment purposes. */ static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName) { local KFCharacterInfo_Monster MonsterInfo; MonsterInfo = InPawn.GetCharacterMonsterInfo(); if ( MonsterInfo != none ) { // Randomly pick the left or right shoulder to dismember if( InHitZoneName == 'chest') { OutBoneName = Rand(2) == 0 ? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName : MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName; } } } defaultproperties { // Uses RadialDamageImpulse for proper impulses with KActors // Also, enables radial damage falloff for pawns RadialDamageImpulse=1500 KDamageImpulse=0 KDeathUpKick=250.0 // unreal physics momentum bExtraMomentumZ=True // hit effects bShouldSpawnBloodSplat=true bCanGib=true GoreDamageGroup=DGT_Explosive KnockdownPower=39 StumblePower=59 // Obliteration bCanObliterate=true ObliterationHealthThreshold=-80 ObliterationDamageThreshold=160 // Doors bAllowAIDoorDestruction=true }