310 lines
8.4 KiB
Ucode
310 lines
8.4 KiB
Ucode
//=============================================================================
|
|
// KFWeap_RocketLauncher_ThermiteBore
|
|
//=============================================================================
|
|
// Impale, burn, repeat
|
|
//=============================================================================
|
|
// Killing Floor 2
|
|
// Copyright (C) 2021 Tripwire Interactive LLC
|
|
//=============================================================================
|
|
|
|
class KFWeap_RocketLauncher_ThermiteBore extends KFWeap_GrenadeLauncher_Base;
|
|
|
|
/** List of spawned harpoons (will be detonated oldest to youngest) */
|
|
var array<KFProj_Rocket_ThermiteBore> DeployedHarpoons;
|
|
|
|
/** Same as DeployedHarpoons.Length, but replicated because harpoons are only tracked on server */
|
|
var int NumDeployedHarpoons;
|
|
|
|
var(Animations) const editconst name DetonateAnim;
|
|
var(Animations) const editconst name DetonateAnimLast;
|
|
var(Animations) const editconst name DetonateAnimIron;
|
|
var(Animations) const editconst name DetonateAnimIronLast;
|
|
|
|
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_ThermiteBore Harpoon;
|
|
|
|
P = super.ProjectileFire();
|
|
|
|
Harpoon = KFProj_Rocket_ThermiteBore(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 (bInSprintState)
|
|
{
|
|
AnimDuration *= 0.25f;
|
|
PlayAnimation(SelectedAnim, AnimDuration);
|
|
}
|
|
else
|
|
{
|
|
PlayAnimation(SelectedAnim);
|
|
}
|
|
}
|
|
|
|
if (Role == ROLE_Authority)
|
|
{
|
|
Detonate();
|
|
}
|
|
|
|
//AnimDuration value here representes the ALTFIRE FireInterval
|
|
AnimDuration = 0.75f; //1.f;
|
|
if (bInSprintState)
|
|
{
|
|
SetTimer(AnimDuration * 0.8f, false, nameof(PlaySprintStart));
|
|
}
|
|
else
|
|
{
|
|
SetTimer(AnimDuration * 0.5f, 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;
|
|
}
|
|
}
|
|
|
|
/** 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);
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
// Content
|
|
PackageKey="Thermite"
|
|
FirstPersonMeshName="wep_1p_thermite_mesh.WEP_1stP_Thermite_Rig"
|
|
FirstPersonAnimSetNames(0)="wep_1p_thermite_anim.WEP_1stP_Thermite_Anim"
|
|
PickupMeshName="WEP_3P_Thermite_MESH.WEP_Thermite_Pickup" //@TODO: Replace me
|
|
AttachmentArchetypeName="wep_thermite_arch.Wep_Thermite_3P"
|
|
MuzzleFlashTemplateName="wep_thermite_arch.Wep_Thermite_MuzzleFlash" //@TODO: Replace me
|
|
|
|
// Inventory / Grouping
|
|
InventorySize=7
|
|
GroupPriority=100
|
|
WeaponSelectTexture=Texture2D'WEP_UI_Thermite_TEX.UI_WeaponSelect_Thermite'
|
|
AssociatedPerkClasses(0)=class'KFPerk_Firebug'
|
|
|
|
// FOV
|
|
MeshFOV=75
|
|
MeshIronSightFOV=40
|
|
PlayerIronSightFOV=65
|
|
|
|
// Depth of field
|
|
DOF_FG_FocalRadius=50
|
|
DOF_FG_MaxNearBlurSize=3.5
|
|
|
|
// Ammo
|
|
MagazineCapacity[0]=6
|
|
SpareAmmoCapacity[0]=36 //42
|
|
InitialSpareMags[0]=1
|
|
bCanBeReloaded=true
|
|
bReloadFromMagazine=true
|
|
|
|
// Zooming/Position
|
|
PlayerViewOffset=(X=11.0,Y=8,Z=-2)
|
|
IronSightPosition=(X=10,Y=-0.15,Z=0.7)
|
|
|
|
// AI warning system
|
|
bWarnAIWhenAiming=true
|
|
AimWarningDelay=(X=0.4f, Y=0.8f)
|
|
AimWarningCooldown=0.0f
|
|
|
|
// 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_ThermiteBore'
|
|
InstantHitDamage(DEFAULT_FIREMODE)=150
|
|
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_ThermiteBoreImpact'
|
|
FireInterval(DEFAULT_FIREMODE)=0.8 //100 RPM
|
|
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_ThermiteBore'
|
|
InstantHitDamage(BASH_FIREMODE)=26
|
|
|
|
// Custom animations
|
|
FireSightedAnims=(Shoot_Iron)
|
|
BonesToLockOnEmpty=(RW_Exhaust, RW_BoltAssembly1, RW_BoltAssembly2, RW_BoltAssembly3)
|
|
bHasFireLastAnims=true
|
|
|
|
// Fire Effects
|
|
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Thermite_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Thermite_Shoot_1P')
|
|
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Dry_Fire'
|
|
EjectedShellForegroundDuration=1.5f
|
|
|
|
// Attachments
|
|
bHasIronSights=true
|
|
bHasFlashlight=false
|
|
|
|
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
|
|
|
|
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
|
|
|
|
DetonateAnim=Alt_Fire
|
|
DetonateAnimLast=Alt_Fire_Last
|
|
DetonateAnimIron=Alt_Fire_Iron
|
|
DetonateAnimIronLast=Alt_Fire_Iron_Last
|
|
}
|