UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
e_parse.cpp
Go to the documentation of this file.
1 
20 /*
21 Copyright (C) 2002-2020 UFO: Alien Invasion.
22 
23 This program is free software; you can redistribute it and/or
24 modify it under the terms of the GNU General Public License
25 as published by the Free Software Foundation; either version 2
26 of the License, or (at your option) any later version.
27 
28 This program is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31 
32 See the GNU General Public License for more details.
33 
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software
36 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37 
38 */
39 
40 #include "../../client.h"
41 #include "e_parse.h"
42 #include "e_main.h"
43 
44 #include "../cl_localentity.h"
45 #include "../../cgame/cl_game.h"
46 
48 
49 typedef struct evTimes_s {
52 } evTimes_t;
53 
54 /**********************************************************
55  * General battlescape event functions
56  **********************************************************/
57 
61 static void CL_LogEvent (const eventRegister_t* eventData)
62 {
63  if (!cl_log_battlescape_events->integer)
64  return;
65 
66  ScopedFile f;
67  FS_OpenFile("events.log", &f, FILE_APPEND);
68  if (!f)
69  return;
70 
71  char tbuf[32];
72  Com_MakeTimestamp(tbuf, sizeof(tbuf));
73 
74  FS_Printf(&f, "%s - %s: %10i %s\n", tbuf, CL_GetConfigString(CS_MAPTITLE), cl.time, eventData->name);
75 }
76 
83 void CL_BlockBattlescapeEvents (bool block)
84 {
85  if (block)
86  Com_DPrintf(DEBUG_EVENTSYS, "block battlescape events\n");
87  else
88  Com_DPrintf(DEBUG_EVENTSYS, "unblock battlescape events\n");
89  cl.eventsBlocked = block;
90 }
91 
96 {
97  return cl.eventsBlocked;
98 }
99 
107 static bool CL_CheckBattlescapeEvent (int now, void* data)
108 {
110  return false;
111 
112  const evTimes_t* event = (evTimes_t*)data;
113  const eventRegister_t* eventData = CL_GetEvent(event->eType);
114 
115  if (eventData->eventCheck == nullptr)
116  return true;
117 
118  return eventData->eventCheck(eventData, event->msg);
119 }
120 
131 static void CL_NotifyBattlescapeEventDelay (int now, void* data, int delay)
132 {
133  eventTiming_t* eventTiming = (eventTiming_t*)data;
134  eventTiming->impactTime += delay;
135  eventTiming->nextTime += delay;
136  eventTiming->shootTime += delay;
137  le_t* le = nullptr;
138  while ((le = LE_GetNextInUse(le))) {
139  if (LE_IsLivingActor(le)) {
140  leStep_t* stepList = le->stepList;
141  if (stepList == nullptr)
142  continue;
143  for (int i = 0; i < le->stepIndex; i++) {
144  stepList = stepList->next;
145  }
146  stepList->lastMoveTime += delay;
147  }
148  }
149 }
150 
156 static bool CL_DelayBattlescapeEvent (int now, void* data)
157 {
159  return false;
160 #ifdef PARANOID
161  const evTimes_t* event = (evTimes_t*)data;
162  const eventRegister_t* eventData = CL_GetEvent(event->eType);
163  Com_DPrintf(DEBUG_EVENTSYS, "delay event %p type %s from %i\n", (const void*)event, eventData->name, now);
164 #endif
165  return true;
166 }
167 
171 static void CL_ExecuteBattlescapeEvent (int now, void* data)
172 {
173  evTimes_t* event = (evTimes_t*)data;
174  const eventRegister_t* eventData = CL_GetEvent(event->eType);
175 
176  if (event->eType <= EV_START || cls.state == ca_active) {
177  Com_DPrintf(DEBUG_EVENTSYS, "event(dispatching at %d): %s %p\n", now, eventData->name, (void*)event);
178 
179  CL_LogEvent(eventData);
180 
181  if (!eventData->eventCallback)
182  Com_Error(ERR_DROP, "Event %i doesn't have a callback", event->eType);
183 
184  GAME_NotifyEvent(event->eType);
185  eventData->eventCallback(eventData, event->msg);
186  } else {
187  Com_DPrintf(DEBUG_EVENTSYS, "event(not executed): %s %p\n", eventData->name, (void*)event);
188  }
189 
190  delete event->msg;
191  Mem_Free(event);
192 }
193 
194 static void CL_FreeBattlescapeEvent (void* data)
195 {
196  evTimes_t* event = (evTimes_t*)data;
197  delete event->msg;
198  Mem_Free(event);
199 }
200 
204 static bool CL_FilterBattlescapeEvents (int when, event_func* func, event_check_func* check, void* data)
205 {
206  if (func == &CL_ExecuteBattlescapeEvent) {
207  const evTimes_t* event = (const evTimes_t*)data;
208  const eventRegister_t* e = CL_GetEvent(event->eType);
209  Com_Printf("Remove pending event %s\n", e->name);
210  return false;
211  }
212  return true;
213 }
214 
216 {
217  const int filtered = CL_FilterEventQueue(&CL_FilterBattlescapeEvents);
219  return filtered;
220 }
221 
234 static int CL_GetEventTime (const event_t eType, dbuffer* msg, eventTiming_t* eventTiming)
235 {
236  const eventRegister_t* eventData = CL_GetEvent(eType);
237 
238  /* get event time */
239  if (eventTiming->nextTime < cl.time)
240  eventTiming->nextTime = cl.time;
241  if (eventTiming->impactTime < cl.time)
242  eventTiming->impactTime = cl.time;
243 
244  int eventTime;
245  if (!eventData->timeCallback)
246  eventTime = eventTiming->nextTime;
247  else
248  eventTime = eventData->timeCallback(eventData, msg, eventTiming);
249 
250  Com_DPrintf(DEBUG_EVENTSYS, "%s => eventTime: %i, nextTime: %i, impactTime: %i, shootTime: %i, cl.time: %i\n",
251  eventData->name, eventTime, eventTiming->nextTime, eventTiming->impactTime, eventTiming->shootTime, cl.time);
252 
253  return eventTime;
254 }
255 
262 {
263  static eventTiming_t eventTiming;
264  int eType = NET_ReadByte(msg);
265  if (eType == EV_NULL)
266  return EV_NULL;
267 
268  bool now;
269  /* check instantly flag */
270  if (eType & EVENT_INSTANTLY) {
271  now = true;
272  eType &= ~EVENT_INSTANTLY;
273  } else
274  now = false;
275 
276  /* check if eType is valid */
277  if (eType >= EV_NUM_EVENTS || eType < 0)
278  Com_Error(ERR_DROP, "CL_ParseEvent: invalid event %i", eType);
279 
280  const eventRegister_t* eventData = CL_GetEvent((event_t)eType);
281  if (!eventData->eventCallback)
282  Com_Error(ERR_DROP, "CL_ParseEvent: no handling function for event %i", eType);
283 
284  if (eType == EV_RESET)
285  OBJZERO(eventTiming);
286 
287  if (now) {
288  /* log and call function */
289  CL_LogEvent(eventData);
290  Com_DPrintf(DEBUG_EVENTSYS, "event(now [%i]): %s\n", cl.time, eventData->name);
291  GAME_NotifyEvent((event_t)eType);
292  eventData->eventCallback(eventData, msg);
293  } else {
295 
296  /* copy the buffer as first action, the event time functions can modify the buffer already */
297  cur->msg = new dbuffer(*msg);
298  cur->eType = (event_t)eType;
299 
300  /* timestamp (msec) that is used to determine when the event should be executed */
301  const int when = CL_GetEventTime(cur->eType, msg, &eventTiming);
303  e->delayFollowing = 50;
304  e->notifyDelay = &CL_NotifyBattlescapeEventDelay;
305  e->notifyDelayUserData = (void*)&eventTiming;
306  e->delay = &CL_DelayBattlescapeEvent;
307 
308  Com_DPrintf(DEBUG_EVENTSYS, "event(at %d): %s %p\n", when, eventData->name, (void*)cur);
309  }
310 
311  return (event_t)eType;
312 }
#define CS_MAPTITLE
Definition: q_shared.h:310
#define DEBUG_EVENTSYS
Definition: defines.h:64
bool(* eventCheck)(const struct eventRegister_s *self, const dbuffer *msg)
Called to determine if this event is ok to run at this point. Should check any conflicts with other o...
Definition: e_main.h:74
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition: files.cpp:162
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition: cvar.h:71
char * CL_GetConfigString(int index)
void event_func(int now, void *data)
Definition: common.h:324
void CL_BlockBattlescapeEvents(bool block)
Adds the ability to block battlescape event execution until something other is finished. E.g. camera movement.
Definition: e_parse.cpp:83
static void CL_LogEvent(const eventRegister_t *eventData)
Definition: e_parse.cpp:61
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
int shootTime
Definition: e_main.h:32
static bool CL_FilterBattlescapeEvents(int when, event_func *func, event_check_func *check, void *data)
Definition: e_parse.cpp:204
int integer
Definition: cvar.h:81
static void CL_FreeBattlescapeEvent(void *data)
Definition: e_parse.cpp:194
void GAME_NotifyEvent(event_t eventType)
Definition: cl_game.cpp:1623
memPool_t * cl_genericPool
Definition: cl_main.cpp:86
CL_ParseEvent timers and vars.
Definition: e_main.h:30
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
int lastMoveTime
client_static_t cls
Definition: cl_main.cpp:83
static void CL_ExecuteBattlescapeEvent(int now, void *data)
Definition: e_parse.cpp:171
#define ERR_DROP
Definition: common.h:211
#define OBJZERO(obj)
Definition: shared.h:178
static void CL_NotifyBattlescapeEventDelay(int now, void *data, int delay)
If we delayed the battlescape events due to event locking (e.g. le is locked or camera is locked)...
Definition: e_parse.cpp:131
static bool CL_AreBattlescapeEventsBlocked(void)
Definition: e_parse.cpp:95
const eventRegister_t * CL_GetEvent(const event_t eType)
Definition: e_main.cpp:157
event_t
Possible event values.
Definition: q_shared.h:79
struct leStep_s * next
int stepIndex
clientBattleScape_t cl
dbuffer * msg
Definition: e_parse.cpp:51
#define EVENT_INSTANTLY
Definition: q_shared.h:73
int FS_Printf(qFILE *f, const char *msg,...)
Can print chunks for 1024 chars into a file.
Definition: files.cpp:1495
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition: common.cpp:398
struct evTimes_s evTimes_t
int(* timeCallback)(const struct eventRegister_s *self, dbuffer *msg, eventTiming_t *eventTiming)
Callback that is returning the time that is needed to execute this event.
Definition: e_main.h:67
static bool CL_CheckBattlescapeEvent(int now, void *data)
Checks if a given battlescape event is ok to run now. Uses the check_func pointer in the event struct...
Definition: e_parse.cpp:107
Struct that defines one particular event with all its callbacks and data.
Definition: e_main.h:42
static int CL_GetEventTime(const event_t eType, dbuffer *msg, eventTiming_t *eventTiming)
Calculates the time the event should get executed. If two events return the same time, they are going to be executed in the order the were parsed.
Definition: e_parse.cpp:234
a local entity
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
le_t * LE_GetNextInUse(le_t *lastLE)
Iterate through the entities that are in use.
event_t eType
Definition: e_parse.cpp:50
void Com_MakeTimestamp(char *ts, const size_t tslen)
Creates a timestamp with date and time at the specified location.
Definition: shared.cpp:352
const char * name
the name of this event (e.g. for logs)
Definition: e_main.h:50
QGL_EXTERN GLint i
Definition: r_gl.h:113
static bool CL_DelayBattlescapeEvent(int now, void *data)
Checks if a given battlescape event should get delayed.
Definition: e_parse.cpp:156
#define Mem_Free(ptr)
Definition: mem.h:35
int impactTime
Definition: e_main.h:33
int CL_FilterEventQueue(event_filter *filter)
Filters every event in the queue using the given function. Keeps all events for which the function re...
Definition: common.cpp:1446
event_t CL_ParseEvent(dbuffer *msg)
Called in case a svc_event was send via the network buffer.
Definition: e_parse.cpp:261
int CL_ClearBattlescapeEvents(void)
Definition: e_parse.cpp:215
void(* eventCallback)(const struct eventRegister_s *self, dbuffer *msg)
Callback that is executing the event.
Definition: e_main.h:60
GLsizei const GLvoid * data
Definition: r_gl.h:152
connstate_t state
Definition: client.h:55
cvar_t * cl_log_battlescape_events
Definition: e_parse.cpp:47
ScheduleEventPtr Schedule_Event(int when, event_func *func, event_check_func *check, event_clean_func *clean, void *data)
Schedules an event to run on or after the given time, and when its check function returns true...
Definition: common.cpp:1362
#define Mem_PoolAllocType(type, pool)
Definition: mem.h:43
bool LE_IsLivingActor(const le_t *le)
Checks whether the given le is a living actor (but might be hidden)
int nextTime
Definition: e_main.h:31
leStep_t * stepList
bool event_check_func(int now, void *data)
Definition: common.h:325
int NET_ReadByte(dbuffer *buf)
Reads a byte from the netchannel.
Definition: netpack.cpp:234