//============================================================================= // KFWeap_Rifle_MosinNagant //============================================================================= // A Mosin-Nagant Rifle //============================================================================= // Killing Floor 2 // Copyright (C) 2019 Tripwire Interactive LLC //============================================================================= class KFWeap_Rifle_MosinNagant extends KFWeap_MeleeBase; var float LastFireInterval; /** Returns trader filter index based on weapon type */ static simulated event EFilterTypeUI GetTraderFilter() { return FT_Rifle; } /** * 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; } super.StartFire(FireModeNum); } /** Returns animation to play based on reload type and status */ simulated function name GetReloadAnimName(bool bTacticalReload) { local name ReloadAnimName; if (AmmoCount[0] > 0) { // Mosin-Nagant uses a "stripper clip" so there are different animations depending on how many bullets are left in the current clip ReloadAnimName = (bTacticalReload) ? ReloadNonEmptyMagEliteAnim : ReloadNonEmptyMagAnim; ReloadAnimName = Name(ReloadAnimName$'_'$AmmoCount[0]); return ReloadAnimName; } else { return (bTacticalReload) ? ReloadEmptyMagEliteAnim : ReloadEmptyMagAnim; } } /** 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 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); } /** 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 } defaultproperties { // MeleeBase bMeleeWeapon=false // Inventory / Grouping InventoryGroup=IG_Primary InventorySize=7 GroupPriority=75 WeaponSelectTexture = Texture2D'wep_ui_mosin_tex.UI_WeaponSelect_MosinNagant' // Perks AssociatedPerkClasses(0) = class'KFPerk_Sharpshooter' // FOV MeshFOV=65 MeshIronSightFOV=45 PlayerIronSightFOV=65 // Depth of field DOF_FG_FocalRadius=50 DOF_FG_MaxNearBlurSize=3.5 // Content PackageKey = "Mosin" FirstPersonMeshName="wep_1p_mosin_mesh.Wep_1stP_Mosin_Rig" FirstPersonAnimSetNames(0)="wep_1p_mosin_anim.Wep_1stP_Mosin_ANIM" PickupMeshName="wep_3p_mosin_mesh.Wep_3rdP_Mosin_Pickup" AttachmentArchetypeName="WEP_Mosin_ARCH.Wep_Mosin_3P" MuzzleFlashTemplateName="WEP_Mosin_ARCH.Wep_Mosin_MuzzleFlash" // Ammo MagazineCapacity[0]=5 SpareAmmoCapacity[0]=60 InitialSpareMags[0]=5 bCanBeReloaded=true bReloadFromMagazine=true // @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 = 550 minRecoilPitch = 400 maxRecoilYaw = 150 minRecoilYaw = -150 RecoilRate = 0.08 RecoilMaxYawLimit = 500 RecoilMinYawLimit = 65035 RecoilMaxPitchLimit = 1250 RecoilMinPitchLimit = 64785 RecoilISMaxYawLimit = 50 RecoilISMinYawLimit = 65485 RecoilISMaxPitchLimit = 500 RecoilISMinPitchLimit = 65485 RecoilViewRotationScale = 0.6 IronSightMeshFOVCompensationScale = 1.5 // DEFAULT_FIREMODE FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle' FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_MosinNagant' InstantHitDamage(DEFAULT_FIREMODE)=250 InstantHitDamageTypes(DEFAULT_FIREMODE) = class'KFDT_Ballistic_MosinNagant' FireInterval(DEFAULT_FIREMODE)=0.85 // 60 RPM Spread(DEFAULT_FIREMODE)=0.007 PenetrationPower(DEFAULT_FIREMODE)=3 FireOffset = (X = 25,Y = 3.0,Z = -2.5) 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_Piercing_MosinNagant' InstantHitDamage(BASH_FIREMODE)=100 FiringStatesArray(BASH_FIREMODE)=MeleeAttackBasic WeaponFireTypes(BASH_FIREMODE)=EWFT_Custom InstantHitMomentum(BASH_FIREMODE)=10000.f // Custom animations FireSightedAnims = (Shoot_Iron, Shoot_Iron2, Shoot_Iron3) BonesToLockOnEmpty = (RW_Bolt_Back) bHasFireLastAnims = true bUseAdditiveMoveAnim = false // @TODO: Remove // 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_MosinNagant.Play_MosinNagant_Shoot_3P', FirstPersonCue = AkEvent'WW_WEP_MosinNagant.Play_MosinNagant_Shoot_1P') // @TODO: Replace Me WeaponDryFireSnd(DEFAULT_FIREMODE) = AkEvent'WW_WEP_MosinNagant.Play_MosinNagant_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 hitbox Begin Object Name=MeleeHelper_0 MaxHitRange=250 HitboxChain.Add((BoneOffset=(X=-3,Z=250))) HitboxChain.Add((BoneOffset=(X=+3,Z=230))) HitboxChain.Add((BoneOffset=(X=-3,Z=210))) 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 End Object // Weapon Upgrades WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1))) WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Damage1, Scale=1.3f), (Stat=EWUS_Weight, Add=2))) }