222 lines
8.2 KiB
C
222 lines
8.2 KiB
C
|
// *************************************
|
||
|
// New AI system defines
|
||
|
|
||
|
#define MAX_CAST_GROUPS 16
|
||
|
#define MAX_CHARACTERS 64 // this includes players
|
||
|
#define DEFAULT_MAX_ATTACK_DISTANCE 1024 // stand and attack enemies within this range
|
||
|
#define DEFAULT_MAX_SIGHTING_DISTANCE 2048 // can't see things outside this range
|
||
|
|
||
|
#define FACE_ANIM_DIST 2048 // AI will play an animation to straighten while attacking if beyind this distance
|
||
|
|
||
|
#define AI_NOT_HOLSTERED_RANGE_1 200
|
||
|
#define AI_NOT_HOLSTERED_RANGE_2 384
|
||
|
#define AI_NOT_HOLSTERED_RANGE_3 800
|
||
|
|
||
|
#define ENEMY_SIGHT_DURATION 3 // enemies sighted "less than this time" ago will be attacked
|
||
|
|
||
|
#define SPAWNFLAG_IMMEDIATE_FOLLOW_PATH 32
|
||
|
|
||
|
// Cast Memory defines
|
||
|
#define NUM_MEMORY_TYPES 3
|
||
|
|
||
|
#define MEMORY_TYPE_FRIEND 0
|
||
|
#define MEMORY_TYPE_NEUTRAL 1
|
||
|
#define MEMORY_TYPE_ENEMY 2
|
||
|
|
||
|
// Pain orientation checks
|
||
|
#define ORIENTATION_CENTER 0
|
||
|
#define ORIENTATION_LEFT 1
|
||
|
#define ORIENTATION_RIGHT 2
|
||
|
|
||
|
// Player order commands
|
||
|
#define ORDER_MOVE 1
|
||
|
#define ORDER_HOLD 2
|
||
|
#define ORDER_FOLLOWME 3
|
||
|
|
||
|
// Side Trace
|
||
|
#define SIDE_RANDOM 0
|
||
|
#define SIDE_RIGHT 1
|
||
|
#define SIDE_LEFT -1
|
||
|
|
||
|
// General movement stuff
|
||
|
#define AI_TOO_CLOSE_DIST 48.0
|
||
|
#define AI_GUARDING_DIST 140.0
|
||
|
|
||
|
// ai flags
|
||
|
#define AI_NOWALK_FACE 0x00000001 // don't walk when turning to face
|
||
|
#define AI_TEMP_STAND_GROUND 0x00000002
|
||
|
#define AI_NO_TALK 0x00000004 // prevent this character from talking (good for waiting in ambush)
|
||
|
#define AI_GOAL_RUN 0x00000008 // set this for entities that the AI should run towards
|
||
|
#define AI_FACE_ATTACK 0x00000010 // always face the enemy when attacking
|
||
|
#define AI_MOVEOUT 0x00000020
|
||
|
#define AI_MELEE 0x00000040 // this character can only do melee attacks
|
||
|
#define AI_GRENADE_GUY 0x00000080
|
||
|
#define AI_DUCKATTACK 0x00000100 // only ducking for attack
|
||
|
#define AI_GOAL_IGNOREENEMY 0x00000200
|
||
|
#define AI_NOSTEP 0x00000400
|
||
|
#define AI_RELOAD 0x00000800 // need to reload before we can fire again
|
||
|
#define AI_TAKECOVER_IGNOREHEALTH 0x00001000 // don't do health checks to see if we should resume attacking
|
||
|
#define AI_GOALENT_MANUAL_CLEAR 0x00002000 // set this on the goal_ent if we should NOT set our ->goal_ent = NULL when we get there
|
||
|
#define AI_DOKEY 0x00004000
|
||
|
#define AI_IMMORTAL 0x00008000
|
||
|
#define AI_REPEAT_TALK_JESTURE 0x00010000 // keep making talking jesture
|
||
|
#define AI_SKILL_LADDER 0x00020000
|
||
|
#define AI_HOLD_POSITION 0x00040000
|
||
|
#define AI_TAKE_COVER 0x00080000
|
||
|
#define AI_IGNORE_ENEMY 0x00100000
|
||
|
#define AI_FASTWALK 0x00200000 // characters will WALK at twice the speed (including faster animation)
|
||
|
#define AI_PLAYERCLIP 0x00400000 // uses PLAYERCLIP bounding instead of MONSTERCLIP
|
||
|
#define AI_NO_TAKE_COVER 0x00800000 // don't take cover from anything
|
||
|
#define AI_ADJUSTPITCH 0x01000000 // used for dogs so they angle up for stairs, ramps, etc
|
||
|
#define AI_TALK 0x02000000 // stop "avoid walking" when we're facing the character
|
||
|
#define AI_SIDE_ATTACK 0x04000000
|
||
|
#define AI_TURN_BLOCKED 0x08000000
|
||
|
#define AI_RUN_LIKE_HELL 0x10000000
|
||
|
#define AI_RUSH_THE_PLAYER 0x20000000
|
||
|
#define AI_HEARD_GUN_SHOT 0x40000000
|
||
|
#define AI_SIT_TALK 0x80000000
|
||
|
|
||
|
|
||
|
typedef enum
|
||
|
{
|
||
|
resp_yes,
|
||
|
resp_no
|
||
|
} response_t;
|
||
|
|
||
|
|
||
|
#define STATE_NORMAL 0 // each character does their own thing
|
||
|
#define STATE_FLEE 1 // abort attack, everyone flee
|
||
|
#define STATE_CHARGE 2 // berzerk at charge_ent
|
||
|
|
||
|
// cast_group_t holds information relating to each team in the game, including fighting formations, etc
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
int state;
|
||
|
int charge_ent; // index into g_edicts[]
|
||
|
} cast_group_t;
|
||
|
|
||
|
// Memory flags
|
||
|
#define MEMORY_PERSONAL_OPINION 0x00000001 // set this if we have a personal vendetta on the character, which is not necessarily that of the group
|
||
|
#define MEMORY_CONFIDENTIAL 0x00000002 // only share this information to a fellow group member, or under extreme conditions (like we are neutral and are bribed, or we are tortured)
|
||
|
#define MEMORY_HOSTILE_ENEMY 0x00000004 // attack upon sighting this character
|
||
|
#define MEMORY_ASSHOLE 0x00000008 // we don't like this person, but they're not an enemy (just effects speech)
|
||
|
#define MEMORY_LASTWARNING 0x00000010 // we want to give a final warning to the player before we become hostile
|
||
|
#define MEMORY_UPSET 0x00000020 // will use specific upset speech
|
||
|
|
||
|
#define MEMORY_AFRAID 0x00000040
|
||
|
#define MEMORY_TAUNT 0x00000080
|
||
|
#define MEMORY_WARNED_BACKOFF 0x00000100 // we've warned this person to backoff already
|
||
|
|
||
|
#define MEMORY_HIRE_FIRST_TIME 0x00000200
|
||
|
#define MEMORY_HIRE_ASK 0x00000400
|
||
|
#define MEMORY_HIRED 0x00000800
|
||
|
#define MEMORY_NO_TALK 0x00001000 // don't talk to this person
|
||
|
#define MEMORY_STARTED_ATTACK 0x00002000 // so AI friends only attack enemies that are attacking (and not evading)
|
||
|
|
||
|
// cast_memory_t stores a particular character's memory and opinion of another cast member,
|
||
|
// for which it is aware of (has either seen, or is associated with)
|
||
|
typedef struct cast_memory_s
|
||
|
{
|
||
|
int cast_ent; // "other" character index in the g_edicts[]
|
||
|
|
||
|
vec3_t last_known_origin;
|
||
|
int flags; // deafult to 0, set various flags under certain conditions
|
||
|
int memory_type; // one of MEMORY_TYPE_* constants, defines which cast_memory type this is in, for fast references
|
||
|
|
||
|
float timestamp; // time that this information was updated
|
||
|
// (when gaining information from another character,
|
||
|
// this information is simply copied across, so we
|
||
|
// don't share information infinitely)
|
||
|
float timestamp_dist; // distance at last sighting
|
||
|
|
||
|
float not_holstered_attack_time;
|
||
|
float ignore_time; // pretend we can't see them until this time
|
||
|
|
||
|
byte inc; // this can be used for anything, like counting the times we've warned this person, etc
|
||
|
|
||
|
void (*response)(edict_t *self, edict_t *other, response_t response); // when a player talks to us, call this response routine
|
||
|
|
||
|
short last_known_closest_node; // so we can speed things up
|
||
|
|
||
|
struct cast_memory_s
|
||
|
*next, *prev;
|
||
|
} cast_memory_t;
|
||
|
|
||
|
// *************************************
|
||
|
|
||
|
// New Procedure defines
|
||
|
|
||
|
// g_ai.c
|
||
|
|
||
|
void ai_onfire_run( edict_t *self, float dist );
|
||
|
|
||
|
void ai_sidestep( edict_t *self, float dist);
|
||
|
|
||
|
void AI_CheckEvade( edict_t *self );
|
||
|
|
||
|
qboolean AI_ClearSight ( edict_t *self, edict_t *other, qboolean boxtrace );
|
||
|
|
||
|
int AI_SideTrace( edict_t *self, float dist, float inyaw, int side );
|
||
|
int AI_YawTrace( edict_t *self, float dist, float inyaw );
|
||
|
|
||
|
void AI_MoveToPlatCenter( edict_t *self, edict_t *plat);
|
||
|
qboolean AI_TooClose(edict_t *self, edict_t *goal);
|
||
|
void AI_CheckStillInair(edict_t *self);
|
||
|
qboolean AI_CheckAttack(edict_t *self);
|
||
|
void AI_StartAttack(edict_t *self, edict_t *enemy);
|
||
|
|
||
|
void AI_StartRun( edict_t *self );
|
||
|
|
||
|
void AI_CheckStillClimbingLadder( edict_t *self );
|
||
|
|
||
|
void AI_EndAttack(edict_t *self);
|
||
|
void AI_EndJump(edict_t *self);
|
||
|
void AI_EndDeath(edict_t *self);
|
||
|
void AI_EndRun(edict_t *self);
|
||
|
|
||
|
void AI_End_CrouchStand_Down(edict_t *self);
|
||
|
void AI_End_CrouchStand_Up(edict_t *self);
|
||
|
|
||
|
int AI_GetOrientation( edict_t *self, edict_t *other );
|
||
|
qboolean AI_CheckTalk( edict_t *self );
|
||
|
void AI_TalkThink( edict_t *self, qboolean ismale );
|
||
|
|
||
|
qboolean ValidBoxAtLoc(vec3_t org, vec3_t mins, vec3_t maxs, edict_t *ignore, int mask);
|
||
|
|
||
|
qboolean AI_CheckTakeCover( edict_t *self );
|
||
|
qboolean AI_ForceTakeCover( edict_t *self, edict_t *enemy, qboolean ignorehealth );
|
||
|
|
||
|
// g_ai_fight.c
|
||
|
|
||
|
qboolean AI_Goto_CombatTarget( edict_t *self );
|
||
|
qboolean AI_BeginAttack( edict_t *self );
|
||
|
qboolean AI_HasLeaderButGoForEnemy( edict_t *self, edict_t *enemy );
|
||
|
void AI_CheckMakeEnemy( edict_t *self, edict_t *other );
|
||
|
void AI_AvoidDangerousEntity( edict_t *ent );
|
||
|
|
||
|
// g_ai_memory.c
|
||
|
|
||
|
qboolean AddCharacterToGame(edict_t *self);
|
||
|
void AI_RemoveFromMemory ( edict_t *self, cast_memory_t *memory );
|
||
|
void AI_AddToMemory ( edict_t *self, cast_memory_t *memory, int memory_type );
|
||
|
void AI_InitMemory( edict_t *self );
|
||
|
void AI_UnloadCastMemory (edict_t *self);
|
||
|
|
||
|
void AI_ShareEnemies ( edict_t *self, edict_t *other );
|
||
|
void AI_RecordSighting(edict_t *src, edict_t *dest, float dist);
|
||
|
void AI_UpdateCharacterMemories( int max_iterations );
|
||
|
void AI_MakeEnemy ( edict_t *self, edict_t *other, int memory_flags );
|
||
|
|
||
|
// g_ai_ents.c
|
||
|
|
||
|
void AI_Ent_droptofloor ( edict_t *self );
|
||
|
void ai_button_think (edict_t *self);
|
||
|
void ai_button_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf);
|
||
|
|
||
|
|
||
|
|
||
|
qboolean directly_infront_angle (vec3_t ang1, edict_t *self, edict_t *other);
|
||
|
|
||
|
|