1
0
KF2-Dev-Scripts/KFGame/Classes/KFMeleeHelperWeaponFrostShotgunAxe.uc
2020-12-13 18:09:05 +03:00

166 lines
5.4 KiB
Ucode

//=============================================================================
// KFMeleeHelperWeapon
//=============================================================================
// Manages melee attack related functionality for 1st person weapons
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFMeleeHelperWeaponFrostShotgunAxe extends KFMeleeHelperWeapon
config(Game);
var bool bIcedEnemy;
var ParticleSystem ChargedEffect;
var ParticleSystemComponent FullyChargedPSC;
var AkEvent oFrozenSound;
var AkEvent oHitSoundAkEvent;
simulated function PawnTakeDamage(ImpactInfo Impact,byte FiringMode, vector Momentum)
{
local int InstantDamage;
bIcedEnemy = false;
if(Impact.HitActor.IsA('KFPawn_Monster'))
{
if(KFPawn_Monster(Impact.HitActor).IsDoingSpecialMove(SM_Frozen))
{
bIcedEnemy = true;
}
}
InstantDamage = GetMeleeDamage(FiringMode, Impact.RayDir);
Impact.HitActor.TakeDamage(InstantDamage, Instigator.Controller,
Impact.HitLocation, Momentum,
GetDamageType(FiringMode), Impact.HitInfo, Outer );
}
simulated function bool IsEnemyIced(){
return bIcedEnemy;
}
/** Called from state MeleeAtacking */
simulated function BeginMeleeAttack(optional bool bIsChainAttack)
{
local Pawn P;
local KFPawn_Monster KFPM;
local vector Projection;
local float MeleeDuration;
// Don't let a weak zed grab us when we just melee attacked
// Ramm - commented out, too exploitable
// SetWeakZedGrabCooldownOnPawn(0.5);
// initialize attack settings
bHasAlreadyHit = false;
bHitEnemyThisAttack = false;
// Let the playercontroller know we did an attack
if ( Instigator != None && Instigator.Controller != none &&
KFPlayerController(Instigator.Controller) != none )
{
KFPlayerController(Instigator.Controller).AddShotsFired(1);
}
// Clear reset flag (see InitAttackSequence, ContinueMeleeAttack)
bResetChainSequence = false;
// save the direction of this attack
CurrentAttackDir = ( CurrentFireMode == CUSTOM_FIREMODE ) ? DIR_None : GetNextAttackDir();
// Notify enemy pawns of melee strike
if( WorldInfo.NetMode != NM_Client )
{
foreach WorldInfo.AllPawns( class'Pawn', P )
{
if( P.GetTeamNum() != Instigator.GetTeamNum() && P.IsAliveAndWell() && !P.IsHumanControlled() )
{
Projection = Instigator.Location - P.Location;
if( VSizeSQ(Projection) <= Square(MaxHitRange + P.CylinderComponent.CollisionRadius) )
{
KFPM = KFPawn_Monster( P );
if( KFPM != none && KFPM.MyKFAIC != none )
{
KFPM.MyKFAIC.ReceiveMeleeWarning( CurrentAttackDir, Projection, Instigator );
}
}
}
}
}
// Select and play attack animation
MeleeDuration = PlayMeleeAttackAnimation();
if ( MeleeDuration > 0.f )
{
// @hack: Add current DeltaSeconds to timer. This fixes an off-by-one frame issue that can
// that can cause the timer to interrupt animation at low framerate. This is particularly
// bad for melee when using impact anim notifies.
SetTimer(MeleeDuration + WorldInfo.DeltaSeconds, FALSE, nameof(MeleeCheckTimer), self);
// set the timer to check for hits
if( bUseMeleeHitTimer && InitialImpactDelay > 0.f )
{
// Clear complete time so it is intialized properly
ImpactComplete_ActorTime = -1.f;
SetTimer(InitialImpactDelay, FALSE, nameof(MeleeImpactTimer), self);
}
}
else
{
`warn("MeleeDuration is zero!!!");
SetTimer(0.001, false, nameof(HandleFinishedFiring));
}
}
/**
* Called by ProcessMeleeHit to spawn effects
* Network: Local Player and Server
*/
simulated function PlayMeleeHitEffects(Actor Target, vector HitLocation, vector HitDirection, optional bool bShakeInstigatorCamera=true)
{
// @note: Skipping super(). No victim camera shake is intentional
if( WorldInfo.NetMode != NM_DedicatedServer )
{
// first person (local) fire effects
if ( Instigator.IsFirstPerson() )
{
PlayerController(Instigator.Controller).ClientPlayCameraShake(MeleeImpactCamShake, MeleeImpactCamShakeScale, true, CAPS_UserDefined, rotator(-HitDirection));
if ( Target.IsA('Pawn') )
{
AddBlood(0.01f, 0.1f);
if(KFPawn_Monster(Target).IsDoingSpecialMove(SM_Frozen))
{
if( IsZero(HitDirection) && Instigator != none )
{
HitDirection = Normal(Instigator.Location - HitLocation);
}
WorldInfo.MyEmitterPool.SpawnEmitter(ChargedEffect, HitLocation, rotator(HitDirection), Target);
Instigator.PlayAkEvent(oFrozenSound);
Instigator.PlayAkEvent(oHitSoundAkEvent);
}
}
}
// If we hit a pawn we can skip the Tracing code in PlayImpactEffects. Pawn FX are handled in
// PlayHit and this prevents incorrect (world) FX from playing if the trace is bad.
if ( !(Target.bCanBeDamaged && Target.IsA('Pawn')) )
{
// Use ImpactEffectManager to material based world impacts
`ImpactEffectManager.PlayImpactEffects(HitLocation, Instigator, HitDirection, WorldImpactEffects);
}
}
}
defaultproperties
{
oFrozenSound=AkEvent'WW_WEP_SA_CompoundBow.Play_Arrow_Impact_Cryo'
oHitSoundAkEvent=AkEvent'WW_WEP_FrostFang.Play_FrostFang_Base_Impact'
ChargedEffect=ParticleSystem'WEP_Frost_Shotgun_Axe_EMIT.FX_FrostFang_Melee_ImpactFrozen_01';
HitboxBoneName=RW_Weapon
}