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