Crossfire Server, Trunk
events.cpp
Go to the documentation of this file.
1 #include <stdarg.h>
2 #include "global.h"
3 #include "events.h"
4 #include <map>
5 #include <string>
6 
7 #include "stats.h"
8 
10 int events_total = 0;
11 
17 static std::map<event_registration, f_plug_event> global_handlers[NR_EVENTS];
19 static std::map<std::string, f_plug_event> object_handlers;
20 
24  global_handlers[eventcode][eg] = hook;
25  return eg;
26 }
27 
29  global_handlers[eventcode].erase(id);
30 }
31 
32 void events_execute_global_event(int eventcode, ...) {
33  va_list args;
34  mapstruct *map;
35  object *op;
36  object *op2;
37  player *pl;
38  const char *buf;
39  int i, rt;
40 
41  va_start(args, eventcode);
42 
43  switch (eventcode) {
44  case EVENT_BORN:
45  /*BORN: op*/
46  op = va_arg(args, object *);
47  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
48  (*(*gh).second)(&rt, eventcode, op);
49  }
50  break;
51 
52  case EVENT_CLOCK:
53  /*CLOCK: -*/
54  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
55  (*(*gh).second)(&rt, eventcode);
56  }
57  break;
58 
59  case EVENT_CRASH:
60  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
61  (*(*gh).second)(&rt, eventcode);
62  }
63  break;
64 
65  case EVENT_PLAYER_DEATH:
66  /*PLAYER_DEATH: op*/
67  op = va_arg(args, object *);
68  op2 = va_arg(args, object *);
69  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
70  (*(*gh).second)(&rt, eventcode, op, op2);
71  }
72  break;
73 
74  case EVENT_GKILL:
75  /*GKILL: op, hitter*/
76  op = va_arg(args, object *);
77  op2 = va_arg(args, object *);
78  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
79  (*(*gh).second)(&rt, eventcode, op, op2);
80  }
81  break;
82 
83  case EVENT_LOGIN:
84  /*LOGIN: pl, pl->socket.host*/
85  pl = va_arg(args, player *);
86  buf = va_arg(args, char *);
87  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
88  (*(*gh).second)(&rt, eventcode, pl, buf);
89  }
90  break;
91 
92  case EVENT_LOGOUT:
93  /*LOGOUT: pl, pl->socket.host*/
94  pl = va_arg(args, player *);
95  buf = va_arg(args, char *);
96  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
97  (*(*gh).second)(&rt, eventcode, pl, buf);
98  }
99  break;
100 
101  case EVENT_MAPENTER:
102  /*MAPENTER: op, map*/
103  op = va_arg(args, object *);
104  map = va_arg(args, mapstruct *);
105  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
106  (*(*gh).second)(&rt, eventcode, op, map);
107  }
108  break;
109 
110  case EVENT_MAPLEAVE:
111  /*MAPLEAVE: op, map*/
112  op = va_arg(args, object *);
113  map = va_arg(args, mapstruct *);
114  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
115  (*(*gh).second)(&rt, eventcode, op, map);
116  }
117  break;
118 
119  case EVENT_MAPRESET:
120  /*MAPRESET: map*/
121  map = va_arg(args, mapstruct *);
122  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
123  (*(*gh).second)(&rt, eventcode, map);
124  }
125  break;
126 
127  case EVENT_REMOVE:
128  /*REMOVE: op*/
129  op = va_arg(args, object *);
130  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
131  (*(*gh).second)(&rt, eventcode, op);
132  }
133  break;
134 
135  case EVENT_SHOUT:
136  /*SHOUT: op, parms, priority*/
137  op = va_arg(args, object *);
138  buf = va_arg(args, char *);
139  i = va_arg(args, int);
140  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
141  (*(*gh).second)(&rt, eventcode, op, buf, i);
142  }
143  break;
144 
145  case EVENT_TELL:
146  /* Tell: who, what, to who */
147  op = va_arg(args, object *);
148  buf = va_arg(args, const char *);
149  op2 = va_arg(args, object *);
150  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
151  (*(*gh).second)(&rt, eventcode, op, buf, op2);
152  }
153  break;
154 
155  case EVENT_MUZZLE:
156  /*MUZZLE: op, parms*/
157  op = va_arg(args, object *);
158  buf = va_arg(args, char *);
159  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
160  (*(*gh).second)(&rt, eventcode, op, buf);
161  }
162  break;
163 
164  case EVENT_KICK:
165  /*KICK: op, parms*/
166  op = va_arg(args, object *);
167  buf = va_arg(args, char *);
168  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
169  (*(*gh).second)(&rt, eventcode, op, buf);
170  }
171  break;
172 
173  case EVENT_MAPUNLOAD:
174  /*MAPUNLOAD: map*/
175  map = va_arg(args, mapstruct *);
176  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
177  (*(*gh).second)(&rt, eventcode, map);
178  }
179  break;
180 
181  case EVENT_MAPLOAD:
182  /*MAPLOAD: map*/
183  map = va_arg(args, mapstruct *);
184  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
185  (*(*gh).second)(&rt, eventcode, map);
186  }
187  break;
188 
189  case EVENT_MAPREADY:
190  /*MAPREADY: map*/
191  map = va_arg(args, mapstruct *);
192  for (auto gh = global_handlers[eventcode].begin(); gh != global_handlers[eventcode].end(); gh++) {
193  (*(*gh).second)(&rt, eventcode, map);
194  }
195  break;
196  }
197  va_end(args);
199 }
200 
201 static void ensure_bitmask(object *op) {
202  if ((op->event_bitmask & BITMASK_VALID) == BITMASK_VALID) {
203  return;
204  }
205 
206  object *inv = op->inv;
207  while (inv) {
208  if (inv->type == EVENT_CONNECTOR) {
209  op->event_bitmask |= BITMASK_EVENT(inv->subtype);
210  }
211  inv = inv->below;
212  }
213  op->event_bitmask |= BITMASK_VALID;
214 }
215 
216 static int do_execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix, talk_info *talk) {
217  int rv = 0;
218  bool debug_events = (getenv("CF_DEBUG_EVENTS") != NULL);
219 
221  if ((op->event_bitmask & BITMASK_EVENT(eventcode)) == 0) {
222  return 0;
223  }
224 
226  if (tmp->type == EVENT_CONNECTOR && tmp->subtype == eventcode) {
227  if (debug_events) {
228  LOG(llevDebug, "********** EVENT HANDLER **********\n");
229  LOG(llevDebug, " - Who am I :%s\n", op->name);
230  if (activator != NULL)
231  LOG(llevDebug, " - Activator :%s\n", activator->name);
232  if (third != NULL)
233  LOG(llevDebug, " - Other object :%s\n", third->name);
234  LOG(llevDebug, " - Event code :%d\n", tmp->subtype);
235  if (tmp->title != NULL)
236  LOG(llevDebug, " - Event plugin :%s\n", tmp->title);
237  if (tmp->slaying != NULL)
238  LOG(llevDebug, " - Event hook :%s\n", tmp->slaying);
239  if (tmp->name != NULL)
240  LOG(llevDebug, " - Event options :%s\n", tmp->name);
241  }
242 
243  if (tmp->title == NULL) {
244  object *env = object_get_env_recursive(tmp);
245  LOG(llevError, "Event object without title at %d/%d in map %s\n", env->x, env->y, env->map ? env->map->name : "(null map)");
248  } else if (tmp->slaying == NULL) {
249  object *env = object_get_env_recursive(tmp);
250  LOG(llevError, "Event object without slaying at %d/%d in map %s\n", env->x, env->y, env->map ? env->map->name : "(null map)");
253  } else {
254  auto handler = object_handlers.find(tmp->title);
255  if (handler == object_handlers.end()) {
256  object *env = object_get_env_recursive(tmp);
257  LOG(llevError, "The requested handler doesn't exist: %s at %d/%d in map %s\n", tmp->title, env->x, env->y, env->map ? env->map->name : "(null map)");
260  } else {
261  int rvt = 0;
262  int rv;
263 
264  tag_t oldtag = op->count;
265  rv = (*(*handler).second)(&rvt, op, activator, third, message, fix, tmp, talk);
266  if (object_was_destroyed(op, oldtag)) {
267  return rv;
268  }
269  if (QUERY_FLAG(tmp, FLAG_UNIQUE)) {
270  if (debug_events) {
271  LOG(llevDebug, "Removing unique event %s\n", tmp->slaying);
272  }
275  }
276  if (rv) {
277  // If non-zero return value, script wants us to stop
278  // applying other methods and return.
279  return rv;
280  }
281  }
282  }
283  }
284  } FOR_INV_FINISH();
285  events_total++;
286  return rv;
287 }
288 
289 void events_register_object_handler(const char *id, f_plug_event handler) {
290  object_handlers[id] = handler;
291  LOG(llevDebug, "events: registered object handler %s\n", id);
292 }
293 
294 void events_unregister_object_handler(const char *id) {
295  object_handlers.erase(id);
296  LOG(llevDebug, "events: unregistered object handler %s\n", id);
297 }
298 
299 int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix) {
300  return do_execute_event(op, eventcode, activator, third, message, fix, NULL);
301 }
302 
304  return do_execute_event(npc, EVENT_SAY, talk->who, NULL, talk->text, SCRIPT_FIX_ALL, talk);
305 }
306 
307 int events_execute_object_user(object *op, object *activator, object *third, const char *message, int fix) {
309 }
object_was_destroyed
#define object_was_destroyed(op, old_tag)
Definition: object.h:70
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:545
object_get_env_recursive
object * object_get_env_recursive(object *op)
Definition: object.cpp:590
llevError
@ llevError
Definition: logger.h:11
EVENT_CONNECTOR
@ EVENT_CONNECTOR
Definition: object.h:232
NR_EVENTS
#define NR_EVENTS
Definition: events.h:59
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
player
Definition: player.h:105
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
BITMASK_EVENT
#define BITMASK_EVENT(evt)
Definition: events.h:62
events_unregister_object_handler
void events_unregister_object_handler(const char *id)
Definition: events.cpp:294
FLAG_UNIQUE
#define FLAG_UNIQUE
Definition: define.h:287
commongive.inv
inv
Definition: commongive.py:29
EVENT_MAPLOAD
#define EVENT_MAPLOAD
Definition: events.h:48
Ice.tmp
int tmp
Definition: Ice.py:207
EVENT_LOGOUT
#define EVENT_LOGOUT
Definition: events.h:45
EVENT_SAY
#define EVENT_SAY
Definition: events.h:29
events_execute_object_event
int events_execute_object_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: events.cpp:299
buf
StringBuffer * buf
Definition: readable.cpp:1565
events_register_global_handler
event_registration events_register_global_handler(int eventcode, f_plug_event hook)
Definition: events.cpp:21
events_register_object_handler
void events_register_object_handler(const char *id, f_plug_event handler)
Definition: events.cpp:289
EVENT_LOGIN
#define EVENT_LOGIN
Definition: events.h:44
events_total
int events_total
Definition: events.cpp:10
disinfect.map
map
Definition: disinfect.py:4
events.h
EVENT_CLOCK
#define EVENT_CLOCK
Definition: events.h:40
diamondslots.activator
activator
Definition: diamondslots.py:10
make_face_from_files.args
args
Definition: make_face_from_files.py:37
EVENT_CRASH
#define EVENT_CRASH
Definition: events.h:41
stats.h
next_event_registration
static event_registration next_event_registration
Definition: events.cpp:18
events_unregister_global_handler
void events_unregister_global_handler(int eventcode, event_registration id)
Definition: events.cpp:28
EVENT_MAPENTER
#define EVENT_MAPENTER
Definition: events.h:46
EVENT_MAPRESET
#define EVENT_MAPRESET
Definition: events.h:50
SCRIPT_FIX_ALL
#define SCRIPT_FIX_ALL
Definition: global.h:389
EVENT_BORN
#define EVENT_BORN
Definition: events.h:39
events_execute_object_user
int events_execute_object_user(object *op, object *activator, object *third, const char *message, int fix)
Definition: events.cpp:307
EVENT_MAPUNLOAD
#define EVENT_MAPUNLOAD
Definition: events.h:51
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1592
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
ensure_bitmask
static void ensure_bitmask(object *op)
Definition: events.cpp:201
tag_t
uint32_t tag_t
Definition: object.h:14
EVENT_USER
#define EVENT_USER
Definition: events.h:36
EVENT_SHOUT
#define EVENT_SHOUT
Definition: events.h:55
global_events_total
int global_events_total
Definition: events.cpp:9
env
static std::shared_ptr< inja::Environment > env
Definition: mapper.cpp:2168
eg
static event_registration eg
Definition: random_house_generator.cpp:205
talk_info::text
const char * text
Definition: dialog.h:52
EVENT_PLAYER_DEATH
#define EVENT_PLAYER_DEATH
Definition: events.h:53
diamondslots.message
string message
Definition: diamondslots.py:57
BITMASK_VALID
#define BITMASK_VALID
Definition: events.h:64
EVENT_MUZZLE
#define EVENT_MUZZLE
Definition: events.h:52
EVENT_TELL
#define EVENT_TELL
Definition: events.h:56
object::name
sstring name
Definition: object.h:319
event_registration
unsigned long event_registration
Definition: events.h:69
global_handlers
static std::map< event_registration, f_plug_event > global_handlers[NR_EVENTS]
Definition: events.cpp:17
mapstruct
Definition: map.h:313
f_plug_event
int(* f_plug_event)(int *type,...)
Definition: events.h:67
give.op
op
Definition: give.py:33
EVENT_MAPLEAVE
#define EVENT_MAPLEAVE
Definition: events.h:47
talk_info
Definition: dialog.h:50
EVENT_REMOVE
#define EVENT_REMOVE
Definition: events.h:54
npc_dialog.npc
npc
Definition: npc_dialog.py:95
object_remove
void object_remove(object *op)
Definition: object.cpp:1833
EVENT_MAPREADY
#define EVENT_MAPREADY
Definition: events.h:49
do_execute_event
static int do_execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix, talk_info *talk)
Definition: events.cpp:216
events_execute_object_say
int events_execute_object_say(object *npc, talk_info *talk)
Definition: events.cpp:303
EVENT_GKILL
#define EVENT_GKILL
Definition: events.h:42
altar_valkyrie.pl
pl
Definition: altar_valkyrie.py:28
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
EVENT_KICK
#define EVENT_KICK
Definition: events.h:43
events_execute_global_event
void events_execute_global_event(int eventcode,...)
Definition: events.cpp:32
llevDebug
@ llevDebug
Definition: logger.h:13
talk_info::who
struct object * who
Definition: dialog.h:51
object_handlers
static std::map< std::string, f_plug_event > object_handlers
Definition: events.cpp:19
diamondslots.id
id
Definition: diamondslots.py:53