upload
This commit is contained in:
244
BaseAI/Classes/AIDebugTool.uc
Normal file
244
BaseAI/Classes/AIDebugTool.uc
Normal file
@ -0,0 +1,244 @@
|
||||
//=============================================================================
|
||||
// AIDebugTool
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class AIDebugTool extends Object
|
||||
dependson(BaseAIController)
|
||||
config(AI)
|
||||
native(Debug);
|
||||
|
||||
var transient float GameFrameTime;
|
||||
|
||||
var int BTPersonalLogSize;
|
||||
var array<string> BTPersonalLog;
|
||||
|
||||
var BaseAIController DebugTarget;
|
||||
var int EntryToDisplay;
|
||||
|
||||
var transient init array<name> Filters;
|
||||
var array<name> ColorCategories;
|
||||
|
||||
var array<Actor> UnreachableActors;
|
||||
|
||||
enum ELogDrawingMode
|
||||
{
|
||||
AIDH_DrawAll,
|
||||
AIDH_EntryDetails,
|
||||
AIDH_BlackBoard,
|
||||
AIDH_Preconditions,
|
||||
AIDH_SquadEnemy,
|
||||
AIDH_Animation,
|
||||
AIDH_Weapon
|
||||
};
|
||||
var int DrawingFlags;
|
||||
|
||||
struct String_Mirror
|
||||
{
|
||||
var string Value;
|
||||
};
|
||||
|
||||
struct native AIDebugLogLine
|
||||
{
|
||||
var native String_Mirror Line{FString};
|
||||
var native Name LineCategory;
|
||||
//@todo Add additional data, like position, hit info, etc
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FAIDebugLogLine(const TCHAR* PtrLine, FName inCategory = NAME_None)
|
||||
{
|
||||
Line = PtrLine;
|
||||
LineCategory = inCategory;
|
||||
}
|
||||
|
||||
FAIDebugLogLine(const FString& LineIn, FName inCategory = NAME_None)
|
||||
{
|
||||
Line = LineIn;
|
||||
LineCategory = inCategory;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct native AIDebugLogEntry
|
||||
{
|
||||
var float TimeStamp;
|
||||
var vector WorldPosition;
|
||||
var vector EnemyPosition;
|
||||
var vector Facing;
|
||||
var native String_Mirror BTStatus{FString};
|
||||
var native array<String_Mirror> BlackBoardEntries{FString};
|
||||
var native array<String_Mirror> BehaviorTrace{FString};
|
||||
var native array<String_Mirror> Preconditions{FString};
|
||||
var native array<String_Mirror> CommandStack{FString};
|
||||
var native array<String_Mirror> SquadEnemyList{FString};
|
||||
var native array<String_Mirror> LocalEnemyList{FString};
|
||||
var native array<String_Mirror> InnerState{FString};
|
||||
var native array<String_Mirror> AnimationProxy{FString};
|
||||
var native array<vector> Route;
|
||||
var native init array<SpaceLineInfo> DebugLines;
|
||||
var native array<String_Mirror> WeaponInfo{FString};
|
||||
var array<AIDebugLogLine> Lines;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FAIDebugLogEntry()
|
||||
{
|
||||
appMemzero(this, sizeof(FAIDebugLogEntry));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct native AIDebugActorsLog
|
||||
{
|
||||
var int Tail;
|
||||
var array<AIDebugLogEntry> Entries;
|
||||
var int NotEmptyElements;
|
||||
|
||||
/** this variable is used for pooling. DO NOT CHANGE! */
|
||||
var private const int nIndex;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
|
||||
enum { LogSize = 500 };
|
||||
|
||||
FAIDebugActorsLog(UBOOL bInit = TRUE)
|
||||
{
|
||||
appMemzero(this, sizeof(FAIDebugLogEntry));
|
||||
if(bInit)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE void Init()
|
||||
{
|
||||
Entries.Reserve(LogSize);
|
||||
Entries.AddZeroed(LogSize);
|
||||
}
|
||||
|
||||
FORCEINLINE void Reset()
|
||||
{
|
||||
Entries.Empty(LogSize);
|
||||
Entries.AddZeroed(LogSize);
|
||||
NotEmptyElements = 0;
|
||||
}
|
||||
|
||||
/** Pooling interface Get*/
|
||||
FORCEINLINE INT GetIndex() const
|
||||
{
|
||||
return nIndex;
|
||||
}
|
||||
/** Pooling interface Set*/
|
||||
FORCEINLINE void SetIndex(INT index)
|
||||
{
|
||||
nIndex = index;
|
||||
}
|
||||
|
||||
void SaveToFile(FArchive* File);
|
||||
void LoadFile(FArchive* File, UBOOL bLoadOldLogs = FALSE);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
struct native ETQDebugEntry
|
||||
{
|
||||
var float TimeStamp;
|
||||
var native init array<String_Mirror> ExecutedQueries{FString};
|
||||
};
|
||||
var transient ETQDebugEntry CurrentETQLog;
|
||||
var init array<ETQDebugEntry> ETQLogHistory;
|
||||
|
||||
var bool bLoadOldLogs;
|
||||
|
||||
var transient Actor LoggingContext;
|
||||
|
||||
var native const Map_Mirror Logs{TMap<const AActor*, FAIDebugActorsLog*>};
|
||||
|
||||
/**
|
||||
* Draws stored log for given Actor. If Actor == None than contents of loaded
|
||||
* ailogex file are displayed
|
||||
*/
|
||||
final native function DrawLog(Canvas Canvas, Actor Actor);
|
||||
final native function bool LoadLogFile(string FileName, optional bool bAppendMapName = true);
|
||||
final native function FlushLogs(optional string DirName, optional BaseAIController AI);
|
||||
|
||||
final native function SetDebugTarget(BaseAIController NewDebugTarget);
|
||||
|
||||
final native noexport function Log(Actor Actor, string LogText, optional Name LogCategory);
|
||||
final native noexport function LogSpaceLine(Actor Actor, vector Start, vector End, EDebugLineType Type, optional string Comment, optional Name Category);
|
||||
|
||||
final native function SetContext(Actor Actor);
|
||||
|
||||
/**
|
||||
* To get previous entries send a negative number as a parameter
|
||||
*/
|
||||
final native function DisplayNextEntry(optional int Count = 1, optional int Direction = 1);
|
||||
|
||||
final native function ToggleLogDrawingMode(ELogDrawingMode Mode);
|
||||
|
||||
final native function SetHistoryFilter(Name Filter, bool bVal);
|
||||
final native function ClearHistoryFilter();
|
||||
|
||||
final native function ColorHistory(Name Filter);
|
||||
final native function ClearHistoryColor();
|
||||
|
||||
final native function LogUnreachableActor(Actor inActor);
|
||||
final native function FlushUnreachableActors();
|
||||
|
||||
final native function AddETQLog(string QueryName, string TestName, Actor Querier);
|
||||
final native function FlushETQHistory();
|
||||
|
||||
final native function AddBTLogEntry(string Entry);
|
||||
|
||||
final native function Vector GetActorEntryLocation(optional Actor inActor, optional int Index=-1);
|
||||
|
||||
final native function DumpNativeCallStack(Actor Actor, optional Name LogCategory = 'CallStack');
|
||||
|
||||
cpptext
|
||||
{
|
||||
void Init();
|
||||
void Tick(FLOAT DeltaTime);
|
||||
void CleanUp(UBOOL bShutDown);
|
||||
|
||||
void FlushAILog(class AActor* Actor, UBOOL bRemoveLog = FALSE);
|
||||
|
||||
enum EAILogElement
|
||||
{
|
||||
AILE_PrevChannel,
|
||||
AILE_Command,
|
||||
AILE_Timestamp,
|
||||
AILE_BlackBoard,
|
||||
AILE_BehaviorStack,
|
||||
AILE_Preconditions,
|
||||
AILE_CommandStack,
|
||||
AILE_SquadEnemies,
|
||||
AILE_LocalEnemies,
|
||||
AILE_Route,
|
||||
AILE_InnerState,
|
||||
AILE_WeaponInfo
|
||||
};
|
||||
|
||||
void Log(const class AActor* Actor,const FString& LogText,FName LogCategory=NAME_None);
|
||||
void LogSpaceLine(const class AActor* Actor,const FVector& Start,const FVector& End,BYTE Type,const FString& Comment=TEXT(""),FName Category=NAME_None);
|
||||
void ContextLog(const FString& LogText,FName LogCategory=NAME_None);
|
||||
void ContextLogSpaceLine(const FVector& Start,const FVector& End,BYTE Type,const FString& Comment=TEXT(""),FName Category=NAME_None);
|
||||
|
||||
protected:
|
||||
void ChannelEntryHeader(const class AActor* Actor, FAIDebugLogEntry* ptrEntry);
|
||||
UBOOL HasAnyLines(struct FAIDebugActorsLog* Log, INT EntryIdx, TArray<FName>& inFilters) const;
|
||||
FAIDebugLogEntry* GetLogEntry(const class AActor* Actor);
|
||||
|
||||
private:
|
||||
static TDataBank<FAIDebugActorsLog> sm_Logs;
|
||||
};
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BTPersonalLogSize=23
|
||||
bLoadOldLogs=false
|
||||
}
|
90
BaseAI/Classes/AIPlugin.uc
Normal file
90
BaseAI/Classes/AIPlugin.uc
Normal file
@ -0,0 +1,90 @@
|
||||
//=============================================================================
|
||||
// AIPlugin
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class AIPlugin extends PluginBase within BaseAIController
|
||||
native(Plugin)
|
||||
abstract;
|
||||
|
||||
var const protected{protected} BaseAIController MyBaseAIController;
|
||||
var const protected{private} bool bCustomSetupController;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual UBOOL SetupController(class ABaseAIController* Owner);
|
||||
// Called if bCustomSetupController == true
|
||||
virtual UBOOL SetupControllerImpl(class ABaseAIController* Owner) PURE_VIRTUAL(UPluginBase::SetupConrollerImpl, return TRUE;);
|
||||
|
||||
UBOOL HasCustomControllerSetup() const
|
||||
{
|
||||
return bCustomSetupController;
|
||||
}
|
||||
|
||||
FORCEINLINE const ABaseAIController* GetController() const
|
||||
{
|
||||
return MyBaseAIController;
|
||||
}
|
||||
|
||||
FORCEINLINE ABaseAIController* GetController()
|
||||
{
|
||||
return MyBaseAIController;
|
||||
}
|
||||
};
|
||||
|
||||
event ScriptSetUp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ===========
|
||||
* DEBUG STATES
|
||||
* ===========
|
||||
*/
|
||||
state DEBUGSTATE
|
||||
{
|
||||
function BeginState( Name PreviousStateName )
|
||||
{
|
||||
//debug
|
||||
`AILog( "BEGINSTATE"@PreviousStateName, 'State' );
|
||||
}
|
||||
|
||||
function EndState( Name NextStateName )
|
||||
{
|
||||
//debug
|
||||
`AILog( "ENDSTATE"@NextStateName, 'State' );
|
||||
}
|
||||
|
||||
function PushedState()
|
||||
{
|
||||
//debug
|
||||
`AILog( "PUSHED", 'State' );
|
||||
}
|
||||
|
||||
function PoppedState()
|
||||
{
|
||||
//debug
|
||||
`AILog( "POPPED", 'State' );
|
||||
}
|
||||
|
||||
function ContinuedState()
|
||||
{
|
||||
//debug
|
||||
`AILog( "CONTINUED", 'State' );
|
||||
}
|
||||
|
||||
function PausedState()
|
||||
{
|
||||
//debug
|
||||
`AILog( "PAUSED", 'State' );
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bCustomSetupController=false
|
||||
}
|
413
BaseAI/Classes/AIPluginLeap.uc
Normal file
413
BaseAI/Classes/AIPluginLeap.uc
Normal file
@ -0,0 +1,413 @@
|
||||
//=============================================================================
|
||||
// AIPluginLeap
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class AIPluginLeap extends AITickablePlugin within BaseAIController
|
||||
native(Plugin)
|
||||
dependson(NavigationPath)
|
||||
abstract
|
||||
config(AI);
|
||||
|
||||
|
||||
//var KFJumpDownNavPoint TheJumpDownNavPointPathObject;
|
||||
|
||||
//var Actor BaseForLeaping;
|
||||
|
||||
//var KFJumpDownNavPoint TheJumpDownNavPointPathObject;
|
||||
//var int LandSpotIndex;
|
||||
|
||||
var Actor BaseForLanding;
|
||||
//var KFJumpDownLandNavPoint LandNavPoint;
|
||||
|
||||
/** Start and End for the leap */
|
||||
var Vector LeapDirection;
|
||||
var transient Vector LocationAtStartOfLeap;
|
||||
var transient Vector ClosestLocOnEdge;
|
||||
|
||||
var transient Vector ExpectedLandingLoc;
|
||||
|
||||
var const public{protected} EActionPriority ActionPriority;
|
||||
|
||||
var const transient bool bObserverNotified;
|
||||
var const transient bool bDontNotifyObserver;
|
||||
var transient bool bDontRestartByKismet;
|
||||
|
||||
|
||||
var float ConfigFactorToIncreaseCalcedLeapVolBy;
|
||||
var float ConfigFactorToIncreasePlottedLeapVolBy;
|
||||
var float ConfigFactorToReduceLeapProjectionSizeBy;
|
||||
|
||||
var float ConfigDistanceOutFromDropEdgeToCalcDropLoc;
|
||||
|
||||
//var transient float DropHeight;
|
||||
|
||||
var float PercentageOfLeapImmuneFromCollision;
|
||||
var float ConfigPercentageOfLeapImmuneFromCollision;
|
||||
|
||||
var bool bCollisionOffPhase;
|
||||
|
||||
var float ConfigDesiredLeapSpeed;
|
||||
var float ConfigMinSpeedAllowed;
|
||||
var float ConfigMaxSpeedAllowed;
|
||||
var float ConfigBaseLeapZ;
|
||||
var float ConfigDesiredZPct;
|
||||
var bool bConfigOnlyTraceUp;
|
||||
|
||||
struct native LeapRequest
|
||||
{
|
||||
//var native MoveParameters MoveParams;
|
||||
var Actor TheJumpDownNavPointPathObject;
|
||||
var int LandSpotIndex;
|
||||
var float EdgesDropHeight;
|
||||
|
||||
var EActionPriority Priority;
|
||||
var const object Observer;
|
||||
|
||||
var int QueryID;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FLeapRequest()
|
||||
{
|
||||
appMemzero(this, sizeof(FLeapRequest));
|
||||
Reset();
|
||||
}
|
||||
|
||||
FLeapRequest(FLeapRequest* pOther)
|
||||
{
|
||||
if(pOther != NULL)
|
||||
{
|
||||
appMemCopy(*this, *pOther);
|
||||
}
|
||||
else
|
||||
{
|
||||
appMemzero(this, sizeof(FLeapRequest));
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
FString GetDescription() const;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Priority = AP_Invalid;
|
||||
TheJumpDownNavPointPathObject = NULL;
|
||||
Observer = NULL;
|
||||
LandSpotIndex = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var LeapRequest MyLeapRequest;
|
||||
|
||||
var bool bWantTotalMovementControl;
|
||||
|
||||
cpptext
|
||||
{
|
||||
void ClearMoveInfo();
|
||||
}
|
||||
|
||||
|
||||
/** Simple constructor that pushes a new instance of the command for the AI */
|
||||
function bool Leap( const out LeapRequest InLeapRequest ) // AIController AI, Actor InTheJumpDownNavPointPathObject, int InLandSpotIndex, float InDropHeight )
|
||||
{
|
||||
//DropHeight = InDropHeight;
|
||||
//LandSpotIndex = InLandSpotIndex;
|
||||
//BaseForLeaping = InTheJumpDownNavPointPathObject;
|
||||
|
||||
MyLeapRequest = InLeapRequest;
|
||||
|
||||
ScriptCommonMovePreparation( AP_Logic );
|
||||
|
||||
GotoState( 'Command_SpecialMove' );
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/** Build debug string */
|
||||
event String GetDumpString()
|
||||
{
|
||||
return "LeapDirection:"@LeapDirection;
|
||||
}
|
||||
|
||||
//function Pushed()
|
||||
event bool ScriptCommonMovePreparation(EActionPriority Priority)
|
||||
{
|
||||
bCollisionOffPhase = false;
|
||||
|
||||
//Super.Pushed();
|
||||
|
||||
//GotoState( 'Command_SpecialMove' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//function Popped()
|
||||
event ScriptCleanUp()
|
||||
{
|
||||
//Super.Popped();
|
||||
Outer.MyBaseAIPawn.bLeaping = false;
|
||||
//bReevaluatePath = TRUE;
|
||||
`AILog( GetFuncName() @ " Turning me on because ScriptCleanUp: " );
|
||||
TurnMeOn();
|
||||
}
|
||||
|
||||
native function protected Success();
|
||||
native function protected Failure();
|
||||
|
||||
native function bool AbortMove(bool bNewRequest);
|
||||
|
||||
state Succeeding `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Leaping - END:"@GetStateName(), 'Leap');
|
||||
Success();
|
||||
}
|
||||
|
||||
state Failing `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Leaping - END:"@GetStateName(), 'Leap');
|
||||
Failure();
|
||||
}
|
||||
|
||||
/* this state does nothing. It's here to leave other states when move is aborted,
|
||||
* and to indicate that it happened */
|
||||
state Aborting `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Leaping - Aborted", 'Leap');
|
||||
//AbortMove(false);
|
||||
StopMovement();
|
||||
}
|
||||
|
||||
/* this state does nothing. It's here to leave other states when move is aborted,
|
||||
* and to indicate that it happened */
|
||||
state Idling `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Leaping - Idling so doing nothing", 'Leap');
|
||||
//StopMovement();
|
||||
}
|
||||
|
||||
|
||||
function TestForTimeToTurnCollisionBackOn()
|
||||
{
|
||||
local float timeDelta;
|
||||
|
||||
if( bCollisionOffPhase )
|
||||
{
|
||||
if( HasPercentOfZDiffBeenCovered() )
|
||||
{
|
||||
`AILog( GetFuncName() @ " Turning me on because HasPercentOfZDiffBeenCovered: " );
|
||||
TurnMeOn();
|
||||
}
|
||||
else
|
||||
{
|
||||
timeDelta = WorldInfo.TimeSeconds - Outer.MyBaseAIPawn.TimeStartedLeap;
|
||||
|
||||
if( timeDelta > Outer.MyBaseAIPawn.TimeImmuneWhileLeaping )
|
||||
{
|
||||
`AILog( GetFuncName() @ " Turning me on because of time in leap of: " @ timeDelta );
|
||||
|
||||
TurnMeOn();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function bool HasPercentOfZDiffBeenCovered();
|
||||
|
||||
|
||||
function TurnMeOn()
|
||||
{
|
||||
Outer.MyBaseAIPawn.SetCollision( true, true );
|
||||
|
||||
Outer.MyBaseAIPawn.bCollideWorld = true;
|
||||
|
||||
Outer.MyBaseAIPawn.SetPushesRigidBodies(true);
|
||||
|
||||
bCollisionOffPhase = false;
|
||||
}
|
||||
|
||||
function vector GetJumpVelForDropEdge( out float TimeToReachLandLoc );
|
||||
|
||||
function vector GetJumpVelForUsingJumpDownNavPointPathObject( out float TimeToReachLandLoc );
|
||||
|
||||
|
||||
state Command_SpecialMove
|
||||
{
|
||||
function BeginState( Name PreviousStateName )
|
||||
{
|
||||
Super.BeginState( PreviousStateName );
|
||||
|
||||
if( MyLeapRequest.TheJumpDownNavPointPathObject != none )
|
||||
{
|
||||
SetDesiredDirectionForJumpDoenNavPointEdge();
|
||||
}
|
||||
else
|
||||
{
|
||||
SetDesiredDirectionForDropEdge();
|
||||
}
|
||||
|
||||
bWantTotalMovementControl = true;
|
||||
}
|
||||
|
||||
function Bool IfShowLeapDownDebugArtifacts()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function vector GetCurrentJumpEdgeDirectionOfLeap()
|
||||
{
|
||||
return Vector(MyLeapRequest.TheJumpDownNavPointPathObject.Rotation);
|
||||
}
|
||||
|
||||
function float GetDistanceDownRangeToFocusForDropEdgeLeap()
|
||||
{
|
||||
return 500.0;
|
||||
}
|
||||
|
||||
//function SetDesiredDirectionForDropEdge()
|
||||
//{
|
||||
// local Vector newFocalPoint;
|
||||
// local float edgesDropHeight;
|
||||
|
||||
// LeapDirection = MyKFNavigationHandle.GetCurrentJumpEdgeDirectionOfLeap( Outer, edgesDropHeight, ClosestLocOnEdge );
|
||||
|
||||
// Focus = none;
|
||||
|
||||
// newFocalPoint = Outer.Pawn.Location + LeapDirection * Outer.DistanceDownRangeToFocusForDropEdgeLeap;
|
||||
|
||||
// SetFocalPoint( newFocalPoint );
|
||||
|
||||
// if( Outer.bShowLeapDownDebugArtifacts )
|
||||
// {
|
||||
// DrawDebugStar( newFocalPoint, 30, 255, 165, 0, true);
|
||||
// }
|
||||
|
||||
// SetDesiredRotation(rotator(LeapDirection));
|
||||
//}
|
||||
|
||||
function SetDesiredDirectionForDropEdge()
|
||||
{
|
||||
local Vector newFocalPoint;
|
||||
//local float edgesDropHeight;
|
||||
|
||||
LeapDirection = GetCurrentJumpEdgeDirectionOfLeap();
|
||||
|
||||
Focus = none;
|
||||
|
||||
newFocalPoint = Outer.Pawn.Location + LeapDirection * GetDistanceDownRangeToFocusForDropEdgeLeap();
|
||||
|
||||
SetFocalPoint( newFocalPoint );
|
||||
|
||||
if( IfShowLeapDownDebugArtifacts() ) // Outer.bShowLeapDownDebugArtifacts )
|
||||
{
|
||||
DrawDebugStar( newFocalPoint, 300, 255, 165, 0, true);
|
||||
}
|
||||
|
||||
SetDesiredRotation(rotator(LeapDirection));
|
||||
}
|
||||
|
||||
//function SetDesiredDirectionForJumpDoenNavPointEdge()
|
||||
//{
|
||||
// local Vector newFocalPoint;
|
||||
|
||||
// LeapDirection = BaseForLanding.Location - Outer.Pawn.Location;
|
||||
|
||||
// Focus = none;
|
||||
|
||||
// newFocalPoint = BaseForLanding.Location;// Outer.Pawn.Location + LeapDirection * Outer.DistanceDownRangeToFocusForDropEdgeLeap;
|
||||
|
||||
// SetFocalPoint( newFocalPoint );
|
||||
|
||||
// if( Outer.bShowLeapDownDebugArtifacts )
|
||||
// {
|
||||
// DrawDebugStar( newFocalPoint, 30, 255, 165, 0, true);
|
||||
// }
|
||||
|
||||
// SetDesiredRotation(rotator(LeapDirection));
|
||||
//}
|
||||
|
||||
function SetDesiredDirectionForJumpDoenNavPointEdge()
|
||||
{
|
||||
local Vector newFocalPoint;
|
||||
|
||||
if( BaseForLanding == none )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LeapDirection = BaseForLanding.Location - Outer.Pawn.Location;
|
||||
|
||||
Focus = none;
|
||||
|
||||
newFocalPoint = BaseForLanding.Location;// Outer.Pawn.Location + LeapDirection * Outer.DistanceDownRangeToFocusForDropEdgeLeap;
|
||||
|
||||
SetFocalPoint( newFocalPoint );
|
||||
|
||||
if( IfShowLeapDownDebugArtifacts() )
|
||||
{
|
||||
DrawDebugStar( newFocalPoint, 300, 255, 165, 0, true);
|
||||
}
|
||||
|
||||
SetDesiredRotation(rotator(LeapDirection));
|
||||
}
|
||||
|
||||
function bool DoLeap()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function LeapLoopPreSleepDataUpdate()
|
||||
{
|
||||
//Outer.LeapBehavior.ProjMeshLocations.AddItem(MyKfPawn.Location);
|
||||
}
|
||||
|
||||
Begin:
|
||||
|
||||
while( !Pawn.ReachedDesiredRotation() )
|
||||
{
|
||||
Sleep(0.03);
|
||||
}
|
||||
|
||||
if( DoLeap() )
|
||||
{
|
||||
do
|
||||
{
|
||||
LeapLoopPreSleepDataUpdate();
|
||||
Sleep( 0.0f );
|
||||
TestForTimeToTurnCollisionBackOn();
|
||||
|
||||
} until( Pawn.Physics != PHYS_Falling );
|
||||
|
||||
`AILog( GetFuncName() @ " Pawn.Physics != PHYS_Falling, so landed" );
|
||||
|
||||
// CGH this is where i am an trying to get the pawn told about the leap.
|
||||
Outer.MyBaseAIPawn.bLeaping = false;
|
||||
Outer.MyBaseAIPawn.SetCollision( true, true, true );
|
||||
|
||||
// Status = 'Success';
|
||||
Focus = Enemy;
|
||||
//PopCommand( self );
|
||||
//Stop;
|
||||
|
||||
NotifyLanded();
|
||||
}
|
||||
bWantTotalMovementControl = false;
|
||||
|
||||
GotoState( 'Succeeding' );
|
||||
}
|
||||
|
||||
function NotifyLanded();
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
367
BaseAI/Classes/AIPluginMovement.uc
Normal file
367
BaseAI/Classes/AIPluginMovement.uc
Normal file
@ -0,0 +1,367 @@
|
||||
//=============================================================================
|
||||
// AIPluginMovement
|
||||
//=============================================================================
|
||||
// A proxy/parent class for all specific movement implementations
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class AIPluginMovement extends AITickablePlugin within BaseAIController
|
||||
native(Plugin)
|
||||
dependson(NavigationPath)
|
||||
abstract;
|
||||
|
||||
struct native MoveParameters
|
||||
{
|
||||
var EBaseMoveMood MoveMood;
|
||||
var EBaseMoveType MoveType;
|
||||
// var EStridePose EndStridePose;
|
||||
var Actor RotateAtEndToMatch;
|
||||
/** When path is actually for following actor. */
|
||||
var Actor FollowingActor;
|
||||
|
||||
/** Movement can be inaccurate. Useful when character ends up around < 2m away and it is not needed for it cover distance. */
|
||||
var bool bMovementCanBeInaccurate;
|
||||
/** Don't stop at the end of path. Useful for charge attacks etc. when character is not expected to stop at the end of path. Doesn't apply for entering cover. */
|
||||
var bool bMoveThroughLastPoint;
|
||||
/** Indicates whether movement needs to start/end with shooting animation. */
|
||||
var bool bStartPathFollowingShooting;
|
||||
var bool bEndPathFollowingShooting;
|
||||
/** makes sure AI will do any move even if destination is close enough */
|
||||
var bool bForceAnyMove;
|
||||
var bool bAllowedToFire;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FMoveParameters()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
appMemzero(this, sizeof(FMoveParameters));
|
||||
// copied from structdefaultproperties
|
||||
MoveMood = BMM_Fast;
|
||||
MoveType = BMT_Normal;
|
||||
bStartPathFollowingShooting = TRUE;
|
||||
bEndPathFollowingShooting = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
structdefaultproperties
|
||||
{
|
||||
// BodyStance=NBS_Stand
|
||||
MoveMood=BMM_Fast
|
||||
MoveType=BMT_Normal
|
||||
bStartPathFollowingShooting=true
|
||||
}
|
||||
};
|
||||
|
||||
enum EMoveRequestDestinationType
|
||||
{
|
||||
MRDT_Invalid,
|
||||
MRDT_Vector,
|
||||
MRDT_Actor,
|
||||
};
|
||||
|
||||
struct native MoveRequestDestination
|
||||
{
|
||||
var vector VectorDest;
|
||||
var Actor ActorDest;
|
||||
var EMoveRequestDestinationType Type;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FMoveRequestDestination()
|
||||
{
|
||||
appMemzero(this, sizeof(FMoveRequestDestination));
|
||||
}
|
||||
|
||||
FMoveRequestDestination(const class FVector& vDestination)
|
||||
{
|
||||
VectorDest = vDestination;
|
||||
Type = MRDT_Vector;
|
||||
}
|
||||
|
||||
FMoveRequestDestination(class AActor* Actor) : Type(MRDT_Invalid)
|
||||
{
|
||||
if(Actor != NULL)
|
||||
{
|
||||
ActorDest = Actor;
|
||||
Type = MRDT_Actor;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Type = MRDT_Invalid;
|
||||
}
|
||||
|
||||
void Set(const class FVector& vDestination)
|
||||
{
|
||||
VectorDest = vDestination;
|
||||
Type = MRDT_Vector;
|
||||
}
|
||||
|
||||
void Set(class AActor* Actor)
|
||||
{
|
||||
if(Actor != NULL)
|
||||
{
|
||||
ActorDest = Actor;
|
||||
Type = MRDT_Actor;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type = MRDT_Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
//void Set(struct FCoverInfo& inCoverInfo)
|
||||
//{
|
||||
// if(inCoverInfo.IsSet() == TRUE)
|
||||
// {
|
||||
// CoverInfoDest = inCoverInfo;
|
||||
// Type = MRDT_Cover;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Type = MRDT_Invalid;
|
||||
// }
|
||||
//}
|
||||
|
||||
UBOOL IsActor() const
|
||||
{
|
||||
return Type == MRDT_Actor;
|
||||
}
|
||||
|
||||
UBOOL IsVector() const
|
||||
{
|
||||
return Type == MRDT_Vector;
|
||||
}
|
||||
|
||||
//UBOOL IsCover() const
|
||||
//{
|
||||
// return Type == MRDT_Cover;
|
||||
//}
|
||||
|
||||
class AActor* GetAsActor()
|
||||
{
|
||||
return Type == MRDT_Actor ? ActorDest : NULL;
|
||||
}
|
||||
|
||||
const class AActor* GetAsActor() const
|
||||
{
|
||||
return Type == MRDT_Actor ? ActorDest : NULL;
|
||||
}
|
||||
|
||||
//struct FCoverInfo GetAsCoverInfo() const
|
||||
//{
|
||||
// return Type == MRDT_Cover ? CoverInfoDest : FCoverInfo();
|
||||
//}
|
||||
|
||||
FVector GetPosition() const
|
||||
{
|
||||
switch(Type)
|
||||
{
|
||||
case MRDT_Vector:
|
||||
return VectorDest;
|
||||
break;
|
||||
//case MRDT_Cover:
|
||||
// return CoverInfoDest.Link ? CoverInfoDest.Link->GetSlotLocation(CoverInfoDest.SlotIdx) : FVector(0.f);
|
||||
// break;
|
||||
case MRDT_Actor:
|
||||
return ActorDest ? ActorDest->Location : FVector(0.f);
|
||||
break;
|
||||
default: // MRDT_Invalid
|
||||
break;
|
||||
}
|
||||
return FVector(0.0f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct native MovementRequest
|
||||
{
|
||||
var native MoveParameters MoveParams;
|
||||
var float AcceptableDistance;
|
||||
var vector DestOffset;
|
||||
var vector MidPointOffset;
|
||||
/** a struct type with union inside representing move destination. It seems
|
||||
* ok to have a native only access to it - script will only be able to modify means
|
||||
* of execution, but not destination itself.
|
||||
*/
|
||||
var native MoveRequestDestination Destination;
|
||||
var native NavigationPath PreComputedPath;
|
||||
var EActionPriority Priority;
|
||||
var const object Observer;
|
||||
var bool bStickToNavmesh;
|
||||
var bool bStickToActionArea;
|
||||
var bool bDynamicDestOffset; // not used at the moment. Added for consistence
|
||||
var bool bDynamicMidPoint;
|
||||
var bool bPostProcessPath;
|
||||
var int QueryID;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FMovementRequest()
|
||||
{
|
||||
appMemzero(this, sizeof(FMovementRequest));
|
||||
Reset();
|
||||
}
|
||||
|
||||
FMovementRequest(FMovementRequest* pOther)
|
||||
{
|
||||
if(pOther != NULL)
|
||||
{
|
||||
appMemCopy(*this, *pOther);
|
||||
}
|
||||
else
|
||||
{
|
||||
appMemzero(this, sizeof(FMovementRequest));
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
FString GetDescription() const;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MoveParams.Reset();
|
||||
AcceptableDistance=0.0f;
|
||||
Destination.Reset();
|
||||
PreComputedPath = NULL;
|
||||
Priority = AP_Invalid;
|
||||
bStickToNavmesh = TRUE;
|
||||
bStickToActionArea = FALSE;
|
||||
bPostProcessPath = FALSE;
|
||||
Observer = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var MovementRequest MoveRequest;
|
||||
var transient float GoalDistanceSq;
|
||||
|
||||
var const public{protected} EActionPriority ActionPriority;
|
||||
|
||||
var const public{private} EActionPriority MovementLock;
|
||||
|
||||
var const transient bool bObserverNotified;
|
||||
var const transient bool bDontNotifyObserver;
|
||||
var transient bool bDontRestartByKismet;
|
||||
|
||||
var float MinimumSuccessDistance;
|
||||
|
||||
cpptext
|
||||
{
|
||||
UBOOL IsMovementLocked(const EActionPriority Priority = AP_Logic) const // AP_Locic, i.e. AP_Invalid + 1.
|
||||
{
|
||||
return MovementLock >= Priority;
|
||||
}
|
||||
|
||||
EActionPriority GetMovementLock() const
|
||||
{
|
||||
return (EActionPriority)MovementLock;
|
||||
}
|
||||
|
||||
UBOOL CanAcceptNewMoveRequest(EActionPriority NewRequestPriority) const
|
||||
{
|
||||
return NewRequestPriority >= ActionPriority;
|
||||
}
|
||||
|
||||
FORCEINLINE EActionPriority GetActionPriority() const
|
||||
{
|
||||
return (EActionPriority)ActionPriority;
|
||||
}
|
||||
|
||||
FVector GetDestination(struct FMovementRequest& Request) const
|
||||
{
|
||||
return Request.Destination.GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
/** overrideable only in native code (no-exported as virtual) */
|
||||
native function bool MoveToRequest(out MovementRequest Request);
|
||||
native function bool MoveToPointRequest(vector InDestLocation, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional bool bStickToNavmesh = true, optional float AcceptableDistance, optional Actor RotateAtEndToMatch);
|
||||
native function bool MoveToActorRequest(Actor inPawnGoal, EActionPriority CommandPriority, optional object ActionObserver, optional bool bInAllowedToFire=true, optional float AcceptableDistance, optional vector DestOffset, optional vector MidPointOffset, optional bool bDynamicMidPoint, optional bool bStopAtEnd=true, optional bool bStickToNavmesh=true);
|
||||
native function bool FollowPlugInsPath(NavigationPath InPath, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional Actor RotateAtEndToMatch, optional Float AcceptableDistance);
|
||||
|
||||
native function bool AbortMove(bool bNewRequest);
|
||||
|
||||
/**
|
||||
* @param bNewRequest if set to false (default) then if there was a move
|
||||
* task paused while lock was being set, then this task will be resumed.
|
||||
* If true, it will not. This param makes sense only for bLock == true
|
||||
*/
|
||||
native function SetMovementLock(bool bLock, optional EActionPriority Priority = AP_Logic, optional bool bNewRequest);
|
||||
|
||||
native function protected Success();
|
||||
native function protected Failure();
|
||||
|
||||
native function bool RePath();
|
||||
|
||||
/** Script interface to get location of destination point from given MovementRequest.
|
||||
* no-exported to make inline. */
|
||||
final native noexport function vector GetDestination(out MovementRequest Request) const;
|
||||
|
||||
final function EMoveRequestDestinationType GetDestinationType()
|
||||
{
|
||||
return MoveRequest.Destination.Type;
|
||||
}
|
||||
|
||||
function StopMovement()
|
||||
{
|
||||
//@todo fill it!
|
||||
}
|
||||
|
||||
/** Called from native code during latent movement when current move is considered unreachable */
|
||||
function bool MoveUnreachable( Vector AttemptedDest, Actor AttemptedTarget )
|
||||
{
|
||||
if( AttemptedTarget != none )
|
||||
{
|
||||
`AILog( GetFuncName()$" AttemptedTarget: "$AttemptedTarget, 'PathWarning' );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
state Succeeding `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Moving - END:"@GetStateName(), 'Move');
|
||||
Success();
|
||||
}
|
||||
|
||||
state Failing `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Moving - END:"@GetStateName(), 'Move');
|
||||
Failure();
|
||||
}
|
||||
|
||||
/* this state does nothing. It's here to leave other states when move is aborted,
|
||||
* and to indicate that it happened */
|
||||
state Aborting `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Moving - Aborted", 'Move');
|
||||
//AbortMove(false);
|
||||
StopMovement();
|
||||
}
|
||||
|
||||
/* this state does nothing. It's here to leave other states when move is aborted,
|
||||
* and to indicate that it happened */
|
||||
state Idling `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Idling", 'Move');
|
||||
StopMovement();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// mz> this change is a little bit hacky and will need further changes. AnimSys accepts path success if destination to cover < 150.0f;
|
||||
//MinimumSuccessDistance=8100.0f //90 units
|
||||
MinimumSuccessDistance=160.0f //90 units
|
||||
}
|
190
BaseAI/Classes/AIPluginStuckFix.uc
Normal file
190
BaseAI/Classes/AIPluginStuckFix.uc
Normal file
@ -0,0 +1,190 @@
|
||||
//=============================================================================
|
||||
// AIPluginStuckFix
|
||||
//=============================================================================
|
||||
// A proxy/parent class for all specific Stuck implementations
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class AIPluginStuckFix extends AITickablePlugin within BaseAIController
|
||||
native(Plugin)
|
||||
dependson(NavigationPath, AIPluginMovement)
|
||||
abstract;
|
||||
|
||||
struct native FixStuckRequest
|
||||
{
|
||||
var native MoveParameters MoveParams;
|
||||
var float AcceptableDistance;
|
||||
var vector DestOffset;
|
||||
//var vector MidPointOffset;
|
||||
/** a struct type with union inside representing move destination. It seems
|
||||
* ok to have a native only access to it - script will only be able to modify means
|
||||
* of execution, but not destination itself.
|
||||
*/
|
||||
var native MoveRequestDestination Destination;
|
||||
//var native NavigationPath PreComputedPath;
|
||||
var EActionPriority Priority;
|
||||
var const object Observer;
|
||||
var bool bFinalApproach;
|
||||
var int QueryID;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
FFixStuckRequest()
|
||||
{
|
||||
appMemzero(this, sizeof(FFixStuckRequest));
|
||||
Reset();
|
||||
}
|
||||
|
||||
FFixStuckRequest(FFixStuckRequest* pOther)
|
||||
{
|
||||
if(pOther != NULL)
|
||||
{
|
||||
appMemCopy(*this, *pOther);
|
||||
}
|
||||
else
|
||||
{
|
||||
appMemzero(this, sizeof(FFixStuckRequest));
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
FString GetDescription() const;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MoveParams.Reset();
|
||||
AcceptableDistance=0.0f;
|
||||
Destination.Reset();
|
||||
Priority = AP_Invalid;
|
||||
bFinalApproach = FALSE;
|
||||
Observer = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var FixStuckRequest MoveRequest;
|
||||
var const public{protected} EActionPriority ActionPriority;
|
||||
|
||||
var const public{private} EActionPriority MovementLock;
|
||||
|
||||
var const transient bool bObserverNotified;
|
||||
var const transient bool bDontNotifyObserver;
|
||||
var transient bool bDontRestartByKismet;
|
||||
|
||||
cpptext
|
||||
{
|
||||
UBOOL IsMovementLocked(const EActionPriority Priority = AP_Logic) const // AP_Locic, i.e. AP_Invalid + 1.
|
||||
{
|
||||
return MovementLock >= Priority;
|
||||
}
|
||||
|
||||
EActionPriority GetMovementLock() const
|
||||
{
|
||||
return (EActionPriority)MovementLock;
|
||||
}
|
||||
|
||||
UBOOL CanAcceptNewMoveRequest(EActionPriority NewRequestPriority) const
|
||||
{
|
||||
return NewRequestPriority >= ActionPriority;
|
||||
}
|
||||
|
||||
FORCEINLINE EActionPriority GetActionPriority() const
|
||||
{
|
||||
return (EActionPriority)ActionPriority;
|
||||
}
|
||||
|
||||
FVector GetDestination(struct FFixStuckRequest& Request) const
|
||||
{
|
||||
return Request.Destination.GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
/** overrideable only in native code (no-exported as virtual) */
|
||||
function bool StuckFixToPointRequest(vector InDestLocation, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional bool bStickToNavmesh = true, optional float AcceptableDistance, optional Actor RotateAtEndToMatch);
|
||||
function bool StuckFixToActorRequest(Actor inPawnGoal, EActionPriority CommandPriority, optional object ActionObserver, optional bool bInAllowedToFire=true, optional float AcceptableDistance, optional vector DestOffset, optional vector MidPointOffset, optional bool bDynamicMidPoint, optional bool bStopAtEnd=true, optional bool bStickToNavmesh=true);
|
||||
|
||||
event bool AbortMove(bool bNewRequest);
|
||||
|
||||
/**
|
||||
* @param bNewRequest if set to false (default) then if there was a move
|
||||
* task paused while lock was being set, then this task will be resumed.
|
||||
* If true, it will not. This param makes sense only for bLock == true
|
||||
*/
|
||||
function SetMovementLock(bool bLock, optional EActionPriority Priority = AP_Logic, optional bool bNewRequest);
|
||||
|
||||
function protected Success();
|
||||
function protected Failure();
|
||||
|
||||
|
||||
/** Script interface to get location of destination point from given MovementRequest.
|
||||
* no-exported to make inline. */
|
||||
final native noexport function vector GetDestination(out MovementRequest Request) const;
|
||||
|
||||
final function EMoveRequestDestinationType GetDestinationType()
|
||||
{
|
||||
return MoveRequest.Destination.Type;
|
||||
}
|
||||
|
||||
function StopMovement()
|
||||
{
|
||||
//@todo fill it!
|
||||
}
|
||||
|
||||
/** Called from native code during latent movement when current move is considered unreachable */
|
||||
function bool MoveUnreachable( Vector AttemptedDest, Actor AttemptedTarget )
|
||||
{
|
||||
if( AttemptedTarget != none )
|
||||
{
|
||||
`AILog( GetFuncName()$" AttemptedTarget: "$AttemptedTarget, 'PathWarning' );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
state Succeeding `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Moving - END:"@GetStateName(), 'Move');
|
||||
Success();
|
||||
|
||||
GotoState( 'Idling' );
|
||||
}
|
||||
|
||||
state Failing `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Moving - END:"@GetStateName(), 'Move');
|
||||
Failure();
|
||||
|
||||
GotoState( 'Idling' );
|
||||
}
|
||||
|
||||
/* this state does nothing. It's here to leave other states when move is aborted,
|
||||
* and to indicate that it happened */
|
||||
state Aborting `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Moving - Aborted", 'Move');
|
||||
//AbortMove(false);
|
||||
StopMovement();
|
||||
|
||||
GotoState( 'Idling' );
|
||||
}
|
||||
|
||||
/* this state does nothing. It's here to leave other states when move is aborted,
|
||||
* and to indicate that it happened */
|
||||
state Idling `DEBUGSTATE
|
||||
{
|
||||
Begin:
|
||||
`AILog("Idling", 'Move');
|
||||
StopMovement();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// mz> this change is a little bit hacky and will need further changes. AnimSys accepts path success if destination to cover < 150.0f;
|
||||
//MinimumSuccessDistance=8100.0f //90 units
|
||||
//MinimumSuccessDistance=160.0f //90 units
|
||||
}
|
57
BaseAI/Classes/AITickablePlugin.uc
Normal file
57
BaseAI/Classes/AITickablePlugin.uc
Normal file
@ -0,0 +1,57 @@
|
||||
//=============================================================================
|
||||
// AITickablePlugin
|
||||
//=============================================================================
|
||||
// this plugin type introduces tickable states functionality to deriving plugins
|
||||
//
|
||||
// NOTE: currently every plugin used is ticked directly by owner (only movement plugins
|
||||
// implemented so far). If more plugins are created and need to be ticked a simple //
|
||||
// registration mechanism should be implemented to store all plugins to be ticked in
|
||||
// some array in owning BaseAIController (much like BaseAISubsystem.SmartObjects for example)
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class AITickablePlugin extends AIPlugin within BaseAIController
|
||||
native(Plugin)
|
||||
abstract;
|
||||
|
||||
var const float LatentTime; // Internal latent function use.
|
||||
var const private{private} bool bTickingEnabled;
|
||||
|
||||
cpptext
|
||||
{
|
||||
void TickPlugin(FLOAT DeltaTime);
|
||||
virtual void ProcessState(FLOAT DeltaSeconds);
|
||||
virtual EGotoState GotoState( FName State, UBOOL bForceEvents = 0, UBOOL bKeepStack = 0 );
|
||||
|
||||
void SetEnableTicking(UBOOL bEnable)
|
||||
{
|
||||
bTickingEnabled = bEnable;
|
||||
}
|
||||
|
||||
UBOOL IsTickingEnabled() const
|
||||
{
|
||||
return bTickingEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
final native latent function Sleep(float Seconds);
|
||||
|
||||
event ScriptTick( float DeltaTime )
|
||||
{
|
||||
}
|
||||
|
||||
function bool NotifyNpcTerminallyStuck()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
function bool NotifyNpcInGrannyMode()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bTickingEnabled=true
|
||||
}
|
318
BaseAI/Classes/BaseAIController.uc
Normal file
318
BaseAI/Classes/BaseAIController.uc
Normal file
@ -0,0 +1,318 @@
|
||||
//=============================================================================
|
||||
// BaseAIController
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class BaseAIController extends GameAIController
|
||||
dependson(BaseAIPawn, PluginBase, AIPluginMovement)
|
||||
implements(PlugInOwnerInterface)
|
||||
native
|
||||
config(AI);
|
||||
|
||||
var transient BaseAIPawn MyBaseAIPawn;
|
||||
var transient BaseAISquad BaseSquad;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// animation related vars
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Plugins
|
||||
// ----------------------------------------------------------------------- //
|
||||
var const public{protected} array<AITickablePlugin> TickablePlugins;
|
||||
|
||||
var instanced PluginSquad SquadPlugin;
|
||||
|
||||
var instanced AIPluginMovement MovementPlugin;
|
||||
var class<AIPluginMovement> MovementPluginClass;
|
||||
|
||||
var instanced AIPluginLeap LeapPlugin;
|
||||
var class<AIPluginLeap> LeapPluginClass;
|
||||
|
||||
var instanced AIPluginStuckFix StuckFixPlugin;
|
||||
var class<AIPluginStuckFix> StuckFixPluginClass;
|
||||
|
||||
// base off KFAICommandHistory
|
||||
var transient BaseAiPlugInHistory MyAiPlugInHistory;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Movement
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// perception
|
||||
// ----------------------------------------------------------------------- //
|
||||
var bool bUsePerceptionHearing;
|
||||
var bool bAlwaysAssignEnemy;
|
||||
|
||||
/** When last time our enemy was visible */
|
||||
var float LastEnemySightedTime;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// firing
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Target selection/limitation
|
||||
// ----------------------------------------------------------------------- //
|
||||
/** List of targets to shoot at */
|
||||
var array<Actor> TargetList;
|
||||
/** List of prohibited targets */
|
||||
var array<Actor> ProhibitedTargetList;
|
||||
|
||||
var transient BaseAIPawn SquadAssignedTarget;
|
||||
|
||||
struct native LocalEnemyInfo
|
||||
{
|
||||
var array<float> PerceptionTimestamp;
|
||||
var EWSPerceptionMode LatestPerception;
|
||||
var EWSPerceptionMode DominantPerception;
|
||||
var int VisibleCoverActions;
|
||||
|
||||
var float CurrentThreat;
|
||||
var vector LatestLocation; //latest location with Seen perception
|
||||
var Pawn Pawn;
|
||||
|
||||
var bool bSeenBefore;
|
||||
var bool bIsPlayer;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
/** Constructors */
|
||||
FLocalEnemyInfo() {}
|
||||
FLocalEnemyInfo(EEventParm)
|
||||
{
|
||||
|
||||
}
|
||||
FLocalEnemyInfo(APawn* InPawn)
|
||||
{
|
||||
appMemzero(this, sizeof(FLocalEnemyInfo));
|
||||
Pawn = InPawn;
|
||||
}
|
||||
|
||||
FORCEINLINE UBOOL CanBeSeenWithAction(BYTE Action) const
|
||||
{
|
||||
return (VisibleCoverActions & (1 << Action)) != 0;
|
||||
}
|
||||
|
||||
UBOOL operator==(const FLocalEnemyInfo& InEnemyInfo) const
|
||||
{
|
||||
return Pawn == InEnemyInfo.Pawn;
|
||||
}
|
||||
|
||||
UBOOL operator==(const APawn* EnemyPawn) const
|
||||
{
|
||||
return Pawn == EnemyPawn;
|
||||
}
|
||||
}
|
||||
};
|
||||
var array<LocalEnemyInfo> LocalEnemyList;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Attachments and SpecialActionSttachments
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Enable/Disable Navmesh and plugins
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
/** If this is on, NPC will always try to use Nav Mesh Path Finding Before Path Node */
|
||||
var bool bUseNavMesh;
|
||||
/** If this is on, NPC will always try to use plugins for movement. Only works with navmesh */
|
||||
var bool bUsePluginsForMovement;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// debug variables
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
var(Debug) config int PlugInHistoryNum;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual void Initialize();
|
||||
void OnLevelStreamedOut(ULevel* Level);
|
||||
virtual UBOOL Tick(FLOAT DeltaTime, enum ELevelTick TickType);
|
||||
|
||||
virtual void PreBeginPlay();
|
||||
virtual void BeginDestroy();
|
||||
virtual void GetSquadEnemies(TArray<class APawn*>& Items, UBOOL bExcludeProhibitedTargets = FALSE, UBOOL bExcludeBeliefInfo = FALSE);
|
||||
|
||||
virtual UBOOL IsFriendly(const class AController* const TestPlayer) const;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Movement
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// perception
|
||||
// ----------------------------------------------------------------------- //
|
||||
void UpdateEnemyKnowledge(INT EnemyIdx, BYTE Perception);
|
||||
|
||||
#if !DO_BASEAI_LOGGING
|
||||
# if COMPILER_SUPPORTS_NOOP
|
||||
# define BaseAILog __noop
|
||||
# else
|
||||
# define BaseAILog GNull->Logf
|
||||
# endif
|
||||
static class FOutputDeviceRedirectorBase* GLog;
|
||||
#else
|
||||
VARARG_DECL(void,void,{},BaseAILog,VARARG_NONE,const TCHAR*,VARARG_NONE,VARARG_NONE);
|
||||
VARARG_DECL(void,void,{},BaseAILog,VARARG_NONE,const TCHAR*,VARARG_EXTRA(enum EName E),VARARG_EXTRA(E));
|
||||
#endif
|
||||
|
||||
// AI debug stuff:
|
||||
virtual void GetGameSpecificDebug(BYTE element, TArrayNoInit<FString>& outLogLines, TArray<struct FSpaceLineInfo>* Lines = NULL) const;
|
||||
|
||||
static TArray<UClass*> InitializedAIClasses;
|
||||
}
|
||||
|
||||
/** Called ONCe per class for class specific initialization (e.g. ETQ queries)
|
||||
*/
|
||||
event InitializeAIClass()
|
||||
{
|
||||
}
|
||||
|
||||
event Possess(Pawn inPawn, bool bVehicleTransition)
|
||||
{
|
||||
super.Possess(inPawn, bVehicleTransition);
|
||||
|
||||
if (inPawn != none)
|
||||
{
|
||||
MyBaseAIPawn = BaseAIPawn(inPawn);
|
||||
`if(`notdefined(__TW_BASEAI_LEAN_))
|
||||
InitializeDefaultBehavior();
|
||||
|
||||
// setup movement properties
|
||||
SetupPathfinding();
|
||||
`endif
|
||||
}
|
||||
}
|
||||
|
||||
function PawnDied(Pawn InPawn)
|
||||
{
|
||||
CleanUp();
|
||||
super.PawnDied(InPawn);
|
||||
}
|
||||
|
||||
/** This function needs to stay final */
|
||||
native final function float UpdateEnemyRange();
|
||||
native final function EWSSymbolicAngle UpdateEnemyAngle();
|
||||
|
||||
native function CleanUp(optional bool bBeingDestroyed);
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// PlugInOwner interface plimentation
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
function BaseAiPlugInHistory GetAiPlugInHistory()
|
||||
{
|
||||
return MyAiPlugInHistory;
|
||||
}
|
||||
|
||||
function float GetTimeSince( float Time2Test )
|
||||
{
|
||||
return `TimeSince(Time2Test);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Squad mechanics
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
native function int BroadcastEnemyKnowledge(Pawn EnemyPawn, EWSPerceptionMode Perception);
|
||||
native function RemoveEnemy(Pawn EnemyPawn);
|
||||
native function RemoveAllEnemies();
|
||||
native final function bool IsFriendlyPawn(Pawn TestPlayer) const;
|
||||
native noexport function bool IsFriendly(Controller TestPlayer) const;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Animation related
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// perception
|
||||
// ----------------------------------------------------------------------- //
|
||||
native final function UpdateEnemyPerception(optional bool bSkipResponseDelay);
|
||||
|
||||
/** Selects a target from the TargetList or selects an enemy normally */
|
||||
native function bool SelectTargetInternal(bool bOnlyFromTargetList);
|
||||
native event bool SetEnemy(Pawn NewEnemy);
|
||||
native function bool SelectEnemy();
|
||||
native function bool SelectTarget();
|
||||
|
||||
// @todo this will be handled by squads
|
||||
//function NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn)
|
||||
function NotifyKilled(Controller Killer, Controller Killed, pawn KilledPawn, class<DamageType> damageTyp)
|
||||
{
|
||||
// remove focus from killed enemy
|
||||
if (KilledPawn == Focus)
|
||||
{
|
||||
Focus = None;
|
||||
}
|
||||
|
||||
// Controller's implementation mess with Enemy, so work on this before calling parent
|
||||
RemoveEnemy(KilledPawn);
|
||||
|
||||
super.NotifyKilled(Killer, Killed, KilledPawn, damageTyp);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// logic flow control
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Navigation
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Movement
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
function StopMovement(optional EActionPriority ActionPriority = AP_Logic)
|
||||
{
|
||||
if(MovementPlugin != None)
|
||||
{
|
||||
MovementPlugin.AbortMove(FALSE);
|
||||
}
|
||||
|
||||
if( LeapPlugin != none )
|
||||
{
|
||||
LeapPlugin.AbortMove(FALSE);
|
||||
}
|
||||
|
||||
if( StuckFixPlugin != none )
|
||||
{
|
||||
StuckFixPlugin.AbortMove(false);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Attachments and SpecialActionSttachments
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Level progress
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Debug functions
|
||||
// ----------------------------------------------------------------------- //
|
||||
native function DrawEnemyPerception(Canvas DrawCanvas);
|
||||
|
||||
function DrawDebugTextToHud( HUD HUD, String Text, optional color TextColor );
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bAlwaysAssignEnemy=true
|
||||
bUsePerceptionHearing=false
|
||||
|
||||
// this one is a legacy thing - this needs to be true even for AI actors
|
||||
// because only then PlayerReplicationInfo will be created - teams for example need that
|
||||
// @todo - really needs to be refactored, but can be soooo tricky
|
||||
//bIsPlayer=TRUE
|
||||
|
||||
MovementPlugin=None
|
||||
//MovementPluginClass="AIPluginMovement_Recast"
|
||||
}
|
229
BaseAI/Classes/BaseAIPawn.uc
Normal file
229
BaseAI/Classes/BaseAIPawn.uc
Normal file
@ -0,0 +1,229 @@
|
||||
//=============================================================================
|
||||
// BaseAIPawn
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class BaseAIPawn extends GamePawn
|
||||
dependson(BaseAITypes)
|
||||
config(Game)
|
||||
native
|
||||
abstract
|
||||
notplaceable
|
||||
nativereplication;
|
||||
|
||||
var transient BaseAIController MyBaseAI;
|
||||
|
||||
/** remembers the team we were on pre-death as our PlayerReplicationInfo will be disconnected
|
||||
* mz> reused as simple team number cache, moved from KFPawn.uc
|
||||
*/
|
||||
var byte LastTeamNum;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Breadcrumbs
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// mz> chaning this remember to change 'kBreadCrumbsMax' in BreadCrumbs struct (below)
|
||||
const kBreadCrumbsMax = 10;
|
||||
|
||||
struct native Breadcrumbs
|
||||
{
|
||||
var transient vector Crumbs[kBreadCrumbsMax];
|
||||
var transient byte CurrentCrumb;
|
||||
var float CrumbDistanceSq;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
// added this way since script consts were unsuable in this case
|
||||
enum
|
||||
{
|
||||
kBreadCrumbsMax = 10
|
||||
};
|
||||
|
||||
FBreadcrumbs()
|
||||
{
|
||||
appMemzero(this, sizeof(FBreadcrumbs));
|
||||
}
|
||||
|
||||
FBreadcrumbs(EEventParm)
|
||||
{
|
||||
appMemzero(this, sizeof(FBreadcrumbs));
|
||||
}
|
||||
|
||||
void Init(const FVector& Location, FLOAT inCrumbDistanceSq=10000.f)
|
||||
{
|
||||
for(INT i = 0; i < kBreadCrumbsMax; ++i)
|
||||
{
|
||||
Crumbs[i] = Location;
|
||||
}
|
||||
|
||||
CrumbDistanceSq = inCrumbDistanceSq;
|
||||
}
|
||||
|
||||
void UpdateCrumbs(const FVector& Location)
|
||||
{
|
||||
if(Crumbs[CurrentCrumb].DistanceSquared(Location) >= CrumbDistanceSq)
|
||||
{
|
||||
const BYTE newCrumb = (CurrentCrumb + 1) % kBreadCrumbsMax;
|
||||
Crumbs[newCrumb] = Location;
|
||||
CurrentCrumb = newCrumb;
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE FVector GetOldestCrumb() const
|
||||
{
|
||||
return Crumbs[(CurrentCrumb + 1) % kBreadCrumbsMax];
|
||||
}
|
||||
|
||||
FVector GetNthCrumb(INT N) const
|
||||
{
|
||||
return N >= kBreadCrumbsMax ? GetOldestCrumb() : Crumbs[(CurrentCrumb + kBreadCrumbsMax - N) % kBreadCrumbsMax];
|
||||
}
|
||||
}
|
||||
|
||||
structdefaultproperties
|
||||
{
|
||||
CrumbDistanceSq=10000.f
|
||||
}
|
||||
};
|
||||
|
||||
var transient BreadCrumbs MyBreadCrumbs;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Target selection/limitation
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
/** Cached value for damage config: AI type */
|
||||
var transient /*const*/ byte MyAIType;
|
||||
|
||||
/** Array of all pawns attacking this controller.*/
|
||||
var const array<BaseAIPawn> Attackers;
|
||||
var const array<INT> AttackersPerTypeCount;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Animation related
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// members moved from GearPawn
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Plugins
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
var transient bool bLeaping;
|
||||
var transient float TimeStartedLeap;
|
||||
var transient float TimeImmuneWhileLeaping;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual void PostBeginPlay();
|
||||
virtual void PostScriptDestroyed();
|
||||
virtual UBOOL Tick(FLOAT DeltaTime, enum ELevelTick TickType);
|
||||
|
||||
void AddAttacker(class ABaseAIPawn* Attacker);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Properties interface
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Weapon handling
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Pawn overrides
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLocation)
|
||||
{
|
||||
`if(`notdefined(__TW_BASEAI_LEAN_))
|
||||
AbortSOUsage();
|
||||
`endif
|
||||
|
||||
class'BaseAISubsystem'.static.DecreaseTeamSize(GetTeamNum());
|
||||
if(MyBaseAI != None && MyBaseAI.Enemy != None)
|
||||
{
|
||||
BaseAIPawn(MyBaseAI.Enemy).RemoveAttacker(self);
|
||||
}
|
||||
|
||||
return Super.Died(Killer,damageType,HitLocation);
|
||||
}
|
||||
|
||||
function PossessedBy(Controller C, bool bVehicleTransition)
|
||||
{
|
||||
Super.PossessedBy(C, bVehicleTransition);
|
||||
MyBaseAI = BaseAIController(C);
|
||||
|
||||
// BaseAIPawn subclasses actually do get possessed by players!
|
||||
if ( MyBaseAI != None )
|
||||
{
|
||||
LastTeamNum = MyBaseAI.GetTeamNum();
|
||||
}
|
||||
}
|
||||
|
||||
function UnPossessed()
|
||||
{
|
||||
MyBaseAI = None;
|
||||
|
||||
super.UnPossessed();
|
||||
`if(`notdefined(__TW_BASEAI_LEAN_))
|
||||
if (AnimationProxy != None)
|
||||
{
|
||||
AnimationProxy.UnPossessed();
|
||||
}
|
||||
`endif
|
||||
}
|
||||
|
||||
simulated function NotifyTeamChanged()
|
||||
{
|
||||
Super.NotifyTeamChanged();
|
||||
|
||||
LastTeamNum = GetTeamNum();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Readabilities (Chatter too)
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Target selection/limitation
|
||||
// ----------------------------------------------------------------------- //
|
||||
/**
|
||||
* @param AIType specifies what type of attackers is of interest, -1 means all
|
||||
* @return number of Pawns of given type (or all if AIType == -1) attacking this controller
|
||||
*/
|
||||
native final function int GetAttackerCount(optional int AIType = -1) const;
|
||||
|
||||
native final function RemoveAttacker(BaseAIPawn Attacker);
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// level progress stuff
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// movement
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// debug
|
||||
// ----------------------------------------------------------------------- //
|
||||
final native function DrawCrumbs(HUD HUD) const;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
`if(`notdefined(__TW_BASEAI_LEAN_))
|
||||
AISelectionModifier=1.0
|
||||
AimAccuracy=Accuracy_Normal
|
||||
bUseAnimationProxy=true
|
||||
MovementProps=(bStartMovementShooting=true, bStartMovementShootingOnRepath=false, bEndMovementShooting=true, bCanCombatWalk=true)
|
||||
bHasAISelectionModifierPerTeam=false
|
||||
`endif
|
||||
|
||||
bCanBeAdheredTo=TRUE
|
||||
bCanBeFrictionedTo=TRUE
|
||||
}
|
79
BaseAI/Classes/BaseAISquad.uc
Normal file
79
BaseAI/Classes/BaseAISquad.uc
Normal file
@ -0,0 +1,79 @@
|
||||
//=============================================================================
|
||||
// AnimationProxy
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class BaseAISquad extends Info
|
||||
native;
|
||||
|
||||
/** Controller for leader of the squad */
|
||||
var() editconst Controller Leader;
|
||||
var() editconst Actor FormationCenter;
|
||||
|
||||
/** whether this squad has a human controlled player in it */
|
||||
var bool bPlayerSquad;
|
||||
|
||||
var bool bIsMP;
|
||||
|
||||
var transient bool bSquadInCombat;
|
||||
|
||||
var transient float NextEnemySelectionTimestamp;
|
||||
/** Call UpdateEnemySelection every X seconds*/
|
||||
var float EnemySelectionInterval;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual void TickSpecial(FLOAT DeltaSeconds);
|
||||
}
|
||||
|
||||
/** Called immediately after gameplay begins. */
|
||||
event PostBeginPlay()
|
||||
{
|
||||
super.PostBeginPlay();
|
||||
|
||||
class'BaseAISubsystem'.static.RegisterSquad(self);
|
||||
|
||||
bIsMP = WorldInfo.GRI.IsMultiplayerGame();
|
||||
}
|
||||
|
||||
event Destroyed()
|
||||
{
|
||||
class'BaseAISubsystem'.static.UnRegisterSquad(self);
|
||||
|
||||
super.Destroyed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by BaseAISubsystem to update enemy info
|
||||
* @return true if given pawn was on squad's enemy list, false otherwise
|
||||
*/
|
||||
native function bool NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn, class<DamageType> damageType);
|
||||
|
||||
/**
|
||||
* Called by PluginSquad
|
||||
*/
|
||||
final native function EnemyPerceivedBy(Controller Member, EWSPerceptionMode PerceptionType, Pawn Enemy);
|
||||
|
||||
native function UpdateLeader(Controller inLeader);
|
||||
|
||||
native function int GetSquadMemberCount() const;
|
||||
native function bool GetSquadMembers(out array<BaseAIPawn> Members);
|
||||
/** Returns FormationCenter when not in combat, and Leader pawn if in combat.
|
||||
* @note could add a flag toggling this behavior. No need for it at the moment
|
||||
*/
|
||||
native final function BaseAIPawn GetSquadCenterPawn();
|
||||
|
||||
/** picks target/enemy for all squad members with BaseAIController.bSquadBasedEnemySelection == true
|
||||
* @return TRUE if any work has been done, and there is a point in re-calling this in some time
|
||||
*/
|
||||
native function bool UpdateEnemySelection();
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
EnemySelectionInterval=0.4f
|
||||
bIsMP=false
|
||||
}
|
114
BaseAI/Classes/BaseAISubsystem.uc
Normal file
114
BaseAI/Classes/BaseAISubsystem.uc
Normal file
@ -0,0 +1,114 @@
|
||||
//=============================================================================
|
||||
// AnimationProxy
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class BaseAISubsystem extends AISubsystem
|
||||
config(Engine)
|
||||
native
|
||||
inherits(FCallbackEventDevice,FTickableObject);
|
||||
|
||||
var AIDebugTool AIDebug;
|
||||
|
||||
var const array<BaseAISquad> Squads;
|
||||
|
||||
var const array<INT> TeamSizes;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// @deprecated with __TW_BASEAI_LEAN_
|
||||
// ----------------------------------------------------------------------- //
|
||||
`if(`notdefined(__TW_BASEAI_LEAN_))
|
||||
var ETQSystem ETQSys;
|
||||
var BTManager BTMgr;
|
||||
var MessageSystem MsgSys;
|
||||
var NavigationSystem NavSys;
|
||||
var DigitalActingManager DAM;
|
||||
var SightSystem SightSys;
|
||||
|
||||
var const SmartObjectReplicationActor SmartObjectReplication;
|
||||
var const array<SOHubComponent> SmartObjects;
|
||||
var const array<SOHubComponent> InitPendingSmartObjects;
|
||||
var const array<CoverLink> SpawnedCovers;
|
||||
var const array<AIAvoidanceComponent> AvoidanceComponents;
|
||||
|
||||
native static final noexport function ETQSystem GetETQSystem();
|
||||
native static final noexport function BTManager GetBTManager();
|
||||
native static final noexport function MessageSystem GetMessageSystem();
|
||||
native static final noexport function NavigationSystem GetNavigationSystem();
|
||||
native static final noexport function DigitalActingManager GetDAM();
|
||||
native static final noexport function SightSystem GetSightSystem();
|
||||
|
||||
native static final noexport function RegisterSmartObject(SOHubComponent SO);
|
||||
native static final noexport function UnRegisterSmartObject(SOHubComponent SO);
|
||||
|
||||
native static final noexport function RegisterSpawnedCover(CoverLink Cover);
|
||||
native static final noexport function UnRegisterSpawnedCover(CoverLink Cover);
|
||||
|
||||
native static final noexport function RegisterAvoidanceComponent(AIAvoidanceComponent AvoidanceComponent);
|
||||
native static final noexport function UnRegisterAvoidanceComponent(AIAvoidanceComponent AvoidanceComponent);
|
||||
`endif
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// END __TW_BASEAI_LEAN_
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
native static final noexport function BaseAISubsystem GetInstance();
|
||||
native static final noexport function AIDebugTool GetAIDebugTool();
|
||||
|
||||
native static final noexport function RegisterSquad(BaseAISquad Squad);
|
||||
native static final noexport function UnRegisterSquad(BaseAISquad Squad);
|
||||
|
||||
native static final noexport function IncreaseTeamSize(BYTE TeamId);
|
||||
native static final noexport function DecreaseTeamSize(BYTE TeamId);
|
||||
native static final noexport function int GetTeamSize(byte TeamId);
|
||||
native static final noexport function int GetEnemyTeamsSize(byte TeamId);
|
||||
|
||||
//NotifyKilled(Controller Killer, Controller Killed, pawn KilledPawn, class<DamageType> damageType)
|
||||
native static final function NotifyKilled(Controller Killer, Controller KilledController, Pawn KilledPawn, class<DamageType> damageType);
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual void Init(UBOOL bEngineStart = FALSE);
|
||||
virtual void Tick(FLOAT DeltaSeconds);
|
||||
virtual void CleanUp(UBOOL bShutDown = FALSE);
|
||||
virtual void PrepareMapChange();
|
||||
virtual void OnLevelStreamedOut(ULevel* Level);
|
||||
|
||||
static UAIDebugTool* GetAIDebugTool(void);
|
||||
|
||||
static void RegisterSquad(class ABaseAISquad* Squad);
|
||||
static void UnRegisterSquad(class ABaseAISquad* Squad);
|
||||
static TArray<ABaseAISquad*>* GetSquads();
|
||||
|
||||
static void ObjectDestroyed(UObject* Object);
|
||||
|
||||
static void IncreaseTeamSize(BYTE TeamId);
|
||||
static void DecreaseTeamSize(BYTE TeamId);
|
||||
|
||||
static void OnPawnDestroyed(class ABaseAIPawn* Pawn);
|
||||
void OnCheckPointLoad();
|
||||
|
||||
private:
|
||||
void DecreaseTeamSizeInternal(BYTE TeamId);
|
||||
public:
|
||||
static int GetTeamSize(BYTE TeamId);
|
||||
static int GetEnemyTeamsSize(BYTE TeamId, BYTE TeamIdLimit = 255);
|
||||
|
||||
//-- editor related methods --//
|
||||
void OnPIEEnd();
|
||||
void OnPIEMapSwitch();
|
||||
|
||||
virtual void Send(ECallbackEventType InType);
|
||||
virtual void Send(ECallbackEventType InType, DWORD Flags);
|
||||
|
||||
virtual UBOOL IsTickable() const { return TRUE; }
|
||||
};
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bImplementsNavMeshGeneration=true
|
||||
}
|
105
BaseAI/Classes/BaseAITypes.uc
Normal file
105
BaseAI/Classes/BaseAITypes.uc
Normal file
@ -0,0 +1,105 @@
|
||||
//=============================================================================
|
||||
// BaseAITypes
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class BaseAITypes extends Object
|
||||
native(Types)
|
||||
abstract
|
||||
config(AI);
|
||||
|
||||
enum EActionPriority
|
||||
{
|
||||
AP_Invalid,
|
||||
AP_Logic,
|
||||
AP_Kismet, // default GoW priority, not only for kismet
|
||||
AP_Reaction,
|
||||
};
|
||||
|
||||
enum EBaseMoveMood
|
||||
{
|
||||
BMM_Invalid,
|
||||
BMM_Static,
|
||||
BMM_Slow,
|
||||
BMM_Normal,
|
||||
BMM_Fast,
|
||||
};
|
||||
|
||||
enum EBaseMoveType
|
||||
{
|
||||
BMT_Invalid,
|
||||
BMT_Normal,
|
||||
BMT_Combat,
|
||||
BMT_Careful,
|
||||
BMT_Pain,
|
||||
};
|
||||
|
||||
enum EWSPerceptionMode
|
||||
{
|
||||
WSPM_None,
|
||||
WSPM_Memory,
|
||||
WSPM_Belief,
|
||||
WSPM_Hearing,
|
||||
WSPM_Sight,
|
||||
};
|
||||
|
||||
enum EWSSymbolicAngle
|
||||
{
|
||||
WSSA_Front,
|
||||
WSSA_Side,
|
||||
WSSA_Back,
|
||||
WSSA_Unknown,
|
||||
};
|
||||
|
||||
enum EBTResult
|
||||
{
|
||||
BTR_Error,
|
||||
BTR_Abort,
|
||||
BTR_Fail,
|
||||
BTR_Success,
|
||||
BTR_NotFinished,
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// Debug types
|
||||
// ----------------------------------------------------------------------- //
|
||||
enum EDebugLineType
|
||||
{
|
||||
DLT_Generic,
|
||||
DLT_InstantFire,
|
||||
DLT_NoPath,
|
||||
DLT_LeaderFollowing,
|
||||
DLT_Failed,
|
||||
DLT_Red,
|
||||
DLT_Green,
|
||||
DLT_Blue,
|
||||
};
|
||||
|
||||
struct native SpaceLineInfo
|
||||
{
|
||||
var vector Start;
|
||||
var vector End;
|
||||
var EDebugLineType Type;
|
||||
var init string Comment;
|
||||
var native Name Category;
|
||||
|
||||
structcpptext
|
||||
{
|
||||
/** Constructors */
|
||||
FSpaceLineInfo() {}
|
||||
FSpaceLineInfo(EEventParm)
|
||||
{
|
||||
appMemzero(this, sizeof(FSpaceLineInfo));
|
||||
}
|
||||
FSpaceLineInfo(FVector inStart,FVector inEnd,BYTE inType, const FString& inComment,FName inCategory=NAME_None)
|
||||
: Start(inStart), End(inEnd), Type(inType), Comment(inComment), Category(inCategory)
|
||||
{}
|
||||
}
|
||||
};
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
111
BaseAI/Classes/BaseAiPlugInHistory.uc
Normal file
111
BaseAI/Classes/BaseAiPlugInHistory.uc
Normal file
@ -0,0 +1,111 @@
|
||||
//=============================================================================
|
||||
// BaseAiPlugInHistory
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class BaseAiPlugInHistory extends Object
|
||||
native(Plugin)
|
||||
dependson(PluginBase);
|
||||
|
||||
|
||||
struct native BaseAIPlugInHistoryItem
|
||||
{
|
||||
var class<AICommandBase> PlugInClass;
|
||||
var string PlugInName;
|
||||
var float TimeStamp; // World time command was started
|
||||
var float Duration; // Total time spent in the command
|
||||
var bool bAborted; // Command was aborted (which is often fine and intentional depending on the context) (TODO:Change to bytes)
|
||||
var bool bFailure; // Command failed (this is also not necessarily bad, at times it's expected)
|
||||
var bool bSuccess; // Command succeeded
|
||||
var string VerboseString; // Optional extra info that can be added
|
||||
|
||||
};
|
||||
|
||||
var transient array<BaseAIPlugInHistoryItem> PlugInHistory;
|
||||
var int PlugInHistoryNum;
|
||||
|
||||
var BaseAIController CtrlOwner;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual void StorePlugInHistory( UPluginBase* ThePlugIn );
|
||||
}
|
||||
|
||||
event Setup( int InPlugInHistoryNum, BaseAIController InCtrlOwner )
|
||||
{
|
||||
PlugInHistoryNum = InPlugInHistoryNum;
|
||||
CtrlOwner = InCtrlOwner;
|
||||
}
|
||||
|
||||
simulated function DrawDebugToHud( HUD HUD, name Category )
|
||||
{
|
||||
//local KFHUDBase kfHUD;
|
||||
local int plugInCnt;
|
||||
local Canvas canToUse;
|
||||
//local BaseAICommand Cmd;
|
||||
local BaseAIPlugInHistoryItem plugInItem;
|
||||
//local bool bDrawDebugCommandStack, bDrawDebugCommandHistory;
|
||||
//local bool bDrawDebugAllPlugins, bDrawDebugPlugInHistory;
|
||||
//local string AddTxt, NullTxt;
|
||||
//local AICommand AC;
|
||||
|
||||
//kfHUD = KFHUDBase(kfHud);
|
||||
////local float Aggression;
|
||||
//bDrawDebugCommandStack = false;
|
||||
//bDrawDebugCommandHistory = false;
|
||||
|
||||
// if( Category == 'Default' || Category == 'All' || Category == 'OverheadNames' )
|
||||
// {
|
||||
// bDrawDebugCommandStack = false;
|
||||
// bDrawDebugCommandHistory = false;
|
||||
// Icon = Texture2D'ENG_EditorResources_TEX.AI.S_AI';
|
||||
// DrawIconOverhead(HUD, Icon);
|
||||
// return;
|
||||
// }
|
||||
// if( bDebug_ShowViewCone )
|
||||
// {
|
||||
// if( MyKFPawn != None )
|
||||
// {
|
||||
// tmp = MyKFPawn.GetPawnViewLocation();
|
||||
// rot = MyKFPawn.GetBaseAimRotation();
|
||||
// }
|
||||
// DrawDebugCone(tmp ,vector( rot),Pawn .SightRadius, Acos(Pawn .PeripheralVision), Acos(Pawn .PeripheralVision),16,MakeColor(255,0,0,255));
|
||||
// }
|
||||
|
||||
//return;
|
||||
// NullTxt = "None";
|
||||
// Draw list of commands down the side of the screen
|
||||
if( /*Pawn != None && Category == 'All'*/ true )
|
||||
{
|
||||
canToUse = HUD.Canvas;
|
||||
canToUse.SetOrigin(0,0);
|
||||
canToUse.Font = class'Engine'.Static.GetSmallFont();
|
||||
canToUse.SetPos(canToUse.SizeX * 0.05f, canToUse.SizeY * 0.25f);
|
||||
|
||||
// WRITE OUT COMMAND HISTORY
|
||||
// C.SetDrawColor(255, 255, 255, 255);
|
||||
CtrlOwner.DrawDebugTextToHud( HUD, "************************************************************" );
|
||||
//C.SetDrawColor(0, 0, 255, 255);
|
||||
CtrlOwner.DrawDebugTextToHud( HUD, "PLUG IN HISTORY (Count:"@PlugInHistoryNum$")" );
|
||||
plugInCnt = 0;
|
||||
foreach PlugInHistory( plugInItem )
|
||||
{
|
||||
plugInCnt++;
|
||||
// C.SetDrawColor(255, 0, 0, 255);
|
||||
CtrlOwner.DrawDebugTextToHud( HUD, "PlugIn"@plugInCnt$":"@String(plugInItem.PlugInClass)@"Time:"@plugInItem.TimeStamp);
|
||||
if( Len(plugInItem.VerboseString) > 0 )
|
||||
{
|
||||
// C.SetDrawColor(255, 64, 64, 255);
|
||||
CtrlOwner.DrawDebugTextToHud( HUD, ".............."@plugInItem.VerboseString );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
PlugInHistoryNum=25
|
||||
}
|
25
BaseAI/Classes/CodeSpeedTestCommandlet.uc
Normal file
25
BaseAI/Classes/CodeSpeedTestCommandlet.uc
Normal file
@ -0,0 +1,25 @@
|
||||
//=============================================================================
|
||||
// AnimationProxy
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class CodeSpeedTestCommandlet extends Commandlet
|
||||
native;
|
||||
|
||||
var transient object CurrentPackage;
|
||||
|
||||
cpptext
|
||||
{
|
||||
/**
|
||||
* Commandlet entry point
|
||||
*
|
||||
* @param Params the command line parameters that were passed in.
|
||||
*
|
||||
* @return 0 if the commandlet succeeded; otherwise, an error code defined by the commandlet.
|
||||
*/
|
||||
virtual INT Main(const FString& Params);
|
||||
};
|
13
BaseAI/Classes/LatentActionObserver.uc
Normal file
13
BaseAI/Classes/LatentActionObserver.uc
Normal file
@ -0,0 +1,13 @@
|
||||
//=============================================================================
|
||||
// AnimationProxy
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
interface LatentActionObserver
|
||||
native;
|
||||
|
||||
native function OnLatentFinished(BaseAIController Observer, Object Action, byte FinishResult);
|
64
BaseAI/Classes/NavigationPath.uc
Normal file
64
BaseAI/Classes/NavigationPath.uc
Normal file
@ -0,0 +1,64 @@
|
||||
//=============================================================================
|
||||
// NavigationPath
|
||||
//=============================================================================
|
||||
// deprecated stub class on 6/29/2015 (script only)
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class NavigationPath extends Object;
|
||||
|
||||
struct BaseTransform
|
||||
{
|
||||
var const private{private} Actor Base;
|
||||
var const private{private} Vector InitialLocation;
|
||||
var const private{private} Rotator InitialRotation;
|
||||
// used in lazy update
|
||||
var const private{private} Vector UpdatedForLocation;
|
||||
var const private{private} Rotator UpdatedForRotation;
|
||||
// to take from initial pos into base pos
|
||||
var const private{private} Matrix InitialReversedTransform;
|
||||
// whole transform from initial pos (as in array) into world pos
|
||||
var const private{private} Matrix IBS2WSTransform;
|
||||
// reverse
|
||||
var const private{private} Matrix WS2IBSTransform;
|
||||
};
|
||||
|
||||
struct PathPoint
|
||||
{
|
||||
var Vector Location;
|
||||
var byte Flags;
|
||||
};
|
||||
|
||||
// -- not to be changed from script! -- //
|
||||
var init const array<PathPoint> PathPoints;
|
||||
|
||||
struct PolyArray_Mirror
|
||||
{
|
||||
var init array<int> Dummy;
|
||||
};
|
||||
var private const PolyArray_Mirror PolysUsed;
|
||||
|
||||
/** Base on which this path is generated. Valid if bDynamic == true. */
|
||||
var const BaseTransform Base;
|
||||
/** Destination expressed in initial navmesh position. */
|
||||
var const vector LocalDestination;
|
||||
|
||||
var private{private} const bool bDynamic;
|
||||
/** variable auto-incremented every new path is stored in this path object */
|
||||
var public{private} const int Version;
|
||||
|
||||
/**
|
||||
* Returns indexed element's position offset and rotated if necessary
|
||||
*/
|
||||
final function vector GetElementPos(int index);
|
||||
|
||||
final function SetRoute(array<PathPoint> Route);
|
||||
|
||||
/** function used to translate given location to path's generation base's space */
|
||||
final function vector WorldToLocal(vector InLocation);
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// debug stuff
|
||||
// ----------------------------------------------------------------------- //
|
||||
final function DrawPath(Canvas Canvas, optional byte R=0, optional byte G=255, optional byte B=128, optional bool bPersistent);
|
52
BaseAI/Classes/PlayerInputRecorder.uc
Normal file
52
BaseAI/Classes/PlayerInputRecorder.uc
Normal file
@ -0,0 +1,52 @@
|
||||
//=============================================================================
|
||||
// AnimationProxy
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class PlayerInputRecorder extends Object
|
||||
native(Tools);
|
||||
|
||||
static native noexport final function StartRecording(string Filename);
|
||||
static native noexport final function StopRecording();
|
||||
static native noexport final function Replay(string Filename);
|
||||
static native noexport final function StopReplay();
|
||||
|
||||
cpptext
|
||||
{
|
||||
#if HASEDITOR
|
||||
// to be specialized in Platforms' drivers
|
||||
template<typename TJoystickInfo, typename TXInputState>
|
||||
static void Replay(TJoystickInfo&, TXInputState&);
|
||||
|
||||
// to be specialized in Platforms' drivers
|
||||
template<typename TJoystickInfo, typename TXInputState>
|
||||
static void Record(TJoystickInfo&, TXInputState&);
|
||||
|
||||
// to be defined in Platforms' drivers
|
||||
static void FlushInputRecBuffer(UBOOL bFinalize);
|
||||
|
||||
static UBOOL IsRecording();
|
||||
static UBOOL IsReplaying();
|
||||
|
||||
static void StopReplay();
|
||||
static void OnReplayingStop();
|
||||
|
||||
static UBOOL ReadInRecordedPlayerInput(UBOOL bFinishing = FALSE);
|
||||
|
||||
enum
|
||||
{
|
||||
kInputRecordBufferSize = 128
|
||||
};
|
||||
|
||||
protected:
|
||||
static FString CurrentFileName;
|
||||
static UBOOL bIsInputRecording;
|
||||
static UBOOL bIsInputReplaying;
|
||||
static INT Version;
|
||||
static INT ReplayIndex;
|
||||
#endif // HASEDITOR
|
||||
};
|
14
BaseAI/Classes/PlugInOwnerInterface.uc
Normal file
14
BaseAI/Classes/PlugInOwnerInterface.uc
Normal file
@ -0,0 +1,14 @@
|
||||
//=============================================================================
|
||||
// PlugInOwnerInterface
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
interface PlugInOwnerInterface;
|
||||
|
||||
function BaseAiPlugInHistory GetAiPlugInHistory();
|
||||
|
||||
//function float GetCurrentTime();
|
||||
function float GetTimeSince( float Time2Test );
|
122
BaseAI/Classes/PluginBase.uc
Normal file
122
BaseAI/Classes/PluginBase.uc
Normal file
@ -0,0 +1,122 @@
|
||||
//=============================================================================
|
||||
// PluginBase
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class PluginBase extends Object
|
||||
abstract
|
||||
native(Plugin);
|
||||
|
||||
var PlugInOwnerInterface PlugInOwner;
|
||||
var const public{private} bool bIsPluginEnabled;
|
||||
|
||||
var bool bAborted;
|
||||
var bool bFailure;
|
||||
var bool bSuccess;
|
||||
|
||||
var BaseAiPlugInHistory OwnersAiPlugInHistory;
|
||||
var string HistoryString;
|
||||
|
||||
/** Exiting status of this plugin */
|
||||
var() transient string StatusStr;
|
||||
|
||||
cpptext
|
||||
{
|
||||
FORCEINLINE UBOOL IsPluginEnabled() const
|
||||
{
|
||||
return bIsPluginEnabled;
|
||||
}
|
||||
|
||||
virtual void CleanUp(UBOOL bBeingDestroyed) {}
|
||||
}
|
||||
|
||||
native function DisablePlugin();
|
||||
native function EnablePlugin();
|
||||
|
||||
simulated function DrawDebugToHud( HUD HUD, name Category );
|
||||
|
||||
|
||||
event ScriptInitialize()
|
||||
{
|
||||
bAborted = false;
|
||||
bFailure = false;
|
||||
bSuccess = false;
|
||||
}
|
||||
|
||||
event DrawDebug(HUD H, Name Category);
|
||||
|
||||
/*********************************************************************************************
|
||||
* Debugging
|
||||
********************************************************************************************* */
|
||||
|
||||
/** Update command history (debugging) */
|
||||
function UpdateCommandHistory()
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( PlugInOwner != none )
|
||||
{
|
||||
if( OwnersAiPlugInHistory == none )
|
||||
{
|
||||
OwnersAiPlugInHistory = PlugInOwner.GetAiPlugInHistory();
|
||||
}
|
||||
|
||||
for( i = 0; i < OwnersAiPlugInHistory.PlugInHistory.Length; i++ )
|
||||
{
|
||||
if( OwnersAiPlugInHistory.PlugInHistory[i].PlugInName != "" && OwnersAiPlugInHistory.PlugInHistory[i].PlugInName == string(name) )
|
||||
{
|
||||
if( bAborted)
|
||||
{
|
||||
OwnersAiPlugInHistory.PlugInHistory[i].bAborted = true;
|
||||
}
|
||||
if( bFailure)
|
||||
{
|
||||
OwnersAiPlugInHistory.PlugInHistory[i].bFailure = true;
|
||||
}
|
||||
if( bSuccess )
|
||||
{
|
||||
OwnersAiPlugInHistory.PlugInHistory[i].bSuccess = true;
|
||||
}
|
||||
|
||||
UpdateHistoryString( "Status: " $ StatusStr );
|
||||
//HistoryString = "Status: "$Status;
|
||||
OwnersAiPlugInHistory.PlugInHistory[i].Duration = PlugInOwner.GetTimeSince(OwnersAiPlugInHistory.PlugInHistory[i].TimeStamp);
|
||||
OwnersAiPlugInHistory.PlugInHistory[i].VerboseString = HistoryString;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the command's HistoryString, which is output when DumpCommandHistory() is called */
|
||||
function UpdateHistoryString( string AddString )
|
||||
{
|
||||
|
||||
if( PlugInOwner != none )
|
||||
{
|
||||
if( OwnersAiPlugInHistory == none )
|
||||
{
|
||||
OwnersAiPlugInHistory = PlugInOwner.GetAiPlugInHistory();
|
||||
}
|
||||
|
||||
if( OwnersAiPlugInHistory.PlugInHistoryNum > 0 )
|
||||
{
|
||||
HistoryString = HistoryString$" "$AddString;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Used when dumping command history to log file */
|
||||
event string GetDebugVerboseText()
|
||||
{
|
||||
return HistoryString;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bIsPluginEnabled=true
|
||||
HistoryString="[I]"
|
||||
}
|
26
BaseAI/Classes/PluginSquad.uc
Normal file
26
BaseAI/Classes/PluginSquad.uc
Normal file
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// AnimationProxy
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This plugin introduces squad mechanics to owning BaseAIController. This class is not the same as a squad itself,
|
||||
* it introduces actions that can be performed on a squad. Advantage of this approach is that any given BaseAIController
|
||||
* can easily change squads just by changing 'Squad' variable of its 'CoveringPlugin'.
|
||||
*/
|
||||
|
||||
class PluginSquad extends AIPlugin within BaseAIController
|
||||
native(Plugin);
|
||||
|
||||
var const BaseAISquad Squad;
|
||||
|
||||
final native function EnemyPerceived(EWSPerceptionMode PerceptionType, Pawn PerceivedEnemy);
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
66
BaseAI/Globals.uci
Normal file
66
BaseAI/Globals.uci
Normal file
@ -0,0 +1,66 @@
|
||||
//=============================================================================
|
||||
// Globals
|
||||
//=============================================================================
|
||||
// /* MessageSystem macros */
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
`define MsgSystem class'MessageSystem'.static.GetInstance()
|
||||
|
||||
|
||||
/* Behavior tree macros */
|
||||
|
||||
`if(`isdefined(FINAL_RELEASE))
|
||||
|
||||
`define BTLog(msg)
|
||||
`define BTLog_Ext(msg, object)
|
||||
|
||||
`define AILog(text)
|
||||
`define AILog(text, category)
|
||||
`define AILog(text, category, bForce)
|
||||
`define AILog_Ext(text, category, object)
|
||||
|
||||
`define AILogNativeCallStack()
|
||||
`define AILogScriptCallStack()
|
||||
`define AILogNativeCallStack_Ext(actor)
|
||||
`define AILogScriptCallStack_Ext(actor)
|
||||
`define AILogSpaceLine(Owner, Start, End)
|
||||
`define AILogSpaceLine(Owner, Start, End, Type)
|
||||
`define AILogSpaceLine(Owner, Start, End, Type, Comment)
|
||||
`define AILogSpaceLine(Owner, Start, End, Type, Comment, Category)
|
||||
|
||||
`define AILogSetContext(Owner)
|
||||
|
||||
`define DEBUGSTATE
|
||||
|
||||
`else
|
||||
|
||||
`define BTLog(msg) AILog_Internal(`msg, 'BehaviorTree')
|
||||
`define BTLog_Ext(msg, object) if (`object != none) { `object.AILog_Internal(`msg, 'BehaviorTree' ); }
|
||||
|
||||
`define StaticEngineContext class'Engine'.static.GetEngine()
|
||||
`define AILog(text) if( ! `StaticEngineContext.bDisableAILogging) {AILog_Internal(`text);}
|
||||
`define AILog(text, category) if( ! `StaticEngineContext.bDisableAILogging) {AILog_Internal(`text,`category);}
|
||||
`define AILog(text, category, bForce) if( ! `StaticEngineContext.bDisableAILogging) {AILog_Internal(`text,`category,`bForce);}
|
||||
`define AILog_Ext(text, category, object) if( !`StaticEngineContext.bDIsableAILogging && `object != None ) { `object.AILog_Internal(`text,`category); }
|
||||
|
||||
`define AILogNativeCallStack() class'BaseAISubsystem'.static.GetAIDebugTool().DumpNativeCallStack(self)
|
||||
`define AILogScriptCallStack() AILog_Internal(GetScriptTrace(),'CallStack')
|
||||
|
||||
`define AILogNativeCallStack_Ext(actor) class'BaseAISubsystem'.static.GetAIDebugTool().DumpNativeCallStack(`actor)
|
||||
`define AILogScriptCallStack_Ext(actor) `actor.AILog_Internal(GetScriptTrace(),'CallStack')
|
||||
|
||||
`define AILogSpaceLine(Owner, Start, End) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, DLT_Generic)
|
||||
`define AILogSpaceLine(Owner, Start, End, Type) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, `Type)
|
||||
`define AILogSpaceLine(Owner, Start, End, Type, Comment) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, `Type, `Comment)
|
||||
`define AILogSpaceLine(Owner, Start, End, Type, Comment, Category) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, `Type, `Comment, `Category)
|
||||
|
||||
|
||||
`define AILogSetContext(Owner) class'BaseAISubsystem'.static.GetAIDebugTool().SetContext(`Owner)
|
||||
|
||||
`define DEBUGSTATE extends DEBUGSTATE
|
||||
|
||||
`endif
|
||||
|
Reference in New Issue
Block a user