1374 lines
49 KiB
C
1374 lines
49 KiB
C
|
/*
|
||
|
================
|
||
|
|
||
|
AI.h
|
||
|
|
||
|
================
|
||
|
*/
|
||
|
|
||
|
#ifndef __AI_H__
|
||
|
#define __AI_H__
|
||
|
|
||
|
// moved all motion related code to AI_Move.h
|
||
|
#ifndef __AI_MOVE_H__
|
||
|
#include "AI_Move.h"
|
||
|
#endif
|
||
|
#ifndef __AAS_TACTICAL_H__
|
||
|
#include "AAS_tactical.h"
|
||
|
#endif
|
||
|
|
||
|
typedef enum {
|
||
|
AITACTICAL_NONE,
|
||
|
AITACTICAL_MELEE, // Rush towards the enemy and perform melee attacks when within range
|
||
|
AITACTICAL_MOVE_FOLLOW, // Move towards leader, stop when within range
|
||
|
AITACTICAL_MOVE_TETHER, // Move within tether, stop when within tether
|
||
|
AITACTICAL_MOVE_PLAYERPUSH, // Move away when the player pushes us (or another ai entity pushes us that was pushe by player)
|
||
|
AITACTICAL_COVER, // Move to cover and perform attacks from that cover position
|
||
|
AITACTICAL_COVER_FLANK,
|
||
|
AITACTICAL_COVER_ADVANCE,
|
||
|
AITACTICAL_COVER_RETREAT,
|
||
|
AITACTICAL_COVER_AMBUSH,
|
||
|
AITACTICAL_RANGED, // Move to position in which the enemy can be attacked from range, stop when there and attack enemy
|
||
|
AITACTICAL_TURRET, // Stay in current position and attack enemy
|
||
|
AITACTICAL_HIDE, // Move to a position where we cannot be seen by our enemy
|
||
|
AITACTICAL_PASSIVE, // Stay in current position with multiple idles, twitch animations, and conversations
|
||
|
|
||
|
AITACTICAL_MAX
|
||
|
} aiTactical_t;
|
||
|
|
||
|
typedef enum {
|
||
|
AICTRESULT_OK,
|
||
|
AICTRESULT_SKIP,
|
||
|
AICTRESULT_NOMOVE,
|
||
|
} aiCTResult_t;
|
||
|
|
||
|
const int AITACTICAL_NONE_BIT = BIT(AITACTICAL_NONE);
|
||
|
const int AITACTICAL_MELEE_BIT = BIT(AITACTICAL_MELEE);
|
||
|
const int AITACTICAL_MOVE_FOLLOW_BIT = BIT(AITACTICAL_MOVE_FOLLOW);
|
||
|
const int AITACTICAL_MOVE_TETHER_BIT = BIT(AITACTICAL_MOVE_TETHER);
|
||
|
const int AITACTICAL_MOVE_PLAYERPUSH_BIT = BIT(AITACTICAL_MOVE_PLAYERPUSH);
|
||
|
const int AITACTICAL_COVER_BIT = BIT(AITACTICAL_COVER);
|
||
|
const int AITACTICAL_COVER_FLANK_BIT = BIT(AITACTICAL_COVER_FLANK);
|
||
|
const int AITACTICAL_COVER_ADVANCE_BIT = BIT(AITACTICAL_COVER_ADVANCE);
|
||
|
const int AITACTICAL_COVER_RETREAT_BIT = BIT(AITACTICAL_COVER_RETREAT);
|
||
|
const int AITACTICAL_COVER_AMBUSH_BIT = BIT(AITACTICAL_COVER_AMBUSH);
|
||
|
const int AITACTICAL_RANGED_BIT = BIT(AITACTICAL_RANGED);
|
||
|
const int AITACTICAL_TURRET_BIT = BIT(AITACTICAL_TURRET);
|
||
|
const int AITACTICAL_HIDE_BIT = BIT(AITACTICAL_HIDE);
|
||
|
const int AITACTICAL_PASSIVE_BIT = BIT(AITACTICAL_PASSIVE);
|
||
|
|
||
|
const int AITACTICAL_COVER_BITS = (AITACTICAL_COVER_BIT|AITACTICAL_COVER_FLANK_BIT|AITACTICAL_COVER_ADVANCE_BIT|AITACTICAL_COVER_RETREAT_BIT|AITACTICAL_COVER_AMBUSH_BIT);
|
||
|
const int AITACTICAL_RANGED_BITS = (AITACTICAL_RANGED_BIT);
|
||
|
const int AITACTICAL_NONMOVING_BITS = (AITACTICAL_NONE_BIT|AITACTICAL_TURRET_BIT|AITACTICAL_PASSIVE_BIT);
|
||
|
|
||
|
typedef enum {
|
||
|
TALKMSG_NONE,
|
||
|
TALKMSG_PRIMARY,
|
||
|
TALKMSG_SECONDARY,
|
||
|
TALKMSG_LOOP,
|
||
|
} talkMessage_t;
|
||
|
|
||
|
typedef enum {
|
||
|
AIFLAGOVERRIDE_DAMAGE,
|
||
|
AIFLAGOVERRIDE_DISABLEPAIN,
|
||
|
AIFLAGOVERRIDE_NOTURN,
|
||
|
AIFLAGOVERRIDE_NOGRAVITY
|
||
|
} aiFlagOverride_t;
|
||
|
|
||
|
typedef enum {
|
||
|
TALK_NEVER, // Never talk to the player
|
||
|
TALK_DEAD, // Cant talk due to being dead
|
||
|
TALK_OK, // Can talk
|
||
|
TALK_FOLLOW, // Talking to will cause a follow
|
||
|
TALK_BUSY, // Cant talk right now, is busy
|
||
|
TALK_WAIT, // Wait a bit - he's probably in the middle of a conversation (this is so you can still see their names but they won't talk to you when clicked on)
|
||
|
NUM_TALK_STATES
|
||
|
} talkState_t;
|
||
|
|
||
|
//chance that AI will make an announcement when they have the option (0 - 1.0f)
|
||
|
#define AISPEAK_CHANCE 0.2f
|
||
|
|
||
|
typedef enum {
|
||
|
AIFOCUS_NONE,
|
||
|
AIFOCUS_LEADER,
|
||
|
AIFOCUS_TARGET,
|
||
|
AIFOCUS_TALK,
|
||
|
AIFOCUS_PLAYER,
|
||
|
AIFOCUS_USE_DIRECTIONAL_MOVE,
|
||
|
AIFOCUS_ENEMY = AIFOCUS_USE_DIRECTIONAL_MOVE,
|
||
|
AIFOCUS_COVER,
|
||
|
AIFOCUS_COVERLOOK,
|
||
|
AIFOCUS_HELPER,
|
||
|
AIFOCUS_TETHER,
|
||
|
AIFOCUS_MAX
|
||
|
} aiFocus_t;
|
||
|
|
||
|
typedef enum {
|
||
|
AIMOVESPEED_DEFAULT, // Choose run/walk depending on situation
|
||
|
AIMOVESPEED_RUN, // Always run
|
||
|
AIMOVESPEED_WALK, // alwasy walk
|
||
|
} aiMoveSpeed_t;
|
||
|
|
||
|
typedef struct rvAIFuncs_s {
|
||
|
rvScriptFuncUtility first_sight; // script to run when an enemy is first sighted
|
||
|
rvScriptFuncUtility sight; // script to run every time an enemy is sighted
|
||
|
rvScriptFuncUtility pain; // script to run when the AI takes pain
|
||
|
rvScriptFuncUtility damage; // script to run when the AI takes damage
|
||
|
rvScriptFuncUtility death; // script to run when the AI dies
|
||
|
rvScriptFuncUtility attack; // script to run when attacking an enemy
|
||
|
rvScriptFuncUtility init; // script to run on initialization
|
||
|
rvScriptFuncUtility onclick; // script to run when a friendly AI is clicked on
|
||
|
rvScriptFuncUtility launch_projectile; // script to run when a projectile is launched
|
||
|
rvScriptFuncUtility footstep; // script to run on a footstep
|
||
|
} rvAIFuncs_t;
|
||
|
|
||
|
typedef struct rvAICombat_s{
|
||
|
struct combatFlags_s {
|
||
|
bool ignoreEnemies :1;
|
||
|
bool alert :1;
|
||
|
bool aware :1;
|
||
|
bool tetherNoBreak :1; // Set to true to prevent enemies from breaking tethers
|
||
|
bool tetherAutoBreak :1; // Set to true to automatically break tethers when within range
|
||
|
bool tetherOutOfRange :1; // Set to true when we are out of range of our curren tether
|
||
|
bool seenEnemyDirectly :1; // Has directly seen an enemy (as opposed to having heard or been told about him)
|
||
|
bool noChatter :1; // No combat announcements
|
||
|
bool crouchViewClear :1; // Can I crouch at the position that I stopped at?
|
||
|
} fl;
|
||
|
|
||
|
float max_chasing_turn;
|
||
|
float shotAtTime;
|
||
|
float shotAtAngle;
|
||
|
idVec2 hideRange;
|
||
|
idVec2 attackRange;
|
||
|
int attackSightDelay;
|
||
|
float meleeRange;
|
||
|
float aggressiveRange; // Range to become more aggressive
|
||
|
float aggressiveScale; // Scale to use when altering numbers due to aggression
|
||
|
int investigateTime;
|
||
|
|
||
|
float visStandHeight; // Height to check enemy visibiliy while standing
|
||
|
float visCrouchHeight; // Height to check enemy visiblity while crouching
|
||
|
float visRange; // Maximum distance to check enemy visibility
|
||
|
float earRange; // Maximum distance to check hearing an enemy from
|
||
|
float awareRange; // Distance to become automatically aware of an enemy
|
||
|
|
||
|
int tacticalMaskAvailable; // Currently available tactical states
|
||
|
int tacticalMaskUpdate; // states currently being evaluated
|
||
|
aiTactical_t tacticalCurrent; // Current tactical state
|
||
|
int tacticalUpdateTime; // Last time the tacitcal state was updated (for delaying updating)
|
||
|
int tacticalPainTaken; // Amount of damage taken in the current tactical state
|
||
|
int tacticalPainThreshold; // Threshold of pain before invalidating the current tactical state
|
||
|
int tacticalFlinches; // Number of flinches that have occured at the current tactical state
|
||
|
|
||
|
float threatBase; // Base amount of threat generated by AI
|
||
|
float threatCurrent; // Current amount of threat generatd by AI based on current state
|
||
|
|
||
|
int maxLostVisTime;
|
||
|
|
||
|
int coverValidTime;
|
||
|
int maxInvalidCoverTime;
|
||
|
} rvAICombat_t;
|
||
|
|
||
|
typedef struct rvAIPain_s {
|
||
|
float threshold;
|
||
|
float takenThisFrame;
|
||
|
int lastTakenTime;
|
||
|
int loopEndTime;
|
||
|
idStr loopType;
|
||
|
} rvAIPain_t;
|
||
|
|
||
|
typedef struct rvAIEnemy_s {
|
||
|
struct flags_s {
|
||
|
bool lockOrigin :1; // Stop tracking enemy origin until state changes
|
||
|
bool dead :1; // Enemy is dead
|
||
|
bool inFov :1; // Enemy is currently in fov
|
||
|
bool sighted :1; // Enemy was sighted at least once
|
||
|
bool visible :1; // Enemy is visible?
|
||
|
} fl;
|
||
|
|
||
|
idEntityPtr<idEntity> ent;
|
||
|
int lastVisibleChangeTime; // last time the visible state of the enemy changed
|
||
|
idVec3 lastVisibleFromEyePosition; // Origin used in last successfull visibility check
|
||
|
idVec3 lastVisibleEyePosition; // Origin of last known visible eye position
|
||
|
idVec3 lastVisibleChestPosition; // Origin of last known visible chest position
|
||
|
int lastVisibleTime; // Time we last saw and enemy
|
||
|
|
||
|
idVec3 smoothedLinearVelocity;
|
||
|
idVec3 smoothedPushedVelocity;
|
||
|
float smoothVelocityRate;
|
||
|
|
||
|
idVec3 lastKnownPosition; // last place the enemy was known to be (does not mean visiblity)
|
||
|
|
||
|
float range; // range to enemy
|
||
|
float range2d; // 2d range to enemy
|
||
|
int changeTime; // Time enemy was last changed
|
||
|
int checkTime; // Time we last checked for a new enemy
|
||
|
} rvAIEnemy_t;
|
||
|
|
||
|
typedef struct rvAIPassive_s {
|
||
|
struct flags_s {
|
||
|
bool disabled :1; // No advanced passive state
|
||
|
bool multipleIdles :1; // Has multiple idle animations to play
|
||
|
bool fidget :1; // Has fidget animations
|
||
|
} fl;
|
||
|
|
||
|
idStr animIdlePrefix;
|
||
|
idStr animFidgetPrefix;
|
||
|
idStr animTalkPrefix;
|
||
|
//idStr talkPrefix;
|
||
|
|
||
|
idStr prefix;
|
||
|
idStr idleAnim;
|
||
|
int idleAnimChangeTime;
|
||
|
int fidgetTime;
|
||
|
int talkTime;
|
||
|
} rvAIPassive_t;
|
||
|
|
||
|
typedef struct rvAIAttackAnimInfo_s {
|
||
|
idVec3 attackOffset;
|
||
|
idVec3 eyeOffset;
|
||
|
} rvAIAttackAnimInfo_t;
|
||
|
|
||
|
#define AIACTIONF_ATTACK BIT(0)
|
||
|
#define AIACTIONF_MELEE BIT(1)
|
||
|
|
||
|
class rvAIActionTimer {
|
||
|
public:
|
||
|
|
||
|
rvAIActionTimer ( void );
|
||
|
|
||
|
bool Init ( const idDict& args, const char* name );
|
||
|
|
||
|
void Save ( idSaveGame *savefile ) const;
|
||
|
void Restore ( idRestoreGame *savefile );
|
||
|
|
||
|
void Clear ( int currentTime );
|
||
|
void Reset ( int currentTime, float diversity = 0.0f, float scale = 1.0f );
|
||
|
void Add ( int _time, float diversity = 0.0f );
|
||
|
|
||
|
bool IsDone ( int currentTime ) const;
|
||
|
|
||
|
int GetTime ( void ) const;
|
||
|
int GetRate ( void ) const;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
int time;
|
||
|
int rate;
|
||
|
};
|
||
|
|
||
|
ID_INLINE bool rvAIActionTimer::IsDone ( int currentTime ) const {
|
||
|
return currentTime >= time;
|
||
|
}
|
||
|
|
||
|
ID_INLINE int rvAIActionTimer::GetTime ( void ) const {
|
||
|
return time;
|
||
|
}
|
||
|
|
||
|
ID_INLINE int rvAIActionTimer::GetRate ( void ) const {
|
||
|
return rate;
|
||
|
}
|
||
|
class rvAIAction {
|
||
|
public:
|
||
|
|
||
|
rvAIAction ( void );
|
||
|
|
||
|
bool Init ( const idDict& args, const char* name, const char* defaultState, int flags );
|
||
|
|
||
|
void Save ( idSaveGame *savefile ) const;
|
||
|
void Restore ( idRestoreGame *savefile );
|
||
|
|
||
|
enum EStatus {
|
||
|
STATUS_UNUSED,
|
||
|
STATUS_OK, // action was performed
|
||
|
STATUS_FAIL_DISABLED, // action is current disabled
|
||
|
STATUS_FAIL_TIMER, // actions timer has not finished
|
||
|
STATUS_FAIL_EXTERNALTIMER, // external timer passed in to PerformAction has not finished
|
||
|
STATUS_FAIL_MINRANGE, // enemy is not within minimum range
|
||
|
STATUS_FAIL_MAXRANGE, // enemy is out of maximum range
|
||
|
STATUS_FAIL_CHANCE, // action chance check failed
|
||
|
STATUS_FAIL_ANIM, // bad animation
|
||
|
STATUS_FAIL_CONDITION, // condition given to PerformAction failed
|
||
|
STATUS_FAIL_NOENEMY, // enemy cant be attacked
|
||
|
STATUS_MAX
|
||
|
};
|
||
|
|
||
|
struct flags_s {
|
||
|
bool disabled :1; // action disabled?
|
||
|
bool noPain :1; // no pain during action
|
||
|
bool noTurn :1; // no turning during action
|
||
|
bool isAttack :1; // attack?
|
||
|
bool isMelee :1; // melee?
|
||
|
bool overrideLegs :1; // override legs on this action?
|
||
|
bool noSimpleThink :1; // dont use simple think logic for this action
|
||
|
} fl;
|
||
|
|
||
|
|
||
|
idStrList anims;
|
||
|
idStr state;
|
||
|
|
||
|
rvAIActionTimer timer;
|
||
|
|
||
|
int blendFrames;
|
||
|
int failRate;
|
||
|
|
||
|
float minRange;
|
||
|
float maxRange;
|
||
|
float minRange2d;
|
||
|
float maxRange2d;
|
||
|
|
||
|
float chance;
|
||
|
float diversity;
|
||
|
|
||
|
EStatus status;
|
||
|
};
|
||
|
|
||
|
typedef bool (idAI::*checkAction_t)(rvAIAction*,int);
|
||
|
|
||
|
class rvPlaybackDriver
|
||
|
{
|
||
|
public:
|
||
|
rvPlaybackDriver( void ) { mPlaybackDecl = NULL; mOldPlaybackDecl = NULL; }
|
||
|
|
||
|
bool Start( const char *playback, idEntity *owner, int flags, int numFrames );
|
||
|
bool UpdateFrame( idEntity *ent, rvDeclPlaybackData &out );
|
||
|
void EndFrame( void );
|
||
|
bool IsActive( void ) { return( !!mPlaybackDecl || !!mOldPlaybackDecl ); }
|
||
|
|
||
|
const char *GetDestination( void );
|
||
|
|
||
|
// cnicholson: Begin Added save/restore functionality
|
||
|
void Save ( idSaveGame *savefile ) const;
|
||
|
void Restore ( idRestoreGame *savefile );
|
||
|
// cnicholson: End Added save/restore functionality
|
||
|
|
||
|
private:
|
||
|
int mLastTime;
|
||
|
int mTransitionTime;
|
||
|
|
||
|
int mStartTime;
|
||
|
int mFlags;
|
||
|
const rvDeclPlayback *mPlaybackDecl;
|
||
|
idVec3 mOffset;
|
||
|
|
||
|
int mOldStartTime;
|
||
|
int mOldFlags;
|
||
|
const rvDeclPlayback *mOldPlaybackDecl;
|
||
|
idVec3 mOldOffset;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
idAI
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
const float AI_TURN_SCALE = 60.0f;
|
||
|
const float AI_SEEK_PREDICTION = 0.3f;
|
||
|
const float AI_FLY_DAMPENING = 0.15f;
|
||
|
const float AI_HEARING_RANGE = 2048.0f;
|
||
|
const float AI_COVER_MINRANGE = 4.0f;
|
||
|
const float AI_PAIN_LOOP_DELAY = 200;
|
||
|
const int DEFAULT_FLY_OFFSET = 68.0f;
|
||
|
|
||
|
#define ATTACK_IGNORE 0
|
||
|
#define ATTACK_ON_DAMAGE BIT(0)
|
||
|
#define ATTACK_ON_ACTIVATE BIT(1)
|
||
|
#define ATTACK_ON_SIGHT BIT(2)
|
||
|
|
||
|
// defined in script/ai_base.script. please keep them up to date.
|
||
|
|
||
|
#define DI_NODIR -1
|
||
|
|
||
|
|
||
|
//
|
||
|
// events
|
||
|
//
|
||
|
extern const idEventDef AI_DirectDamage;
|
||
|
extern const idEventDef AI_JumpFrame;
|
||
|
extern const idEventDef AI_EnableClip;
|
||
|
extern const idEventDef AI_DisableClip;
|
||
|
extern const idEventDef AI_EnableGravity;
|
||
|
extern const idEventDef AI_DisableGravity;
|
||
|
extern const idEventDef AI_EnablePain;
|
||
|
extern const idEventDef AI_DisablePain;
|
||
|
extern const idEventDef AI_EnableTarget;
|
||
|
extern const idEventDef AI_DisableTarget;
|
||
|
extern const idEventDef AI_EnableMovement;
|
||
|
extern const idEventDef AI_DisableMovement;
|
||
|
extern const idEventDef AI_Vagary_ChooseObjectToThrow;
|
||
|
extern const idEventDef AI_Speak;
|
||
|
extern const idEventDef AI_SpeakRandom;
|
||
|
extern const idEventDef AI_Attack;
|
||
|
extern const idEventDef AI_AttackMelee;
|
||
|
extern const idEventDef AI_WaitMove;
|
||
|
extern const idEventDef AI_EnableDamage;
|
||
|
extern const idEventDef AI_DisableDamage;
|
||
|
extern const idEventDef AI_LockEnemyOrigin;
|
||
|
extern const idEventDef AI_SetEnemy;
|
||
|
extern const idEventDef AI_ScriptedAnim;
|
||
|
extern const idEventDef AI_ScriptedDone;
|
||
|
extern const idEventDef AI_ScriptedStop;
|
||
|
extern const idEventDef AI_SetScript;
|
||
|
extern const idEventDef AI_BecomeSolid;
|
||
|
extern const idEventDef AI_BecomePassive;
|
||
|
extern const idEventDef AI_BecomeAggressive;
|
||
|
extern const idEventDef AI_SetHealth;
|
||
|
extern const idEventDef AI_TakeDamage;
|
||
|
extern const idEventDef AI_EnableBlink;
|
||
|
extern const idEventDef AI_DisableBlink;
|
||
|
extern const idEventDef AI_EnableAutoBlink;
|
||
|
extern const idEventDef AI_DisableAutoBlink;
|
||
|
|
||
|
class idPathCorner;
|
||
|
class idProjectile;
|
||
|
class rvSpawner;
|
||
|
class rvAIHelper;
|
||
|
class rvAITether;
|
||
|
|
||
|
class idAI : public idActor {
|
||
|
friend class rvAIManager;
|
||
|
friend class idAASFindAttackPosition;
|
||
|
public:
|
||
|
CLASS_PROTOTYPE( idAI );
|
||
|
|
||
|
idAI();
|
||
|
~idAI();
|
||
|
|
||
|
void Save ( idSaveGame *savefile ) const;
|
||
|
void Restore ( idRestoreGame *savefile );
|
||
|
|
||
|
void Spawn ( void );
|
||
|
virtual void TalkTo ( idActor *actor );
|
||
|
|
||
|
idEntity* GetEnemy ( void ) const;
|
||
|
idEntity* GetGoalEntity ( void ) const;
|
||
|
talkState_t GetTalkState ( void ) const;
|
||
|
const idVec2& GetAttackRange ( void ) const;
|
||
|
const idVec2& GetFollowRange ( void ) const;
|
||
|
int GetTravelFlags ( void ) const;
|
||
|
|
||
|
void TouchedByFlashlight ( idActor *flashlight_owner );
|
||
|
|
||
|
idEntity * FindEnemy ( bool inFov, bool forceNearest, float maxDistSqr = 0.0f );
|
||
|
void SetSpawner ( rvSpawner* _spawner );
|
||
|
rvSpawner* GetSpawner ( void );
|
||
|
|
||
|
idActor* GetLeader ( void ) const;
|
||
|
|
||
|
// Outputs a list of all monsters to the console.
|
||
|
static void List_f( const idCmdArgs &args );
|
||
|
|
||
|
|
||
|
// Add some dynamic externals for debugging
|
||
|
virtual void GetDebugInfo ( debugInfoProc_t proc, void* userData );
|
||
|
|
||
|
|
||
|
bool IsEnemyVisible ( void ) const;
|
||
|
bool InCoverMode ( void ) const;
|
||
|
bool InCrouchCoverMode ( void ) const;
|
||
|
bool LookAtCoverTall ( void ) const;
|
||
|
bool InLookAtCoverMode ( void ) const;
|
||
|
bool IsBehindCover ( void ) const;
|
||
|
bool IsLipSyncing ( void ) const;
|
||
|
bool IsSpeaking ( void ) const;
|
||
|
bool IsFacingEnt ( idEntity* targetEnt );
|
||
|
bool IsCoverValid ( void ) const;
|
||
|
virtual bool IsCrouching ( void ) const;
|
||
|
|
||
|
|
||
|
public:
|
||
|
|
||
|
idLinkList<idAI> simpleThinkNode;
|
||
|
|
||
|
// navigation
|
||
|
idAAS* aas;
|
||
|
idAASCallback* aasFind;
|
||
|
|
||
|
// movement
|
||
|
idMoveState move;
|
||
|
idMoveState savedMove;
|
||
|
|
||
|
// physics
|
||
|
idPhysics_Monster physicsObj;
|
||
|
|
||
|
// weapon/attack vars
|
||
|
bool lastHitCheckResult;
|
||
|
int lastHitCheckTime;
|
||
|
int lastAttackTime;
|
||
|
float projectile_height_to_distance_ratio; // calculates the maximum height a projectile can be thrown
|
||
|
idList<rvAIAttackAnimInfo_t> attackAnimInfo;
|
||
|
|
||
|
mutable idClipModel* projectileClipModel;
|
||
|
idEntityPtr<idProjectile> projectile;
|
||
|
|
||
|
// chatter/talking
|
||
|
int chatterTime;
|
||
|
int chatterRateCombat;
|
||
|
int chatterRateIdle;
|
||
|
talkState_t talkState;
|
||
|
idEntityPtr<idActor> talkTarget;
|
||
|
talkMessage_t talkMessage;
|
||
|
int talkBusyCount;
|
||
|
int speakTime;
|
||
|
|
||
|
// Focus
|
||
|
idEntityPtr<idEntity> lookTarget;
|
||
|
aiFocus_t focusType;
|
||
|
idEntityPtr<idEntity> focusEntity;
|
||
|
float focusRange;
|
||
|
int focusAlignTime;
|
||
|
int focusTime;
|
||
|
idVec3 currentFocusPos;
|
||
|
|
||
|
// Looking
|
||
|
bool allowJointMod;
|
||
|
int alignHeadTime;
|
||
|
int forceAlignHeadTime;
|
||
|
idAngles eyeAng;
|
||
|
idAngles lookAng;
|
||
|
idAngles destLookAng;
|
||
|
idAngles lookMin;
|
||
|
idAngles lookMax;
|
||
|
idList<jointHandle_t> lookJoints;
|
||
|
idList<idAngles> lookJointAngles;
|
||
|
float eyeVerticalOffset;
|
||
|
float eyeHorizontalOffset;
|
||
|
float headFocusRate;
|
||
|
float eyeFocusRate;
|
||
|
|
||
|
// joint controllers
|
||
|
idAngles eyeMin;
|
||
|
idAngles eyeMax;
|
||
|
jointHandle_t orientationJoint;
|
||
|
|
||
|
idEntityPtr<idEntity> pusher;
|
||
|
idEntityPtr<idEntity> scriptedActionEnt;
|
||
|
|
||
|
// script variables
|
||
|
struct aiFlags_s {
|
||
|
bool awake :1; // set to false until state_wakeup is called.
|
||
|
bool damage :1;
|
||
|
bool pain :1;
|
||
|
bool dead :1;
|
||
|
bool activated :1;
|
||
|
bool jump :1;
|
||
|
bool hitEnemy :1;
|
||
|
bool pushed :1;
|
||
|
bool disableAttacks :1;
|
||
|
bool scriptedEndWithIdle :1;
|
||
|
bool scriptedNeverDormant :1; // Prevent going dormant while in scripted sequence
|
||
|
bool scripted :1;
|
||
|
bool simpleThink :1;
|
||
|
bool ignoreFlashlight :1;
|
||
|
bool action :1;
|
||
|
bool lookAtPlayer :1;
|
||
|
bool disableLook :1;
|
||
|
bool undying :1;
|
||
|
bool tetherMover :1; // Currently using a dynamic tether to a mover
|
||
|
bool meleeSuperhero :1;
|
||
|
bool killerGuard :1; // Do 100 points of damage with each hit
|
||
|
} aifl;
|
||
|
|
||
|
//
|
||
|
// ai/ai.cpp
|
||
|
//
|
||
|
void SetAAS ( void );
|
||
|
virtual void DormantBegin ( void ); // called when entity becomes dormant
|
||
|
virtual void DormantEnd ( void ); // called when entity wakes from being dormant
|
||
|
virtual void Think ( void );
|
||
|
void Activate ( idEntity *activator );
|
||
|
virtual void Hide ( void );
|
||
|
virtual void Show ( void );
|
||
|
virtual void AdjustHealthByDamage ( int inDamage );
|
||
|
void CalculateAttackOffsets ( void );
|
||
|
|
||
|
void InitNonPersistentSpawnArgs ( void );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Speaking & Chatter
|
||
|
===============================================================================
|
||
|
*/
|
||
|
public:
|
||
|
|
||
|
bool Speak ( const char *speechDecl, bool random = false );
|
||
|
void StopSpeaking ( bool stopAnims );
|
||
|
virtual void CheckBlink ( void );
|
||
|
|
||
|
protected:
|
||
|
|
||
|
virtual bool CanPlayChatterSounds ( void ) const;
|
||
|
void UpdateChatter ( void );
|
||
|
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Movement
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
// static helper functions
|
||
|
public:
|
||
|
// Finds a path around dynamic obstacles.
|
||
|
static bool FindPathAroundObstacles ( const idPhysics *physics, const idAAS *aas, const idEntity *ignore, const idVec3 &startPos, const idVec3 &seekPos, obstaclePath_t &path );
|
||
|
// Frees any nodes used for the dynamic obstacle avoidance.
|
||
|
static void FreeObstacleAvoidanceNodes ( void );
|
||
|
// Predicts movement, returns true if a stop event was triggered.
|
||
|
static bool PredictPath ( const idEntity *ent, const idAAS *aas, const idVec3 &start, const idVec3 &velocity, int totalTime, int frameTime, int stopEvent, predictedPath_t &path, const idEntity *ignore = NULL );
|
||
|
// Return true if the trajectory of the clip model is collision free.
|
||
|
static bool TestTrajectory ( const idVec3 &start, const idVec3 &end, float zVel, float gravity, float time, float max_height, const idClipModel *clip, int clipmask, const idEntity *ignore, const idEntity *targetEntity, int drawtime );
|
||
|
// Finds the best collision free trajectory for a clip model.
|
||
|
static bool PredictTrajectory ( const idVec3 &firePos, const idVec3 &target, float projectileSpeed, const idVec3 &projGravity, const idClipModel *clip, int clipmask, float max_height, const idEntity *ignore, const idEntity *targetEntity, int drawtime, idVec3 &aimDir );
|
||
|
|
||
|
|
||
|
// special flying code
|
||
|
void AdjustFlyingAngles ( void );
|
||
|
void AddFlyBob ( idVec3 &vel );
|
||
|
void AdjustFlyHeight ( idVec3 &vel, const idVec3 &goalPos );
|
||
|
void FlySeekGoal ( idVec3 &vel, idVec3 &goalPos );
|
||
|
void AdjustFlySpeed ( idVec3 &vel );
|
||
|
void FlyTurn ( void );
|
||
|
|
||
|
// movement types
|
||
|
void Move ( void );
|
||
|
virtual void DeadMove ( void );
|
||
|
void AnimMove ( void );
|
||
|
void SlideMove ( void );
|
||
|
void PlaybackMove ( void );
|
||
|
void FlyMove ( void );
|
||
|
void StaticMove ( void );
|
||
|
void RVMasterMove ( void );
|
||
|
void SetMoveType ( moveType_t moveType );
|
||
|
//twhitaker: added custom move type
|
||
|
virtual void CustomMove ( void );
|
||
|
|
||
|
// movement actions
|
||
|
void KickObstacles ( const idVec3 &dir, float force, idEntity *alwaysKick );
|
||
|
|
||
|
// steering
|
||
|
virtual void ApplyImpulse ( idEntity *ent, int id, const idVec3 &point, const idVec3 &impulse, bool splash = false );
|
||
|
void GetAnimMoveDelta ( const idMat3 &oldaxis, const idMat3 &axis, idVec3 &delta );
|
||
|
void CheckObstacleAvoidance ( const idVec3 &goalPos, idVec3 &newPos, idReachability* goalReach=0 );
|
||
|
bool GetMovePos ( idVec3 &seekPos, idReachability** seekReach=0 );
|
||
|
|
||
|
|
||
|
// navigation
|
||
|
float TravelDistance ( const idVec3 &end ) const;
|
||
|
float TravelDistance ( const idVec3 &start, const idVec3 &end ) const;
|
||
|
float TravelDistance ( idEntity* ent ) const;
|
||
|
float TravelDistance ( idEntity* start, idEntity* end ) const;
|
||
|
int PointReachableAreaNum ( const idVec3 &pos, const float boundsScale = 2.0f ) const;
|
||
|
bool PathToGoal ( aasPath_t &path, int areaNum, const idVec3 &origin, int goalAreaNum, const idVec3 &goalOrigin ) const;
|
||
|
void BlockedFailSafe ( void );
|
||
|
|
||
|
// turning
|
||
|
void Turn ( void );
|
||
|
bool TurnToward ( float yaw );
|
||
|
bool TurnToward ( const idVec3 &pos );
|
||
|
bool TurnTowardLeader ( bool faceLeaderByDefault=false );
|
||
|
bool FacingIdeal ( void );
|
||
|
bool DirectionalTurnToward ( const idVec3 &pos );
|
||
|
|
||
|
// movement control
|
||
|
bool FaceEnemy ( void );
|
||
|
bool FaceEntity ( idEntity *ent );
|
||
|
bool SlideToPosition ( const idVec3 &pos, float time );
|
||
|
bool WanderAround ( void );
|
||
|
bool StepDirection ( float dir );
|
||
|
bool NewWanderDir ( const idVec3 &dest );
|
||
|
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Reactions
|
||
|
===============================================================================
|
||
|
*/
|
||
|
void ReactToShotAt ( idEntity* attacker, const idVec3 &origOrigin, const idVec3 &origDir );
|
||
|
void ReactToPain ( idEntity* attacker, int damage );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
AI helpers
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
void UpdateHelper ( void );
|
||
|
rvAIHelper* GetActiveHelper ( void );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Sensory Perception
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
const idVec3& LastKnownPosition ( const idEntity *ent );
|
||
|
const idVec3& LastKnownFacing ( const idEntity *ent );
|
||
|
idEntity * HeardSound ( int ignore_team );
|
||
|
int ReactionTo ( const idEntity *ent );
|
||
|
void SetLastVisibleEnemyTime ( int time=-1/* DEFAULT IS CURRENT TIME*/ );
|
||
|
bool IsEnemyRecentlyVisible ( float maxLostVisTimeScale = 1.0f ) const;
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Passive
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
void SetTalkState ( talkState_t state );
|
||
|
void SetPassivePrefix ( const char* prefix );
|
||
|
|
||
|
protected:
|
||
|
|
||
|
bool GetPassiveAnimPrefix ( const char* animName, idStr& animPrefix );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Combat
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
// enemy managment
|
||
|
bool SetEnemy ( idEntity *newEnemy );
|
||
|
void ClearEnemy ( bool dead = false );
|
||
|
|
||
|
void UpdateEnemy ( void );
|
||
|
void UpdateEnemyPosition ( bool force = true );
|
||
|
void UpdateEnemyVisibility ( void );
|
||
|
|
||
|
// Attack direction
|
||
|
bool GetAimDir ( const idVec3& source, const idEntity* aimAtEnt, const idDict* projectileDict, idEntity *ignore, idVec3 &aimDir, float aimOffset, float predict ) const;
|
||
|
void GetPredictedAimDirOffset ( const idVec3& source, const idVec3& target, float projectileSpeed, const idVec3& targetVelocity, idVec3& offset ) const;
|
||
|
|
||
|
// damage
|
||
|
virtual bool Pain ( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||
|
virtual void Killed ( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location );
|
||
|
bool CheckDeathCausesMissionFailure ( void );
|
||
|
|
||
|
// attacks
|
||
|
virtual bool Attack ( const char* attackName, jointHandle_t joint, idEntity* target, const idVec3& pushVelocity = vec3_origin );
|
||
|
virtual idProjectile* AttackRanged ( const char* attackName, const idDict* attackDict, jointHandle_t joint, idEntity* target, const idVec3& pushVelocity = vec3_origin );
|
||
|
virtual idProjectile* AttackProjectile ( const idDict* projectileDict, const idVec3 &org, const idAngles &ang );
|
||
|
virtual bool AttackMelee ( const char* attackName, const idDict* meleeDict );
|
||
|
|
||
|
void CreateProjectileClipModel ( void ) const;
|
||
|
idProjectile* CreateProjectile ( const idDict* projectileDict, const idVec3 &pos, const idVec3 &dir );
|
||
|
void RemoveProjectile ( void );
|
||
|
virtual void DamageFeedback ( idEntity *victim, idEntity *inflictor, int &damage );
|
||
|
void DirectDamage ( const char *meleeDefName, idEntity *ent );
|
||
|
bool TestMelee ( void ) const;
|
||
|
void PushWithAF ( void );
|
||
|
bool IsMeleeNeeded ( void );
|
||
|
|
||
|
// special effects
|
||
|
void GetMuzzle ( jointHandle_t joint, idVec3 &muzzle, idMat3 &axis );
|
||
|
void LerpLookAngles ( idAngles &curAngles, idAngles newAngles, float orientationJointYaw, float focusRate );
|
||
|
virtual bool UpdateAnimationControllers ( void );
|
||
|
|
||
|
// AI script state management
|
||
|
void UpdateStates ( void );
|
||
|
void UpdateFocus ( const idMat3& orientationAxis );
|
||
|
void SetFocus ( aiFocus_t focus, int time );
|
||
|
|
||
|
// event?
|
||
|
virtual void FootStep ( void );
|
||
|
|
||
|
void CreateMissile ( jointHandle_t joint );
|
||
|
void RadiusDamageFromJoint ( const char *jointname, const char *damageDefName );
|
||
|
void BecomeSolid ( void );
|
||
|
void BecomeNonSolid ( void );
|
||
|
const char * ChooseAnim ( int channel, const char *animname );
|
||
|
|
||
|
//
|
||
|
// ai/ai_events.cpp
|
||
|
//
|
||
|
public:
|
||
|
|
||
|
|
||
|
virtual bool CanTakeDamage ( void ) const;
|
||
|
virtual bool CanTakePain ( void ) const;
|
||
|
virtual bool CanTurn ( void ) const;
|
||
|
virtual bool CanMove ( void ) const;
|
||
|
virtual bool CanAnnounce ( float chance ) const;
|
||
|
|
||
|
virtual bool SkipCurrentDestination ( void ) const;
|
||
|
|
||
|
// ----------------------------- Functions ------------------------------------
|
||
|
|
||
|
virtual bool DoDormantTests ( void );
|
||
|
|
||
|
void OverrideFlag ( aiFlagOverride_t flag, bool value );
|
||
|
void RestoreFlag ( aiFlagOverride_t flag );
|
||
|
|
||
|
virtual bool SkipImpulse ( idEntity *ent, int id );
|
||
|
|
||
|
virtual const char* GetIdleAnimName ( void );
|
||
|
|
||
|
bool RespondToFlashlight ( void ) { return !aifl.ignoreFlashlight;}
|
||
|
bool ForceFaceEnemy ( void ) { return ( move.moveCommand == MOVE_TO_ENEMY ); }
|
||
|
|
||
|
bool CanBecomeSolid ( void );
|
||
|
bool CanHitEnemyFromAnim ( int animNum, idVec3 offset = vec3_origin );
|
||
|
bool CanHitEnemy ( void );
|
||
|
bool CanHitEnemyFromJoint ( const char *jointname );
|
||
|
|
||
|
float GetTurnDelta ( void );
|
||
|
|
||
|
int TestTrajectory ( const idVec3 &firePos, const idVec3 &target, const char *projectileName );
|
||
|
bool TestAnimMove ( int animNum, idEntity *ignore = NULL, idVec3 *pMoveVec = NULL );
|
||
|
void ExecScriptFunction ( rvScriptFuncUtility& func, idEntity* parm = NULL );
|
||
|
void SetLeader ( idEntity *newLeader );
|
||
|
|
||
|
int CheckMelee ( bool disableAttack );
|
||
|
bool CheckForEnemy ( bool useFov, bool force = false );
|
||
|
bool CheckForCloserEnemy ( void );
|
||
|
bool CheckForReplaceEnemy ( idEntity* replacement );
|
||
|
bool CheckForTeammateEnemy ( void );
|
||
|
|
||
|
void DrawSuspicion ( void );
|
||
|
float RateSuspiciousness ( idActor* shady, bool rateSound = false );
|
||
|
void RateSuspicionLevel ( void );
|
||
|
|
||
|
void UpdatePlayback ( idVec3 &goalPos, idVec3 &delta, idVec3 &oldorigin, idMat3 &oldaxis );
|
||
|
|
||
|
void LookAtEntity ( idEntity *ent, float duration );
|
||
|
|
||
|
// ----------------------------- Variables ------------------------------------
|
||
|
|
||
|
int actionAnimNum; // Index of animation to use for the upcoming action
|
||
|
int actionTime; // Time line for actions (time is stopped when an action is running)
|
||
|
int actionSkipTime; // Time to use if an action is skipped by another
|
||
|
|
||
|
int flagOverrides;
|
||
|
|
||
|
float announceRate; // How often (0 - 1.0f) the AI will make certain announcements.
|
||
|
|
||
|
rvAICombat_t combat; // Members related to combat state
|
||
|
rvAIPassive_t passive; // Members related to passive state
|
||
|
rvAIEnemy_t enemy; // Members related to tracking enemies
|
||
|
rvAIPain_t pain;
|
||
|
rvAIFuncs_t funcs;
|
||
|
|
||
|
rvPlaybackDriver mPlayback;
|
||
|
rvPlaybackDriver mLookPlayback;
|
||
|
|
||
|
rvAASTacticalSensor* aasSensor;
|
||
|
|
||
|
idEntityPtr<rvAITether> tether;
|
||
|
idEntityPtr<rvAIHelper> helperCurrent;
|
||
|
idEntityPtr<rvAIHelper> helperIdeal;
|
||
|
idEntityPtr<idActor> leader;
|
||
|
idEntityPtr<rvSpawner> spawner;
|
||
|
|
||
|
bool ValidateCover ( void );
|
||
|
|
||
|
virtual bool UpdateRunStatus ( void );
|
||
|
bool UpdateTactical ( int delay = 0 );
|
||
|
void ForceTacticalUpdate ( void );
|
||
|
bool UpdateTactical_r ( void );
|
||
|
virtual int FilterTactical ( int availableTactical );
|
||
|
void WakeUpTargets ( void );
|
||
|
|
||
|
virtual aiCTResult_t CheckTactical ( aiTactical_t tactical );
|
||
|
|
||
|
void Begin ( void );
|
||
|
void WakeUp ( void );
|
||
|
|
||
|
virtual void Prethink ( void );
|
||
|
virtual void Postthink ( void );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Threat Management
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
protected:
|
||
|
|
||
|
virtual void UpdateThreat ( void );
|
||
|
virtual float CalculateEnemyThreat ( idEntity* enemy );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Tethers
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
virtual bool IsTethered ( void ) const;
|
||
|
bool IsWithinTether ( void ) const;
|
||
|
rvAITether* GetTether ( void );
|
||
|
virtual void SetTether ( rvAITether* newTether );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Scripting
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
void ScriptedMove ( idEntity* destEnt, float minDist, bool endWithIdle );
|
||
|
void ScriptedFace ( idEntity* faceEnt, bool endWithIdle );
|
||
|
void ScriptedAnim ( const char* animname, int blendFrames, bool loop, bool endWithIdle );
|
||
|
void ScriptedPlaybackMove ( const char* playback, int flags, int numFrames );
|
||
|
void ScriptedPlaybackAim ( const char* playback, int flags, int numFrames );
|
||
|
void ScriptedAction ( idEntity* actionEnt, bool endWithIdle );
|
||
|
void ScriptedStop ( void );
|
||
|
|
||
|
void SetScript ( const char* scriptName, const char* funcName );
|
||
|
|
||
|
private:
|
||
|
|
||
|
bool ScriptedBegin ( bool endWithIdle, bool allowDormant = false );
|
||
|
void ScriptedEnd ( void );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Handlers
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
protected:
|
||
|
|
||
|
virtual void OnDeath ( void );
|
||
|
virtual void OnStateChange ( int channel );
|
||
|
virtual void OnUpdatePlayback ( const rvDeclPlaybackData& pbd );
|
||
|
virtual void OnEnemyChange ( idEntity* oldEnemy );
|
||
|
virtual void OnLeaderChange ( idEntity* oldLeader );
|
||
|
virtual void OnStartMoving ( void );
|
||
|
virtual void OnStopMoving ( aiMoveCommand_t oldMoveCommand );
|
||
|
virtual void OnTacticalChange ( aiTactical_t oldTactical );
|
||
|
virtual void OnFriendlyFire ( idActor* attacker );
|
||
|
virtual void OnWakeUp ( void );
|
||
|
virtual void OnTouch ( idEntity *other, trace_t *trace );
|
||
|
virtual void OnCoverInvalidated ( void );
|
||
|
virtual void OnCoverNotFacingEnemy ( void );
|
||
|
virtual void OnEnemyVisiblityChange ( bool oldVisible );
|
||
|
virtual void OnStartAction ( void );
|
||
|
virtual void OnStopAction ( void );
|
||
|
virtual void OnSetKey ( const char* key, const char* value );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Movement / Turning
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
protected:
|
||
|
|
||
|
bool StartMove ( aiMoveCommand_t command, const idVec3& goalOrigin, int goalArea, idEntity* goalEntity, aasFeature_t* feature, float range );
|
||
|
void StopMove ( moveStatus_t status );
|
||
|
|
||
|
bool MoveTo ( const idVec3 &pos, float range = 0.0f );
|
||
|
bool MoveToAttack ( idEntity *ent, int attack_anim );
|
||
|
bool MoveToTether ( rvAITether* tether );
|
||
|
virtual bool MoveToEnemy ( void );
|
||
|
bool MoveToEntity ( idEntity *ent, float range = 0.0f );
|
||
|
bool MoveToCover ( float minRange, float maxRange, aiTactical_t coverType );
|
||
|
bool MoveToHide ( void );
|
||
|
|
||
|
bool MoveOutOfRange ( idEntity *entity, float range, float minRange=0.0f );
|
||
|
|
||
|
void AnimTurn ( float angles, bool force );
|
||
|
|
||
|
bool ReachedPos ( const idVec3 &pos, const aiMoveCommand_t moveCommand, float range = 0.0f ) const;
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Debug
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
void DrawRoute ( void ) const;
|
||
|
void DrawTactical ( void );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Announcements
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
public:
|
||
|
|
||
|
bool ActorIsBehindActor ( idActor* ambusher, idActor* victim );
|
||
|
void AnnounceNewEnemy ( void );
|
||
|
void AnnounceKill ( idActor *victim );
|
||
|
void AnnounceTactical ( aiTactical_t newTactical );
|
||
|
void AnnounceSuppressed ( idActor *suppressor );
|
||
|
void AnnounceSuppressing ( void );
|
||
|
void AnnounceFlinch ( idEntity *attacker );
|
||
|
void AnnounceInjured ( void );
|
||
|
void AnnounceFriendlyFire ( idActor* attacker );
|
||
|
void AnnounceGrenade ( void );
|
||
|
void AnnounceGrenadeThrow ( void );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Actions
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
protected:
|
||
|
|
||
|
rvAIActionTimer actionTimerRangedAttack;
|
||
|
rvAIActionTimer actionTimerEvade;
|
||
|
rvAIActionTimer actionTimerSpecialAttack;
|
||
|
rvAIActionTimer actionTimerPain;
|
||
|
|
||
|
rvAIAction actionEvadeLeft;
|
||
|
rvAIAction actionEvadeRight;
|
||
|
rvAIAction actionRangedAttack;
|
||
|
rvAIAction actionMeleeAttack;
|
||
|
rvAIAction actionLeapAttack;
|
||
|
rvAIAction actionJumpBack;
|
||
|
|
||
|
bool UpdateAction ( void );
|
||
|
virtual bool CheckActions ( void );
|
||
|
virtual bool CheckPainActions ( void );
|
||
|
|
||
|
bool PerformAction ( rvAIAction* action, bool (idAI::*)(rvAIAction*,int), rvAIActionTimer* timer = NULL );
|
||
|
void PerformAction ( const char* stateName, int blendFrames = 0, bool noPain = false );
|
||
|
|
||
|
// RAVEN BEGIN
|
||
|
// twhitaker: needed this for difficulty settings
|
||
|
virtual void Event_PostSpawn ( void );
|
||
|
// RAVEN END
|
||
|
|
||
|
public:
|
||
|
|
||
|
virtual bool CheckAction_EvadeLeft ( rvAIAction* action, int animNum );
|
||
|
virtual bool CheckAction_EvadeRight ( rvAIAction* action, int animNum );
|
||
|
virtual bool CheckAction_RangedAttack ( rvAIAction* action, int animNum );
|
||
|
virtual bool CheckAction_MeleeAttack ( rvAIAction* action, int animNum );
|
||
|
bool CheckAction_LeapAttack ( rvAIAction* action, int animNum );
|
||
|
virtual bool CheckAction_JumpBack ( rvAIAction* action, int animNum );
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
Events
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
private:
|
||
|
|
||
|
// Orphaned events
|
||
|
void Event_ClosestReachableEnemyOfEntity ( idEntity *team_mate );
|
||
|
void Event_GetReachableEntityPosition ( idEntity *ent );
|
||
|
void Event_EntityInAttackCone ( idEntity *ent );
|
||
|
void Event_TestAnimMoveTowardEnemy ( const char *animname );
|
||
|
void Event_TestAnimMove ( const char *animname );
|
||
|
void Event_TestMoveToPosition ( const idVec3 &position );
|
||
|
void Event_TestMeleeAttack ( void );
|
||
|
void Event_TestAnimAttack ( const char *animname );
|
||
|
void Event_SaveMove ( void );
|
||
|
void Event_RestoreMove ( void );
|
||
|
void Event_ThrowMoveable ( void );
|
||
|
void Event_ThrowAF ( void );
|
||
|
void Event_PredictEnemyPos ( float time );
|
||
|
void Event_FindActorsInBounds ( const idVec3 &mins, const idVec3 &maxs );
|
||
|
|
||
|
void Event_Activate ( idEntity *activator );
|
||
|
void Event_Touch ( idEntity *other, trace_t *trace );
|
||
|
void Event_LookAt ( idEntity* lookAt );
|
||
|
|
||
|
void Event_SetAngles ( idAngles const &ang );
|
||
|
void Event_SetEnemy ( idEntity *ent );
|
||
|
void Event_SetHealth ( float newHealth );
|
||
|
void Event_SetTalkTarget ( idEntity *target );
|
||
|
void Event_SetTalkState ( int state );
|
||
|
void Event_SetLeader ( idEntity *newLeader );
|
||
|
void Event_SetScript ( const char* scriptName, const char* funcName );
|
||
|
void Event_SetMoveSpeed ( int speed );
|
||
|
void Event_SetPassivePrefix ( const char* prefix );
|
||
|
|
||
|
void Event_GetAngles ( void );
|
||
|
void Event_GetEnemy ( void );
|
||
|
void Event_GetLeader ( void );
|
||
|
|
||
|
void Event_Attack ( const char* attackName, const char* jointName );
|
||
|
void Event_AttackMelee ( const char *meleeDefName );
|
||
|
|
||
|
void Event_DirectDamage ( idEntity *damageTarget, const char *damageDefName );
|
||
|
void Event_RadiusDamageFromJoint ( const char *jointname, const char *damageDefName );
|
||
|
void Event_CanBecomeSolid ( void );
|
||
|
void Event_BecomeSolid ( void );
|
||
|
void Event_BecomeNonSolid ( void );
|
||
|
void Event_BecomeRagdoll ( void );
|
||
|
void Event_StopRagdoll ( void );
|
||
|
void Event_FaceEnemy ( void );
|
||
|
void Event_FaceEntity ( idEntity *ent );
|
||
|
void Event_WaitMove ( void );
|
||
|
|
||
|
void Event_BecomePassive ( int ignoreEnemies );
|
||
|
void Event_BecomeAggressive ( void );
|
||
|
|
||
|
void Event_EnableDamage ( void );
|
||
|
void Event_EnableClip ( void );
|
||
|
void Event_EnableGravity ( void );
|
||
|
void Event_EnableAFPush ( void );
|
||
|
void Event_EnablePain ( void );
|
||
|
void Event_DisableDamage ( void );
|
||
|
void Event_DisableClip ( void );
|
||
|
void Event_DisableGravity ( void );
|
||
|
void Event_DisableAFPush ( void );
|
||
|
void Event_DisablePain ( void );
|
||
|
void Event_EnableTarget ( void );
|
||
|
void Event_DisableTarget ( void );
|
||
|
void Event_TakeDamage ( float takeDamage );
|
||
|
void Event_SetUndying ( float setUndying );
|
||
|
void Event_EnableAutoBlink ( void );
|
||
|
void Event_DisableAutoBlink ( void );
|
||
|
|
||
|
void Event_LockEnemyOrigin ( void );
|
||
|
|
||
|
void Event_StopThinking ( void );
|
||
|
void Event_JumpFrame ( void );
|
||
|
void Event_RealKill ( void );
|
||
|
void Event_Kill ( void );
|
||
|
void Event_RemoveUpdateSpawner ( void );
|
||
|
void Event_AllowHiddenMovement ( int enable );
|
||
|
void Event_CanReachPosition ( const idVec3 &pos );
|
||
|
void Event_CanReachEntity ( idEntity *ent );
|
||
|
void Event_CanReachEnemy ( void );
|
||
|
|
||
|
void Event_IsSpeaking ( void );
|
||
|
void Event_IsTethered ( void );
|
||
|
void Event_IsWithinTether ( void );
|
||
|
void Event_IsMoving ( void );
|
||
|
|
||
|
void Event_Speak ( const char *speechDecl );
|
||
|
void Event_SpeakRandom ( const char *speechDecl );
|
||
|
|
||
|
void Event_ScriptedMove ( idEntity* destEnt, float minDist, bool endWithIdle );
|
||
|
void Event_ScriptedFace ( idEntity* faceEnt, bool endWithIdle );
|
||
|
void Event_ScriptedAnim ( const char* animname, int blendFrames, bool loop, bool endWithIdle );
|
||
|
void Event_ScriptedPlaybackMove ( const char* playback, int flags, int numFrames );
|
||
|
void Event_ScriptedPlaybackAim ( const char* playback, int flags, int numFrames );
|
||
|
void Event_ScriptedAction ( idEntity* actionEnt, bool endWithIdle );
|
||
|
void Event_ScriptedDone ( void );
|
||
|
void Event_ScriptedStop ( void );
|
||
|
void Event_ScriptedJumpDown ( float yaw );
|
||
|
|
||
|
void Event_FindEnemy ( float distSquare );
|
||
|
void Event_SetKey ( const char *key, const char *value );
|
||
|
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
States
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
protected:
|
||
|
|
||
|
// Wait states
|
||
|
stateResult_t State_Wait_Activated ( const stateParms_t& parms );
|
||
|
stateResult_t State_Wait_ScriptedDone ( const stateParms_t& parms );
|
||
|
stateResult_t State_Wait_Action ( const stateParms_t& parms );
|
||
|
stateResult_t State_Wait_ActionNoPain ( const stateParms_t& parms );
|
||
|
|
||
|
// Global states
|
||
|
stateResult_t State_WakeUp ( const stateParms_t& parms );
|
||
|
stateResult_t State_TriggerAnim ( const stateParms_t& parms );
|
||
|
stateResult_t State_Wander ( const stateParms_t& parms );
|
||
|
stateResult_t State_Killed ( const stateParms_t& parms );
|
||
|
stateResult_t State_Dead ( const stateParms_t& parms );
|
||
|
stateResult_t State_LightningDeath ( const stateParms_t& parms );
|
||
|
stateResult_t State_Burn ( const stateParms_t& parms );
|
||
|
stateResult_t State_Remove ( const stateParms_t& parms );
|
||
|
|
||
|
stateResult_t State_Passive ( const stateParms_t& parms );
|
||
|
|
||
|
stateResult_t State_Combat ( const stateParms_t& parms );
|
||
|
stateResult_t State_CombatCover ( const stateParms_t& parms );
|
||
|
stateResult_t State_CombatMelee ( const stateParms_t& parms );
|
||
|
stateResult_t State_CombatRanged ( const stateParms_t& parms );
|
||
|
stateResult_t State_CombatTurret ( const stateParms_t& parms );
|
||
|
virtual stateResult_t State_CombatHide ( const stateParms_t& parms );
|
||
|
|
||
|
stateResult_t State_MovePlayerPush ( const stateParms_t& parms );
|
||
|
stateResult_t State_MoveTether ( const stateParms_t& parms );
|
||
|
stateResult_t State_MoveFollow ( const stateParms_t& parms );
|
||
|
|
||
|
stateResult_t State_ScriptedMove ( const stateParms_t& parms );
|
||
|
stateResult_t State_ScriptedFace ( const stateParms_t& parms );
|
||
|
stateResult_t State_ScriptedStop ( const stateParms_t& parms );
|
||
|
stateResult_t State_ScriptedPlaybackMove ( const stateParms_t& parms );
|
||
|
stateResult_t State_ScriptedPlaybackAim ( const stateParms_t& parms );
|
||
|
stateResult_t State_ScriptedJumpDown ( const stateParms_t& parms );
|
||
|
|
||
|
// Torso States
|
||
|
stateResult_t State_Torso_Idle ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_Sight ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_CustomCycle ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_Action ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_FinishAction ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_Pain ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_ScriptedAnim ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_PassiveIdle ( const stateParms_t& parms );
|
||
|
stateResult_t State_Torso_PassiveFidget ( const stateParms_t& parms );
|
||
|
|
||
|
// Leg States
|
||
|
stateResult_t State_Legs_Idle ( const stateParms_t& parms );
|
||
|
stateResult_t State_Legs_TurnLeft ( const stateParms_t& parms );
|
||
|
stateResult_t State_Legs_TurnRight ( const stateParms_t& parms );
|
||
|
stateResult_t State_Legs_Move ( const stateParms_t& parms );
|
||
|
stateResult_t State_Legs_MoveThink ( const stateParms_t& parms );
|
||
|
stateResult_t State_Legs_ChangeDirection ( const stateParms_t& parms );
|
||
|
|
||
|
// Head states
|
||
|
stateResult_t State_Head_Idle ( const stateParms_t& parms );
|
||
|
|
||
|
CLASS_STATES_PROTOTYPE ( idAI );
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
idAI Inlines
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
ID_INLINE int DelayTime( int min, int range ) {
|
||
|
return min + gameLocal.random.RandomInt ( range + 1 );
|
||
|
}
|
||
|
|
||
|
ID_INLINE const idVec2& idAI::GetAttackRange ( void ) const {
|
||
|
return combat.attackRange;
|
||
|
}
|
||
|
|
||
|
ID_INLINE const idVec2& idAI::GetFollowRange ( void ) const {
|
||
|
return move.followRange;
|
||
|
}
|
||
|
|
||
|
ID_INLINE int idAI::GetTravelFlags ( void ) const {
|
||
|
return move.travelFlags;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::IsEnemyVisible ( void ) const {
|
||
|
return enemy.ent && enemy.fl.visible;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::IsEnemyRecentlyVisible( float maxLostVisTimeScale ) const {
|
||
|
return (enemy.ent
|
||
|
&& combat.fl.seenEnemyDirectly
|
||
|
&& (enemy.lastVisibleTime && gameLocal.time-enemy.lastVisibleTime < (combat.maxLostVisTime * maxLostVisTimeScale)));
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::LookAtCoverTall( void ) const {
|
||
|
return ( aasSensor->Look()
|
||
|
&& (aasSensor->Look()->flags&FEATURE_LOOK_OVER)
|
||
|
&& aasSensor->Look()->height > 40.0f );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::InLookAtCoverMode ( void ) const {
|
||
|
return (!IsBehindCover()
|
||
|
&& !aifl.action
|
||
|
&& move.fl.moving
|
||
|
&& (combat.fl.alert || combat.fl.aware)
|
||
|
&& aasSensor->Look()
|
||
|
&& combat.tacticalCurrent != AITACTICAL_MELEE
|
||
|
&& combat.tacticalCurrent != AITACTICAL_HIDE
|
||
|
&& !IsEnemyRecentlyVisible(0.2f));
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::InCoverMode ( void ) const {
|
||
|
return ( (1<<combat.tacticalCurrent) & AITACTICAL_COVER_BITS ) && aasSensor->Reserved ( );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::InCrouchCoverMode ( void ) const {
|
||
|
return ( InCoverMode() && (aasSensor->Reserved()->flags&FEATURE_LOOK_OVER) );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::IsBehindCover ( void ) const {
|
||
|
return ( InCoverMode() && move.fl.done && (aifl.action || DistanceTo2d ( aasSensor->ReservedOrigin() ) < AI_COVER_MINRANGE) );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::IsSpeaking ( void ) const {
|
||
|
return speakTime && gameLocal.time < speakTime;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::IsFacingEnt ( idEntity* targetEnt ) {
|
||
|
return( move.moveCommand == MOVE_FACE_ENTITY && move.goalEntity == targetEnt && FacingIdeal() );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::IsCoverValid ( ) const {
|
||
|
return combat.coverValidTime && (gameLocal.time - combat.coverValidTime < combat.maxInvalidCoverTime);
|
||
|
}
|
||
|
|
||
|
ID_INLINE idActor* idAI::GetLeader ( void ) const {
|
||
|
return leader;
|
||
|
}
|
||
|
|
||
|
ID_INLINE idEntity* idAI::GetGoalEntity ( void ) const {
|
||
|
return move.goalEntity;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::CanTakeDamage( void ) const {
|
||
|
return idActor::CanTakeDamage( );
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::CanTakePain ( void ) const {
|
||
|
return !disablePain;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::CanTurn ( void ) const {
|
||
|
return move.turnRate && !move.fl.noTurn && !move.fl.disabled;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::CanMove ( void ) const {
|
||
|
return !move.fl.disabled && !move.fl.blocked && gameLocal.GetTime()>move.blockTime;
|
||
|
}
|
||
|
|
||
|
ID_INLINE bool idAI::CanAnnounce ( float chance ) const {
|
||
|
return !aifl.dead && !IsSpeaking ( ) && !af.IsActive ( ) && !combat.fl.noChatter && ( gameLocal.random.RandomFloat() < chance );
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idAI::SetFocus ( aiFocus_t focus, int time ) {
|
||
|
focusType = focus;
|
||
|
focusTime = gameLocal.time + time;
|
||
|
}
|
||
|
|
||
|
ID_INLINE idEntity *idAI::GetEnemy( void ) const {
|
||
|
return enemy.ent;
|
||
|
}
|
||
|
|
||
|
ID_INLINE void idAI::ForceTacticalUpdate ( void ) {
|
||
|
combat.tacticalUpdateTime = 0;
|
||
|
combat.tacticalMaskUpdate = 0;
|
||
|
delete aasFind;
|
||
|
aasFind = NULL;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
===============================================================================
|
||
|
|
||
|
externs
|
||
|
|
||
|
===============================================================================
|
||
|
*/
|
||
|
|
||
|
extern const char* aiActionStatusString [ rvAIAction::STATUS_MAX ];
|
||
|
extern const char* aiTalkMessageString [ ];
|
||
|
extern const char* aiTacticalString [ AITACTICAL_MAX ];
|
||
|
extern const char* aiMoveCommandString [ NUM_MOVE_COMMANDS ];
|
||
|
extern const char* aiFocusString [ AIFOCUS_MAX ];
|
||
|
|
||
|
#endif /* !__AI_H__ */
|
||
|
|