2020-12-13 15:01:13 +00:00
//=============================================================================
// KFWeap_RocketLauncher_SealSqueal
//=============================================================================
// The Seal Squeal rocket launcher
//=============================================================================
// Killing Floor 2
// Copyright (C) 2019 Tripwire Interactive LLC
//=============================================================================
class KFWeap _RocketLauncher _SealSqueal extends KFWeap _GrenadeLauncher _Base ;
var ( Animations ) const editconst name DetonateAnim ;
var ( Animations ) const editconst name DetonateAnimLast ;
var ( Animations ) const editconst name DetonateAnimIron ;
var ( Animations ) const editconst name DetonateAnimIronLast ;
/** List of spawned harpoons (will be detonated oldest to youngest) */
var array < KFProj _Rocket _SealSqueal > DeployedHarpoons ;
/** Same as DeployedHarpoons.Length, but replicated because harpoons are only tracked on server */
var int NumDeployedHarpoons ;
/** Camera shake when detonating the harpoons */
var CameraAnim DetonateCameraAnim ;
var float DetonateCameraAnimPlayRate ;
var float DetonateCameraAnimScale ;
replication
{
if ( bNetDirty )
NumDeployedHarpoons ;
}
/ * *
* Toggle between DEFAULT and ALTFIRE
* /
simulated function AltFireMode ( )
{
// skip super
if ( ! Instigator . IsLocallyControlled ( ) )
{
return ;
}
StartFire ( ALTFIRE _FIREMODE ) ;
}
/** Overridded to add spawned charge to list of spawned charges */
simulated function Projectile ProjectileFire ( )
{
local Projectile P ;
local KFProj _Rocket _SealSqueal Harpoon ;
P = super . ProjectileFire ( ) ;
Harpoon = KFProj _Rocket _SealSqueal ( P ) ;
if ( Harpoon != none )
{
DeployedHarpoons . AddItem ( Harpoon ) ;
NumDeployedHarpoons = DeployedHarpoons . Length ;
bForceNetUpdate = true ;
}
return P ;
}
/** Returns animation to play based on reload type and status */
simulated function name GetReloadAnimName ( bool bTacticalReload )
{
// magazine relaod
if ( AmmoCount [ 0 ] > 0 )
{
return ( bTacticalReload ) ? ReloadNonEmptyMagEliteAnim : ReloadNonEmptyMagAnim ;
}
else
{
return ( bTacticalReload ) ? ReloadEmptyMagEliteAnim : ReloadEmptyMagAnim ;
}
}
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* State WeaponDetonating
* The weapon is in this state while detonating a charge
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
simulated function GotoActiveState ( ) ;
simulated state WeaponDetonating
{
ignores AllowSprinting ;
simulated event BeginState ( name PreviousStateName )
{
PrepareAndDetonate ( ) ;
}
simulated function GotoActiveState ( )
{
GotoState ( 'Active' ) ;
}
}
// GrenadeLaunchers determine ShouldPlayFireLast based on the spare ammo
// overriding to use the base KFWeapon version since that uses the current ammo in the mag
simulated function bool ShouldPlayFireLast ( byte FireModeNum )
{
return Super ( KFWeapon ) . ShouldPlayFireLast ( FireModeNum ) ;
}
simulated function PrepareAndDetonate ( )
{
local name SelectedAnim ;
local float AnimDuration ;
local bool bInSprintState ;
// choose the detonate animation based on whether it is in ironsights and whether it is the last harpoon
if ( bUsingSights )
{
SelectedAnim = ShouldPlayFireLast ( DEFAULT _FIREMODE ) ? DetonateAnimIronLast : DetonateAnimIron ;
}
else
{
SelectedAnim = ShouldPlayFireLast ( DEFAULT _FIREMODE ) ? DetonateAnimLast : DetonateAnim ;
}
AnimDuration = MySkelMesh . GetAnimLength ( SelectedAnim ) ;
bInSprintState = IsInState ( 'WeaponSprinting' ) ;
if ( WorldInfo . NetMode != NM _DedicatedServer )
{
if ( NumDeployedHarpoons > 0 )
{
PlayCameraAnim ( DetonateCameraAnim , DetonateCameraAnimScale , DetonateCameraAnimPlayRate , 0.2 f , 0.2 f ) ;
//PlaySoundBase( DetonateAkEvent, true );
}
else
{
//PlaySoundBase( DryFireAkEvent, true );
}
if ( bInSprintState )
{
AnimDuration *= 0.25 f ;
PlayAnimation ( SelectedAnim , AnimDuration ) ;
}
else
2020-12-13 15:09:05 +00:00
{
2020-12-13 15:01:13 +00:00
PlayAnimation ( SelectedAnim ) ;
}
}
if ( Role == ROLE _Authority )
{
Detonate ( ) ;
}
// Don't want to play muzzle effects or shoot animation on detonate in 3p
//IncrementFlashCount();
2020-12-13 15:09:05 +00:00
//AnimDuration value here representes the ALTFIRE FireInterval
AnimDuration = 0.75 f ; //1.f;
2020-12-13 15:01:13 +00:00
if ( bInSprintState )
{
SetTimer ( AnimDuration * 0.8 f , false , nameof ( PlaySprintStart ) ) ;
}
else
{
SetTimer ( AnimDuration * 0.5 f , false , nameof ( GotoActiveState ) ) ;
}
}
/** Detonates all the harpoons */
simulated function Detonate ( )
{
local int i ;
// auto switch weapon when out of ammo and after detonating the last deployed charge
if ( Role == ROLE _Authority )
{
for ( i = DeployedHarpoons . Length - 1 ; i >= 0 ; i -- )
{
DeployedHarpoons [ i ] . Detonate ( ) ;
}
if ( ! HasAnyAmmo ( ) && NumDeployedHarpoons == 0 )
{
if ( CanSwitchWeapons ( ) )
{
Instigator . Controller . ClientSwitchToBestWeapon ( false ) ;
}
}
}
}
/** Removes a charge from the list using either an index or an actor and updates NumDeployedHarpoons */
function RemoveDeployedHarpoon ( optional int HarpoonIndex = INDEX _NONE , optional Actor HarpoonActor )
{
if ( HarpoonIndex == INDEX _NONE )
{
if ( HarpoonActor != none )
{
HarpoonIndex = DeployedHarpoons . Find ( HarpoonActor ) ;
}
}
if ( HarpoonIndex != INDEX _NONE )
{
DeployedHarpoons . Remove ( HarpoonIndex , 1 ) ;
NumDeployedHarpoons = DeployedHarpoons . Length ;
bForceNetUpdate = true ;
}
}
2020-12-13 15:09:05 +00:00
/** Allow reloads for primary weapon to be interupted by firing secondary weapon. */
simulated function bool CanOverrideMagReload ( byte FireModeNum )
{
if ( FireModeNum == ALTFIRE _FIREMODE )
{
return true ;
}
return Super . CanOverrideMagReload ( FireModeNum ) ;
}
2020-12-13 15:01:13 +00:00
defaultproperties
{
// Content
PackageKey = "Seal_Squeal"
FirstPersonMeshName = "wep_1p_seal_squeal_mesh.WEP_1stP_Seal_Squeal_Rig"
FirstPersonAnimSetNames ( 0 ) = "wep_1p_seal_squeal_anim.Wep_1stP_Seal_Squeal_Anim"
PickupMeshName = "wep_3p_seal_squeal_mesh.WEP_3rdP_Seal_Squeal_Pickup" //@TODO: Replace me
AttachmentArchetypeName = "wep_seal_squeal_arch.Wep_Seal_Squeal_3P"
MuzzleFlashTemplateName = "WEP_Seal_Squeal_ARCH.Wep_Seal_Squeal_MuzzleFlash" //@TODO: Replace me
// Inventory / Grouping
2020-12-13 15:09:05 +00:00
InventorySize = 7 //8
2020-12-13 15:01:13 +00:00
GroupPriority = 75
WeaponSelectTexture = Texture2D 'WEP_UI_Seal_Squeal_TEX.UI_WeaponSelect_SealSqueal'
AssociatedPerkClasses ( 0 ) = class 'KFPerk_Demolitionist'
// FOV
MeshFOV = 75
MeshIronSightFOV = 40
PlayerIronSightFOV = 65
// Depth of field
DOF _FG _FocalRadius = 50
DOF _FG _MaxNearBlurSize = 3.5
// Ammo
MagazineCapacity [ 0 ] = 5
2020-12-13 15:09:05 +00:00
SpareAmmoCapacity [ 0 ] = 30 //25
2020-12-13 15:01:13 +00:00
InitialSpareMags [ 0 ] = 1
bCanBeReloaded = true
bReloadFromMagazine = true
// Zooming/Position
PlayerViewOffset = ( X = 11.0 , Y = 8 , Z = - 2 )
2022-05-11 15:13:25 +00:00
IronSightPosition = ( X = 10 , Y = - 0.09 , Z = - 0.2 )
2020-12-13 15:01:13 +00:00
// AI warning system
bWarnAIWhenAiming = true
AimWarningDelay = ( X = 0.4 f , Y = 0.8 f )
AimWarningCooldown = 0.0 f
// Recoil
maxRecoilPitch = 500
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 _Projectile
WeaponProjectiles ( DEFAULT _FIREMODE ) = class 'KFProj_Rocket_SealSqueal'
InstantHitDamage ( DEFAULT _FIREMODE ) = 125
InstantHitDamageTypes ( DEFAULT _FIREMODE ) = class 'KFDT_Ballistic_SealSquealImpact'
2020-12-13 15:09:05 +00:00
FireInterval ( DEFAULT _FIREMODE ) = 0.5 //0.75
2020-12-13 15:01:13 +00:00
Spread ( DEFAULT _FIREMODE ) = 0
PenetrationPower ( DEFAULT _FIREMODE ) = 0
FireOffset = ( X = 25 , Y = 3.0 , Z = - 2.5 )
// ALTFIRE_FIREMODE (remote detonate)
FiringStatesArray ( ALTFIRE _FIREMODE ) = WeaponDetonating
WeaponFireTypes ( ALTFIRE _FIREMODE ) = EWFT _Custom
AmmoCost ( ALTFIRE _FIREMODE ) = 0
// BASH_FIREMODE
InstantHitDamageTypes ( BASH _FIREMODE ) = class 'KFDT_Bludgeon_SealSqueal'
InstantHitDamage ( BASH _FIREMODE ) = 25
// Custom animations
FireSightedAnims = ( Shoot _Iron , Shoot _Iron2 , Shoot _Iron3 )
BonesToLockOnEmpty = ( RW _BoltAssembly1 , RW _BoltAssembly2 , RW _BoltAssembly3 )
bHasFireLastAnims = true
// Fire Effects
WeaponFireSnd ( DEFAULT _FIREMODE ) = ( DefaultCue = AkEvent 'WW_WEP_SealSqueal.Play_WEP_SealSqueal_Shoot_3P' , FirstPersonCue = AkEvent 'WW_WEP_SealSqueal.Play_WEP_SealSqueal_Shoot_1P' ) //@TODO: Replace me
WeaponDryFireSnd ( DEFAULT _FIREMODE ) = AkEvent 'WW_WEP_SealSqueal.Play_WEP_SealSqueal_Shoot_DryFire' //@TODO: Replace me
EjectedShellForegroundDuration = 1.5 f
// Attachments
bHasIronSights = true
bHasFlashlight = false
WeaponFireWaveForm = ForceFeedbackWaveform 'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
DetonateAnim = Alt _Fire
DetonateAnimLast = Alt _Fire _Last
DetonateAnimIron = Alt _Fire _Iron
DetonateAnimIronLast = Alt _Fire _Iron _Last
WeaponUpgrades [ 1 ] = ( Stats = ( ( Stat = EWUS _Damage0 , Scale = 1.15 f ) , ( Stat = EWUS _Weight , Add = 1 ) ) )
WeaponUpgrades [ 2 ] = ( Stats = ( ( Stat = EWUS _Damage0 , Scale = 1.3 f ) , ( Stat = EWUS _Weight , Add = 2 ) ) )
DetonateCameraAnim = CameraAnim 'WEP_1P_Seal_Squeal_ANIM.Shoot_MB500'
DetonateCameraAnimPlayRate = 2.0 f
DetonateCameraAnimScale = 0.4 f
}