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