1 /* 2 =========================================================================== 3 Copyright (C) 2000 - 2013, Raven Software, Inc. 4 Copyright (C) 2001 - 2013, Activision, Inc. 5 Copyright (C) 2013 - 2015, OpenJK contributors 6 7 This file is part of the OpenJK source code. 8 9 OpenJK is free software; you can redistribute it and/or modify it 10 under the terms of the GNU General Public License version 2 as 11 published by the Free Software Foundation. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, see <http://www.gnu.org/licenses/>. 20 =========================================================================== 21 */ 22 23 #pragma once 24 25 //B_local.h 26 //re-added by MCG 27 28 #include "g_local.h" 29 #include "b_public.h" 30 #include "say.h" 31 32 #include "ai.h" 33 34 #define AI_TIMERS 0//turn on to see print-outs of AI/nav timing 35 // 36 // Navigation susbsystem 37 // 38 39 #define NAVF_DUCK 0x00000001 40 #define NAVF_JUMP 0x00000002 41 #define NAVF_HOLD 0x00000004 42 #define NAVF_SLOW 0x00000008 43 44 #define DEBUG_LEVEL_DETAIL 4 45 #define DEBUG_LEVEL_INFO 3 46 #define DEBUG_LEVEL_WARNING 2 47 #define DEBUG_LEVEL_ERROR 1 48 #define DEBUG_LEVEL_NONE 0 49 50 #define MAX_GOAL_REACHED_DIST_SQUARED 256//16 squared 51 #define MIN_ANGLE_ERROR 0.01f 52 53 #define MIN_ROCKET_DIST_SQUARED 16384//128*128 54 // 55 // NPC.cpp 56 // 57 // ai debug cvars 58 void SetNPCGlobals( gentity_t *ent ); 59 void SaveNPCGlobals(void); 60 void RestoreNPCGlobals(void); 61 extern void NPC_Think ( gentity_t *self); 62 63 //NPC_reactions.cpp 64 extern void NPC_Pain(gentity_t *self, gentity_t *attacker, int damage); 65 extern void NPC_Touch( gentity_t *self, gentity_t *other, trace_t *trace ); 66 extern void NPC_Use( gentity_t *self, gentity_t *other, gentity_t *activator ); 67 extern float NPC_GetPainChance( gentity_t *self, int damage ); 68 69 // 70 // NPC_misc.cpp 71 // 72 extern void Debug_Printf( vmCvar_t *cv, int level, char *fmt, ... ); 73 extern void Debug_NPCPrintf( gentity_t *printNPC, vmCvar_t *cv, int debugLevel, char *fmt, ... ); 74 75 //MCG - Begin============================================================ 76 //NPC_ai variables - shared by NPC.cpp and the following modules 77 //OJKFIXME: Should probably construct these at the NPC entry points and pass as arguments to any function that needs them 78 typedef struct npcStatic_s { 79 gentity_t *NPC; 80 gNPC_t *NPCInfo; 81 gclient_t *client; 82 usercmd_t ucmd; 83 visibility_t enemyVisibility; 84 } npcStatic_t; 85 extern npcStatic_t NPCS; 86 87 //AI_Default 88 extern qboolean NPC_CheckInvestigate( int alertEventNum ); 89 extern qboolean NPC_StandTrackAndShoot (gentity_t *NPC, qboolean canDuck); 90 extern void NPC_BSIdle( void ); 91 extern void NPC_BSPointShoot(qboolean shoot); 92 extern void NPC_BSStandGuard (void); 93 extern void NPC_BSPatrol (void); 94 extern void NPC_BSHuntAndKill (void); 95 extern void NPC_BSStandAndShoot (void); 96 extern void NPC_BSRunAndShoot (void); 97 extern void NPC_BSWait( void ); 98 extern void NPC_BSDefault( void ); 99 100 //NPC_behavior 101 extern void NPC_BSAdvanceFight (void); 102 extern void NPC_BSInvestigate (void); 103 extern void NPC_BSSleep( void ); 104 extern void NPC_BSFlee (void); 105 extern void NPC_BSFollowLeader (void); 106 extern void NPC_BSJump (void); 107 extern void NPC_BSRemove (void); 108 extern void NPC_BSSearch (void); 109 extern void NPC_BSSearchStart (int homeWp, bState_t bState); 110 extern void NPC_BSWander (void); 111 extern void NPC_BSFlee( void ); 112 extern void NPC_StartFlee( gentity_t *enemy, vec3_t dangerPoint, int dangerLevel, int fleeTimeMin, int fleeTimeMax ); 113 extern void G_StartFlee( gentity_t *self, gentity_t *enemy, vec3_t dangerPoint, int dangerLevel, int fleeTimeMin, int fleeTimeMax ); 114 115 //NPC_combat 116 extern int ChooseBestWeapon( void ); 117 extern void NPC_ChangeWeapon( int newWeapon ); 118 extern void ShootThink( void ); 119 extern void WeaponThink( qboolean inCombat ); 120 extern qboolean HaveWeapon( int weapon ); 121 extern qboolean CanShoot ( gentity_t *ent, gentity_t *shooter ); 122 extern void NPC_CheckPossibleEnemy( gentity_t *other, visibility_t vis ); 123 extern gentity_t *NPC_PickEnemy (gentity_t *closestTo, int enemyTeam, qboolean checkVis, qboolean findPlayersFirst, qboolean findClosest); 124 extern gentity_t *NPC_CheckEnemy (qboolean findNew, qboolean tooFarOk, qboolean setEnemy ); //setEnemy = qtrue 125 extern qboolean NPC_CheckAttack (float scale); 126 extern qboolean NPC_CheckDefend (float scale); 127 extern qboolean NPC_CheckCanAttack (float attack_scale, qboolean stationary); 128 extern int NPC_AttackDebounceForWeapon (void); 129 extern qboolean EntIsGlass (gentity_t *check); 130 extern qboolean ShotThroughGlass (trace_t *tr, gentity_t *target, vec3_t spot, int mask); 131 extern qboolean ValidEnemy (gentity_t *ent); 132 extern void G_ClearEnemy (gentity_t *self); 133 extern gentity_t *NPC_PickAlly ( qboolean facingEachOther, float range, qboolean ignoreGroup, qboolean movingOnly ); 134 extern void NPC_LostEnemyDecideChase(void); 135 extern float NPC_MaxDistSquaredForWeapon( void ); 136 extern qboolean NPC_EvaluateShot( int hit, qboolean glassOK ); 137 extern int NPC_ShotEntity( gentity_t *ent, vec3_t impactPos ); //impactedPos = NULL 138 139 //NPC_formation 140 extern qboolean NPC_SlideMoveToGoal (void); 141 extern float NPC_FindClosestTeammate (gentity_t *self); 142 extern void NPC_CalcClosestFormationSpot(gentity_t *self); 143 extern void G_MaintainFormations (gentity_t *self); 144 extern void NPC_BSFormation (void); 145 extern void NPC_CreateFormation (gentity_t *self); 146 extern void NPC_DropFormation (gentity_t *self); 147 extern void NPC_ReorderFormation (gentity_t *self); 148 extern void NPC_InsertIntoFormation (gentity_t *self); 149 extern void NPC_DeleteFromFormation (gentity_t *self); 150 151 #define COLLISION_RADIUS 32 152 #define NUM_POSITIONS 30 153 154 //NPC spawnflags 155 #define SFB_RIFLEMAN 2 156 #define SFB_PHASER 4 157 158 #define SFB_CINEMATIC 32 159 #define SFB_NOTSOLID 64 160 #define SFB_STARTINSOLID 128 161 162 //NPC_goal 163 extern void SetGoal( gentity_t *goal, float rating ); 164 extern void NPC_SetGoal( gentity_t *goal, float rating ); 165 extern void NPC_ClearGoal( void ); 166 extern void NPC_ReachedGoal( void ); 167 extern qboolean ReachedGoal( gentity_t *goal ); 168 extern gentity_t *UpdateGoal( void ); 169 extern qboolean NPC_ClearPathToGoal(vec3_t dir, gentity_t *goal); 170 extern qboolean NPC_MoveToGoal( qboolean tryStraight ); 171 172 //NPC_reactions 173 174 //NPC_senses 175 #define ALERT_CLEAR_TIME 200 176 #define CHECK_PVS 1 177 #define CHECK_360 2 178 #define CHECK_FOV 4 179 #define CHECK_SHOOT 8 180 #define CHECK_VISRANGE 16 181 extern qboolean CanSee ( gentity_t *ent ); 182 extern qboolean InFOV ( gentity_t *ent, gentity_t *from, int hFOV, int vFOV ); 183 extern qboolean InFOV2( vec3_t origin, gentity_t *from, int hFOV, int vFOV ); 184 extern qboolean InFOV3( vec3_t spot, vec3_t from, vec3_t fromAngles, int hFOV, int vFOV ); 185 extern visibility_t NPC_CheckVisibility ( gentity_t *ent, int flags ); 186 extern qboolean InVisrange ( gentity_t *ent ); 187 188 //NPC_spawn 189 extern void NPC_Spawn ( gentity_t *ent, gentity_t *other, gentity_t *activator ); 190 191 //NPC_stats 192 extern int NPC_ReactionTime ( void ); 193 extern qboolean NPC_ParseParms( const char *NPCName, gentity_t *NPC ); 194 extern void NPC_LoadParms( void ); 195 196 //NPC_utils 197 extern int teamNumbers[TEAM_NUM_TEAMS]; 198 extern int teamStrength[TEAM_NUM_TEAMS]; 199 extern int teamCounter[TEAM_NUM_TEAMS]; 200 extern void CalcEntitySpot ( const gentity_t *ent, const spot_t spot, vec3_t point ); 201 extern qboolean NPC_UpdateAngles ( qboolean doPitch, qboolean doYaw ); 202 extern void NPC_UpdateShootAngles (vec3_t angles, qboolean doPitch, qboolean doYaw ); 203 extern qboolean NPC_UpdateFiringAngles ( qboolean doPitch, qboolean doYaw ); 204 extern void SetTeamNumbers (void); 205 extern qboolean G_ActivateBehavior (gentity_t *self, int bset ); 206 extern void NPC_AimWiggle( vec3_t enemy_org ); 207 extern void NPC_ClearLookTarget( gentity_t *self ); 208 extern void NPC_SetLookTarget( gentity_t *self, int entNum, int clearTime ); 209 210 //g_nav.cpp 211 extern int NAV_FindClosestWaypointForEnt (gentity_t *ent, int targWp); 212 extern qboolean NAV_CheckAhead( gentity_t *self, vec3_t end, trace_t *trace, int clipmask ); 213 214 //NPC_combat 215 extern float IdealDistance ( gentity_t *self ); 216 217 //g_squad 218 extern void NPC_SetSayState (gentity_t *self, gentity_t *to, int saying); 219 220 //g_utils 221 extern qboolean G_CheckInSolid (gentity_t *self, qboolean fix); 222 223 //MCG - End============================================================ 224 225 // NPC.cpp 226 extern void NPC_SetAnim(gentity_t *ent, int type, int anim, int priority); 227 extern qboolean NPC_EnemyTooFar(gentity_t *enemy, float dist, qboolean toShoot); 228 229 // ================================================================== 230 231 //rww - special system for sync'ing bone angles between client and server. 232 void NPC_SetBoneAngles(gentity_t *ent, char *bone, vec3_t angles); 233 234 //rww - and another method of automatically managing surface status for the client and server at once 235 void NPC_SetSurfaceOnOff(gentity_t *ent, const char *surfaceName, int surfaceFlags); 236 237 extern qboolean NPC_ClearLOS( const vec3_t start, const vec3_t end ); 238 extern qboolean NPC_ClearLOS5( const vec3_t end ); 239 extern qboolean NPC_ClearLOS4( gentity_t *ent ) ; 240 extern qboolean NPC_ClearLOS3( const vec3_t start, gentity_t *ent ); 241 extern qboolean NPC_ClearLOS2( gentity_t *ent, const vec3_t end ); 242 243 extern qboolean NPC_ClearShot( gentity_t *ent ); 244 245 extern int NPC_FindCombatPoint( const vec3_t position, const vec3_t avoidPosition, vec3_t enemyPosition, const int flags, const float avoidDist, const int ignorePoint ); //ignorePoint = -1 246 247 248 extern qboolean NPC_ReserveCombatPoint( int combatPointID ); 249 extern qboolean NPC_FreeCombatPoint( int combatPointID, qboolean failed ); //failed = qfalse 250 extern qboolean NPC_SetCombatPoint( int combatPointID ); 251 252 #define CP_ANY 0 //No flags 253 #define CP_COVER 0x00000001 //The enemy cannot currently shoot this position 254 #define CP_CLEAR 0x00000002 //This cover point has a clear shot to the enemy 255 #define CP_FLEE 0x00000004 //This cover point is marked as a flee point 256 #define CP_DUCK 0x00000008 //This cover point is marked as a duck point 257 #define CP_NEAREST 0x00000010 //Find the nearest combat point 258 #define CP_AVOID_ENEMY 0x00000020 //Avoid our enemy 259 #define CP_INVESTIGATE 0x00000040 //A special point worth enemy investigation if searching 260 #define CP_SQUAD 0x00000080 //Squad path 261 #define CP_AVOID 0x00000100 //Avoid supplied position 262 #define CP_APPROACH_ENEMY 0x00000200 //Try to get closer to enemy 263 #define CP_CLOSEST 0x00000400 //Take the closest combatPoint to the enemy that's available 264 #define CP_FLANK 0x00000800 //Pick a combatPoint behind the enemy 265 #define CP_HAS_ROUTE 0x00001000 //Pick a combatPoint that we have a route to 266 #define CP_SNIPE 0x00002000 //Pick a combatPoint that is marked as a sniper spot 267 #define CP_SAFE 0x00004000 //Pick a combatPoint that is not have dangerTime 268 #define CP_HORZ_DIST_COLL 0x00008000 //Collect combat points within *horizontal* dist 269 #define CP_NO_PVS 0x00010000 //A combat point out of the PVS of enemy pos 270 #define CP_RETREAT 0x00020000 //Try to get farther from enemy 271 272 #define CPF_NONE 0 273 #define CPF_DUCK 0x00000001 274 #define CPF_FLEE 0x00000002 275 #define CPF_INVESTIGATE 0x00000004 276 #define CPF_SQUAD 0x00000008 277 #define CPF_LEAN 0x00000010 278 #define CPF_SNIPE 0x00000020 279 280 #define MAX_COMBAT_POINT_CHECK 32 281 282 extern qboolean NPC_ValidEnemy( gentity_t *ent ); 283 extern qboolean NPC_CheckEnemyExt( qboolean checkAlerts ); //checkAlerts = qfalse 284 extern qboolean NPC_FindPlayer( void ); 285 extern qboolean NPC_CheckCanAttackExt( void ); 286 287 extern int NPC_CheckAlertEvents( qboolean checkSight, qboolean checkSound, int ignoreAlert, qboolean mustHaveOwner, int minAlertLevel ); //ignoreAlert = -1, mustHaveOwner = qfalse, minAlertLevel = AEL_MINOR 288 extern qboolean NPC_CheckForDanger( int alertEvent ); 289 extern void G_AlertTeam( gentity_t *victim, gentity_t *attacker, float radius, float soundDist ); 290 291 extern int NPC_FindSquadPoint( vec3_t position ); 292 293 extern void ClearPlayerAlertEvents( void ); 294 295 extern qboolean G_BoundsOverlap(const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2); 296 extern qboolean NAV_HitNavGoal( vec3_t point, vec3_t mins, vec3_t maxs, vec3_t dest, int radius, qboolean flying ); 297 298 extern void NPC_SetMoveGoal( gentity_t *ent, vec3_t point, int radius, qboolean isNavGoal, int combatPoint, gentity_t *targetEnt ); //isNavGoal = qfalse, combatPoint = -1, targetEnt = NULL 299 300 extern qboolean NAV_ClearPathToPoint(gentity_t *self, vec3_t pmins, vec3_t pmaxs, vec3_t point, int clipmask, int okToHitEnt ); 301 extern void NPC_ApplyWeaponFireDelay(void); 302 303 //NPC_FaceXXX suite 304 extern qboolean NPC_FacePosition( vec3_t position, qboolean doPitch ); //doPitch = qtrue 305 extern qboolean NPC_FaceEntity( gentity_t *ent, qboolean doPitch ); //doPitch = qtrue 306 extern qboolean NPC_FaceEnemy( qboolean doPitch ); //doPitch = qtrue 307 308 //Skill level cvar 309 extern vmCvar_t g_npcspskill; 310 311 #define NIF_NONE 0x00000000 312 #define NIF_FAILED 0x00000001 //failed to find a way to the goal 313 #define NIF_MACRO_NAV 0x00000002 //using macro navigation 314 #define NIF_COLLISION 0x00000004 //resolving collision with an entity 315 #define NIF_BLOCKED 0x00000008 //blocked from moving 316 317 /* 318 ------------------------- 319 struct navInfo_s 320 ------------------------- 321 */ 322 323 typedef struct navInfo_s 324 { 325 gentity_t *blocker; 326 vec3_t direction; 327 vec3_t pathDirection; 328 float distance; 329 trace_t trace; 330 int flags; 331 } navInfo_t; 332 333 extern int NAV_MoveToGoal( gentity_t *self, navInfo_t *info ); 334 extern void NAV_GetLastMove( navInfo_t *info ); 335 extern qboolean NAV_AvoidCollision( gentity_t *self, gentity_t *goal, navInfo_t *info ); 336