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