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:70
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:536
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: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:1552
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:37
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:388
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
message
TIPS on SURVIVING Crossfire is populated with a wealth of different monsters These monsters can have varying immunities and attack types In some of them can be quite a bit smarter than others It will be important for new players to learn the abilities of different monsters and learn just how much it will take to kill them This section discusses how monsters can interact with players Most monsters in the game are out to mindlessly kill and destroy the players These monsters will help boost a player s after he kills them When fighting a large amount of monsters in a single attempt to find a narrower hallway so that you are not being attacked from all sides Charging into a room full of Beholders for instance would not be open the door and fight them one at a time For there are several maps designed for them Find these areas and clear them out All throughout these a player can find signs and books which they can read by stepping onto them and hitting A to apply the book sign These messages will help the player to learn the system One more always keep an eye on your food If your food drops to your character will soon so BE CAREFUL ! NPCs Non Player Character are special monsters which have intelligence Players may be able to interact with these monsters to help solve puzzles and find items of interest To speak with a monster you suspect to be a simply move to an adjacent square to them and push the double ie Enter your message
Definition: survival-guide.txt:34
EVENT_MAPUNLOAD
#define EVENT_MAPUNLOAD
Definition: events.h:51
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1587
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:14
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:2170
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
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:12
mapstruct
Definition: map.h:314
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:1828
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:51
object_handlers
static std::map< std::string, f_plug_event > object_handlers
Definition: events.cpp:14
diamondslots.id
id
Definition: diamondslots.py:53