//============================================================================= // KFWeap_Rifle_FrostShotgunAxe //============================================================================= // A Rifle with an axe that freezes enemies //============================================================================= // Killing Floor 2 // Copyright (C) 2019 Tripwire Interactive LLC //============================================================================= class KFWeap_Rifle_FrostShotgunAxe extends KFWeap_MeleeBase; var float LastFireInterval; var int iInstantHitDamageOnEnemyFrozen; var int iNormalInstantHitDamage; /** Returns trader filter index based on weapon type */ static simulated event EFilterTypeUI GetTraderFilter() { return FT_Rifle; } simulated event PreBeginPlay() { super.PreBeginPlay(); iNormalInstantHitDamage = InstantHitDamage[BASH_FIREMODE]; } /** * See Pawn.ProcessInstantHit * @param DamageReduction: Custom KF parameter to handle penetration damage reduction */ simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optional int NumHits, optional out float out_PenetrationVal, optional int ImpactNum) { local KFPerk InstigatorPerk; InstigatorPerk = GetPerk(); if (InstigatorPerk != none) { InstigatorPerk.UpdatePerkHeadShots(Impact, InstantHitDamageTypes[FiringMode], ImpactNum); } super.ProcessInstantHitEx(FiringMode, Impact, NumHits, out_PenetrationVal, ImpactNum); } /** process local player impact for clientside hit detection */ event RecieveClientImpact(byte FiringMode, const out ImpactInfo Impact, optional out float PenetrationValue, optional int ImpactNum) { // skip KFWeap_MeleeBase because it does melee stuff super(KFWeapon).RecieveClientImpact(FiringMode, Impact, PenetrationValue, ImpactNum); } /** Override melee SetIronSights (which sends to heavy attack) so that this weapon ironsights normally*/ simulated function SetIronSights(bool bNewIronSights) { super(KFWeapon).SetIronSights(bNewIronSights); } /** Override melee ShouldOwnerWalk which doesn't account for walking when in ironsights */ simulated function bool ShouldOwnerWalk() { return super(KFWeapon).ShouldOwnerWalk(); } /** Save off the start time for the bash to determine whether this will be a normal stab or a bullet stab */ simulated function StartFire(byte FireModeNum) { // copying over auto reload functionality since MeleeBase overrides this by default if (FireModeNum == DEFAULT_FIREMODE && ShouldAutoReload(FireModeNum)) { FireModeNum = RELOAD_FIREMODE; } if (FireModeNum == RELOAD_FIREMODE) { // Skip Super/ ServerStartFire and let server wait for ServerSendToReload to force state synchronization BeginFire(FireModeNum); return; } if( FireModeNum == BASH_FIREMODE && WeaponFireTypes[FireModeNum] == EWFT_Custom ) { super.StartMeleeFire(FireModeNum, MeleeAttackHelper.ChooseAttackDir(), ATK_Normal); return; } super.StartFire(FireModeNum); } /** Override to drop the player out of ironsights first */ simulated function AltFireMode() { if (!Instigator.IsLocallyControlled()) { return; } // break out of ironsights when starting to block if (bUsingSights) { SetIronSights(false); } StartFire(BLOCK_FIREMODE); } simulated state MeleeBlocking { simulated function BeginState(name PreviousStateName) { super.BeginState(PreviousStateName); if (bUsingSights) { SetIronSights(false); } } simulated function bool AllowIronSights() { return false; } } simulated function float GetFireInterval(byte FireModeNum) { if (FireModeNum == DEFAULT_FIREMODE && AmmoCount[FireModeNum] == 0) { return LastFireInterval; } return super.GetFireInterval(FireModeNum); } /** Called during reload state */ simulated function bool CanOverrideMagReload(byte FireModeNum) { if (FireModeNum == BLOCK_FIREMODE) { return true; } return super.CanOverrideMagReload(FireModeNum); } /** returns the damage amount for this attack */ simulated function int GetMeleeDamage(byte FireModeNum, optional vector RayDir) { local KFMeleeHelperWeaponFrostShotgunAxe oHelper; local int Damage; oHelper = KFMeleeHelperWeaponFrostShotgunAxe(MeleeAttackHelper); if(oHelper.IsEnemyIced()) { InstantHitDamage[FireModeNum] = iInstantHitDamageOnEnemyFrozen; } else { InstantHitDamage[FireModeNum] = iNormalInstantHitDamage; } Damage = Super.GetMeleeDamage(FireModeNum, RayDir); return Damage; } simulated function int GetModifiedDamage(byte FireModeNum, optional vector RayDir) { switch(FireModeNum) { case DEFAULT_FIREMODE: return GetUpgradedStatValue(InstantHitDamage[FireModeNum], EWUS_Damage0 , CurrentWeaponUpgradeIndex); break; case ALTFIRE_FIREMODE: return GetUpgradedStatValue(InstantHitDamage[FireModeNum], EWUS_Damage1 , CurrentWeaponUpgradeIndex); break; case BASH_FIREMODE: return GetUpgradedStatValue(InstantHitDamage[FireModeNum], EWUS_Damage2 , CurrentWeaponUpgradeIndex); break; } return GetUpgradedStatValue(InstantHitDamage[FireModeNum], EWUS_Damage0 , CurrentWeaponUpgradeIndex); } /** Allows weapon to calculate its own damage for display in trader */ static simulated function float CalculateTraderWeaponStatDamage() { local float BaseDamage, DoTDamage; local class DamageType; BaseDamage = default.InstantHitDamage[DEFAULT_FIREMODE]; DamageType = class(default.InstantHitDamageTypes[DEFAULT_FIREMODE]); if (DamageType != none && DamageType.default.DoT_Type != DOT_None) { DoTDamage = (DamageType.default.DoT_Duration / DamageType.default.DoT_Interval) * (BaseDamage * DamageType.default.DoT_DamageScale); } return BaseDamage * default.NumPellets[DEFAULT_FIREMODE] + DoTDamage; } /** Allows weapon to calculate its own fire rate for display in trader */ static simulated function float CalculateTraderWeaponStatFireRate() { return 60.f / default.FireInterval[DEFAULT_FIREMODE]; // attacks per minute } /** Spawn projectile is called once for each shot pellet fired */ simulated function KFProjectile SpawnAllProjectiles(class KFProjClass, vector RealStartLoc, vector AimDir) { local KFPerk InstigatorPerk; if (CurrentFireMode == GRENADE_FIREMODE) { return Super.SpawnProjectile(KFProjClass, RealStartLoc, AimDir); } InstigatorPerk = GetPerk(); if (InstigatorPerk != none) { Spread[CurrentFireMode] = default.Spread[CurrentFireMode] * InstigatorPerk.GetTightChokeModifier(); } return super.SpawnAllProjectiles(KFProjClass, RealStartLoc, AimDir); } /** Plays a 'settle' animation after a melee attack is finished */ simulated function PlayMeleeSettleAnim() { PlayAnimation(MeleeAttackSettleAnims[0], 0.0, false, 0.1); } defaultproperties { // MeleeBase bMeleeWeapon=true // Inventory / Grouping InventoryGroup=IG_Primary InventorySize=7 GroupPriority=80 //75 WeaponSelectTexture = Texture2D'WEP_UI_Frost_Shotgun_Axe_TEX.UI_WeaponSelect_FrostGun' // Perks AssociatedPerkClasses(0)=class'KFPerk_Support' AssociatedPerkClasses(1)=class'KFPerk_Berserker' // FOV MeshFOV=65 MeshIronSightFOV=45 PlayerIronSightFOV=65 // Depth of field DOF_FG_FocalRadius=50 DOF_FG_MaxNearBlurSize=3.5 // Content PackageKey = "Frost_Shotgun_Axe" FirstPersonMeshName="WEP_1P_Frost_Shotgun_Axe_MESH.Wep_1stP_Frost_Shotgun_Axe_Rig" FirstPersonAnimSetNames(0)="WEP_1P_Frost_Shotgun_Axe_ANIM.WEP_1stP_Frost_Shotgun_Axe" PickupMeshName="WEP_3P_Frost_Shotgun_Axe_MESH.Wep_3rdP_Frost_Shotgun_Pickup" AttachmentArchetypeName="WEP_Frost_Shotgun_Axe_ARCH.Wep_Frost_Shotgun_Axe_3P" MuzzleFlashTemplateName="WEP_Frost_Shotgun_Axe_ARCH.Wep_Frost_Shotgun_Axe_MuzzleFlash" // Ammo MagazineCapacity[0]=6 SpareAmmoCapacity[0]=66 InitialSpareMags[0]=4 AmmoPickupScale[0]=1 bCanBeReloaded=true bReloadFromMagazine=false // @TODO: Turn off once animations are done // Zooming/Position PlayerViewOffset = (X = 8.0,Y = 7,Z = -3.5) IronSightPosition = (X = 0,Y = 0,Z = 0) // AI warning system bWarnAIWhenAiming = true AimWarningDelay = (X = 0.4f, Y = 0.8f) AimWarningCooldown = 0.0f // Recoil maxRecoilPitch = 1050 //550 minRecoilPitch = 900 //400 maxRecoilYaw = 350 //150 minRecoilYaw = -350 //-150 RecoilRate = 0.075 RecoilMaxYawLimit = 500 RecoilMinYawLimit = 65035 RecoilMaxPitchLimit = 900 RecoilMinPitchLimit = 64785 RecoilISMaxYawLimit = 50 RecoilISMinYawLimit = 65485 RecoilISMaxPitchLimit = 500 RecoilISMinPitchLimit = 65485 RecoilViewRotationScale = 0.6 FallingRecoilModifier=1.5 HippedRecoilModifier=1.3 IronSightMeshFOVCompensationScale = 1.5 // DEFAULT_FIREMODE FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle' FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_Frost_Shotgun_Axe' InstantHitDamage(DEFAULT_FIREMODE)=30 //32 //30 InstantHitDamageTypes(DEFAULT_FIREMODE) = class'KFDT_Ballistic_Frost_Shotgun_Axe' FireInterval(DEFAULT_FIREMODE)=0.5 //0.25 // 240 RPM Spread(DEFAULT_FIREMODE)=0.13 //0.007 PenetrationPower(DEFAULT_FIREMODE)=2 FireOffset = (X = 25,Y = 3.0,Z = -2.5) NumPellets(DEFAULT_FIREMODE)=7 AmmoCost(DEFAULT_FIREMODE)=1 LastFireInterval=0.5 // RELOAD_FIREMODE FiringStatesArray(RELOAD_FIREMODE)="Reloading" WeaponFireTypes(RELOAD_FIREMODE)=EWFT_InstantHit // BASH_FIREMODE InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Slashing_Frost_Shotgun_Axe' InstantHitDamage(BASH_FIREMODE)=75 //120 FiringStatesArray(BASH_FIREMODE)=MeleeChainAttacking WeaponFireTypes(BASH_FIREMODE)=EWFT_Custom InstantHitMomentum(BASH_FIREMODE)=10000.f iInstantHitDamageOnEnemyFrozen = 185 //360; //300; // Custom animations FireSightedAnims = (Shoot_Iron) BonesToLockOnEmpty = (RW_Hammer) bHasFireLastAnims = true // Defensive BlockDamageMitigation=0.6f ParryDamageMitigationPercent=0.5 ParryStrength=4 // Block Effects BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Hammer' ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Wood' // Fire Effects WeaponFireSnd(DEFAULT_FIREMODE) = (DefaultCue = AkEvent'WW_WEP_FrostFang.Play_FrostFang_Shoot_3p', FirstPersonCue = AkEvent'WW_WEP_FrostFang.Play_FrostFang_Shoot_1p') // @TODO: Replace Me WeaponDryFireSnd(DEFAULT_FIREMODE) = AkEvent'WW_WEP_FrostFang.Play_FrostFang_Dryfire' // @TODO: Replace Me EjectedShellForegroundDuration = 1.5f // Attachments bHasIronSights = true bHasFlashlight = false WeaponFireWaveForm = ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil' // Aim Assist AimCorrectionSize=40.f // Melee // Melee hitbox Begin Object Class=KFMeleeHelperWeaponFrostShotgunAxe Name=MeleeHelper_0 MaxHitRange=250 HitboxChain.Add((BoneOffset=(X=+3,Z=-190))) HitboxChain.Add((BoneOffset=(X=-3,Z=-170))) HitboxChain.Add((BoneOffset=(X=+3,Z=-150))) HitboxChain.Add((BoneOffset=(X=-3,Z=-130))) HitboxChain.Add((BoneOffset=(X=+3,Z=-110))) HitboxChain.Add((BoneOffset=(X=-3,Z=-90))) HitboxChain.Add((BoneOffset=(X=+3,Z=-70))) HitboxChain.Add((BoneOffset=(X=-3,Z=-50))) HitboxChain.Add((BoneOffset=(X=+3,Z=-30))) HitboxChain.Add((BoneOffset=(Z=10))) WorldImpactEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Bladed_melee_impact' MeleeImpactCamShakeScale=0.03f bUseDirectionalMelee=true bHasChainAttacks=true bUseMeleeHitTimer=false // modified combo sequences ChainSequence_F=(DIR_Left, DIR_ForwardRight, DIR_ForwardLeft, DIR_ForwardRight, DIR_ForwardLeft) ChainSequence_B=(DIR_BackwardRight, DIR_ForwardLeft, DIR_BackwardLeft, DIR_ForwardRight, DIR_Left, DIR_Right, DIR_Left) ChainSequence_L=(DIR_Right, DIR_Left, DIR_ForwardRight, DIR_ForwardLeft, DIR_Right, DIR_Left) ChainSequence_R=(DIR_Left, DIR_Right, DIR_ForwardLeft, DIR_ForwardRight, DIR_Left, DIR_Right) End Object MeleeAttackHelper=MeleeHelper_0 // Weapon Upgrades WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Damage1, Scale=1.125f), (Stat=EWUS_Damage2, Scale=1.1f), (Stat=EWUS_Weight, Add=1))) WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.25f), (Stat=EWUS_Damage1, Scale=1.25f), (Stat=EWUS_Damage2, Scale=1.2f), (Stat=EWUS_Weight, Add=2))) bHasToBeConsideredAsRangedWeaponForPerks=true; }