1
0
KF2-Dev-Scripts/KFGame/Classes/KFDT_Slashing.uc
2020-12-13 18:01:13 +03:00

159 lines
5.2 KiB
Ucode

//=============================================================================
// KFDT_Slashing
//=============================================================================
// Melee slashing attacks designed to cut
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFDT_Slashing extends KFDamageType
abstract;
`include(KFGameDialog.uci)
`define COSINE_0_DEGREES 1
`define COSINE_40_DEGREES 0.76
`define COSINE_70_DEGREES 0.34
`define COSINE_90_DEGREES 0
/** @return The slast type from the HitFxInfo. This returns a 8-way slash info. */
static simulated function EPawnOctant GetLastSlashDirection(KFPawn_Monster InPawn, vector HitDirection)
{
local vector SlashPlaneNormal;
local rotator InstigatorRotation;
local vector InstigatorFaceDir, InstigatorRightDir;
local float UpDotSlash, RightDotSlash, UpThresholdValue;
if( InPawn != none && InPawn.HitFxInstigator != none )
{
HitDirection = Normal( HitDirection );
InstigatorRotation = InPawn.HitFxInstigator.GetBaseAimRotation();
InstigatorFaceDir = GetRotatorAxis(InstigatorRotation, 0);
InstigatorRightDir = GetRotatorAxis(InstigatorRotation, 1);
// Cross the face direction of the instigator with the hit direction to find
// the normal to the "slashing" plane
SlashPlaneNormal = Normal(InstigatorFaceDir Cross HitDirection);
// Dot the slash plane normal with the world up direction to figure out
// the quadrant for the normal of the slash plane
UpDotSlash = vect(0,0,1) Dot SlashPlaneNormal;
UpThresholdValue = Abs(UpDotSlash);
// Dot the slash plane normal with the instigator right to figure out
// the direction of the slash
RightDotSlash = InstigatorRightDir Dot SlashPlaneNormal;
// Threshhold against the preset values to find out the type of slash. The sign (+ or -) of the
// dot products are used to further classify the direction of the slash
if( UpThresholdValue <= `COSINE_0_DEGREES && UpThresholdValue >= `COSINE_40_DEGREES )
{
if( UpDotSlash > 0 )
return DIR_Right;
else
return DIR_Left;
}
else if( UpThresholdValue <= `COSINE_40_DEGREES && UpThresholdValue >= `COSINE_70_DEGREES )
{
if( UpDotSlash < 0 && RightDotSlash > 0 )
return DIR_ForwardLeft;
else if( UpDotSlash > 0 && RightDotSlash > 0 )
return DIR_ForwardRight;
else if( UpDotSlash > 0 && RightDotSlash < 0 )
return DIR_BackwardRight;
else if( UpDotSlash < 0 && RightDotSlash < 0 )
return DIR_BackwardLeft;
}
else if( UpThresholdValue <= `COSINE_70_DEGREES && UpThresholdValue >= `COSINE_90_DEGREES )
{
if( RightDotSlash > 0 )
return DIR_Forward;
else
return DIR_Backward;
}
}
return DIR_None;
}
/**
* Take the primary HitDirection and modify it to add more spread.
* Additional hit directions are added per hit to create a longish blood splat.
*/
static simulated function AddBloodSpread(KFPawn_Monster InPawn, vector HitDirection, out array<vector> HitSpread, bool bIsDismemberingHit, bool bWasObliterated)
{
local rotator InstigatorRotation;
local float Angle;
local Quat Rotation;
local vector InstigatorFaceDir, SlashPlaneNormal;
if( InPawn.HitFxInstigator != none )
{
InstigatorRotation = InPawn.HitFxInstigator.GetBaseAimRotation();
}
else
{
// Use inverse of pawn yaw in the event our FX instigator has been destroyed
InstigatorRotation.Yaw = NormalizeRotAxis( -InPawn.Rotation.Yaw );
}
InstigatorFaceDir = GetRotatorAxis(InstigatorRotation, 0);
// Cross the face direction of the instigator with the hit direction to find
// the normal to the "slashing" plane
SlashPlaneNormal = Normal(InstigatorFaceDir Cross HitDirection);
for( Angle=-Pi/2.f; Angle <= Pi/2.f; Angle += Pi/6.f)
{
Rotation = QuatFromAxisAndAngle(SlashPlaneNormal, Angle);
HitSpread.AddItem(QuatRotateVector(Rotation, HitDirection));
}
}
/**
* Modify the "amount of blood" for persistent blood splatters. For slash attacks,
* we do not take the damage scale into account to keep the (streak) effect more
* consistent.
*/
static simulated function float GetBloodScale(float HitZoneDamageScale, bool bIsDismemberingHit, bool bWasObliterated)
{
return default.BloodScale * (bIsDismemberingHit ? 4.f : 1.f);
}
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
switch ( InHitZoneName )
{
case 'head':
case 'lhand':
case 'rhand':
case 'lfoot':
case 'rfoot':
case 'lforearm':
case 'rforearm':
return true;
}
return false;
}
/** Returns ID of dialog event for killer to speak after killing a zed using this damage type */
static function int GetKillerDialogID()
{
return `KILL_Slashing;
}
defaultproperties
{
KDamageImpulse=300
bShouldSpawnPersistentBlood=true
BloodScale=0.5
BodyWoundDecalMaterials[0]=MaterialInstanceConstant'FX_Impacts_MAT.FX_Bladed_Impact_Slice_01_MIC'
CameraLensEffectTemplate=class'KFCameraLensEmit_BloodBase'
GoreDamageGroup=DGT_MeleeSlash
EffectGroup=FXG_Slashing
}