159 lines
5.2 KiB
Ucode
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
|
||
|
}
|