230 lines
6.7 KiB
Ucode
230 lines
6.7 KiB
Ucode
//=============================================================================
|
|
// 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
|
|
}
|