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 #include "ai.h"
26 
27 #define NPCAI_CHECK_WEAPON		0x00000001
28 #define NPCAI_BURST_WEAPON		0x00000002
29 #define NPCAI_MOVING			0x00000004
30 #define NPCAI_TOUCHED_GOAL		0x00000008
31 #define NPCAI_PUSHED			0x00000010
32 #define NPCAI_NO_COLL_AVOID		0x00000020
33 #define NPCAI_BLOCKED			0x00000040
34 #define NPCAI_OFF_PATH			0x00000100
35 #define NPCAI_IN_SQUADPOINT		0x00000200
36 #define NPCAI_STRAIGHT_TO_DESTPOS	0x00000400
37 #define NPCAI_NO_SLOWDOWN		0x00001000
38 #define NPCAI_LOST				0x00002000	//Can't nav to his goal
39 #define NPCAI_SHIELDS			0x00004000	//Has shields, borg can adapt
40 #define NPCAI_GREET_ALLIES		0x00008000	//Say hi to nearby allies
41 #define NPCAI_FORM_TELE_NAV		0x00010000	//Tells formation people to use nav info to get to
42 #define NPCAI_ENROUTE_TO_HOMEWP 0x00020000	//Lets us know to run our lostenemyscript when we get to homeWp
43 #define NPCAI_MATCHPLAYERWEAPON 0x00040000	//Match the player's weapon except when it changes during cinematics
44 #define NPCAI_DIE_ON_IMPACT		0x00100000	//Next time you crashland, die!
45 #define NPCAI_CUSTOM_GRAVITY	0x00200000	//Don't use g_gravity, I fly!
46 
47 //Script flags
48 #define	SCF_CROUCHED		0x00000001	//Force ucmd.upmove to be -127
49 #define	SCF_WALKING			0x00000002	//Force BUTTON_WALKING to be pressed
50 #define	SCF_MORELIGHT		0x00000004	//NPC will have a minlight of 96
51 #define	SCF_LEAN_RIGHT		0x00000008	//Force rightmove+BUTTON_USE
52 #define	SCF_LEAN_LEFT		0x00000010	//Force leftmove+BUTTON_USE
53 #define	SCF_RUNNING			0x00000020	//Takes off walking button, overrides SCF_WALKING
54 #define	SCF_ALT_FIRE		0x00000040	//Force to use alt-fire when firing
55 #define	SCF_NO_RESPONSE		0x00000080	//NPC will not do generic responses to being used
56 #define	SCF_FFDEATH			0x00000100	//Just tells player_die to run the friendly fire deathscript
57 #define	SCF_NO_COMBAT_TALK	0x00000200	//NPC will not use their generic combat chatter stuff
58 #define	SCF_CHASE_ENEMIES	0x00000400	//NPC chase enemies - FIXME: right now this is synonymous with using combat points... should it be?
59 #define	SCF_LOOK_FOR_ENEMIES	0x00000800	//NPC be on the lookout for enemies
60 #define	SCF_FACE_MOVE_DIR	0x00001000	//NPC face direction it's moving - FIXME: not really implemented right now
61 #define	SCF_IGNORE_ALERTS	0x00002000	//NPC ignore alert events
62 #define SCF_DONT_FIRE		0x00004000	//NPC won't shoot
63 #define	SCF_DONT_FLEE		0x00008000	//NPC never flees
64 #define	SCF_FORCED_MARCH	0x00010000	//NPC that the player must aim at to make him walk
65 #define	SCF_NO_GROUPS		0x00020000	//NPC cannot alert groups or be part of a group
66 #define	SCF_FIRE_WEAPON		0x00040000	//NPC will fire his (her) weapon
67 #define	SCF_NO_MIND_TRICK	0x00080000	//Not succeptible to mind tricks
68 #define	SCF_USE_CP_NEAREST	0x00100000	//Will use combat point close to it, not next to player or try and flank player
69 #define	SCF_NO_FORCE		0x00200000	//Not succeptible to force powers
70 #define	SCF_NO_FALLTODEATH	0x00400000	//NPC will not scream and tumble and fall to hit death over large drops
71 #define	SCF_NO_ACROBATICS	0x00800000	//Jedi won't jump, roll or cartwheel
72 #define	SCF_USE_SUBTITLES	0x01000000	//Regardless of subtitle setting, this NPC will display subtitles when it speaks lines
73 #define	SCF_NO_ALERT_TALK	0x02000000	//Will not say alert sounds, but still can be woken up by alerts
74 
75 //#ifdef __DEBUG
76 
77 //Debug flag definitions
78 
79 #define	AID_IDLE		0x00000000	//Nothing is happening
80 #define AID_ACQUIRED	0x00000001	//A target has been found
81 #define AID_LOST		0x00000002	//Alert, but no target is in sight
82 #define AID_CONFUSED	0x00000004	//Is unable to come up with a course of action
83 #define AID_LOSTPATH	0x00000008	//Cannot make a valid movement due to lack of connections
84 
85 //#endif //__DEBUG
86 
87 typedef enum {VIS_UNKNOWN, VIS_NOT, VIS_PVS, VIS_360, VIS_FOV, VIS_SHOOT} visibility_t;
88 typedef enum {SPOT_ORIGIN, SPOT_CHEST, SPOT_HEAD, SPOT_HEAD_LEAN, SPOT_WEAPON, SPOT_LEGS, SPOT_GROUND} spot_t;
89 
90 typedef enum //# lookMode_e
91 {
92 	LM_ENT = 0,
93 	LM_INTEREST
94 } lookMode_t;
95 
96 typedef enum //# jumpState_e
97 {
98 	JS_WAITING = 0,
99 	JS_FACING,
100 	JS_CROUCHING,
101 	JS_JUMPING,
102 	JS_LANDING
103 } jumpState_t;
104 
105 typedef struct gNPCstats_e
106 {//Stats, loaded in, and can be set by scripts
107 	//AI
108 	int		aggression;			//			"
109 	int		aim;				//			"
110 	float	earshot;			//			"
111 	int		evasion;			//			"
112 	int		hfov;				// horizontal field of view
113 	int		intelligence;		//			"
114 	int		move;				//			"
115 	int		reactions;			// 1-5, higher is better
116 	float	shootDistance;		//Maximum range- overrides range set for weapon if nonzero
117 	int		vfov;				// vertical field of view
118 	float	vigilance;			//			"
119 	float	visrange;			//			"
120 	//Movement
121 	int		runSpeed;
122 	int		walkSpeed;
123 	float	yawSpeed;			// 1 - whatever, default is 50
124 	int		health;
125 	int		acceleration;
126 } gNPCstats_t;
127 
128 // NOTE!!!  If you add any ptr fields into this structure could you please tell me so I can update the load/save code?
129 //	so far the only things I've got to cope with are a bunch of gentity_t*'s, but tell me if any more get added -slc
130 //
131 
132 #define	MAX_ENEMY_POS_LAG	2400
133 #define	ENEMY_POS_LAG_INTERVAL	100
134 #define	ENEMY_POS_LAG_STEPS	(MAX_ENEMY_POS_LAG/ENEMY_POS_LAG_INTERVAL)
135 typedef struct
136 {
137 	//FIXME: Put in playerInfo or something
138 	int			timeOfDeath;			//FIXME do we really need both of these
139 	gentity_t	*touchedByPlayer;
140 
141 	visibility_t	enemyLastVisibility;
142 
143 	int			aimTime;
144 	float		desiredYaw;
145 	float		desiredPitch;
146 	float		lockedDesiredYaw;
147 	float		lockedDesiredPitch;
148 	gentity_t	*aimingBeam;		// debugging aid
149 
150 	vec3_t		enemyLastSeenLocation;
151 	int			enemyLastSeenTime;
152 	vec3_t		enemyLastHeardLocation;
153 	int			enemyLastHeardTime;
154 	int			lastAlertID;		//unique ID
155 
156 	int			eFlags;
157 	int			aiFlags;
158 
159 	int			currentAmmo;		// this sucks, need to find a better way
160 	int			shotTime;
161 	int			burstCount;
162 	int			burstMin;
163 	int			burstMean;
164 	int			burstMax;
165 	int			burstSpacing;
166 	int			attackHold;
167 	int			attackHoldTime;
168 	vec3_t		shootAngles;		//Angles to where bot is shooting - fixme: make he torso turn to reflect these
169 
170 	//extra character info
171 	rank_t		rank;		//for pips
172 
173 	//Behavior state info
174 	bState_t	behaviorState;	//determines what actions he should be doing
175 	bState_t	defaultBehavior;//State bot will default to if none other set
176 	bState_t	tempBehavior;//While valid, overrides other behavior
177 
178 	qboolean	ignorePain;		//only play pain scripts when take pain
179 
180 	int			duckDebounceTime;//Keeps them ducked for a certain time
181 	int			walkDebounceTime;
182 	int			enemyCheckDebounceTime;
183 	int			investigateDebounceTime;
184 	int			investigateCount;
185 	vec3_t		investigateGoal;
186 	int			investigateSoundDebounceTime;
187 	int			greetingDebounceTime;//when we can greet someone next
188 	gentity_t	*eventOwner;
189 
190 	//bState-specific fields
191 	gentity_t	*coverTarg;
192 	jumpState_t	jumpState;
193 	float		followDist;
194 
195 	// goal, navigation & pathfinding
196 	gentity_t	*tempGoal;			// used for locational goals (player's last seen/heard position)
197 	gentity_t	*goalEntity;
198 	gentity_t	*lastGoalEntity;
199 	gentity_t	*eventualGoal;
200 	gentity_t	*captureGoal;		//Where we should try to capture
201 	gentity_t	*defendEnt;			//Who we're trying to protect
202 	gentity_t	*greetEnt;			//Who we're greeting
203 	int			goalTime;	//FIXME: This is never actually used
204 	qboolean	straightToGoal;	//move straight at navgoals
205 	float		distToGoal;
206 	int			navTime;
207 	int			blockingEntNum;
208 	int			blockedSpeechDebounceTime;
209 	int			lastSideStepSide;
210 	int			sideStepHoldTime;
211 	int			homeWp;
212 	AIGroupInfo_t	*group;
213 
214 	vec3_t		lastPathAngles;		//So we know which way to face generally when we stop
215 
216 	//stats
217 	gNPCstats_t	stats;
218 	int			aimErrorDebounceTime;
219 	float		lastAimErrorYaw;
220 	float		lastAimErrorPitch;
221 	vec3_t		aimOfs;
222 	int			currentAim;
223 	int			currentAggression;
224 
225 	//scriptflags
226 	int			scriptFlags;//in b_local.h
227 
228 	//moveInfo
229 	int			desiredSpeed;
230 	int			currentSpeed;
231 	char		last_forwardmove;
232 	char		last_rightmove;
233 	vec3_t		lastClearOrigin;
234 	int			consecutiveBlockedMoves;
235 	int			blockedDebounceTime;
236 	int			shoveCount;
237 	vec3_t		blockedDest;
238 
239 	//
240 	int			combatPoint;//NPCs in bState BS_COMBAT_POINT will find their closest empty combat_point
241 	int			lastFailedCombatPoint;//NPCs in bState BS_COMBAT_POINT will find their closest empty combat_point
242 	int			movementSpeech;	//what to say when you first successfully move
243 	float		movementSpeechChance;//how likely you are to say it
244 
245 	//Testing physics at 20fps
246 	int			nextBStateThink;
247 	usercmd_t	last_ucmd;
248 
249 	//
250 	//JWEIER ADDITIONS START
251 
252 	qboolean	combatMove;
253 	int			goalRadius;
254 
255 	//FIXME: These may be redundant
256 
257 	/*
258 	int			weaponTime;		//Time until refire is valid
259 	int			jumpTime;
260 	*/
261 	int			pauseTime;		//Time to stand still
262 	int			standTime;
263 
264 	int			localState;		//Tracking information local to entity
265 	int			squadState;		//Tracking information for team level interaction
266 
267 	//JWEIER ADDITIONS END
268 	//
269 
270 	int			confusionTime;	//Doesn't respond to alerts or pick up enemies (unless shot) until this time is up
271 	int			charmedTime;	//charmed to enemy team
272 	int			controlledTime;	//controlled by player
273 	int			surrenderTime;	//Hands up
274 
275 	//Lagging enemy position - FIXME: seems awful wasteful...
276 	vec3_t		enemyLaggedPos[ENEMY_POS_LAG_STEPS];
277 
278 	gentity_t	*watchTarget;	//for BS_CINEMATIC, keeps facing this ent
279 
280 	int			ffireCount;		//sigh... you'd think I'd be able to find a way to do this without having to use 3 int fields, but...
281 	int			ffireDebounce;
282 	int			ffireFadeDebounce;
283 } gNPC_t;
284 
285 void G_SquadPathsInit(void);
286 void NPC_InitGame( void );
287 void G_LoadBoltOns( void );
288 void Svcmd_NPC_f( void );
289 void NAV_DebugShowWaypoints (void);
290 void NAV_DebugShowBoxes (void);
291 void NAV_DebugShowSquadPaths (void);
292