2022-09-01 15:58:51 +00:00
|
|
|
//=============================================================================
|
|
|
|
// KFWeap_Edged_AbominationAxe
|
|
|
|
//=============================================================================
|
|
|
|
//=============================================================================
|
|
|
|
// Killing Floor 2
|
|
|
|
// Copyright (C) 2022 Tripwire Interactive LLC
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
class KFWeap_Edged_Scythe extends KFWeap_MeleeBase;
|
|
|
|
|
|
|
|
var const array<MeleeHitBoxInfo> HitboxChainFolded;
|
|
|
|
var const array<MeleeHitBoxInfo> HitboxChainUnfolded;
|
|
|
|
|
|
|
|
var const int MaxHitRangeFolded;
|
|
|
|
var const int MaxHitRangeUnfolded;
|
|
|
|
|
|
|
|
var const int FoldedDamage;
|
|
|
|
var const int FoldedDamageAlt;
|
|
|
|
|
|
|
|
var const int UnfoldedDamage;
|
|
|
|
var const int UnfoldedDamageAlt;
|
|
|
|
|
|
|
|
var const class<DamageType> FoldedDT;
|
|
|
|
var const class<DamageType> FoldedDTAlt;
|
|
|
|
|
|
|
|
var const class<DamageType> UnfoldedDT;
|
|
|
|
var const class<DamageType> UnfoldedDTAlt;
|
|
|
|
|
|
|
|
var const float UnfoldBlendingDuration;
|
|
|
|
|
|
|
|
var const float FoldedAttackAnimRate;
|
|
|
|
|
|
|
|
var const vector PlayerViewOffsetUnfolded;
|
|
|
|
|
|
|
|
var transient vector OriginalPlayerViewOffset;
|
|
|
|
var transient bool bIsFolded;
|
|
|
|
|
|
|
|
var AnimNodeBlendPerBone FoldBlendNode;
|
|
|
|
|
|
|
|
var const ParticleSystem BloodParticles;
|
|
|
|
|
|
|
|
const BloodParticlesSocket = 'BlockEffect';
|
|
|
|
|
|
|
|
var ParticleSystem FoldedTrailParticleSystem;
|
|
|
|
var ParticleSystem UnfoldedTrailParticleSystem;
|
|
|
|
|
|
|
|
simulated event PreBeginPlay()
|
|
|
|
{
|
|
|
|
Super.PreBeginPlay();
|
|
|
|
|
|
|
|
OriginalPlayerViewOffset = PlayerViewOffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
event PostBeginPlay()
|
|
|
|
{
|
|
|
|
Super.PostBeginPlay();
|
|
|
|
|
|
|
|
ChangeMode(true, false);
|
|
|
|
|
|
|
|
SetFoldedBladeBlendTarget(1.0f, 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/** The SkeletalMeshComponents Animations are being instanced from AnimTreeTemplate
|
|
|
|
* before PostInitAnimTree. Be sure to never set the Mesh's animations directly through
|
|
|
|
* the package */
|
|
|
|
simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
|
|
|
|
{
|
|
|
|
Super.PostInitAnimTree(SkelComp);
|
|
|
|
|
|
|
|
FoldBlendNode = AnimNodeBlendPerBone(SkelComp.FindAnimNode('FoldBlendNode'));
|
|
|
|
|
|
|
|
SetFoldedBladeBlendTarget(1.0f, 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
/** Returns true if weapon can potentially be reloaded */
|
|
|
|
simulated function bool CanReload(optional byte FireModeNum)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated state WeaponUpkeep
|
|
|
|
{
|
|
|
|
simulated function BeginState(name PreviousStateName)
|
|
|
|
{
|
|
|
|
local name AnimName;
|
|
|
|
local float Duration;
|
|
|
|
|
|
|
|
AnimName = CleanNonBloodyAnim;
|
|
|
|
|
|
|
|
Duration = MySkelMesh.GetAnimLength(AnimName);
|
|
|
|
if ( Duration > 0.f )
|
|
|
|
{
|
|
|
|
if ( Instigator.IsFirstPerson() )
|
|
|
|
{
|
|
|
|
PlayAnimation(AnimName);
|
|
|
|
SetTimer(Duration, FALSE, nameof(SwapComplete));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
`warn("Duration is zero!!!"@AnimName);
|
|
|
|
SetTimer(0.001, FALSE, nameof(SwapComplete));
|
|
|
|
}
|
|
|
|
|
|
|
|
NotifyBeginState();
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function BeginFire(byte FireModeNum)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated event EndState(Name NextStateName)
|
|
|
|
{
|
|
|
|
ClearTimer(nameof(SwapComplete));
|
|
|
|
Super.EndState(NextStateName);
|
|
|
|
NotifyEndState();
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function SwapComplete()
|
|
|
|
{
|
|
|
|
if (Role == ROLE_Authority)
|
|
|
|
{
|
|
|
|
GotoState('Active');
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GotoState('Active');
|
|
|
|
ServerSwapComplete();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
server reliable function ServerSwapComplete()
|
|
|
|
{
|
|
|
|
GotoState('Active');
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function ChangeMode(bool IsFolded, bool bApplyBlend = true)
|
|
|
|
{
|
|
|
|
if (MeleeAttackHelper == none)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (IsFolded)
|
|
|
|
{
|
|
|
|
MeleeAttackHelper.SetMeleeRange(MaxHitRangeFolded);
|
|
|
|
MeleeAttackHelper.SetHitBoxChain(HitboxChainFolded);
|
|
|
|
|
|
|
|
InstantHitDamage[DEFAULT_FIREMODE] = FoldedDamage;
|
|
|
|
InstantHitDamage[HEAVY_ATK_FIREMODE] = FoldedDamageAlt;
|
|
|
|
|
|
|
|
InstantHitDamageTypes[DEFAULT_FIREMODE] = FoldedDT;
|
|
|
|
InstantHitDamageTypes[HEAVY_ATK_FIREMODE] = FoldedDTAlt;
|
|
|
|
|
|
|
|
PlayerViewOffset = OriginalPlayerViewOffset;
|
2022-11-27 21:40:54 +00:00
|
|
|
|
|
|
|
InstantHitDamageTypes[BASH_FIREMODE]=class'KFDT_Piercing_ScytheStabFolded';
|
|
|
|
InstantHitMomentum[BASH_FIREMODE]=100000.f;
|
|
|
|
InstantHitDamage[BASH_FIREMODE]=40;
|
2022-09-01 15:58:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MeleeAttackHelper.SetMeleeRange(MaxHitRangeUnfolded);
|
|
|
|
MeleeAttackHelper.SetHitBoxChain(HitboxChainUnfolded);
|
|
|
|
|
|
|
|
InstantHitDamage[DEFAULT_FIREMODE] = UnfoldedDamage;
|
|
|
|
InstantHitDamage[HEAVY_ATK_FIREMODE] = UnfoldedDamageAlt;
|
|
|
|
|
|
|
|
InstantHitDamageTypes[DEFAULT_FIREMODE] = UnfoldedDT;
|
|
|
|
InstantHitDamageTypes[HEAVY_ATK_FIREMODE] = UnfoldedDTAlt;
|
|
|
|
|
|
|
|
PlayerViewOffset = PlayerViewOffsetUnfolded;
|
2022-11-27 21:40:54 +00:00
|
|
|
|
|
|
|
InstantHitDamageTypes[BASH_FIREMODE]=class'KFDT_Piercing_ScytheStab';
|
|
|
|
InstantHitMomentum[BASH_FIREMODE]=100000.f;
|
|
|
|
InstantHitDamage[BASH_FIREMODE]=60;
|
2022-09-01 15:58:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NotifyServerMode(bIsFolded);
|
|
|
|
|
|
|
|
if (bApplyBlend)
|
|
|
|
{
|
|
|
|
SetFoldedBladeBlendTarget(bIsFolded ? 1.0f : 0.0f, UnfoldBlendingDuration);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function SetFoldedBladeBlendTarget(float Value, float BlendTime)
|
|
|
|
{
|
|
|
|
if ( FoldBlendNode != None )
|
|
|
|
{
|
|
|
|
FoldBlendNode.SetBlendTarget(Value, BlendTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function StartFire(byte FireModeNum)
|
|
|
|
{
|
|
|
|
if (StartFireDisabled && FireModeNum == BLOCK_FIREMODE)
|
|
|
|
{
|
|
|
|
StartFireDisabled = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FireModeNum == DEFAULT_FIREMODE || FireModeNum == HEAVY_ATK_FIREMODE)
|
|
|
|
{
|
|
|
|
DistortTrailParticle = bIsFolded ? FoldedTrailParticleSystem : UnfoldedTrailParticleSystem;
|
|
|
|
}
|
|
|
|
else if (FireModeNum == BASH_FIREMODE)
|
|
|
|
{
|
|
|
|
DistortTrailParticle = none;
|
|
|
|
}
|
|
|
|
|
|
|
|
super.StartFire(FireModeNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
static simulated function float CalculateTraderWeaponStatDamage()
|
|
|
|
{
|
|
|
|
// How is this calculated for this weapon?
|
|
|
|
return default.UnfoldedDamage;
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function PlayAnimation(name Sequence, optional float fDesiredDuration, optional bool bLoop, optional float BlendInTime=0.1, optional float BlendOutTime=0.0)
|
|
|
|
{
|
|
|
|
local string NewAnimName;
|
|
|
|
|
|
|
|
if (Sequence == 'Idle' ||
|
|
|
|
Sequence == 'Guncheck_V1' ||
|
|
|
|
Sequence == 'Guncheck_V2' ||
|
|
|
|
Sequence == 'Guncheck_V3')
|
|
|
|
{
|
|
|
|
NewAnimName = string(Sequence);
|
|
|
|
NewAnimName $= ((bIsFolded) ? "_Folded" : "_Unfolded");
|
|
|
|
Super.PlayAnimation(name(NewAnimName), fDesiredDuration, bLoop, BlendInTime, BlendOutTime);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Super.PlayAnimation(Sequence, fDesiredDuration, bLoop, BlendInTime, BlendOutTime);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function ModifyMeleeAttackSpeed(out float InSpeed, optional int FireMode = DEFAULT_FIREMODE, optional int UpgradeIndex = INDEX_NONE, optional KFPerk CurrentPerk)
|
|
|
|
{
|
|
|
|
Super.ModifyMeleeAttackSpeed(InSpeed, FireMode, UpgradeIndex, CurrentPerk);
|
|
|
|
|
|
|
|
if (bIsFolded)
|
|
|
|
{
|
|
|
|
InSpeed *= FoldedAttackAnimRate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Overriden to apply fold/unfold logic
|
|
|
|
*/
|
|
|
|
simulated function ANIMNOTIFY_LockBolt()
|
|
|
|
{
|
|
|
|
bIsFolded = !bIsFolded;
|
|
|
|
ChangeMode(bIsFolded);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Unused */
|
|
|
|
simulated function ANIMNOTIFY_UnLockBolt()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Play blood VFX as we only use one anim. */
|
|
|
|
simulated function ANIMNOTIFY_CleanBlood()
|
|
|
|
{
|
|
|
|
if (!bIsBloody)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (WorldInfo.NetMode != NM_DedicatedServer && BloodParticles != none)
|
|
|
|
{
|
|
|
|
WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(BloodParticles, MySkelMesh, BloodParticlesSocket, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
Super.ANIMNOTIFY_CleanBlood();
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated state WeaponEquipping
|
|
|
|
{
|
|
|
|
/** Initialize the weapon as being active and ready to go. */
|
|
|
|
simulated event BeginState(Name PreviousStateName)
|
|
|
|
{
|
|
|
|
Super.BeginState(PreviousStateName);
|
|
|
|
|
|
|
|
if (WorldInfo.NetMode != NM_Client)
|
|
|
|
{
|
|
|
|
NotifyInitialState(bIsFolded);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Should replicate to 3P to show the shield effects
|
|
|
|
*/
|
|
|
|
simulated function NotifyInitialState(bool bFolded)
|
|
|
|
{
|
|
|
|
local KFPawn KFP;
|
|
|
|
|
|
|
|
if (WorldInfo.NetMode != NM_Client)
|
|
|
|
{
|
|
|
|
`Log("NotifyInitialState: " $bFolded);
|
|
|
|
|
|
|
|
KFP = KFPawn(Instigator);
|
|
|
|
KFP.OnWeaponSpecialAction(bFolded ? 0 : 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
reliable server function NotifyServerMode(bool bFolded)
|
|
|
|
{
|
|
|
|
bIsFolded = bFolded;
|
|
|
|
}
|
|
|
|
|
|
|
|
defaultproperties
|
|
|
|
{
|
|
|
|
// Zooming/Position
|
|
|
|
PlayerViewOffset=(X=10,Y=0,Z=-10) // (X=2,Y=0,Z=0)
|
|
|
|
PlayerViewOffsetUnfolded=(X=12,Y=0,Z=-7)
|
|
|
|
|
|
|
|
// Content
|
|
|
|
PackageKey="Scythe"
|
|
|
|
FirstPersonMeshName="WEP_1P_Scythe_MESH.Wep_1stP_Scythe_Rig"
|
|
|
|
FirstPersonAnimSetNames(0)="WEP_1P_Scythe_ANIM.Wep_1st_Scythe_Anim"
|
|
|
|
FirstPersonAnimTree="WEP_1P_Scythe_ANIM.1P_Scythe_Animtree"
|
|
|
|
PickupMeshName="wep_3p_scythe_mesh.Wep_3rdP_Scythe_Pickup"
|
|
|
|
AttachmentArchetypeName="WEP_Scythe_ARCH.Wep_Scythe_3P"
|
|
|
|
|
|
|
|
// Short Range Mode Params
|
|
|
|
MaxHitRangeFolded=220
|
2022-11-27 21:40:54 +00:00
|
|
|
FoldedDamage = 70
|
|
|
|
FoldedDamageAlt = 120
|
2022-09-01 15:58:51 +00:00
|
|
|
FoldedDT=class'KFDT_Slashing_ScytheShort'
|
|
|
|
FoldedDTAlt=class'KFDT_Slashing_ScytheShortAlt'
|
|
|
|
HitboxChainFolded = {(
|
|
|
|
(BoneOffset=(X=+3,Z=190)),
|
|
|
|
(BoneOffset=(X=-3,Z=170)),
|
|
|
|
(BoneOffset=(X=+3,Z=150)),
|
|
|
|
(BoneOffset=(X=-3,Z=130)),
|
|
|
|
(BoneOffset=(X=+3,Z=110)),
|
|
|
|
(BoneOffset=(X=-3,Z=90)),
|
|
|
|
(BoneOffset=(X=+3,Z=70)),
|
|
|
|
(BoneOffset=(X=-3,Z=50)),
|
|
|
|
(BoneOffset=(X=+3,Z=30)),
|
|
|
|
(BoneOffset=(Z=10))
|
|
|
|
)}
|
|
|
|
|
|
|
|
// Long Range Mode Params
|
|
|
|
MaxHitRangeUnfolded=300
|
2022-11-27 21:40:54 +00:00
|
|
|
UnfoldedDamage=140
|
|
|
|
UnfoldedDamageAlt=190
|
2022-09-01 15:58:51 +00:00
|
|
|
UnfoldedDT=class'KFDT_Slashing_ScytheLong'
|
|
|
|
UnfoldedDTAlt=class'KFDT_Slashing_ScytheLongAlt'
|
|
|
|
HitboxChainUnfolded = {(
|
|
|
|
(BoneOffset=(X=-3,Z=290)),
|
|
|
|
(BoneOffset=(X=-3,Z=270)),
|
|
|
|
(BoneOffset=(X=-3,Z=250)),
|
|
|
|
(BoneOffset=(X=+3,Z=230)),
|
|
|
|
(BoneOffset=(X=-3,Z=210)),
|
|
|
|
(BoneOffset=(X=+3,Z=190)),
|
|
|
|
(BoneOffset=(X=-3,Z=170)),
|
|
|
|
(BoneOffset=(X=+3,Z=150)),
|
|
|
|
(BoneOffset=(X=-3,Z=130)),
|
|
|
|
(BoneOffset=(X=+3,Z=110)),
|
|
|
|
(BoneOffset=(X=-3,Z=90)),
|
|
|
|
(BoneOffset=(X=+3,Z=70)),
|
|
|
|
(BoneOffset=(X=-3,Z=50)),
|
|
|
|
(BoneOffset=(X=+3,Z=30)),
|
|
|
|
(BoneOffset=(Z=10))
|
|
|
|
)}
|
|
|
|
|
|
|
|
Begin Object Name=MeleeHelper_0
|
|
|
|
WorldImpactEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Bladed_melee_impact'
|
|
|
|
MeleeImpactCamShakeScale=0.04f //0.5
|
|
|
|
// modified combo sequences
|
|
|
|
ChainSequence_F=(DIR_ForwardRight, DIR_ForwardLeft, DIR_ForwardRight, DIR_ForwardLeft)
|
|
|
|
ChainSequence_B=(DIR_BackwardLeft, DIR_BackwardRight, DIR_BackwardLeft, DIR_ForwardRight, DIR_Left, DIR_Right, DIR_Left)
|
|
|
|
ChainSequence_L=(DIR_Right, DIR_Left)
|
|
|
|
ChainSequence_R=(DIR_Left, DIR_Right, DIR_ForwardLeft, DIR_ForwardRight, DIR_Left, DIR_Right)
|
|
|
|
End Object
|
|
|
|
|
|
|
|
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Slashing_ScytheShort'
|
|
|
|
InstantHitMomentum(DEFAULT_FIREMODE)=30000.f
|
|
|
|
|
|
|
|
InstantHitDamageTypes(HEAVY_ATK_FIREMODE)=class'KFDT_Slashing_ScytheShortAlt'
|
|
|
|
FiringStatesArray(HEAVY_ATK_FIREMODE)=MeleeHeavyAttacking
|
|
|
|
InstantHitMomentum(HEAVY_ATK_FIREMODE)=30000.f
|
|
|
|
|
2022-11-27 21:40:54 +00:00
|
|
|
// Defined in ChangeMode function
|
|
|
|
//InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Piercing_ScytheStab'
|
|
|
|
//InstantHitMomentum(BASH_FIREMODE)=100000.f
|
|
|
|
//InstantHitDamage(BASH_FIREMODE)=50
|
2022-09-01 15:58:51 +00:00
|
|
|
|
|
|
|
// Inventory
|
|
|
|
GroupPriority=50
|
|
|
|
InventorySize=7
|
|
|
|
WeaponSelectTexture=Texture2D'WEP_UI_Scythe_TEX.UI_WeaponSelect_Scythe'
|
|
|
|
|
|
|
|
|
|
|
|
AssociatedPerkClasses(0)=class'KFPerk_Berserker'
|
|
|
|
|
|
|
|
// Block Sounds
|
|
|
|
BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Katana'
|
|
|
|
ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Metal'
|
|
|
|
|
|
|
|
ParryDamageMitigationPercent=0.4
|
|
|
|
BlockDamageMitigation=0.5
|
|
|
|
ParryStrength=5
|
|
|
|
|
|
|
|
bIsFolded=true
|
|
|
|
|
|
|
|
BonesToLockOnEmpty.Empty()
|
|
|
|
|
|
|
|
UnfoldBlendingDuration=0.05f
|
|
|
|
|
|
|
|
FoldedAttackAnimRate=0.65f
|
|
|
|
|
|
|
|
// IdleFidgetAnims=(Guncheck_v1, Guncheck_v2, Guncheck_v3)
|
|
|
|
|
|
|
|
// Weapon Upgrade stat boosts
|
|
|
|
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
|
|
|
|
|
|
|
DistortTrailParticle = none
|
|
|
|
WhiteTrailParticle = none
|
|
|
|
BlueTrailParticle = none
|
|
|
|
RedTrailParticle = none
|
|
|
|
|
|
|
|
FoldedTrailParticleSystem=ParticleSystem'WEP_Scythe_EMIT.FX_Scythe_Custom_R_01'
|
|
|
|
UnfoldedTrailParticleSystem=ParticleSystem'WEP_Scythe_EMIT.FX_Scythe_Custom_Unfold_01';
|
|
|
|
|
|
|
|
BloodParticles = ParticleSystem'WEP_1P_KATANA_EMIT.FX_katana_blood_flick_01'
|
|
|
|
}
|