UFO: Alien Invasion
e_event_actorappear.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 2002-2022 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 #include "../../../../client.h"
26 #include "e_event_actorappear.h"
27 #include "../../../cl_localentity.h"
28 #include "../../../cl_ugv.h"
29 #include "../../../cl_actor.h"
30 #include "../../../cl_hud.h"
31 #include "../../../../cgame/cl_game.h"
32 #include "../../../cl_particle.h"
33 #include "../../../../../common/grid.h"
34 
38 int CL_ActorAppearTime (const eventRegister_t* self, dbuffer* msg, eventTiming_t* eventTiming)
39 {
40  const int eventTime = eventTiming->nextTime;
41 
42  /* delay following events */
43  if (!cls.isOurRound())
44  eventTiming->nextTime += 600;
45 
46  return eventTime;
47 }
48 
52 static void CL_DrawLineOfSight (const le_t* watcher, const le_t* target)
53 {
54  if (!watcher || !target)
55  return;
56 
57  /* start is the watchers origin */
58  vec3_t eyes;
59  VectorCopy(watcher->origin, eyes);
60  if (LE_IsCrouched(watcher))
61  eyes[2] += EYE_HT_CROUCH;
62  else
63  eyes[2] += EYE_HT_STAND;
64 
65  ptl_t* ptl = CL_ParticleSpawn("fadeTracer", 0, eyes, target->origin);
66  if (ptl == nullptr)
67  return;
68 
69  if (LE_IsCivilian(target))
70  VectorSet(ptl->color, 0.2, 0.2, 1);
71 }
72 
79 void CL_ActorAppear (const eventRegister_t* self, dbuffer* msg)
80 {
81 
82  /* check if the actor is already visible */
83  const int entnum = NET_ReadShort(msg);
84  const int entnumResponsible = NET_ReadShort(msg);
85  le_t* le = LE_Get(entnum);
86  le_t* leResponsible = LE_Get(entnumResponsible);
87 
88  if (entnumResponsible != SKIP_LOCAL_ENTITY && !leResponsible)
89  LE_NotFoundError(entnumResponsible);
90 
91  /* mission start - no actor is spawned yet - so create it */
92  if (!le)
93  le = LE_Add(entnum);
94 
95  /* Locking should be unnecessary if CL_CheckDefault filters this call, since this event starts and
96  * ends in this function only. Adding lock/unlock just to be sure. */
97  LE_Lock(le);
98 
99  /* maybe added via CL_ActorAdd before */
100  le->flags &= ~LE_INVISIBLE;
101 
102  /* get the info */
103  int teamDefID = -1;
104  int modelnum1, modelnum2;
105  NET_ReadFormat(msg, self->formatString,
106  &le->team, &teamDefID, &le->gender, &le->ucn, &le->pnum, &le->pos,
107  &le->angle, &le->right, &le->left,
108  &modelnum1, &modelnum2, &le->bodySkin, &le->headSkin,
109  &le->state, &le->fieldSize,
110  &le->maxTU, &le->maxMorale, &le->maxHP);
111 
112  if (teamDefID < 0 || teamDefID > csi.numTeamDefs)
113  Com_Printf("CL_ActorAppear: Invalid teamDef index\n");
114  else
115  le->teamDef = &csi.teamDef[teamDefID];
116 
117  switch (le->fieldSize) {
118  case ACTOR_SIZE_NORMAL:
119  le->addFunc = CL_AddActor;
120  le->type = ET_ACTOR;
121  break;
122  case ACTOR_SIZE_2x2:
123  le->addFunc = CL_AddUGV;
124  le->type = ET_ACTOR2x2;
125  break;
126  default:
127  Com_Error(ERR_DROP, "Unknown fieldSize for le in CL_ActorAppear (EV_ACTOR_APPEAR)");
128  }
129  le->modelnum1 = modelnum1;
130  le->modelnum2 = modelnum2;
131  le->model1 = LE_GetDrawModel(modelnum1);
132  le->model2 = LE_GetDrawModel(modelnum2);
134  le->angles[YAW] = directionAngles[le->angle];
135 
136  if (LE_IsDead(le) && !LE_IsStunned(le))
138  else
139  le->contents = CONTENTS_ACTOR;
140  le->aabb.setMins(player_mins);
141  if (LE_IsDead(le))
143  else
144  le->aabb.setMaxs(player_maxs);
145 
147 
148  /* count spotted aliens (also stunned) */
150  Cvar_SetValue("mn_numaliensspotted", cl.numEnemiesSpotted);
151 
152  if (LE_IsLivingActor(le)) {
153  if (!cls.isOurRound()) {
154  /* center view (if wanted) */
155  if (leResponsible) {
156  CL_CheckCameraRoute(leResponsible->pos, le->pos);
157  } else {
158  LE_CenterView(le);
159  }
160  }
161 
162  /* draw line of sight */
163  if (le->team != cls.team) {
164  if (leResponsible)
165  CL_DrawLineOfSight(leResponsible, le);
166 
167  /* message */
168  if (le->team != TEAM_CIVILIAN) {
169  if (GAME_TeamIsKnown(le->teamDef)) {
170  char tmpbuf[128];
171  Com_sprintf(tmpbuf, sizeof(tmpbuf), _("Enemy spotted: %s!"), _(le->teamDef->name));
172  HUD_DisplayMessage(tmpbuf);
173  } else
174  HUD_DisplayMessage(_("Unknown enemy spotted!"));
175  } else
176  HUD_DisplayMessage(_("Civilian spotted."));
177 
178  /* update pathing as new actor could block path */
179  CL_ActorConditionalMoveCalc(leResponsible ? leResponsible : selActor);
180  }
181  }
182 
183  /* add team members to the actor list */
185  LE_Unlock(le);
186 }
#define LE_IsStunned(le)
int state
#define VectorCopy(src, dest)
Definition: vector.h:51
int maxTU
int numTeamDefs
Definition: q_shared.h:549
#define ACTOR_SIZE_2x2
Definition: defines.h:303
#define VectorSet(v, x, y, z)
Definition: vector.h:59
#define LE_IsCrouched(le)
unsigned int modelnum2
unsigned int headSkin
localEntitiyAddFunc_t addFunc
void LE_CenterView(const le_t *le)
Center the camera on the local entity&#39;s origin.
CL_ParseEvent timers and vars.
Definition: e_main.h:30
static void CL_DrawLineOfSight(const le_t *watcher, const le_t *target)
draw a simple &#39;spotted&#39; line from a spotter to the spotted
#define _(String)
Definition: cl_shared.h:44
ptl_t * CL_ParticleSpawn(const char *name, int levelFlags, const vec3_t s, const vec3_t v, const vec3_t a)
Spawn a new particle to the map.
csi_t csi
Definition: common.cpp:39
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
void LE_Unlock(le_t *le)
Unlocks a previously locked le_t struct.
#define LE_IsCivilian(le)
int flags
void CL_ActorAppear(const eventRegister_t *self, dbuffer *msg)
void NET_ReadFormat(dbuffer *buf, const char *format,...)
The user-friendly version of NET_ReadFormat that reads variable arguments from a buffer according to ...
Definition: netpack.cpp:533
int pnum
#define TEAM_CIVILIAN
Definition: q_shared.h:61
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
model_t * LE_GetDrawModel(unsigned int index)
model_t * model2
int contents
#define EYE_HT_CROUCH
Definition: cl_actor.h:32
vec3_t origin
void CL_CheckCameraRoute(const pos3_t from, const pos3_t target)
Only moves the camera to the given target location if its not yet close enough.
Definition: cl_camera.cpp:285
void CL_ActorAddToTeamList(le_t *le)
Adds the actor to the team list.
Definition: cl_actor.cpp:362
void setMins(const vec3_t mini)
Definition: aabb.h:68
int angle
vec4_t color
Definition: cl_renderer.h:120
#define YAW
Definition: mathlib.h:55
int right
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
#define SKIP_LOCAL_ENTITY
Definition: q_shared.h:255
model_t * model1
Struct that defines one particular event with all its callbacks and data.
Definition: e_main.h:42
bool isOurRound() const
Definition: client.h:106
client_static_t cls
Definition: cl_main.cpp:83
void CL_ActorConditionalMoveCalc(le_t *le)
Recalculate forbidden list, available moves and actor&#39;s move length for the current selected actor...
Definition: cl_actor.cpp:682
float angles[3]
#define EYE_HT_STAND
Definition: cl_actor.h:30
#define ERR_DROP
Definition: common.h:211
a local entity
le_t * LE_Get(int entnum)
Searches all local entities for the one with the searched entnum.
int nextTime
Definition: e_main.h:31
int maxMorale
int gender
#define CONTENTS_ACTOR
Definition: defines.h:247
le_t * LE_Add(int entnum)
Add a new local entity to the scene.
static const vec3_t player_dead_maxs
int left
int NET_ReadShort(dbuffer *buf)
Definition: netpack.cpp:242
clientBattleScape_t cl
int CL_CountVisibleEnemies(void)
Counts visible enemies on the battlescape.
int CL_ActorAppearTime(const eventRegister_t *self, dbuffer *msg, eventTiming_t *eventTiming)
Decides if following events should be delayed.
int maxHP
static const vec3_t player_mins
bool GAME_TeamIsKnown(const teamDef_t *teamDef)
Definition: cl_game.cpp:1463
int team
bool CL_AddUGV(le_t *le, entity_t *ent)
Adds an UGV to the render entities.
Definition: cl_ugv.cpp:35
#define LE_INVISIBLE
#define CONTENTS_DEADACTOR
Definition: defines.h:250
Routing routing
Definition: typedefs.h:341
le_t * selActor
Definition: cl_actor.cpp:49
unsigned int modelnum1
char name[MAX_VAR]
Definition: chr_shared.h:310
#define LE_IsDead(le)
bool CL_AddActor(le_t *le, entity_t *ent)
Adds an actor to the render entities with all it&#39;s models and items.
Definition: cl_actor.cpp:1515
void LE_Lock(le_t *le)
Markes a le_t struct as locked. Should be called at the beginning of an event handler on this le_t...
vec_t vec3_t[3]
Definition: ufotypes.h:39
teamDef_t * teamDef
AABB aabb
unsigned int bodySkin
const float directionAngles[CORE_DIRECTIONS]
Definition: mathlib.cpp:105
entity_type_t type
int ucn
bool LE_IsLivingActor(const le_t *le)
Checks whether the given le is a living actor (but might be hidden)
actorSizeEnum_t fieldSize
void setMaxs(const vec3_t maxi)
Definition: aabb.h:71
#define ACTOR_SIZE_NORMAL
Definition: defines.h:302
void Grid_PosToVec(const Routing &routing, const actorSizeEnum_t actorSize, const pos3_t pos, vec3_t vec)
Converts a grid position to world coordinates.
Definition: grid.cpp:832
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition: cvar.cpp:671
void LE_SetThink(le_t *le, localEntityThinkFunc_t think)
teamDef_t teamDef[MAX_TEAMDEFS]
Definition: q_shared.h:548
void LET_StartIdle(le_t *le)
Change the animation of an actor to the idle animation (which can be panic, dead or stand) ...
static const vec3_t player_maxs
void HUD_DisplayMessage(const char *text)
Displays a message on the hud.
Definition: cl_hud.cpp:138
#define LE_NotFoundError(entnum)
pos3_t pos