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