1 /**
2  * @file
3  */
4 
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
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.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23 */
24 
25 #pragma once
26 
27 #include "../renderer/r_entity.h"
28 
29 /** @brief Actor actions */
30 typedef enum {
31 	M_MOVE,		/**< We are currently in move-mode (destination selection). */
32 	M_FIRE_R,	/**< We are currently in fire-mode for the right weapon (target selection). */
33 	M_FIRE_L,	/**< We are currently in fire-mode for the left weapon (target selection). */
34 	M_FIRE_HEADGEAR, /**< We'll fire headgear item shortly. */
35 	M_PEND_MOVE,	/**< A move target has been selected, we are waiting for player-confirmation. */
36 	M_PEND_FIRE_R,	/**< A fire target (right weapon) has been selected, we are waiting for player-confirmation. */
37 	M_PEND_FIRE_L	/**< A fire target (left weapon) has been selected, we are waiting for player-confirmation. */
38 } actorModes_t;
39 
40 #define IS_MODE_FIRE_RIGHT(x)		((x) == M_FIRE_R || (x) == M_PEND_FIRE_R)
41 #define IS_MODE_FIRE_LEFT(x)		((x) == M_FIRE_L || (x) == M_PEND_FIRE_L)
42 #define IS_MODE_FIRE_HEADGEAR(x)	((x) == M_FIRE_HEADGEAR)
43 #define IS_MODE_FIRE_PENDING(x)		((x) == M_PEND_FIRE_L || (x) == M_PEND_FIRE_R)
44 
45 typedef bool (*localEntitiyAddFunc_t) (struct le_s*  le, entity_t* ent);
46 typedef void (*localEntityThinkFunc_t) (struct le_s*  le);
47 
48 #define LE_CHECK_LEVELFLAGS		0x0001
49 #define LE_ALWAYS_VISIBLE		0x0002
50 #define LE_LOCKED				0x0004 /**< if there is an event going on involving
51 			 * this le_t.  Used to limit to one event per le_t struct at any time. */
52 #define LE_REMOVE_NEXT_FRAME	0x0008 /**< will set the inuse value to false in the next frame */
53 #define LE_INVISIBLE			0x0010
54 #define LE_SELECTED				0x0020 /**< used for actors - for the current selected actor this is true */
55 
56 typedef struct leStep_s {
57 	int steps;
58 	int lastMoveTime;
59 	int lastMoveDuration;
60 	int stepTimes[MAX_ROUTE]; 	/**< the time each steps needs */
61 	struct leStep_s* next;
62 } leStep_t;
63 
64 /** @brief a local entity */
65 typedef struct le_s {
66 	bool inuse;
67 	entity_type_t type;			/**< the local entity type */
68 	int entnum;					/**< the server side edict num this le belongs to */
69 
70 	vec3_t origin, oldOrigin;	/**< position given via world coordinates */
71 	pos3_t pos, oldPos, newPos;	/**< position on the grid */
72 	int angle;					/**< the current dir the le is facing into. Beware, this can either
73 								* be an index in the bytedirs array or an index for the angles
74 								* array of the le */
75 	int dir;
76 
77 	int TU, maxTU;				/**< time units */
78 	int morale, maxMorale;		/**< morale value - used for soldier panic and the like */
79 	int HP, maxHP;				/**< health points */
80 	int STUN;					/**< if stunned - state STATE_STUN */
81 	int state;					/**< rf states, dead, crouched and so on */
82 	woundInfo_t wounds;
83 
84 	float angles[3];	/**< rotation angle, for actors only the YAW is used */
85 	float alpha;		/**< alpha color value for rendering */
86 
87 	int team;		/**< the team number this local entity belongs to */
88 	int pnum;		/**< the player number this local entity belongs to */
89 	int ucn;		/**< the unique character number to match between server and client characters */
90 
91 	int flags;
92 
93 	fireDefIndex_t currentSelectedFiremode;
94 
95 	actorModes_t actorMode;		/**< current selected action for this actor */
96 	/** for double-click movement and confirmations ... */
97 	pos3_t mousePendPos;
98 	/**
99 	 * @brief The TUs that the current selected actor needs to walk to the
100 	 * current grid position marked by the mouse cursor (mousePos)
101 	 * @sa CL_MoveLength
102 	 */
103 	byte actorMoveLength;
104 
105 	struct le_s* clientAction;	/**< entity from server that is currently triggered and wait for client action */
106 
107 	int contents;				/**< content flags for this LE - used for tracing */
108 	AABB aabb;					/**< the bounding box */
109 	vec3_t size;
110 
111 	char inlineModelName[8];	/**< for bmodels */
112 	unsigned int modelnum1;		/**< the number of the body model in the cl.model_draw array */
113 	unsigned int modelnum2;		/**< the number of the head model in the cl.model_draw array */
114 	unsigned int bodySkin;		/**< the skin number of the body */
115 	unsigned int headSkin;		/**< the skin number of the head */
116 	model_t* model1, *model2;	/**< pointers to the cl.model_draw array
117 								* that holds the models for body and head - model1 is body,
118 								* model2 is head */
119 
120 	/** is called every frame */
121 	localEntityThinkFunc_t think;
122 	/** number of milliseconds to skip the think function for */
123 	int thinkDelay;
124 
125 	/** various think function vars */
126 	dvec_t dvtab[MAX_ROUTE];
127 	int pathContents[MAX_ROUTE];	/**< content flags of the brushes the actor is walking in */
128 	int positionContents;			/**< content flags for the current brush the actor is standing in */
129 	int pathLength, pathPos;
130 	leStep_t* stepList;				/**< list of steps - each new step is appended to this list (fifo) */
131 	int stepIndex;					/**< marks the current step in the @c stepList that should be used to get the
132 									 * event time for following step based events */
133 	int startTime, endTime;
134 	int speed[MAX_ROUTE];			/**< the speed the le is moving with */
135 	float rotationSpeed;
136 	int slidingSpeed;
137 
isMovingle_s138 	inline bool isMoving () const
139 	{
140 		return pathLength > 0;
141 	}
142 
143 	/** sound effects */
144 	int sampleIdx;
145 	float attenuation;		/**< attenuation value for local entity sounds */
146 	float volume;			/**< loop sound volume - 0.0f-1.0f */
147 
148 	/** gfx */
149 	animState_t as;			/**< holds things like the current active frame and so on */
150 	const char* particleID;
151 	int levelflags;			/**< the levels this local entity should be visible at */
152 	ptl_t* ptl;				/**< particle pointer to display */
153 	const char* ref1, *ref2;
154 	const struct le_s* ref3;
155 	Inventory inv;
156 	int left, right, headgear;	/**< item indices that the actor holds in his hands */
157 	actorSizeEnum_t fieldSize;	/**< ACTOR_SIZE_* */
158 
159 	lighting_t lighting;
160 
161 	teamDef_t* teamDef;
162 	int gender;				/**< @sa @c nametypes_t */
163 	const fireDef_t* fd;	/**< in case this is a projectile or an actor */
164 
165 	/** is called before adding a le to scene */
166 	localEntitiyAddFunc_t addFunc;
167 
getRightHandItemle_s168 	inline Item* getRightHandItem () const
169 	{
170 		return inv.getRightHandContainer();
171 	}
getLeftHandItemle_s172 	inline Item* getLeftHandItem () const
173 	{
174 		return inv.getLeftHandContainer();
175 	}
getHandItemle_s176 	inline Item* getHandItem (actorHands_t hand) const
177 	{
178 		if (hand == ACTOR_HAND_RIGHT)
179 			return inv.getRightHandContainer();
180 		else if (hand == ACTOR_HAND_LEFT)
181 			return inv.getLeftHandContainer();
182 		return nullptr;
183 	}
getFloorContainerle_s184 	inline Item* getFloorContainer () const
185 	{
186 		return inv.getFloorContainer();
187 	}
setFloorContainerle_s188 	inline void setFloorContainer (Item* il)
189 	{
190 		inv.setFloorContainer(il);
191 	}
setFloorle_s192 	inline void setFloor (le_s* other)
193 	{
194 		inv.setFloorContainer(other->getFloorContainer());
195 	}
resetFloorle_s196 	inline void resetFloor ()
197 	{
198 		inv.setFloorContainer(nullptr);
199 	}
200 } le_t;
201 
202 #define MAX_LOCALMODELS		1024
203 
204 /** @brief local models */
205 typedef struct localModel_s {
206 	char id[MAX_VAR];				/**< in case this local model is referenced by some other local
207 									 * model (e.g. for tags) - this id is set in the mapeditor */
208 	char name[MAX_QPATH];			/**< the name of the model file */
209 	char target[MAX_VAR];
210 	char tagname[MAX_VAR];			/**< in case a tag should be used to place the model */
211 	char animname[MAX_QPATH];		/**< is this an animated model */
212 
213 	struct localModel_s* parent;	/**< in case a tag should be used to place the model a parent local model id must be given */
214 	bool inuse;
215 
216 	vec3_t origin;
217 	vec3_t angles;
218 	vec3_t scale;			/**< default is 1.0 - no scaling */
219 
220 	int entnum;				/**< entnum from the entity string (if available in the server, they match) */
221 	int renderEntityNum;	/**< entity number in the renderer entity array */
222 	int skin;
223 	int renderFlags;		/**< effect flags */
224 	int frame;				/**< which static frame to show (this can't be used if animname is set) */
225 	int levelflags;
226 	animState_t as;
227 	lighting_t lighting;
228 
229 	/** is called every frame */
230 	void (*think) (struct localModel_s*  localModel);
231 
232 	model_t* model;
233 } localModel_t;
234 
235 static const vec3_t player_mins = { -PLAYER_WIDTH, -PLAYER_WIDTH, PLAYER_MIN };
236 static const vec3_t player_maxs = { PLAYER_WIDTH, PLAYER_WIDTH, PLAYER_STAND };
237 static const vec3_t player_dead_maxs = { PLAYER_WIDTH, PLAYER_WIDTH, PLAYER_DEAD };
238 
239 extern cvar_t* cl_le_debug;
240 extern cvar_t* cl_trace_debug;
241 extern cvar_t* cl_leshowinvis;
242 extern cvar_t* cl_map_draw_rescue_zone;
243 
244 const char* LE_GetAnim(const char* anim, int right, int left, int state);
245 void LE_AddProjectile(const fireDef_t* fd, int flags, const vec3_t muzzle, const vec3_t impact, int normal, le_t* leVictim);
246 void LE_AddGrenade(const fireDef_t* fd, int flags, const vec3_t muzzle, const vec3_t v0, int dt, le_t* leVictim);
247 void LE_AddAmbientSound(const char* sound, const vec3_t origin, int levelflags, float volume, float attenuation);
248 int LE_ActorGetStepTime(const le_t* le, const pos3_t pos, const pos3_t oldPos, const int dir, const int sped);
249 
250 #define LE_IsStunned(le)	(((le)->state & STATE_STUN) & ~STATE_DEAD)
251 /** @note This check also includes the IsStunned check - see the STATE_* bitmasks */
252 #define LE_IsDead(le)		((le)->state & STATE_DEAD)
253 #define LE_IsPanicked(le)	((le)->state & STATE_PANIC)
254 #define LE_IsCrouched(le)	((le)->state & STATE_CROUCHED)
255 
256 #define LE_IsInvisible(le)	((le)->flags & LE_INVISIBLE)
257 #define LE_IsSelected(le)	((le)->flags & LE_SELECTED)
258 
259 #define LE_SetInvisible(le) do { if (cl_leshowinvis->integer) le->flags &= ~LE_INVISIBLE; else le->flags |= LE_INVISIBLE; } while (0)
260 
261 #define LE_IsItem(le)		((le)->type == ET_ITEM)
262 #define LE_IsCamera(le)		((le)->type == ET_CAMERA)
263 #define LE_IsCivilian(le)	((le)->team == TEAM_CIVILIAN)
264 #define LE_IsAlien(le)		((le)->team == TEAM_ALIEN)
265 #define LE_IsPhalanx(le)	((le)->team == TEAM_PHALANX)
266 #define LE_IsRotating(le)	((le)->type == ET_ROTATING)
267 #define LE_IsDoor(le)		((le)->type == ET_DOOR || (le)->type == ET_DOOR_SLIDING)
268 #define LE_IsBreakable(le)	((le)->type == ET_BREAKABLE)
269 #define LE_IsBrushModel(le)	(LE_IsBreakable(le) || LE_IsDoor(le) || LE_IsRotating(le))
270 #define LE_IsNotSolid(le)	((le)->type == ET_TRIGGER_RESCUE || (le)->type == ET_TRIGGER_NEXTMAP)
271 
272 /** @brief Valid indices from 1 - MAX_DEATH */
273 #define LE_GetAnimationIndexForDeath(le)	((le)->state & MAX_DEATH)
274 
275 #ifdef DEBUG
276 void LE_List_f(void);
277 void LM_List_f(void);
278 #endif
279 
280 void LE_SetThink(le_t* le, localEntityThinkFunc_t think);
281 void LE_ExecuteThink(le_t* le);
282 void LE_Think(void);
283 /* think functions */
284 void LET_StartIdle(le_t* le);
285 void LET_Appear(le_t* le);
286 void LET_StartPathMove(le_t* le);
287 void LET_HiddenMove(le_t* le);
288 void LET_BrushModel(le_t* le);
289 void LE_DoEndPathMove(le_t* le);
290 
291 /* local model functions */
292 void LM_Think(void);
293 void LMT_Init(localModel_t* localModel);
294 localModel_t* LM_AddModel(const char* model, const vec3_t origin, const vec3_t angles, int entnum, int levelflags, int flags, const vec3_t scale);
295 void LM_Perish(dbuffer* msg);
296 void LM_AddToScene(void);
297 
298 bool LE_BrushModelAction(le_t* le, entity_t* ent);
299 void CL_RecalcRouting(const le_t* le);
300 void CL_CompleteRecalcRouting(void);
301 
302 void LE_LinkFloorContainer(le_t* le);
303 bool LE_IsLivingAndVisibleActor(const le_t* le);
304 bool LE_IsLivingActor(const le_t* le);
305 bool LE_IsActor(const le_t* le);
306 le_t* LE_Add(int entnum);
307 le_t* LE_Get(int entnum);
308 le_t* LE_GetNextInUse(le_t* lastLE);
309 le_t* LE_GetNext(le_t* lastLE);
310 void LE_Lock(le_t* le);
311 void LE_Unlock(le_t* le);
312 bool LE_IsLocked(int entnum);
313 #define LE_NotFoundError(entnum) _LE_NotFoundError(entnum, -1, __FILE__, __LINE__)
314 #define LE_NotFoundWithTypeError(entnum, type) _LE_NotFoundError(entnum, type, __FILE__, __LINE__)
315 void _LE_NotFoundError(int entnum, int type, const char* file, const int line) __attribute__((noreturn));
316 le_t* LE_Find(entity_type_t type, const pos3_t pos);
317 le_t* LE_FindRadius(le_t* from, const vec3_t org, float rad, entity_type_t type);
318 le_t* LE_GetFromPos(const pos3_t pos);
319 void LE_PlaceItem(le_t* le);
320 void LE_Cleanup(void);
321 void LE_AddToScene(void);
322 void LE_CenterView(const le_t* le);
323 const cBspModel_t* LE_GetClipModel(const le_t* le);
324 model_t* LE_GetDrawModel(unsigned int modelIndex);
325 void LET_SlideDoor(le_t* le, int speed);
326 void LET_RotateDoor(le_t* le, int speed);
327 
328 trace_t CL_Trace(const vec3_t start, const vec3_t end, const AABB &box, const le_t* passle, le_t* passle2, int contentmask, int worldLevel);
329 
330 void LM_Register(void);
331 localModel_t* LM_GetByID(const char* id);
332