607 lines
14 KiB
Ucode
607 lines
14 KiB
Ucode
//=============================================================================
|
|
// KFWeap_MinigunBase
|
|
//=============================================================================
|
|
// Minigun base
|
|
//=============================================================================
|
|
// Killing Floor 2
|
|
// Copyright (C) 2015 Tripwire Interactive LLC
|
|
//=============================================================================
|
|
|
|
class KFWeap_MinigunBase extends KFWeapon
|
|
abstract
|
|
native
|
|
nativereplication;
|
|
|
|
/* The minigun is winded up and ready to fire */
|
|
var bool bWindUpReady;
|
|
|
|
/* The zoom is active, keeps track of the current status of the zoom */
|
|
var bool bZoomActive;
|
|
|
|
/* Time used to wind up the weapon (also acts as the cooldown) */
|
|
var float WindUpActivationTime;
|
|
|
|
/* Control variable to check the current state of the wind up */
|
|
var transient float WindUpControlTime;
|
|
|
|
/* Rotation speed of the barrel when fully warmed up*/
|
|
var float WindUpRotationSpeed;
|
|
|
|
/* Rotation info of the barrel, controls the rotation for the selected bone via c++ */
|
|
var CylinderRotationInfo CylinderRotInfo;
|
|
|
|
/* The weapon is winding up */
|
|
var repnotify bool bWindUpModeActive;
|
|
|
|
/* The system stores the status of the winding up in case some animation interrupts the process */
|
|
var repnotify bool bStoredWindUpMode;
|
|
|
|
/* The weapon is firing and the barrels should be rotating */
|
|
var repnotify bool bFiringModeActive;
|
|
|
|
/* Replicated status of the rotation of the barrels */
|
|
var bool bReplicatedFiringModeActive;
|
|
|
|
/* Replicated rotation speed of the barrel when fully warmed up */
|
|
var repnotify float ReplicatedWindUpControlTime;
|
|
|
|
/* Rotation speed used in the player controller when the weapon is winding up but no firing */
|
|
var float WindUpViewRotationSpeed;
|
|
|
|
/* Pawn movement speed used when the weapon is winding up but no firing */
|
|
var float WindUpPawnMovementSpeed;
|
|
|
|
/* Rotation speed used in the player controller when the weapon is firing */
|
|
var float FiringViewRotationSpeed;
|
|
|
|
/* Pawn movement speed used when the weapon is firing */
|
|
var float FiringPawnMovementSpeed;
|
|
|
|
simulated event ReplicatedEvent(name VarName)
|
|
{
|
|
switch (VarName)
|
|
{
|
|
case nameof(bWindUpModeActive):
|
|
bReplicatedFiringModeActive = bWindUpModeActive || bFiringModeActive;
|
|
NotifyRotationState();
|
|
break;
|
|
case nameof(bStoredWindUpMode):
|
|
NotifyRotationState();
|
|
break;
|
|
case nameof(bFiringModeActive):
|
|
bReplicatedFiringModeActive = bWindUpModeActive || bFiringModeActive;
|
|
NotifyRotationState();
|
|
break;
|
|
case nameof(ReplicatedWindUpControlTime):
|
|
if( Instigator == none || !Instigator.IsLocallyControlled() )
|
|
{
|
|
WindUpControlTime = ReplicatedWindUpControlTime;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
replication
|
|
{
|
|
if (bNetDirty && Role == ROLE_Authority)
|
|
bWindUpModeActive, bStoredWindUpMode, bFiringModeActive, ReplicatedWindUpControlTime;
|
|
}
|
|
|
|
cpptext
|
|
{
|
|
// replication is coming boys
|
|
INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel );
|
|
|
|
// cylinder is incrementally rotated
|
|
virtual void TickSpecial( FLOAT DeltaSeconds );
|
|
};
|
|
|
|
/** Cache Anim Nodes from the tree
|
|
* @note: skipped on server because AttachComponent/AttachWeaponTo is not called
|
|
*/
|
|
simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
|
|
{
|
|
super.PostInitAnimTree( SkelComp );
|
|
PostInitAnimTreeMinigun( SkelComp );
|
|
}
|
|
|
|
simulated event PostInitAnimTreeMinigun( SkeletalMeshComponent SkelComp )
|
|
{
|
|
CylinderRotInfo.Control = SkelControlSingleBone( SkelComp.FindSkelControl('CylinderControl') );
|
|
if( CylinderRotInfo.Control != none )
|
|
{
|
|
CylinderRotInfo.Control.SetSkelControlActive( true );
|
|
}
|
|
}
|
|
|
|
/* updates the cylinder rotation in Tick Special */
|
|
native simulated function UpdateCylinderRotation( out CylinderRotationInfo RotInfo, float Degrees );
|
|
|
|
/* function called from C++ to access perk time modifier when winding up */
|
|
simulated event float GetPerkFireRateModifier()
|
|
{
|
|
local KFPerk_Commando Perk;
|
|
|
|
Perk = KFPerk_Commando(GetPerk());
|
|
if( WorldInfo.TimeDilation < 1 && Perk != none )
|
|
{
|
|
return Perk.GetZedTimeModifierForWindUp();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
simulated function Activate()
|
|
{
|
|
Local KFPlayerController KFPC;
|
|
Local KFPlayerInput KFPI;
|
|
|
|
super.Activate();
|
|
|
|
if (!WeaponContentLoaded || Instigator == none)
|
|
{
|
|
return;
|
|
}
|
|
|
|
KFPC = KFPlayerController(Instigator.Controller);
|
|
if(KFPC != none && KFPC.PlayerInput != none)
|
|
{
|
|
KFPI = KFPlayerInput(KFPC.PlayerInput);
|
|
if(KFPI != none && KFPI.bIronsightsActive)
|
|
{
|
|
SetIronSights(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated event vector GetMuzzleLoc()
|
|
{
|
|
local Rotator ViewRotation;
|
|
|
|
if( Instigator != none )
|
|
{
|
|
ViewRotation = Instigator.GetViewRotation();
|
|
|
|
// Add in the free-aim rotation
|
|
if ( KFPlayerController(Instigator.Controller) != None )
|
|
{
|
|
ViewRotation += KFPlayerController(Instigator.Controller).WeaponBufferRotation;
|
|
}
|
|
|
|
return Instigator.GetPawnViewLocation() + (FireOffset >> ViewRotation);
|
|
}
|
|
|
|
return Location;
|
|
}
|
|
|
|
simulated function BeginFire(Byte FireModeNum)
|
|
{
|
|
if(FireModeNum == DEFAULT_FIREMODE)
|
|
{
|
|
bFiringModeActive = true;
|
|
bForceNetUpdate = true;
|
|
}
|
|
Super.BeginFire(FireModeNum);
|
|
}
|
|
|
|
simulated function EndFire(byte FireModeNum)
|
|
{
|
|
if(FireModeNum == DEFAULT_FIREMODE)
|
|
{
|
|
bFiringModeActive = false;
|
|
bForceNetUpdate = true;
|
|
}
|
|
Super.EndFire(FireModeNum);
|
|
}
|
|
|
|
/** If TRUE, Instigator/Owner moves at walking speed when this weapon is equipped */
|
|
simulated function bool ShouldOwnerWalk()
|
|
{
|
|
return IsFiring() && IsInState('WeaponFiring');
|
|
}
|
|
|
|
/** Disable the rotation of the barrels when sprinting */
|
|
simulated function SetWeaponSprint(bool bNewSprintStatus)
|
|
{
|
|
if(bNewSprintStatus && bWindUpModeActive)
|
|
{
|
|
return;
|
|
}
|
|
Super.SetWeaponSprint(bNewSprintStatus);
|
|
}
|
|
|
|
simulated function bool AllowSprinting()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/** Force iron sights as the default configuration is set to false */
|
|
simulated function bool AllowIronSights()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
/** Used in KFPlayerInput to change the behaviour of the iron sight */
|
|
simulated function bool IsUsingSights()
|
|
{
|
|
return bWindUpModeActive;
|
|
}
|
|
|
|
/**
|
|
* Network: LocalPlayer
|
|
* Changes the functionality of the Iron sight
|
|
*/
|
|
simulated function SetIronSights(bool bNewIronSights)
|
|
{
|
|
if ( !Instigator.IsLocallyControlled() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
ServerSetIronSights(bNewIronSights);
|
|
|
|
bStoredWindUpMode = bNewIronSights;
|
|
|
|
if(GetStateName() == 'Reloading')
|
|
{
|
|
WindUp(false);
|
|
UpdateZoom();
|
|
return;
|
|
}
|
|
|
|
PlayIdleAnim();
|
|
|
|
WindUp(bNewIronSights);
|
|
UpdateZoom();
|
|
bForceNetUpdate = true;
|
|
}
|
|
|
|
reliable server function ServerSetIronSights(bool bNewIronSights)
|
|
{
|
|
bStoredWindUpMode = bNewIronSights;
|
|
|
|
if(GetStateName() == 'Reloading')
|
|
{
|
|
WindUp(false);
|
|
UpdateZoom();
|
|
return;
|
|
}
|
|
|
|
WindUp(bNewIronSights);
|
|
UpdateZoom();
|
|
}
|
|
|
|
simulated function WindUp(bool bWindUpActive)
|
|
{
|
|
bWindUpModeActive = bWindUpActive;
|
|
NotifyRotationState();
|
|
}
|
|
|
|
/** Updates the rotation in the 3rd person character */
|
|
simulated function NotifyRotationState()
|
|
{
|
|
local KFPawn KFPawn;
|
|
local KFWeapAttach_Minigun KFWeapAttach;
|
|
|
|
KFPawn = KFPawn(Instigator);
|
|
KFWeapAttach = KFWeapAttach_Minigun(KFPawn.WeaponAttachment);
|
|
|
|
if(KFWeapAttach != none)
|
|
{
|
|
KFWeapAttach.UpdateWindUp(bReplicatedFiringModeActive || bWindUpModeActive || IsFiring());
|
|
}
|
|
}
|
|
|
|
/** Updates the zoom status (active when firing or winding up) */
|
|
simulated function UpdateZoom()
|
|
{
|
|
local bool bNewZoomStatus;
|
|
|
|
if ( !Instigator.IsLocallyControlled() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
bNewZoomStatus = bWindUpModeActive || IsFiring();
|
|
|
|
if(bZoomActive == bNewZoomStatus)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bZoomActive = bNewZoomStatus;
|
|
PerformZoom(bZoomActive);
|
|
}
|
|
|
|
simulated event OnZoomInFinished(){ }
|
|
simulated event OnZoomOutFinished(){ }
|
|
|
|
simulated event Tick( float DeltaTime )
|
|
{
|
|
local KFPawn_Human OwnerHuman;
|
|
local KFPlayerController OwnerController;
|
|
local float NewMovementSpeedMod;
|
|
local float NewRotationSpeedLimit;
|
|
local bool bLimitFiring, bLimitWindingUp;
|
|
|
|
Super.Tick(DeltaTime);
|
|
|
|
// Replicate WindUp time to simulated clients
|
|
if ( WorldInfo.NetMode == NM_DedicatedServer || WorldInfo.NetMode == NM_ListenServer )
|
|
{
|
|
ReplicatedWindUpControlTime = WindUpControlTime;
|
|
}
|
|
|
|
OwnerHuman = KFPawn_Human(Instigator);
|
|
if ( OwnerHuman != None )
|
|
{
|
|
OwnerController = KFPlayerController(OwnerHuman.Controller);
|
|
if( OwnerController != none )
|
|
{
|
|
bLimitFiring = IsFiring() && IsInState('WeaponFiring');
|
|
bLimitWindingUp = IsFiring() || bWindUpModeActive;
|
|
|
|
if( Role == Role_Authority )
|
|
{
|
|
NewMovementSpeedMod = MovementSpeedMod;
|
|
|
|
if ( bLimitFiring )
|
|
{
|
|
NewMovementSpeedMod = FiringPawnMovementSpeed;
|
|
}
|
|
else if( bLimitWindingUp )
|
|
{
|
|
NewMovementSpeedMod = WindUpPawnMovementSpeed;
|
|
}
|
|
else
|
|
{
|
|
NewMovementSpeedMod = 1;
|
|
}
|
|
|
|
if( NewMovementSpeedMod != MovementSpeedMod )
|
|
{
|
|
MovementSpeedMod = NewMovementSpeedMod;
|
|
OwnerHuman.UpdateGroundSpeed();
|
|
}
|
|
}
|
|
|
|
NewRotationSpeedLimit = OwnerController.RotationSpeedLimit;
|
|
|
|
if ( bLimitFiring )
|
|
{
|
|
NewRotationSpeedLimit = FiringViewRotationSpeed;
|
|
}
|
|
else if( bLimitWindingUp )
|
|
{
|
|
NewRotationSpeedLimit = WindUpViewRotationSpeed;
|
|
}
|
|
else
|
|
{
|
|
NewRotationSpeedLimit = 2000.0f;
|
|
}
|
|
|
|
if( NewRotationSpeedLimit != OwnerController.RotationSpeedLimit )
|
|
{
|
|
OwnerController.RotationSpeedLimit = NewRotationSpeedLimit;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function NotifyBeginState()
|
|
{
|
|
Super.NotifyBeginState();
|
|
NotifyRotationState();
|
|
}
|
|
|
|
simulated function NotifyEndState()
|
|
{
|
|
Super.NotifyEndState();
|
|
NotifyRotationState();
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
* State WeaponWindingUp
|
|
* The weapon is in this state to wind up and prepare for firing
|
|
*********************************************************************************************/
|
|
|
|
simulated state WeaponWindingUp
|
|
{
|
|
ignores AllowSprinting;
|
|
|
|
simulated event bool IsFiring()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
simulated function BeginState(Name PrevStateName)
|
|
{
|
|
local KFPerk InstigatorPerk;
|
|
local int IdleIndex;
|
|
|
|
NotifyBeginState();
|
|
|
|
InstigatorPerk = GetPerk();
|
|
if( InstigatorPerk != none )
|
|
{
|
|
SetZedTimeResist( InstigatorPerk.GetZedTimeModifierForWindUp() );
|
|
}
|
|
|
|
UpdateZoom();
|
|
|
|
if ( Instigator.IsLocallyControlled() )
|
|
{
|
|
if ( IdleAnims.Length > 0 )
|
|
{
|
|
IdleIndex = Rand(IdleAnims.Length);
|
|
PlayAnimation(IdleAnims[IdleIndex], 0.0, true, 0.2);
|
|
}
|
|
|
|
StartIdleFidgetTimer();
|
|
ToggleAdditiveBobAnim(!bUsingSights);
|
|
}
|
|
|
|
if( bWindUpReady )
|
|
{
|
|
GoToState('WeaponFiring');
|
|
}
|
|
}
|
|
|
|
simulated function EndState(Name NextStateName)
|
|
{
|
|
NotifyEndState();
|
|
}
|
|
|
|
simulated event Tick(float DeltaTime)
|
|
{
|
|
Global.Tick(DeltaTime);
|
|
|
|
// Stop the looping fire sound if we're in zed time and want to play single fire sounds
|
|
if( bPlayingLoopingFireSnd && ShouldForceSingleFireSound() )
|
|
{
|
|
StopLoopingFireSound(CurrentFireMode);
|
|
}
|
|
|
|
if(bWindUpReady)
|
|
{
|
|
GoToState('WeaponFiring');
|
|
}
|
|
else if(!bFiringModeActive)
|
|
{
|
|
HandleFinishedFiring();
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
* State WeaponFiring
|
|
* The weapon is in this state while holding fire button
|
|
*********************************************************************************************/
|
|
|
|
simulated state WeaponFiring
|
|
{
|
|
simulated event BeginState(Name PreviousStateName)
|
|
{
|
|
local KFPerk InstigatorPerk;
|
|
|
|
Super.BeginState(PreviousStateName);
|
|
|
|
InstigatorPerk = GetPerk();
|
|
if( InstigatorPerk != none )
|
|
{
|
|
SetZedTimeResist( InstigatorPerk.GetZedTimeModifierForWindUp() );
|
|
}
|
|
}
|
|
|
|
simulated function EndState(Name NextStateName)
|
|
{
|
|
Super.EndState(NextStateName);
|
|
UpdateZoom();
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
* State MeleeAttackBasic
|
|
* We are doing a melee attack
|
|
*********************************************************************************************/
|
|
|
|
simulated state MeleeAttackBasic
|
|
{
|
|
ignores AllowSprinting, AllowIronSights;
|
|
|
|
simulated function BeginState(Name PreviousStateName)
|
|
{
|
|
local KFPerk InstigatorPerk;
|
|
|
|
InstigatorPerk = GetPerk();
|
|
if( InstigatorPerk != none )
|
|
{
|
|
SetZedTimeResist( InstigatorPerk.GetZedTimeModifier(self) );
|
|
}
|
|
|
|
TimeWeaponFiring(CurrentFireMode);
|
|
NotifyBeginState();
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
* State Active
|
|
* The weapon idle state (not firing, not reloading, ...)
|
|
*********************************************************************************************/
|
|
|
|
simulated state Active
|
|
{
|
|
/** Initialize the weapon as being active and ready to go. */
|
|
simulated event BeginState(Name PreviousStateName)
|
|
{
|
|
local KFPerk InstigatorPerk;
|
|
|
|
WindUp(bStoredWindUpMode);
|
|
UpdateZoom();
|
|
|
|
Super.BeginState(PreviousStateName);
|
|
|
|
InstigatorPerk = GetPerk();
|
|
if( InstigatorPerk != none )
|
|
{
|
|
SetZedTimeResist( InstigatorPerk.GetZedTimeModifierForWindUp() );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************
|
|
* State GrenadeFiring
|
|
* Handles firing grenades.
|
|
*********************************************************************************************/
|
|
|
|
simulated state GrenadeFiring
|
|
{
|
|
simulated event bool IsFiring()
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/** Called on local player when reload starts and replicated to server */
|
|
simulated function InitializeReload()
|
|
{
|
|
WindUp(false);
|
|
bZoomActive = false;
|
|
Super.InitializeReload();
|
|
}
|
|
|
|
reliable server function ServerSendToReload(byte ClientReloadAmount)
|
|
{
|
|
Super.ServerSendToReload(ClientReloadAmount);
|
|
WindUp(false);
|
|
bZoomActive = false;
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
// Wind Up variables
|
|
WindUpActivationTime=1.5
|
|
WindUpRotationSpeed=200
|
|
|
|
bHasIronSights=false
|
|
bKeepIronSightsOnJump=true
|
|
bSkipZoomInRotation=true
|
|
|
|
FireSightedAnims[0]=Shoot
|
|
FireLastSightedAnim=Shoot_Last
|
|
FireLoopSightedAnim=ShootLoop
|
|
FireLoopEndLastSightedAnim=ShootLoop_End_Last
|
|
IdleSightedAnims(0)=Idle
|
|
FireLoopStartSightedAnim=ShootLoop_Start
|
|
FireLoopEndSightedAnim=ShootLoop_End
|
|
|
|
bAlwaysRelevant=True
|
|
bOnlyRelevantToOwner=False
|
|
|
|
WindUpViewRotationSpeed=2000 // base rotation
|
|
WindUpPawnMovementSpeed=1 // base speed
|
|
|
|
FiringViewRotationSpeed=2000
|
|
FiringPawnMovementSpeed=0.75f
|
|
}
|