202 lines
5.5 KiB
Ucode
202 lines
5.5 KiB
Ucode
|
//=============================================================================
|
||
|
// KFAIPluginRage_Fleshpound
|
||
|
//=============================================================================
|
||
|
// AICommand executing while Fleshpound is enraged
|
||
|
//=============================================================================
|
||
|
// Killing Floor 2
|
||
|
// Copyright (C) 2015 Tripwire Interactive LLC
|
||
|
//=============================================================================
|
||
|
class KFAIPluginRage_Fleshpound extends AITickablePlugin
|
||
|
within KFAIController_ZedFleshpound
|
||
|
native(AI)
|
||
|
config(AI);
|
||
|
|
||
|
`include(KFGame\KFGameAnalytics.uci);
|
||
|
|
||
|
var vector StartLocation;
|
||
|
|
||
|
/** Track damage taken over the past AccumulatedDOTDuration seconds */
|
||
|
var int AccumulatedDOT;
|
||
|
/** The time when we found an enemy */
|
||
|
var float RageFrustrationStartTime;
|
||
|
/** The max time we can stay in rage mode*/
|
||
|
var float MaxEnemyNotVisibleRageTime;
|
||
|
/** The base time to wait before becoming frustrated and raging anyways */
|
||
|
var float RageFrustrationBaseTime;
|
||
|
/** The (randomized) final time to wait before becoming frustrated */
|
||
|
var float RageFrustrationTime;
|
||
|
/** The amount of damage we need to accumulate before entering rage */
|
||
|
var float RageDamageThreshold;
|
||
|
|
||
|
var bool bIsEnraged;
|
||
|
|
||
|
/** Ticked to determine when we should start and end rage mode */
|
||
|
event TickRage()
|
||
|
{
|
||
|
if( bIsEnraged && !bEnemyIsVisible && `TimeSince(LastEnemySightedTime) > MaxEnemyNotVisibleRageTime )
|
||
|
{
|
||
|
EndRage();
|
||
|
}
|
||
|
else if( CanDoRage() )
|
||
|
{
|
||
|
AIActionStatus = "Enraged!";
|
||
|
GotoState( 'Enraged' );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function DoSpawnRage()
|
||
|
{
|
||
|
AIActionStatus = "Enraged!";
|
||
|
GotoState( 'Enraged' );
|
||
|
}
|
||
|
|
||
|
/** Checks if it's possible to enter rage */
|
||
|
function bool CanDoRage()
|
||
|
{
|
||
|
if( bIsEnraged || !MyKFPawn.IsCombatCapable() )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// If it's been longer than RageFrustrationTime since we've had an enemy, rage anyways
|
||
|
if( Enemy != none && RageFrustrationStartTime > 0 && `TimeSince(RageFrustrationStartTime) > RageFrustrationTime )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// If we've taken more than the RageDamageThreshold in damage, begin rage
|
||
|
if( AccumulatedDOT >= RageDamageThreshold )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/** Begins the timer until the FleshPound can rage */
|
||
|
function StartRageTimer(optional bool bJustSawEnemy)
|
||
|
{
|
||
|
// Already raging!
|
||
|
if( bIsEnraged )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RageFrustrationStartTime = WorldInfo.TimeSeconds;
|
||
|
SetRageTime();
|
||
|
|
||
|
// If the FP hasn't seen its enemy for a long time, rage (almost) immediately
|
||
|
if( bJustSawEnemy && `TimeSince(LastEnemySightedTime) > MaxEnemyNotVisibleRageTime )
|
||
|
{
|
||
|
RageFrustrationStartTime += RageFrustrationTime - 0.5f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Sets our rage timer (RageFrustrationBaseTime + RandRange(1,5)) */
|
||
|
function SetRageTime()
|
||
|
{
|
||
|
RageFrustrationTime = RageFrustrationBaseTime + RandRange(1.f,5.f);
|
||
|
}
|
||
|
|
||
|
/** Leave Rage Mode */
|
||
|
function EndRage()
|
||
|
{
|
||
|
// Any time we end call end rage, we are no longer frustrated
|
||
|
if( bIsEnraged )
|
||
|
{
|
||
|
GotoState( InitialState );
|
||
|
StartRageTimer();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*********************************************************************************************
|
||
|
* Enraged state
|
||
|
********************************************************************************************* */
|
||
|
|
||
|
state Enraged
|
||
|
{
|
||
|
function BeginState( name PreviousStateName )
|
||
|
{
|
||
|
bIsEnraged = true;
|
||
|
MyKFPawn.SetEnraged( true );
|
||
|
|
||
|
`AILog( GetStateName()$" "$GetFuncName()$"() Prev: "$PreviousStateName, 'Charging' );
|
||
|
SetFocalPoint(vect(0,0,0));
|
||
|
Focus = none;
|
||
|
//bAdjustFromWalls = false; // Experimenting **NOTE this prevented FP from jumping when raging - Matt
|
||
|
AIZeroMovementVariables();
|
||
|
|
||
|
/** Rotate to enemy - state code will resume execution after RotateToFocus is popped */
|
||
|
PushState( 'RotateToFocus' );
|
||
|
/** Finished rotating - see if I need to taunt first */
|
||
|
|
||
|
if( !MyKFPawn.IsDoingSpecialMove() )
|
||
|
{
|
||
|
// Start the rage-taunt command - no more state code will execute below until the taunt is finished
|
||
|
DoRageTauntAt( KFPawn(Enemy) );
|
||
|
// Finished taunting
|
||
|
LastTauntTime = WorldInfo.TimeSeconds;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function EndState( name NextStateName )
|
||
|
{
|
||
|
bIsEnraged = false;
|
||
|
MyKFPawn.SetEnraged( false );
|
||
|
|
||
|
AccumulatedDOT = 0;
|
||
|
|
||
|
if( Enemy == none || VSize(Enemy.Location - Pawn.Location) > 1024.f || !CanSee(Enemy) )
|
||
|
{
|
||
|
SetEnemy(GetClosestEnemy());
|
||
|
}
|
||
|
AIActionStatus = "No longer engraged";
|
||
|
EnableMeleeRangeEventProbing();
|
||
|
|
||
|
MyKFPawn.bForceMaxAccel = false;
|
||
|
bPreciseDestination = false;
|
||
|
//bAdjustFromWalls = true;
|
||
|
}
|
||
|
|
||
|
function ContinuedState()
|
||
|
{
|
||
|
AIActionStatus = "Enraged, and preparing to charge";
|
||
|
}
|
||
|
|
||
|
Finished:
|
||
|
UnlockPawnRotation();
|
||
|
AIZeroMovementVariables();
|
||
|
SetDestinationPosition( Pawn.Location );
|
||
|
Pawn.ResetDesiredRotation();
|
||
|
RotationRateMultiplier = 1.f;
|
||
|
PushState( 'RotateToFocus' );
|
||
|
}
|
||
|
|
||
|
/*********************************************************************************************
|
||
|
* RotateToFocus state
|
||
|
********************************************************************************************* */
|
||
|
|
||
|
state RotateToFocus `DEBUGSTATE
|
||
|
{
|
||
|
Begin:
|
||
|
AIActionStatus = "Rotating to focus";
|
||
|
SetFocalPoint( vect(0,0,0) );
|
||
|
Focus = Enemy;
|
||
|
FinishRotation();
|
||
|
PopState();
|
||
|
}
|
||
|
|
||
|
/*********************************************************************************************
|
||
|
* Debugging
|
||
|
********************************************************************************************* */
|
||
|
|
||
|
|
||
|
DefaultProperties
|
||
|
{
|
||
|
// ---------------------------------------------
|
||
|
// Settings
|
||
|
RageFrustrationBaseTime=9
|
||
|
RageDamageThreshold=276
|
||
|
MaxEnemyNotVisibleRageTime=30
|
||
|
}
|