1
0
KF2-Dev-Scripts/KFGameContent/Classes/KFWeap_Edged_Scythe.uc

438 lines
12 KiB
Ucode

//=============================================================================
// 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;
InstantHitDamageTypes[BASH_FIREMODE]=class'KFDT_Piercing_ScytheStabFolded';
InstantHitMomentum[BASH_FIREMODE]=100000.f;
InstantHitDamage[BASH_FIREMODE]=40;
}
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;
InstantHitDamageTypes[BASH_FIREMODE]=class'KFDT_Piercing_ScytheStab';
InstantHitMomentum[BASH_FIREMODE]=100000.f;
InstantHitDamage[BASH_FIREMODE]=60;
}
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
FoldedDamage = 70
FoldedDamageAlt = 120
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
UnfoldedDamage=140
UnfoldedDamageAlt=190
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
// Defined in ChangeMode function
//InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Piercing_ScytheStab'
//InstantHitMomentum(BASH_FIREMODE)=100000.f
//InstantHitDamage(BASH_FIREMODE)=50
// 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'
}