Crossfire Server, Trunk  R20608
plugins.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
22 #if 0
23 
24 #define PLUGIN_DEBUG
25 #endif
26 
27 /*****************************************************************************/
28 /* First, the headers. We only include plugin.h, because all other includes */
29 /* are done into it, and plugproto.h (which is used only by this file). */
30 /*****************************************************************************/
31 
32 #include <assert.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include "plugin.h"
37 #include "shop.h"
38 #include "sproto.h"
39 #include "svnversion.h"
40 #include "timers.h"
41 
43 #define NR_OF_HOOKS (sizeof(plug_hooks)/sizeof(*plug_hooks))
44 
45 static void cfapi_cost_string_from_value(int *type, ...);
46 static void cfapi_system_find_animation(int *type, ...);
47 static void cfapi_system_find_face(int *type, ...);
48 static void cfapi_system_strdup_local(int *type, ...);
49 static void cfapi_system_register_global_event(int *type, ...);
50 static void cfapi_system_unregister_global_event(int *type, ...);
51 static void cfapi_system_add_string(int *type, ...);
52 static void cfapi_system_remove_string(int *type, ...);
53 static void cfapi_system_find_string(int *type, ...);
54 static void cfapi_system_check_path(int *type, ...);
55 static void cfapi_system_re_cmp(int *type, ...);
56 static void cfapi_system_directory(int *type, ...);
57 static void cfapi_get_time(int *type, ...);
58 static void cfapi_get_season_name(int *type, ...);
59 static void cfapi_get_weekday_name(int *type, ...);
60 static void cfapi_get_month_name(int *type, ...);
61 static void cfapi_get_periodofday_name(int *type, ...);
62 static void cfapi_timer_create(int *type, ...);
63 static void cfapi_timer_destroy(int *type, ...);
64 static void cfapi_log(int *type, ...);
65 static void cfapi_map_get_map(int *type, ...);
66 static void cfapi_map_has_been_loaded(int *type, ...);
67 static void cfapi_map_create_path(int *type, ...);
68 static void cfapi_map_get_map_property(int *type, ...);
69 static void cfapi_map_set_map_property(int *type, ...);
70 static void cfapi_map_out_of_map(int *type, ...);
71 static void cfapi_map_update_position(int *type, ...);
72 static void cfapi_map_delete_map(int *type, ...);
73 static void cfapi_map_message(int *type, ...);
74 static void cfapi_map_get_object_at(int *type, ...);
75 static void cfapi_map_find_by_archetype_name(int *type, ...);
76 static void cfapi_map_change_light(int *type, ...);
77 static void cfapi_object_move(int *type, ...);
78 static void cfapi_object_get_key(int *type, ...);
79 static void cfapi_object_set_key(int *type, ...);
80 static void cfapi_object_get_property(int *type, ...);
81 static void cfapi_object_set_property(int *type, ...);
82 static void cfapi_object_apply_below(int *type, ...);
83 static void cfapi_object_apply(int *type, ...);
84 static void cfapi_object_identify(int *type, ...);
85 static void cfapi_object_describe(int *type, ...);
86 static void cfapi_object_drain(int *type, ...);
87 static void cfapi_object_remove_depletion(int *type, ...);
88 static void cfapi_object_fix(int *type, ...);
89 static void cfapi_object_give_skill(int *type, ...);
90 static void cfapi_object_transmute(int *type, ...);
91 static void cfapi_object_remove(int *type, ...);
92 static void cfapi_object_delete(int *type, ...);
93 static void cfapi_object_clone(int *type, ...);
94 static void cfapi_object_create(int *type, ...);
95 static void cfapi_object_insert(int *type, ...);
96 static void cfapi_object_split(int *type, ...);
97 static void cfapi_object_merge(int *type, ...);
98 static void cfapi_object_distance(int *type, ...);
99 static void cfapi_object_update(int *type, ...);
100 static void cfapi_object_clear(int *type, ...);
101 static void cfapi_object_reset(int *type, ...);
102 static void cfapi_object_clean_object(int *type, ...);
103 static void cfapi_object_on_same_map(int *type, ...);
104 static void cfapi_object_spring_trap(int *type, ...);
105 static void cfapi_object_check_trigger(int *type, ...);
106 static void cfapi_map_trigger_connected(int *type, ...);
107 static void cfapi_object_query_money(int *type, ...);
108 static void cfapi_object_cast(int *type, ...);
109 static void cfapi_object_learn_spell(int *type, ...);
110 static void cfapi_object_forget_spell(int *type, ...);
111 static void cfapi_object_check_spell(int *type, ...);
112 static void cfapi_object_pay_amount(int *type, ...);
113 static void cfapi_object_pay_item(int *type, ...);
114 static void cfapi_object_transfer(int *type, ...);
115 static void cfapi_object_find_archetype_inside(int *type, ...);
116 static void cfapi_object_find_by_arch_name(int *type, ...);
117 static void cfapi_object_find_by_name(int *type, ...);
118 static void cfapi_object_drop(int *type, ...);
119 static void cfapi_object_change_abil(int *type, ...);
120 static void cfapi_object_say(int *type, ...);
121 static void cfapi_player_find(int *type, ...);
122 static void cfapi_player_message(int *type, ...);
123 static void cfapi_object_change_exp(int *type, ...);
124 static void cfapi_player_can_pay(int *type, ...);
125 static void cfapi_player_knowledge(int *type, ...);
126 static void cfapi_object_teleport(int *type, ...);
127 static void cfapi_object_pickup(int *type, ...);
128 static void cfapi_archetype_get_property(int *type, ...);
129 static void cfapi_party_get_property(int *type, ...);
130 static void cfapi_region_get_property(int *type, ...);
131 static void cfapi_friendlylist_get_next(int *type, ...);
132 static void cfapi_set_random_map_variable(int *type, ...);
133 static void cfapi_generate_random_map(int *type, ...);
134 static void cfapi_object_user_event(int *type, ...);
135 static void cfapi_player_quest(int *type, ...);
136 
140 static const hook_entry plug_hooks[] = {
141  { cfapi_system_add_string, 0, "cfapi_system_add_string" },
142  { cfapi_system_register_global_event, 1, "cfapi_system_register_global_event" },
143  { cfapi_system_remove_string, 2, "cfapi_system_remove_string" },
144  { cfapi_system_unregister_global_event, 3, "cfapi_system_unregister_global_event" },
145  { cfapi_system_check_path, 4, "cfapi_system_check_path" },
146  { cfapi_system_re_cmp, 5, "cfapi_system_re_cmp" },
147  { cfapi_system_strdup_local, 6, "cfapi_system_strdup_local" },
148  { cfapi_system_directory, 7, "cfapi_system_directory" },
149  { cfapi_system_find_animation, 8, "cfapi_system_find_animation" },
150  { cfapi_object_clean_object, 9, "cfapi_object_clean_object" },
151  { cfapi_object_on_same_map, 10, "cfapi_object_on_same_map" },
152  { cfapi_object_get_key, 11, "cfapi_object_get_key" },
153  { cfapi_object_set_key, 12, "cfapi_object_set_key" },
154  { cfapi_object_get_property, 13, "cfapi_object_get_property" },
155  { cfapi_object_set_property, 14, "cfapi_object_set_property" },
156  { cfapi_object_apply, 15, "cfapi_object_apply" },
157  { cfapi_object_identify, 16, "cfapi_object_identify" },
158  { cfapi_object_describe, 17, "cfapi_object_describe" },
159  { cfapi_object_drain, 18, "cfapi_object_drain" },
160  { cfapi_object_fix, 19, "cfapi_object_fix" },
161  { cfapi_object_give_skill, 20, "cfapi_object_give_skill" },
162  { cfapi_object_transmute, 21, "cfapi_object_transmute" },
163  { cfapi_object_remove, 22, "cfapi_object_remove" },
164  { cfapi_object_delete, 23, "cfapi_object_delete" },
165  { cfapi_object_clone, 24, "cfapi_object_clone" },
166  { cfapi_object_create, 26, "cfapi_object_create" },
167  { cfapi_object_insert, 27, "cfapi_object_insert" },
168  { cfapi_object_split, 28, "cfapi_object_split" },
169  { cfapi_object_merge, 29, "cfapi_object_merge" },
170  { cfapi_object_distance, 30, "cfapi_object_distance" },
171  { cfapi_object_update, 31, "cfapi_object_update" },
172  { cfapi_object_clear, 32, "cfapi_object_clear" },
173  { cfapi_object_reset, 33, "cfapi_object_reset" },
174  { cfapi_object_spring_trap, 35, "cfapi_object_spring_trap" },
175  { cfapi_object_check_trigger, 36, "cfapi_object_check_trigger" },
176  { cfapi_object_query_money, 38, "cfapi_object_query_money" },
177  { cfapi_object_cast, 39, "cfapi_object_cast" },
178  { cfapi_object_learn_spell, 40, "cfapi_object_learn_spell" },
179  { cfapi_object_forget_spell, 41, "cfapi_object_forget_spell" },
180  { cfapi_object_check_spell, 42, "cfapi_object_check_spell" },
181  { cfapi_object_pay_amount, 43, "cfapi_object_pay_amount" },
182  { cfapi_object_pay_item, 44, "cfapi_object_pay_item" },
183  { cfapi_object_transfer, 45, "cfapi_object_transfer" },
184  { cfapi_object_drop, 46, "cfapi_object_drop" },
185  { cfapi_object_change_abil, 47, "cfapi_object_change_abil" },
186  { cfapi_object_find_archetype_inside, 48, "cfapi_object_find_archetype_inside" },
187  { cfapi_object_say, 49, "cfapi_object_say" },
188  { cfapi_map_get_map, 50, "cfapi_map_get_map" },
189  { cfapi_map_has_been_loaded, 51, "cfapi_map_has_been_loaded" },
190  { cfapi_map_create_path, 52, "cfapi_map_create_path" },
191  { cfapi_map_get_map_property, 53, "cfapi_map_get_property" },
192  { cfapi_map_set_map_property, 54, "cfapi_map_set_property" },
193  { cfapi_map_out_of_map, 55, "cfapi_map_out_of_map" },
194  { cfapi_map_update_position, 56, "cfapi_map_update_position" },
195  { cfapi_map_delete_map, 57, "cfapi_map_delete_map" },
196  { cfapi_map_message, 58, "cfapi_map_message" },
197  { cfapi_map_get_object_at, 59, "cfapi_map_get_object_at" },
198  { cfapi_map_change_light, 60, "cfapi_map_change_light" },
199  { cfapi_map_find_by_archetype_name, 61, "cfapi_map_find_by_archetype_name" },
200  { cfapi_player_find, 62, "cfapi_player_find" },
201  { cfapi_player_message, 63, "cfapi_player_message" },
202  { cfapi_object_change_exp, 64, "cfapi_object_change_exp" },
203  { cfapi_object_teleport, 65, "cfapi_object_teleport" },
204  { cfapi_object_pickup, 67, "cfapi_object_pickup" },
205  { cfapi_object_move, 68, "cfapi_object_move" },
206  { cfapi_object_apply_below, 69, "cfapi_object_apply_below" },
207  { cfapi_generate_random_map, 70, "cfapi_generate_random_map" },
208  { cfapi_archetype_get_property, 71, "cfapi_archetype_get_property" },
209  { cfapi_party_get_property, 72, "cfapi_party_get_property" },
210  { cfapi_region_get_property, 73, "cfapi_region_get_property" },
211  { cfapi_player_can_pay, 74, "cfapi_player_can_pay" },
212  { cfapi_log, 75, "cfapi_log" },
213  { cfapi_get_time, 76, "cfapi_system_get_time" },
214  { cfapi_timer_create, 77, "cfapi_system_timer_create" },
215  { cfapi_timer_destroy, 78, "cfapi_system_timer_destroy" },
216  { cfapi_friendlylist_get_next, 79, "cfapi_friendlylist_get_next" },
217  { cfapi_set_random_map_variable, 80, "cfapi_set_random_map_variable" },
218  { cfapi_system_find_face, 81, "cfapi_system_find_face" },
219  { cfapi_get_season_name, 82, "cfapi_system_get_season_name" },
220  { cfapi_get_month_name, 83, "cfapi_system_get_month_name" },
221  { cfapi_get_weekday_name, 84, "cfapi_system_get_weekday_name" },
222  { cfapi_get_periodofday_name, 85, "cfapi_system_get_periodofday_name" },
223  { cfapi_map_trigger_connected, 86, "cfapi_map_trigger_connected" },
224  { cfapi_object_user_event, 87, "cfapi_object_user_event" },
225  { cfapi_system_find_string, 88, "cfapi_system_find_string" },
226  { cfapi_cost_string_from_value, 90, "cfapi_cost_string_from_value" },
227  { cfapi_player_quest, 91, "cfapi_player_quest" },
228  { cfapi_object_remove_depletion, 92, "cfapi_object_remove_depletion" },
229  { cfapi_object_find_by_arch_name, 93, "cfapi_object_find_by_arch_name" },
230  { cfapi_object_find_by_name, 94, "cfapi_object_find_by_name" },
231  { cfapi_player_knowledge, 95, "cfapi_player_knowledge" }
232 };
233 
236 
237 /*****************************************************************************/
238 /* NEW PLUGIN STUFF STARTS HERE */
239 /*****************************************************************************/
240 
246 static crossfire_plugin *plugins_find_plugin(const char *id) {
247  crossfire_plugin *cp;
248 
249  if (plugins_list == NULL)
250  return NULL;
251 
252  for (cp = plugins_list; cp != NULL; cp = cp->next) {
253  if (!strcmp(id, cp->id)) {
254  return cp;
255  }
256  }
257  return NULL;
258 }
259 
260 #ifdef WIN32
261 static const char *plugins_dlerror(void) {
262  static char buf[256];
263  DWORD err;
264  char *p;
265 
266  err = GetLastError();
267  if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL) == 0)
268  snprintf(buf, sizeof(buf), "error %lu", err);
269  p = strchr(buf, '\0');
270  while (p > buf && (p[-1] == '\r' || p[-1] == '\n'))
271  p--;
272  *p = '\0';
273  return buf;
274 }
275 #endif /* WIN32 */
276 
282 static void send_changed_object(object *op) {
283  object *tmp;
284  player *pl;
285 
286  if (op->env != NULL) {
287  tmp = object_get_player_container(op->env);
288  if (!tmp) {
289  for (pl = first_player; pl; pl = pl->next)
290  if (pl->ob->container == op->env)
291  break;
292  if (pl)
293  tmp = pl->ob;
294  else
295  tmp = NULL;
296  }
297  if (tmp)
298  /* We don't know what changed, so we send everything. */
299  esrv_update_item(UPD_ALL, tmp, op);
300  } else {
301  FOR_ABOVE_PREPARE(op, tmp)
302  if (tmp->type == PLAYER)
303  tmp->contr->socket.update_look = 1;
305  }
306 }
307 
308 int user_event(object *op, object *activator, object *third, const char *message, int fix) {
309  return execute_event(op, EVENT_USER, activator, third, message, fix);
310 }
311 
312 static int do_execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix, talk_info *talk) {
313  crossfire_plugin *plugin;
314  int rv = 0;
315 
316  FOR_INV_PREPARE(op, tmp) {
317  if (tmp->type == EVENT_CONNECTOR && tmp->subtype == eventcode) {
318 #ifdef PLUGIN_DEBUG
319  LOG(llevDebug, "********** EVENT HANDLER **********\n");
320  LOG(llevDebug, " - Who am I :%s\n", op->name);
321  if (activator != NULL)
322  LOG(llevDebug, " - Activator :%s\n", activator->name);
323  if (third != NULL)
324  LOG(llevDebug, " - Other object :%s\n", third->name);
325  LOG(llevDebug, " - Event code :%d\n", tmp->subtype);
326  if (tmp->title != NULL)
327  LOG(llevDebug, " - Event plugin :%s\n", tmp->title);
328  if (tmp->slaying != NULL)
329  LOG(llevDebug, " - Event hook :%s\n", tmp->slaying);
330  if (tmp->name != NULL)
331  LOG(llevDebug, " - Event options :%s\n", tmp->name);
332 #endif
333 
334  if (tmp->title == NULL) {
335  object *env = object_get_env_recursive(tmp);
336  LOG(llevError, "Event object without title at %d/%d in map %s\n", env->x, env->y, env->map->name);
337  object_remove(tmp);
339  } else if (tmp->slaying == NULL) {
340  object *env = object_get_env_recursive(tmp);
341  LOG(llevError, "Event object without slaying at %d/%d in map %s\n", env->x, env->y, env->map->name);
342  object_remove(tmp);
344  } else {
345  plugin = plugins_find_plugin(tmp->title);
346  if (plugin == NULL) {
347  object *env = object_get_env_recursive(tmp);
348  LOG(llevError, "The requested plugin doesn't exist: %s at %d/%d in map %s\n", tmp->title, env->x, env->y, env->map->name);
349  object_remove(tmp);
351  } else {
352  int rvt = 0;
353  int rv;
354 
355  rv = plugin->eventfunc(&rvt, op, activator, third, message, fix, tmp, talk);
356  if (QUERY_FLAG(tmp, FLAG_UNIQUE)) {
357 #ifdef PLUGIN_DEBUG
358  LOG(llevDebug, "Removing unique event %s\n", tmp->slaying);
359 #endif
360  object_remove(tmp);
362  }
363  return rv;
364  }
365  }
366  }
367  } FOR_INV_FINISH();
368  return rv;
369 }
370 
371 int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix) {
372  return do_execute_event(op, eventcode, activator, third, message, fix, NULL);
373 }
374 
375 int plugin_event_say(object *npc, talk_info *talk) {
376  return do_execute_event(npc, EVENT_SAY, talk->who, NULL, talk->text, SCRIPT_FIX_ALL, talk);
377 }
378 
379 int execute_global_event(int eventcode, ...) {
380  va_list args;
381  mapstruct *map;
382  object *op;
383  object *op2;
384  player *pl;
385  const char *buf;
386  int i, rt;
387  crossfire_plugin *cp;
388 
389  if (plugins_list == NULL)
390  return -1;
391 
392  va_start(args, eventcode);
393 
394  switch (eventcode) {
395  case EVENT_BORN:
396  /*BORN: op*/
397  op = va_arg(args, object *);
398  for (cp = plugins_list; cp != NULL; cp = cp->next) {
399  if (cp->gevent[eventcode] != NULL)
400  cp->gevent[eventcode](&rt, eventcode, op);
401  }
402  break;
403 
404  case EVENT_CLOCK:
405  /*CLOCK: -*/
406  for (cp = plugins_list; cp != NULL; cp = cp->next) {
407  if (cp->gevent[eventcode] != NULL)
408  cp->gevent[eventcode](&rt, eventcode);
409  }
410  break;
411 
412  case EVENT_CRASH:
413  for (cp = plugins_list; cp != NULL; cp = cp->next) {
414  if (cp->gevent[eventcode] != NULL)
415  cp->gevent[eventcode](&rt, eventcode);
416  }
417  break;
418 
419  case EVENT_PLAYER_DEATH:
420  /*PLAYER_DEATH: op*/
421  op = va_arg(args, object *);
422  op2 = va_arg(args, object *);
423  for (cp = plugins_list; cp != NULL; cp = cp->next) {
424  if (cp->gevent[eventcode] != NULL)
425  cp->gevent[eventcode](&rt, eventcode, op, op2);
426  }
427  break;
428 
429  case EVENT_GKILL:
430  /*GKILL: op, hitter*/
431  op = va_arg(args, object *);
432  op2 = va_arg(args, object *);
433  for (cp = plugins_list; cp != NULL; cp = cp->next) {
434  if (cp->gevent[eventcode] != NULL)
435  cp->gevent[eventcode](&rt, eventcode, op, op2);
436  }
437  break;
438 
439  case EVENT_LOGIN:
440  /*LOGIN: pl, pl->socket.host*/
441  pl = va_arg(args, player *);
442  buf = va_arg(args, char *);
443  for (cp = plugins_list; cp != NULL; cp = cp->next) {
444  if (cp->gevent[eventcode] != NULL)
445  cp->gevent[eventcode](&rt, eventcode, pl, buf);
446  }
447  break;
448 
449  case EVENT_LOGOUT:
450  /*LOGOUT: pl, pl->socket.host*/
451  pl = va_arg(args, player *);
452  buf = va_arg(args, char *);
453  for (cp = plugins_list; cp != NULL; cp = cp->next) {
454  if (cp->gevent[eventcode] != NULL)
455  cp->gevent[eventcode](&rt, eventcode, pl, buf);
456  }
457  break;
458 
459  case EVENT_MAPENTER:
460  /*MAPENTER: op, map*/
461  op = va_arg(args, object *);
462  map = va_arg(args, mapstruct *);
463  for (cp = plugins_list; cp != NULL; cp = cp->next) {
464  if (cp->gevent[eventcode] != NULL)
465  cp->gevent[eventcode](&rt, eventcode, op, map);
466  }
467  break;
468 
469  case EVENT_MAPLEAVE:
470  /*MAPLEAVE: op, map*/
471  op = va_arg(args, object *);
472  map = va_arg(args, mapstruct *);
473  for (cp = plugins_list; cp != NULL; cp = cp->next) {
474  if (cp->gevent[eventcode] != NULL)
475  cp->gevent[eventcode](&rt, eventcode, op, map);
476  }
477  break;
478 
479  case EVENT_MAPRESET:
480  /*MAPRESET: map*/
481  map = va_arg(args, mapstruct *);
482  for (cp = plugins_list; cp != NULL; cp = cp->next) {
483  if (cp->gevent[eventcode] != NULL)
484  cp->gevent[eventcode](&rt, eventcode, map);
485  }
486  break;
487 
488  case EVENT_REMOVE:
489  /*REMOVE: op*/
490  op = va_arg(args, object *);
491  for (cp = plugins_list; cp != NULL; cp = cp->next) {
492  if (cp->gevent[eventcode] != NULL)
493  cp->gevent[eventcode](&rt, eventcode, op);
494  }
495  break;
496 
497  case EVENT_SHOUT:
498  /*SHOUT: op, parms, priority*/
499  op = va_arg(args, object *);
500  buf = va_arg(args, char *);
501  i = va_arg(args, int);
502  for (cp = plugins_list; cp != NULL; cp = cp->next) {
503  if (cp->gevent[eventcode] != NULL)
504  cp->gevent[eventcode](&rt, eventcode, op, buf, i);
505  }
506  break;
507 
508  case EVENT_TELL:
509  /* Tell: who, what, to who */
510  op = va_arg(args, object *);
511  buf = va_arg(args, const char *);
512  op2 = va_arg(args, object *);
513  for (cp = plugins_list; cp != NULL; cp = cp->next) {
514  if (cp->gevent[eventcode] != NULL)
515  cp->gevent[eventcode](&rt, eventcode, op, buf, op2);
516  }
517  break;
518 
519  case EVENT_MUZZLE:
520  /*MUZZLE: op, parms*/
521  op = va_arg(args, object *);
522  buf = va_arg(args, char *);
523  for (cp = plugins_list; cp != NULL; cp = cp->next) {
524  if (cp->gevent[eventcode] != NULL)
525  cp->gevent[eventcode](&rt, eventcode, op, buf);
526  }
527  break;
528 
529  case EVENT_KICK:
530  /*KICK: op, parms*/
531  op = va_arg(args, object *);
532  buf = va_arg(args, char *);
533  for (cp = plugins_list; cp != NULL; cp = cp->next) {
534  if (cp->gevent[eventcode] != NULL)
535  cp->gevent[eventcode](&rt, eventcode, op, buf);
536  }
537  break;
538 
539  case EVENT_MAPUNLOAD:
540  /*MAPUNLOAD: map*/
541  map = va_arg(args, mapstruct *);
542  for (cp = plugins_list; cp != NULL; cp = cp->next) {
543  if (cp->gevent[eventcode] != NULL)
544  cp->gevent[eventcode](&rt, eventcode, map);
545  }
546  break;
547 
548  case EVENT_MAPLOAD:
549  /*MAPLOAD: map*/
550  map = va_arg(args, mapstruct *);
551  for (cp = plugins_list; cp != NULL; cp = cp->next) {
552  if (cp->gevent[eventcode] != NULL)
553  cp->gevent[eventcode](&rt, eventcode, map);
554  }
555  break;
556  }
557  va_end(args);
558  return 0;
559 }
560 
561 static void cfapi_get_hooks(int *type, ...) {
562  va_list args;
563  int request_type;
564  char *buf;
565  f_plug_api *rapi;
566 
567  *type = CFAPI_NONE;
568 
569  va_start(args, type);
570  request_type = va_arg(args, int);
571  if (request_type == 0) { /* By nr */
572  size_t fid;
573 
574  fid = va_arg(args, int);
575  rapi = va_arg(args, f_plug_api *);
576  if (fid >= NR_OF_HOOKS) {
577  *rapi = NULL;
578  *type = CFAPI_NONE;
579  } else {
580  *rapi = plug_hooks[fid].func;
581  *type = CFAPI_FUNC;
582  }
583  } else { /* by name */
584  size_t i;
585 
586  buf = va_arg(args, char *);
587  rapi = va_arg(args, f_plug_api *);
588  *rapi = NULL;
589  *type = CFAPI_NONE;
590  for (i = 0; i < NR_OF_HOOKS; i++) {
591  if (!strcmp(buf, plug_hooks[i].fname)) {
592  *rapi = plug_hooks[i].func;
593  *type = CFAPI_FUNC;
594  break;
595  }
596  }
597  }
598  va_end(args);
599 }
600 
607 int plugins_init_plugin(const char *libfile) {
608  LIBPTRTYPE ptr;
609  f_plug_init initfunc;
610  f_plug_property propfunc;
611  f_plug_event eventfunc;
612  f_plug_postinit postfunc;
613  f_plug_postinit closefunc;
614  int i;
615  crossfire_plugin *cp;
616  crossfire_plugin *ccp;
617  char *svn_rev;
618 
619 
620  /* Open the plugin lib and load the required functions */
621  ptr = plugins_dlopen(libfile);
622  if (ptr == NULL) {
623  LOG(llevError, "Error trying to load %s: %s\n", libfile, plugins_dlerror());
624  return -1;
625  }
626  svn_rev = (char*) plugins_dlsym(ptr, "SvnRevPlugin");
627  if (svn_rev == NULL) {
628  LOG(llevError, "Unable to find SvnRevPlugin in %s\n", libfile);
629  plugins_dlclose(ptr);
630  return -1;
631  }
632  if (settings.ignore_plugin_compatibility == 0 && strcmp(svn_rev, SVN_REV)) {
633  LOG(llevError, "SVN Version mismatch in in %s (%s != %s)\n", libfile, svn_rev, SVN_REV);
634  plugins_dlclose(ptr);
635  return -1;
636  }
637 
638  initfunc = (f_plug_init)plugins_dlsym(ptr, "initPlugin");
639  if (initfunc == NULL) {
640  LOG(llevError, "Plugin error while requesting %s.initPlugin: %s\n", libfile, plugins_dlerror());
641  plugins_dlclose(ptr);
642  return -1;
643  }
644  propfunc = (f_plug_property)plugins_dlsym(ptr, "getPluginProperty");
645  if (propfunc == NULL) {
646  LOG(llevError, "Plugin error while requesting %s.getPluginProperty: %s\n", libfile, plugins_dlerror());
647  plugins_dlclose(ptr);
648  return -1;
649  }
650  eventfunc = (f_plug_event)plugins_dlsym(ptr, "eventListener");
651  if (eventfunc == NULL) {
652  LOG(llevError, "Plugin error while requesting %s.eventListener: %s\n", libfile, plugins_dlerror());
653  plugins_dlclose(ptr);
654  return -1;
655  }
656  postfunc = (f_plug_postinit)plugins_dlsym(ptr, "postInitPlugin");
657  if (postfunc == NULL) {
658  LOG(llevError, "Plugin error while requesting %s.postInitPlugin: %s\n", libfile, plugins_dlerror());
659  plugins_dlclose(ptr);
660  return -1;
661  }
662  closefunc = (f_plug_postinit)plugins_dlsym(ptr, "closePlugin");
663  if (closefunc == NULL) {
664  LOG(llevError, "Plugin error while requesting %s.closePlugin: %s\n", libfile, plugins_dlerror());
665  plugins_dlclose(ptr);
666  return -1;
667  }
668  i = initfunc("2.0", cfapi_get_hooks);
669  cp = malloc(sizeof(crossfire_plugin));
670  for (i = 0; i < NR_EVENTS; i++)
671  cp->gevent[i] = NULL;
672  cp->eventfunc = eventfunc;
673  cp->propfunc = propfunc;
674  cp->closefunc = closefunc;
675  cp->libptr = ptr;
676  propfunc(&i, "Identification", cp->id, sizeof(cp->id));
677  propfunc(&i, "FullName", cp->fullname, sizeof(cp->fullname));
678  cp->next = NULL;
679  cp->prev = NULL;
680  if (plugins_list == NULL) {
681  plugins_list = cp;
682  } else {
683  for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next)
684  ;
685  ccp->next = cp;
686  cp->prev = ccp;
687  }
688  postfunc();
689  return 0;
690 }
691 
698 int plugins_remove_plugin(const char *id) {
699  crossfire_plugin *cp;
700 
701  if (plugins_list == NULL)
702  return -1;
703 
704  for (cp = plugins_list; cp != NULL; cp = cp->next) {
705  if (!strcmp(id, cp->id)) {
706  crossfire_plugin *n;
707  crossfire_plugin *p;
708 
709  n = cp->next;
710  p = cp->prev;
711  if (cp->closefunc)
712  cp->closefunc();
713  plugins_dlclose(cp->libptr);
714  if (n != NULL) {
715  if (p != NULL) {
716  n->prev = p;
717  p->next = n;
718  } else {
719  n->prev = NULL;
720  plugins_list = n;
721  }
722  } else {
723  if (p != NULL)
724  p->next = NULL;
725  else
726  plugins_list = NULL;
727  }
728  free(cp);
729  return 0;
730  }
731  }
732  return -1;
733 }
734 
740 void plugins_display_list(object *op) {
741  crossfire_plugin *cp;
742 
744  "List of loaded plugins:\n-----------------------");
745 
746  if (plugins_list == NULL)
747  return;
748 
749  for (cp = plugins_list; cp != NULL; cp = cp->next) {
751  "%s, %s",
752  cp->id, cp->fullname);
753  }
754 }
755 
756 /* SYSTEM-RELATED HOOKS */
757 
763 static void cfapi_cost_string_from_value(int *type, ...) {
764  uint64_t cost;
765  char *buffer, *final;
766  int length, largest_coin;
767  va_list args;
768 
769  va_start(args, type);
770  cost = va_arg(args, uint64_t);
771  largest_coin = va_arg(args, int);
772  buffer = va_arg(args, char*);
773  length = va_arg(args, int);
774  va_end(args);
775 
776  *type = CFAPI_NONE;
777 
778  if (length < 1)
779  return;
780 
781  final = cost_string_from_value(cost, largest_coin);
782 
783  strncpy(buffer, final, length - 1);
784  buffer[length - 1] = '\0';
785  free(final);
786 }
787 
793 static void cfapi_system_find_animation(int *type, ...) {
794  va_list args;
795  const char *anim;
796  int *num;
797 
798  va_start(args, type);
799  anim = va_arg(args, const char *);
800  num = va_arg(args, int *);
801  va_end(args);
802 
803  *num = find_animation(anim);
804  *type = CFAPI_INT;
805 }
806 
812 static void cfapi_system_find_face(int *type, ...) {
813  va_list args;
814  const char *face;
815  int error;
816  int *num;
817 
818  va_start(args, type);
819  face = va_arg(args, const char *);
820  error = va_arg(args, int);
821  num = va_arg(args, int *);
822  va_end(args);
823 
824  *num = find_face(face, error);
825  *type = CFAPI_INT;
826 }
827 
833 static void cfapi_system_strdup_local(int *type, ...) {
834  va_list args;
835  const char *txt;
836  char **ret;
837 
838  va_start(args, type);
839  txt = va_arg(args, const char *);
840  ret = va_arg(args, char **);
841  va_end(args);
842 
843  *ret = strdup_local(txt);
844  *type = CFAPI_STRING;
845 }
846 
847 static void cfapi_system_register_global_event(int *type, ...) {
848  va_list args;
849  int eventcode;
850  char *pname;
851  f_plug_event hook;
852  crossfire_plugin *cp;
853 
854  va_start(args, type);
855  eventcode = va_arg(args, int);
856  pname = va_arg(args, char *);
857  hook = va_arg(args, f_plug_event);
858  va_end(args);
859 
860  *type = CFAPI_NONE;
861 
862  cp = plugins_find_plugin(pname);
863  cp->gevent[eventcode] = hook;
864 }
865 
866 static void cfapi_system_unregister_global_event(int *type, ...) {
867  va_list args;
868  int eventcode;
869  char *pname;
870  crossfire_plugin *cp;
871 
872  va_start(args, type);
873  eventcode = va_arg(args, int);
874  pname = va_arg(args, char *);
875  va_end(args);
876 
877  *type = CFAPI_NONE;
878 
879  cp = plugins_find_plugin(pname);
880  cp->gevent[eventcode] = NULL;
881 }
882 
889 static void cfapi_system_add_string(int *type, ...) {
890  va_list args;
891  const char *str;
892  sstring *rv;
893 
894  va_start(args, type);
895  str = va_arg(args, const char *);
896  rv = va_arg(args, sstring *);
897  va_end(args);
898 
899  *rv = add_string(str);
900  *type = CFAPI_SSTRING;
901 }
902 
909 static void cfapi_system_remove_string(int *type, ...) {
910  va_list args;
911  sstring str;
912 
913  va_start(args, type);
914  str = va_arg(args, sstring);
915  va_end(args);
916 
917  free_string(str);
918  *type = CFAPI_NONE;
919 }
920 
927 static void cfapi_system_find_string(int *type, ...) {
928  va_list args;
929  const char *str;
930  sstring *rv;
931 
932  va_start(args, type);
933  str = va_arg(args, const char *);
934  rv = va_arg(args, sstring *);
935  va_end(args);
936 
937  *rv = find_string(str);
938  *type = CFAPI_SSTRING;
939 }
940 
946 static void cfapi_system_check_path(int *type, ...) {
947  va_list args;
948  const char *name;
949  int prepend_dir;
950  int *ret;
951 
952  va_start(args, type);
953 
954  name = va_arg(args, char *);
955  prepend_dir = va_arg(args, int);
956  ret = va_arg(args, int *);
957 
958  *ret = check_path(name, prepend_dir);
959 
960  va_end(args);
961  *type = CFAPI_INT;
962 }
963 
969 static void cfapi_system_re_cmp(int *type, ...) {
970  va_list args;
971  const char *str;
972  const char *regexp;
973  const char **rv;
974 
975  va_start(args, type);
976 
977  str = va_arg(args, char *);
978  regexp = va_arg(args, char *);
979  rv = va_arg(args, const char **);
980 
981  *rv = re_cmp(str, regexp);
982 
983  va_end(args);
984  *type = CFAPI_STRING;
985 }
986 
987 static void cfapi_system_directory(int *type, ...) {
988  va_list args;
989  int dirtype;
990  const char **str;
991 
992  va_start(args, type);
993 
994  dirtype = va_arg(args, int);
995  str = va_arg(args, const char **);
996  va_end(args);
997 
998  *type = CFAPI_STRING;
999 
1000  switch (dirtype) {
1001  case 0:
1002  *str = settings.mapdir;
1003  break;
1004 
1005  case 1:
1006  *str = settings.uniquedir;
1007  break;
1008 
1009  case 2:
1010  *str = settings.tmpdir;
1011  break;
1012 
1013  case 3:
1014  *str = settings.confdir;
1015  break;
1016 
1017  case 4:
1018  *str = settings.localdir;
1019  break;
1020 
1021  case 5:
1022  *str = settings.playerdir;
1023  break;
1024 
1025  case 6:
1026  *str = settings.datadir;
1027  break;
1028 
1029  default:
1030  *str = NULL;
1031  }
1032 }
1033 
1040 static void cfapi_get_time(int *type, ...) {
1041  va_list args;
1042  timeofday_t *tod;
1043 
1044  va_start(args, type);
1045  tod = va_arg(args, timeofday_t *);
1046  va_end(args);
1047 
1048  get_tod(tod);
1049  *type = CFAPI_NONE;
1050 }
1051 
1052 #define string_get_int(name) \
1053  va_list args; \
1054  int index; \
1055  const char **str; \
1056  va_start(args, type); \
1057  index = va_arg(args, int); \
1058  str = va_arg(args, const char **); \
1059  va_end(args); \
1060  *str = name(index); \
1061  *type = CFAPI_STRING; \
1062 
1063 
1071 static void cfapi_get_season_name(int *type, ...) {
1073 }
1074 
1083 static void cfapi_get_weekday_name(int *type, ...) {
1085 }
1086 
1095 static void cfapi_get_month_name(int *type, ...) {
1097 }
1098 
1107 static void cfapi_get_periodofday_name(int *type, ...) {
1109 }
1110 
1122 static void cfapi_timer_create(int *type, ...) {
1123  va_list args;
1124  int res;
1125  object *ob;
1126  long delay;
1127  int mode;
1128  int *timer;
1129 
1130  va_start(args, type);
1131  ob = va_arg(args, object *);
1132  delay = va_arg(args, long);
1133  mode = va_arg(args, int);
1134  timer = va_arg(args, int *);
1135  va_end(args);
1136  *type = CFAPI_INT;
1137 
1138  *timer = cftimer_find_free_id();
1139  if (*timer != TIMER_ERR_ID) {
1140  res = cftimer_create(*timer, delay, ob, mode);
1141  if (res != TIMER_ERR_NONE)
1142  *timer = res;
1143  }
1144 }
1145 
1155 static void cfapi_timer_destroy(int *type, ...) {
1156  va_list args;
1157  int id;
1158  int *err;
1159 
1160  va_start(args, type);
1161  id = va_arg(args, int);
1162  err = va_arg(args, int *);
1163  va_end(args);
1164  *type = CFAPI_INT;
1165 
1166  *err = cftimer_destroy(id);
1167 }
1168 
1174 static void cfapi_log(int *type, ...) {
1175  va_list args;
1176  LogLevel logLevel;
1177  const char *message;
1178 
1179  va_start(args, type);
1180  logLevel = va_arg(args, LogLevel);
1181  message = va_arg(args, const char *);
1182  LOG(logLevel, "%s", message);
1183  va_end(args);
1184 
1185  *type = CFAPI_NONE;
1186 }
1187 
1188 /* MAP RELATED HOOKS */
1189 
1198 static void cfapi_map_get_map(int *type, ...) {
1199  va_list args;
1200  mapstruct **ret;
1201  int ctype;
1202  int x, y;
1203  int16_t nx, ny;
1204  const char *name;
1205  mapstruct *m;
1206 
1207  va_start(args, type);
1208 
1209  ctype = va_arg(args, int);
1210 
1211  switch (ctype) {
1212  case 0:
1213  x = va_arg(args, int);
1214  y = va_arg(args, int);
1215  ret = va_arg(args, mapstruct **);
1216  *ret = get_empty_map(x, y);
1217  break;
1218 
1219  case 1:
1220  name = va_arg(args, const char *);
1221  x = va_arg(args, int);
1222  ret = va_arg(args, mapstruct **);
1223  *ret = ready_map_name(name, x);
1224  break;
1225 
1226  case 2:
1227  m = va_arg(args, mapstruct *);
1228  nx = va_arg(args, int);
1229  ny = va_arg(args, int);
1230  ret = va_arg(args, mapstruct **);
1231  *ret = get_map_from_coord(m, &nx, &ny);
1232  break;
1233 
1234  default:
1235  *type = CFAPI_NONE;
1236  va_end(args);
1237  return;
1238  break;
1239  }
1240  va_end(args);
1241  *type = CFAPI_PMAP;
1242 }
1243 
1249 static void cfapi_map_has_been_loaded(int *type, ...) {
1250  va_list args;
1251  mapstruct **map;
1252  char *string;
1253 
1254  va_start(args, type);
1255  string = va_arg(args, char *);
1256  map = va_arg(args, mapstruct **);
1257  *map = has_been_loaded(string);
1258  va_end(args);
1259  *type = CFAPI_PMAP;
1260 }
1261 
1267 static void cfapi_map_create_path(int *type, ...) {
1268  va_list args;
1269  int ctype, size;
1270  const char *str;
1271  char *name;
1272 
1273  va_start(args, type);
1274 
1275  ctype = va_arg(args, int);
1276  str = va_arg(args, const char *);
1277  name = va_arg(args, char *);
1278  size = va_arg(args, int);
1279  *type = CFAPI_STRING;
1280 
1281  switch (ctype) {
1282  case 0:
1283  create_pathname(str, name, size);
1284  break;
1285 
1286  case 1:
1287  create_overlay_pathname(str, name, MAX_BUF);
1288  break;
1289 
1290 /* case 2:
1291  rv = create_items_path(str);
1292  break;*/
1293 
1294  default:
1295  *type = CFAPI_NONE;
1296  break;
1297  }
1298  va_end(args);
1299 }
1300 
1301 static void cfapi_map_get_map_property(int *type, ...) {
1302  va_list args;
1303  mapstruct *map;
1304  int property;
1305 
1306  int *rint;
1307  mapstruct **rmap;
1308  sstring *rstr;
1309  region **rreg;
1310  int16_t *nx, *ny;
1311  int x, y;
1312 
1313  va_start(args, type);
1314 
1315  map = va_arg(args, mapstruct *);
1316  property = va_arg(args, int);
1317 
1318  switch (property) {
1319  case CFAPI_MAP_PROP_FLAGS:
1320  rmap = va_arg(args, mapstruct **);
1321  x = va_arg(args, int);
1322  y = va_arg(args, int);
1323  nx = va_arg(args, int16_t *);
1324  ny = va_arg(args, int16_t *);
1325  rint = va_arg(args, int *);
1326  *rint = get_map_flags(map, rmap, x, y, nx, ny);
1327  *type = CFAPI_INT;
1328  break;
1329 
1331  rint = va_arg(args, int *);
1332  *rint = calculate_difficulty(map);
1333  *type = CFAPI_INT;
1334  break;
1335 
1336  case CFAPI_MAP_PROP_PATH:
1337  rstr = va_arg(args, sstring *);
1338  *rstr = map->path;
1339  *type = CFAPI_SSTRING;
1340  break;
1341 
1343  rstr = va_arg(args, sstring *);
1344  *rstr = map->tmpname;
1345  *type = CFAPI_SSTRING;
1346  break;
1347 
1348  case CFAPI_MAP_PROP_NAME:
1349  rstr = va_arg(args, sstring *);
1350  *rstr = map->name;
1351  *type = CFAPI_SSTRING;
1352  break;
1353 
1355  rint = va_arg(args, int *);
1356  *rint = map->reset_time;
1357  *type = CFAPI_INT;
1358  break;
1359 
1361  rint = va_arg(args, int *);
1362  *rint = map->reset_timeout;
1363  *type = CFAPI_INT;
1364  break;
1365 
1367  rint = va_arg(args, int *);
1368  *rint = map->players;
1369  *type = CFAPI_INT;
1370  break;
1371 
1373  rint = va_arg(args, int *);
1374  *rint = map->darkness;
1375  *type = CFAPI_INT;
1376  break;
1377 
1378  case CFAPI_MAP_PROP_WIDTH:
1379  rint = va_arg(args, int *);
1380  *rint = map->width;
1381  *type = CFAPI_INT;
1382  break;
1383 
1384  case CFAPI_MAP_PROP_HEIGHT:
1385  rint = va_arg(args, int *);
1386  *rint = map->height;
1387  *type = CFAPI_INT;
1388  break;
1389 
1391  rint = va_arg(args, int *);
1392  *rint = map->enter_x;
1393  *type = CFAPI_INT;
1394  break;
1395 
1397  rint = va_arg(args, int *);
1398  *rint = map->enter_y;
1399  *type = CFAPI_INT;
1400  break;
1401 
1403  rstr = va_arg(args, sstring *);
1404  *rstr = map->msg;
1405  *type = CFAPI_SSTRING;
1406  break;
1407 
1408  case CFAPI_MAP_PROP_NEXT:
1409  rmap = va_arg(args, mapstruct **);
1410  *rmap = map ? map->next : first_map;
1411  *type = CFAPI_PMAP;
1412  break;
1413 
1414  case CFAPI_MAP_PROP_REGION:
1415  rreg = va_arg(args, region **);
1416  *rreg = get_region_by_map(map);
1417  *type = CFAPI_PREGION;
1418  break;
1419 
1420  case CFAPI_MAP_PROP_UNIQUE:
1421  rint = va_arg(args, int *);
1422  *rint = map->unique;
1423  *type = CFAPI_INT;
1424  break;
1425 
1426  default:
1427  *type = CFAPI_NONE;
1428  break;
1429  }
1430  va_end(args);
1431 }
1432 
1433 static void cfapi_map_set_map_property(int *type, ...) {
1434  va_list args;
1435  mapstruct *map;
1436  int property;
1437  const char *buf;
1438 
1439  va_start(args, type);
1440 
1441  map = va_arg(args, mapstruct *);
1442  property = va_arg(args, int);
1443 
1444  switch (property) {
1445  case CFAPI_MAP_PROP_PATH:
1446  buf = va_arg(args, const char *);
1447  snprintf(map->path, sizeof(map->path), "%s", buf);
1448  *type = CFAPI_STRING;
1449  break;
1450 
1451  default:
1452  *type = CFAPI_NONE;
1453  break;
1454  }
1455  va_end(args);
1456 }
1457 
1463 static void cfapi_map_out_of_map(int *type, ...) {
1464  va_list args;
1465  mapstruct *map;
1466  int x, y;
1467  int *rint;
1468 
1469  va_start(args, type);
1470  map = va_arg(args, mapstruct *);
1471  x = va_arg(args, int);
1472  y = va_arg(args, int);
1473  rint = va_arg(args, int *);
1474 
1475  *rint = out_of_map(map, x, y);
1476  va_end(args);
1477  *type = CFAPI_INT;
1478 }
1479 
1485 static void cfapi_map_update_position(int *type, ...) {
1486  va_list args;
1487  mapstruct *map;
1488  int x, y;
1489 
1490  va_start(args, type);
1491 
1492  map = va_arg(args, mapstruct *);
1493  x = va_arg(args, int);
1494  y = va_arg(args, int);
1495 
1496  update_position(map, x, y);
1497  va_end(args);
1498  *type = CFAPI_NONE;
1499 }
1500 
1501 static void cfapi_map_delete_map(int *type, ...) {
1502  va_list args;
1503  mapstruct *map;
1504  va_start(args, type);
1505 
1506  map = va_arg(args, mapstruct *);
1507 
1508  delete_map(map);
1509 
1510  va_end(args);
1511  *type = CFAPI_NONE;
1512 }
1513 
1514 static void cfapi_map_message(int *type, ...) {
1515  va_list args;
1516  mapstruct *map;
1517  const char *string;
1518  int color;
1519 
1520  va_start(args, type);
1521  map = va_arg(args, mapstruct *);
1522  string = va_arg(args, const char *);
1523  color = va_arg(args, int);
1524  va_end(args);
1525 
1526  /* function should be extended to take message types probably */
1527  ext_info_map(color, map, MSG_TYPE_MISC, MSG_SUBTYPE_NONE, string);
1528  *type = CFAPI_NONE;
1529 }
1530 
1536 static void cfapi_map_get_object_at(int *type, ...) {
1537  va_list args;
1538  mapstruct *map;
1539  int x, y;
1540  int16_t sx, sy;
1541  object **robj;
1542 
1543  va_start(args, type);
1544  map = va_arg(args, mapstruct *);
1545  x = va_arg(args, int);
1546  y = va_arg(args, int);
1547  robj = va_arg(args, object **);
1548  va_end(args);
1549 
1550  sx = x;
1551  sy = y;
1552  if (get_map_flags(map, &map, x, y, &sx, &sy)&P_OUT_OF_MAP)
1553  *robj = NULL;
1554  else
1555  *robj = GET_MAP_OB(map, sx, sy);
1556  *type = CFAPI_POBJECT;
1557 }
1558 
1565 static void cfapi_map_find_by_archetype_name(int *type, ...) {
1566  va_list args;
1567  int x, y;
1568  mapstruct *map;
1569  char *msg;
1570  object **robj;
1571 
1572  va_start(args, type);
1573 
1574  msg = va_arg(args, char *);
1575  map = va_arg(args, mapstruct *);
1576  x = va_arg(args, int);
1577  y = va_arg(args, int);
1578  robj = va_arg(args, object **);
1579 
1580  va_end(args);
1581 
1582  *robj = map_find_by_archetype(map, x, y, try_find_archetype(msg));
1583  *type = CFAPI_POBJECT;
1584 }
1585 
1591 static void cfapi_map_change_light(int *type, ...) {
1592  va_list args;
1593  int change;
1594  mapstruct *map;
1595  int *rint;
1596 
1597  va_start(args, type);
1598  map = va_arg(args, mapstruct *);
1599  change = va_arg(args, int);
1600  rint = va_arg(args, int *);
1601  va_end(args);
1602 
1603  *type = CFAPI_INT;
1604  *rint = change_map_light(map, change);
1605 }
1606 
1607 /* OBJECT-RELATED HOOKS */
1608 
1622 static void cfapi_object_move(int *type, ...) {
1623  va_list args;
1624  int kind;
1625  object *op;
1626  object *activator;
1627  player *pl;
1628  int direction;
1629  int *ret;
1630 
1631  va_start(args, type);
1632  kind = va_arg(args, int);
1633  switch (kind) {
1634  case 0:
1635  op = va_arg(args, object *);
1636  direction = va_arg(args, int);
1637  activator = va_arg(args, object *);
1638  ret = va_arg(args, int *);
1639  va_end(args);
1640  *ret = move_ob(op, direction, activator);
1641  break;
1642 
1643  case 1:
1644  pl = va_arg(args, player *);
1645  direction = va_arg(args, int);
1646  ret = va_arg(args, int *);
1647  va_end(args);
1648  *ret = move_player(pl->ob, direction);
1649  break;
1650 
1651  case 2:
1652  op = va_arg(args, object *);
1653  ret = va_arg(args, int *);
1654  va_end(args);
1655  *ret = player_arrest(op);
1656  break;
1657 
1658  default:
1659  // Just end the use of variable args. We got a wrong type.
1660  va_end(args);
1661  }
1662  *type = CFAPI_INT;
1663 }
1664 
1672 static void cfapi_object_get_key(int *type, ...) {
1673  va_list args;
1674  const char *keyname;
1675  const char **value;
1676  object *op;
1677 
1678  va_start(args, type);
1679  op = va_arg(args, object *);
1680  keyname = va_arg(args, const char *);
1681  value = va_arg(args, const char **);
1682  va_end(args);
1683 
1684  *value = object_get_value(op, keyname);
1685  *type = CFAPI_SSTRING;
1686 }
1687 
1694 static void cfapi_object_set_key(int *type, ...) {
1695  va_list args;
1696  const char *keyname;
1697  const char *value;
1698  int *ret;
1699  object *op;
1700  int add_key;
1701 
1702  va_start(args, type);
1703  op = va_arg(args, object *);
1704  keyname = va_arg(args, char *);
1705  value = va_arg(args, char *);
1706  add_key = va_arg(args, int);
1707  ret = va_arg(args, int *);
1708  va_end(args);
1709 
1710  *ret = object_set_value(op, keyname, value, add_key);
1711  *type = CFAPI_INT;
1712 }
1713 
1717 static void cfapi_object_get_property(int *type, ...) {
1718  va_list args;
1719  int property;
1720  object *op;
1721  int *rint;
1722  object **robject;
1723  mapstruct **rmap;
1724  float *rfloat;
1725  archetype **rarch;
1726  sstring *rsstring;
1727  char *rbuffer;
1728  int rbufsize;
1729  MoveType *rmove;
1730  int64_t *rint64;
1731  partylist **rparty;
1732  double *rdouble;
1733  long *rlong;
1734 
1735  va_start(args, type);
1736 
1737  op = va_arg(args, object *);
1738  property = va_arg(args, int);
1739  switch (property) {
1741  robject = va_arg(args, object **);
1742  *robject = op->above;
1743  *type = CFAPI_POBJECT;
1744  break;
1745 
1747  robject = va_arg(args, object **);
1748  *robject = op->below;
1749  *type = CFAPI_POBJECT;
1750  break;
1751 
1753  robject = va_arg(args, object **);
1754  *robject = op->active_next;
1755  *type = CFAPI_POBJECT;
1756  break;
1757 
1759  robject = va_arg(args, object **);
1760  *robject = op->active_prev;
1761  *type = CFAPI_POBJECT;
1762  break;
1763 
1765  robject = va_arg(args, object **);
1766  *robject = op->inv;
1767  *type = CFAPI_POBJECT;
1768  break;
1769 
1771  robject = va_arg(args, object **);
1772  *robject = op->env;
1773  *type = CFAPI_POBJECT;
1774  break;
1775 
1777  robject = va_arg(args, object **);
1778  *robject = op->head;
1779  *type = CFAPI_POBJECT;
1780  break;
1781 
1783  robject = va_arg(args, object **);
1784  *robject = op->container;
1785  *type = CFAPI_POBJECT;
1786  break;
1787 
1788  case CFAPI_OBJECT_PROP_MAP:
1789  rmap = va_arg(args, mapstruct **);
1790  *rmap = op->map;
1791  *type = CFAPI_PMAP;
1792  break;
1793 
1795  rint = va_arg(args, int *);
1796  *rint = op->count;
1797  *type = CFAPI_INT;
1798  break;
1799 
1801  rbuffer = va_arg(args, char *);
1802  rbufsize = va_arg(args, int);
1803  query_name(op, rbuffer, rbufsize);
1804  *type = CFAPI_STRING;
1805  break;
1806 
1808  rsstring = va_arg(args, sstring *);
1809  *rsstring = op->name_pl;
1810  *type = CFAPI_SSTRING;
1811  break;
1812 
1814  rsstring = va_arg(args, sstring *);
1815  *rsstring = op->title;
1816  *type = CFAPI_SSTRING;
1817  break;
1818 
1820  rsstring = va_arg(args, sstring *);
1821  *rsstring = op->race;
1822  *type = CFAPI_SSTRING;
1823  break;
1824 
1826  rsstring = va_arg(args, sstring *);
1827  *rsstring = op->slaying;
1828  *type = CFAPI_SSTRING;
1829  break;
1830 
1832  rsstring = va_arg(args, sstring *);
1833  *rsstring = op->skill;
1834  *type = CFAPI_SSTRING;
1835  break;
1836 
1838  rsstring = va_arg(args, sstring *);
1839  *rsstring = op->msg;
1840  *type = CFAPI_SSTRING;
1841  break;
1842 
1844  rsstring = va_arg(args, sstring *);
1845  *rsstring = op->lore;
1846  *type = CFAPI_SSTRING;
1847  break;
1848 
1849  case CFAPI_OBJECT_PROP_X:
1850  rint = va_arg(args, int *);
1851  *rint = op->x;
1852  *type = CFAPI_INT;
1853  break;
1854 
1855  case CFAPI_OBJECT_PROP_Y:
1856  rint = va_arg(args, int *);
1857  *rint = op->y;
1858  *type = CFAPI_INT;
1859  break;
1860 
1862  rfloat = va_arg(args, float *);
1863  *rfloat = op->speed;
1864  *type = CFAPI_FLOAT;
1865  break;
1866 
1868  rfloat = va_arg(args, float *);
1869  *rfloat = op->speed_left;
1870  *type = CFAPI_FLOAT;
1871  break;
1872 
1874  rint = va_arg(args, int *);
1875  *rint = op->nrof;
1876  *type = CFAPI_INT;
1877  break;
1878 
1880  rint = va_arg(args, int *);
1881  *rint = op->direction;
1882  *type = CFAPI_INT;
1883  break;
1884 
1886  rint = va_arg(args, int *);
1887  *rint = op->facing;
1888  *type = CFAPI_INT;
1889  break;
1890 
1892  rint = va_arg(args, int *);
1893  *rint = op->type;
1894  *type = CFAPI_INT;
1895  break;
1896 
1898  rint = va_arg(args, int *);
1899  *rint = op->subtype;
1900  *type = CFAPI_INT;
1901  break;
1902 
1904  rint = va_arg(args, int *);
1905  *rint = op->client_type;
1906  *type = CFAPI_INT;
1907  break;
1908 
1909  case CFAPI_OBJECT_PROP_RESIST: {
1910  int idx;
1911  int16_t *resist;
1912 
1913  idx = va_arg(args, int);
1914  resist = va_arg(args, int16_t *);
1915  *resist = op->resist[idx];
1916  }
1917  *type = CFAPI_INT16;
1918  break;
1919 
1921  rint = va_arg(args, int *);
1922  *rint = op->attacktype;
1923  *type = CFAPI_INT;
1924  break;
1925 
1927  rint = va_arg(args, int *);
1928  *rint = op->path_attuned;
1929  *type = CFAPI_INT;
1930  break;
1931 
1933  rint = va_arg(args, int *);
1934  *rint = op->path_repelled;
1935  *type = CFAPI_INT;
1936  break;
1937 
1939  rint = va_arg(args, int *);
1940  *rint = op->path_denied;
1941  *type = CFAPI_INT;
1942  break;
1943 
1945  rint = va_arg(args, int *);
1946  *rint = op->material;
1947  *type = CFAPI_INT;
1948  break;
1949 
1951  rsstring = va_arg(args, sstring *);
1952  *rsstring = op->materialname;
1953  *type = CFAPI_SSTRING;
1954  break;
1955 
1957  rint = va_arg(args, int *);
1958  *rint = op->magic;
1959  *type = CFAPI_INT;
1960  break;
1961 
1963  rlong = va_arg(args, long *);
1964  *rlong = op->value;
1965  *type = CFAPI_LONG;
1966  break;
1967 
1969  rint = va_arg(args, int *);
1970  *rint = op->level;
1971  *type = CFAPI_INT;
1972  break;
1973 
1975  rint = va_arg(args, int *);
1976  *rint = op->last_heal;
1977  *type = CFAPI_INT;
1978  break;
1979 
1981  rint = va_arg(args, int *);
1982  *rint = op->last_sp;
1983  *type = CFAPI_INT;
1984  break;
1985 
1987  rint = va_arg(args, int *);
1988  *rint = op->last_grace;
1989  *type = CFAPI_INT;
1990  break;
1991 
1993  rint = va_arg(args, int *);
1994  *rint = op->last_eat;
1995  *type = CFAPI_INT;
1996  break;
1997 
1999  rint = va_arg(args, int *);
2000  *rint = op->invisible;
2001  *type = CFAPI_INT;
2002  break;
2003 
2005  rint = va_arg(args, int *);
2006  *rint = op->pick_up;
2007  *type = CFAPI_INT;
2008  break;
2009 
2011  rint = va_arg(args, int *);
2012  *rint = op->item_power;
2013  *type = CFAPI_INT;
2014  break;
2015 
2017  rint = va_arg(args, int *);
2018  *rint = op->gen_sp_armour;
2019  *type = CFAPI_INT;
2020  break;
2021 
2023  rint = va_arg(args, int *);
2024  *rint = op->weight;
2025  *type = CFAPI_INT;
2026  break;
2027 
2029  rint = va_arg(args, int *);
2030  *rint = op->weight_limit;
2031  *type = CFAPI_INT;
2032  break;
2033 
2035  rint = va_arg(args, int *);
2036  *rint = op->carrying;
2037  *type = CFAPI_INT;
2038  break;
2039 
2041  rint = va_arg(args, int *);
2042  *rint = op->glow_radius;
2043  *type = CFAPI_INT;
2044  break;
2045 
2047  rint64 = va_arg(args, int64_t *);
2048  *rint64 = op->perm_exp;
2049  *type = CFAPI_SINT64;
2050  break;
2051 
2053  robject = va_arg(args, object **);
2054  *robject = op->current_weapon;
2055  *type = CFAPI_POBJECT;
2056  break;
2057 
2059  robject = va_arg(args, object **);
2060  *robject = op->enemy;
2061  *type = CFAPI_POBJECT;
2062  break;
2063 
2065  robject = va_arg(args, object **);
2066  *robject = op->attacked_by;
2067  *type = CFAPI_POBJECT;
2068  break;
2069 
2071  rint = va_arg(args, int *);
2072  *rint = op->run_away;
2073  *type = CFAPI_INT;
2074  break;
2075 
2077  robject = va_arg(args, object **);
2078  *robject = op->chosen_skill;
2079  *type = CFAPI_POBJECT;
2080  break;
2081 
2083  rint = va_arg(args, int *);
2084  *rint = op->hide;
2085  *type = CFAPI_INT;
2086  break;
2087 
2089  rint = va_arg(args, int *);
2090  *rint = op->move_status;
2091  *type = CFAPI_INT;
2092  break;
2093 
2095  rint = va_arg(args, int *);
2096  *rint = op->attack_movement;
2097  *type = CFAPI_INT;
2098  break;
2099 
2101  robject = va_arg(args, object **);
2102  *robject = op->spellitem;
2103  *type = CFAPI_POBJECT;
2104  break;
2105 
2107  rdouble = va_arg(args, double *);
2108  *rdouble = op->expmul;
2109  *type = CFAPI_DOUBLE;
2110  break;
2111 
2113  rarch = va_arg(args, archetype **);
2114  *rarch = op->arch;
2115  *type = CFAPI_PARCH;
2116  break;
2117 
2119  rarch = va_arg(args, archetype **);
2120  *rarch = op->other_arch;
2121  *type = CFAPI_PARCH;
2122  break;
2123 
2125  rsstring = va_arg(args, sstring *);
2126  *rsstring = op->custom_name;
2127  *type = CFAPI_SSTRING;
2128  break;
2129 
2131  rint = va_arg(args, int *);
2132  *rint = op->anim_speed;
2133  *type = CFAPI_INT;
2134  break;
2135 
2137  rint = va_arg(args, int *);
2138  *rint = is_friendly(op);
2139  *type = CFAPI_INT;
2140  break;
2141 
2143  rbuffer = va_arg(args, char *);
2144  rbufsize = va_arg(args, int);
2145  query_short_name(op, rbuffer, rbufsize);
2146  *type = CFAPI_STRING;
2147  break;
2148 
2150  int i;
2151 
2152  i = va_arg(args, int);
2153  rbuffer = va_arg(args, char *);
2154  rbufsize = va_arg(args, int);
2155  query_base_name(op, i, rbuffer, rbufsize);
2156  *type = CFAPI_STRING;
2157  }
2158  break;
2159 
2161  rsstring = va_arg(args, sstring *);
2162  *rsstring = op->name;
2163  *type = CFAPI_SSTRING;
2164  break;
2165 
2167  rint = va_arg(args, int *);
2168  *rint = is_magical(op);
2169  *type = CFAPI_INT;
2170  break;
2171 
2173  rint = va_arg(args, int *);
2174  *rint = op->stats.luck;
2175  *type = CFAPI_INT;
2176  break;
2177 
2178  case CFAPI_OBJECT_PROP_EXP:
2179  rint64 = va_arg(args, int64_t *);
2180  *rint64 = op->stats.exp;
2181  *type = CFAPI_SINT64;
2182  break;
2183 
2185  robject = va_arg(args, object **);
2186  *robject = object_get_owner(op);
2187  *type = CFAPI_POBJECT;
2188  break;
2189 
2191  int stype;
2192 
2193  stype = va_arg(args, int);
2194  switch (stype) {
2195  unsigned char ptype;
2196  char *buf;
2197  archetype *at;
2198 
2199  case 0: /* present_in_ob */
2200  ptype = (unsigned char)(va_arg(args, int));
2201  robject = va_arg(args, object **);
2202  *robject = object_present_in_ob(ptype, op);
2203  break;
2204 
2205  case 1: /* present_in_ob_by_name */
2206  ptype = (unsigned char)(va_arg(args, int));
2207  buf = va_arg(args, char *);
2208  robject = va_arg(args, object **);
2209  *robject = object_present_in_ob_by_name(ptype, buf, op);
2210  break;
2211 
2212  case 2: /* arch_present_in_ob */
2213  at = va_arg(args, archetype *);
2214  robject = va_arg(args, object **);
2215  *robject = arch_present_in_ob(at, op);
2216  break;
2217  }
2218  }
2219  *type = CFAPI_POBJECT;
2220  break;
2221 
2223  rint = va_arg(args, int *);
2224  *rint = (QUERY_FLAG(op, FLAG_WAS_WIZ));
2225  *type = CFAPI_INT;
2226  break;
2227 
2229  object *op2;
2230 
2231  op2 = va_arg(args, object *);
2232  rint = va_arg(args, int *);
2233  *rint = object_can_merge(op, op2);
2234  }
2235  *type = CFAPI_INT;
2236  break;
2237 
2239  object *op2;
2240 
2241  op2 = va_arg(args, object *);
2242  rint = va_arg(args, int *);
2243  *rint = object_can_pick(op2, op);
2244  }
2245  *type = CFAPI_INT;
2246  break;
2247 
2248  case CFAPI_OBJECT_PROP_FLAGS: {
2249  int fl;
2250 
2251  fl = va_arg(args, int);
2252  rint = va_arg(args, int *);
2253  *rint = QUERY_FLAG(op, fl);
2254  }
2255  *type = CFAPI_INT;
2256  break;
2257 
2258  case CFAPI_OBJECT_PROP_STR:
2259  rint = va_arg(args, int *);
2260  *rint = op->stats.Str;
2261  *type = CFAPI_INT;
2262  break;
2263 
2264  case CFAPI_OBJECT_PROP_DEX:
2265  rint = va_arg(args, int *);
2266  *rint = op->stats.Dex;
2267  *type = CFAPI_INT;
2268  break;
2269 
2270  case CFAPI_OBJECT_PROP_CON:
2271  rint = va_arg(args, int *);
2272  *rint = op->stats.Con;
2273  *type = CFAPI_INT;
2274  break;
2275 
2276  case CFAPI_OBJECT_PROP_WIS:
2277  rint = va_arg(args, int *);
2278  *rint = op->stats.Wis;
2279  *type = CFAPI_INT;
2280  break;
2281 
2282  case CFAPI_OBJECT_PROP_INT:
2283  rint = va_arg(args, int *);
2284  *rint = op->stats.Int;
2285  *type = CFAPI_INT;
2286  break;
2287 
2288  case CFAPI_OBJECT_PROP_POW:
2289  rint = va_arg(args, int *);
2290  *rint = op->stats.Pow;
2291  *type = CFAPI_INT;
2292  break;
2293 
2294  case CFAPI_OBJECT_PROP_CHA:
2295  rint = va_arg(args, int *);
2296  *rint = op->stats.Cha;
2297  *type = CFAPI_INT;
2298  break;
2299 
2300  case CFAPI_OBJECT_PROP_WC:
2301  rint = va_arg(args, int *);
2302  *rint = op->stats.wc;
2303  *type = CFAPI_INT;
2304  break;
2305 
2306  case CFAPI_OBJECT_PROP_AC:
2307  rint = va_arg(args, int *);
2308  *rint = op->stats.ac;
2309  *type = CFAPI_INT;
2310  break;
2311 
2312  case CFAPI_OBJECT_PROP_HP:
2313  rint = va_arg(args, int *);
2314  *rint = op->stats.hp;
2315  *type = CFAPI_INT;
2316  break;
2317 
2318  case CFAPI_OBJECT_PROP_SP:
2319  rint = va_arg(args, int *);
2320  *rint = op->stats.sp;
2321  *type = CFAPI_INT;
2322  break;
2323 
2324  case CFAPI_OBJECT_PROP_GP:
2325  rint = va_arg(args, int *);
2326  *rint = op->stats.grace;
2327  *type = CFAPI_INT;
2328  break;
2329 
2330  case CFAPI_OBJECT_PROP_FP:
2331  rint = va_arg(args, int *);
2332  *rint = op->stats.food;
2333  *type = CFAPI_INT;
2334  break;
2335 
2337  rint = va_arg(args, int *);
2338  *rint = op->stats.maxhp;
2339  *type = CFAPI_INT;
2340  break;
2341 
2343  rint = va_arg(args, int *);
2344  *rint = op->stats.maxsp;
2345  *type = CFAPI_INT;
2346  break;
2347 
2349  rint = va_arg(args, int *);
2350  *rint = op->stats.maxgrace;
2351  *type = CFAPI_INT;
2352  break;
2353 
2354  case CFAPI_OBJECT_PROP_DAM:
2355  rint = va_arg(args, int *);
2356  *rint = op->stats.dam;
2357  *type = CFAPI_INT;
2358  break;
2359 
2360  case CFAPI_OBJECT_PROP_GOD:
2361  rsstring = va_arg(args, sstring *);
2362  *rsstring = determine_god(op);
2363  *type = CFAPI_SSTRING;
2364  break;
2365 
2367  rsstring = va_arg(args, sstring *);
2368  *rsstring = op->arch->name;
2369  *type = CFAPI_SSTRING;
2370  break;
2371 
2373  rint = va_arg(args, int *);
2374  *rint = op->invisible;
2375  *type = CFAPI_INT;
2376  break;
2377 
2379  rbuffer = va_arg(args, char *);
2380  rbufsize = va_arg(args, int);
2381  if (rbufsize > 0) {
2382  strncpy(rbuffer, op->face->name, rbufsize);
2383  rbuffer[rbufsize - 1] = '\0';
2384  }
2385  *type = CFAPI_STRING;
2386  break;
2387 
2389  rbuffer = va_arg(args, char *);
2390  rbufsize = va_arg(args, int);
2391  if (rbufsize > 0) {
2392  if (op->animation_id != 0) {
2393  strncpy(rbuffer, animations[op->animation_id].name, rbufsize);
2394  rbuffer[rbufsize - 1] = '\0';
2395  }
2396  else
2397  rbuffer[0] = '\0';
2398  }
2399  *type = CFAPI_STRING;
2400  break;
2401 
2402  case CFAPI_PLAYER_PROP_IP:
2403  rsstring = va_arg(args, sstring *);
2404  *rsstring = op->contr->socket.host;
2405  *type = CFAPI_SSTRING;
2406  break;
2407 
2409  robject = va_arg(args, object **);
2410  *robject = find_marked_object(op);
2411  *type = CFAPI_POBJECT;
2412  break;
2413 
2415  rparty = va_arg(args, partylist **);
2416  *rparty = (op->contr ? op->contr->party : NULL);
2417  *type = CFAPI_PPARTY;
2418  break;
2419 
2421  robject = va_arg(args, object **);
2422  if (op)
2423  *robject = op->contr->next ? op->contr->next->ob : NULL;
2424  else
2425  /* This can be called when there is no player. */
2426  *robject = first_player ? first_player->ob : NULL;
2427  *type = CFAPI_POBJECT;
2428  break;
2429 
2431  rbuffer = va_arg(args, char *);
2432  rbufsize = va_arg(args, int);
2433  player_get_title(op->contr, rbuffer, rbufsize);
2434  *type = CFAPI_STRING;
2435  break;
2436 
2438  rmove = va_arg(args, MoveType *);
2439  *rmove = op->move_type;
2440  *type = CFAPI_MOVETYPE;
2441  break;
2442 
2444  rmove = va_arg(args, MoveType *);
2445  *rmove = op->move_block;
2446  *type = CFAPI_MOVETYPE;
2447  break;
2448 
2450  rmove = va_arg(args, MoveType *);
2451  *rmove = op->move_allow;
2452  *type = CFAPI_MOVETYPE;
2453  break;
2454 
2456  rmove = va_arg(args, MoveType *);
2457  *rmove = op->move_on;
2458  *type = CFAPI_MOVETYPE;
2459  break;
2460 
2462  rmove = va_arg(args, MoveType *);
2463  *rmove = op->move_off;
2464  *type = CFAPI_MOVETYPE;
2465  break;
2466 
2468  rmove = va_arg(args, MoveType *);
2469  *rmove = op->move_type;
2470  *type = CFAPI_MOVETYPE;
2471  break;
2472 
2474  rfloat = va_arg(args, float *);
2475  *rfloat = op->move_slow_penalty;
2476  *type = CFAPI_FLOAT;
2477  break;
2478 
2480  rbuffer = va_arg(args, char *);
2481  rbufsize = va_arg(args, int);
2482  snprintf(rbuffer, rbufsize, "%s", op->contr->savebed_map);
2483  *type = CFAPI_STRING;
2484  break;
2485 
2487  rint = va_arg(args, int *);
2488  *rint = op->contr->bed_x;
2489  *type = CFAPI_INT;
2490  break;
2491 
2493  rint = va_arg(args, int *);
2494  *rint = op->contr->bed_y;
2495  *type = CFAPI_INT;
2496  break;
2497 
2499  rint = va_arg(args, int *);
2500  *rint = op->duration;
2501  *type = CFAPI_INT;
2502  break;
2503 
2504  default:
2505  *type = CFAPI_NONE;
2506  break;
2507  }
2508  va_end(args);
2509 }
2510 
2519 static void copy_message(object *op, const char *msg) {
2520  char *temp;
2521  int size;
2522 
2523  if (!msg)
2524  return;
2525 
2526  /* need to reset parsed dialog information */
2528 
2529  size = strlen(msg);
2530 
2531  if (msg[0] != 0 && msg[size-1] == '\n') {
2532  object_set_msg(op, msg);
2533  return;
2534  }
2535 
2536  temp = malloc(size+2);
2537  if (!temp)
2539  snprintf(temp, size+2, "%s\n", msg);
2540  object_set_msg(op, temp);
2541  free(temp);
2542 }
2543 
2552 static void cfapi_object_set_property(int *type, ...) {
2553  va_list args;
2554  int iarg, *ret;
2555  long larg;
2556  char *sarg;
2557  double darg;
2558  object *oparg;
2559  object *op;
2560  int property;
2561  int64_t s64arg;
2562  partylist *partyarg;
2563  float farg;
2564  MoveType *move; /* MoveType can't be used through va_arg so use MoveType * */
2565 
2566  va_start(args, type);
2567  op = va_arg(args, object *);
2568  property = va_arg(args, int);
2569  *type = CFAPI_NONE;
2570 
2571  if (op != NULL && (!op->arch || (op != &op->arch->clone))) {
2572  switch (property) {
2574  sarg = va_arg(args, char *);
2575  *type = CFAPI_STRING;
2576  FREE_AND_COPY(op->name, sarg);
2577  send_changed_object(op);
2578  break;
2579 
2581  sarg = va_arg(args, char *);
2582  *type = CFAPI_STRING;
2583  FREE_AND_COPY(op->name_pl, sarg);
2584  send_changed_object(op);
2585  break;
2586 
2588  sarg = va_arg(args, char *);
2589  *type = CFAPI_STRING;
2590  FREE_AND_COPY(op->title, sarg);
2591  break;
2592 
2594  sarg = va_arg(args, char *);
2595  *type = CFAPI_STRING;
2596  FREE_AND_COPY(op->race, sarg);
2597  break;
2598 
2600  sarg = va_arg(args, char *);
2601  *type = CFAPI_STRING;
2602  FREE_AND_COPY(op->slaying, sarg);
2603  break;
2604 
2606  sarg = va_arg(args, char *);
2607  *type = CFAPI_STRING;
2608  FREE_AND_COPY(op->skill, sarg);
2609  break;
2610 
2612  sarg = va_arg(args, char *);
2613  *type = CFAPI_STRING;
2614  copy_message(op, sarg);
2615  break;
2616 
2618  sarg = va_arg(args, char *);
2619  *type = CFAPI_STRING;
2620  FREE_AND_COPY(op->lore, sarg);
2621  break;
2622 
2624  farg = va_arg(args, double);
2625  *type = CFAPI_FLOAT;
2626  if (farg != op->speed) {
2627  op->speed = farg;
2628  object_update_speed(op);
2629  }
2630  break;
2631 
2633  farg = va_arg(args, double);
2634  *type = CFAPI_FLOAT;
2635  op->speed_left = farg;
2636  break;
2637 
2639  iarg = va_arg(args, int);
2640  *type = CFAPI_INT;
2641  if (iarg < 0)
2642  iarg = 0;
2643  if (op->nrof > (uint32_t)iarg)
2644  object_decrease_nrof(op, op->nrof-iarg);
2645  else if (op->nrof < (uint32_t)iarg) {
2646  object *tmp;
2647  player *pl;
2648 
2649  op->nrof = iarg;
2650  if (op->env != NULL) {
2651  tmp = object_get_player_container(op->env);
2652  if (!tmp) {
2653  for (pl = first_player; pl; pl = pl->next)
2654  if (pl->ob->container == op->env)
2655  break;
2656  if (pl)
2657  tmp = pl->ob;
2658  else
2659  tmp = NULL;
2660  } else {
2661  object_sum_weight(tmp);
2662  fix_object(tmp);
2663  }
2664  if (tmp)
2665  esrv_update_item(UPD_NROF, tmp, op);
2666  } else {
2667  FOR_ABOVE_PREPARE(op, tmp)
2668  if (tmp->type == PLAYER)
2669  tmp->contr->socket.update_look = 1;
2670  FOR_ABOVE_FINISH();
2671  }
2672  }
2673  break;
2674 
2676  iarg = va_arg(args, int);
2677  *type = CFAPI_INT;
2678  op->direction = iarg;
2679  break;
2680 
2682  iarg = va_arg(args, int);
2683  *type = CFAPI_INT;
2684  op->facing = iarg;
2685  break;
2686 
2687  case CFAPI_OBJECT_PROP_RESIST: {
2688  int iargbis = va_arg(args, int);
2689 
2690  *type = CFAPI_INT16;
2691  iarg = va_arg(args, int);
2692  op->resist[iargbis] = iarg;
2693  }
2694  break;
2695 
2697  iarg = va_arg(args, int);
2698  *type = CFAPI_INT;
2699  op->attacktype = iarg;
2700  break;
2701 
2703  iarg = va_arg(args, int);
2704  *type = CFAPI_INT;
2705  op->path_attuned = iarg;
2706  break;
2707 
2709  iarg = va_arg(args, int);
2710  *type = CFAPI_INT;
2711  op->path_repelled = iarg;
2712  break;
2713 
2715  iarg = va_arg(args, int);
2716  *type = CFAPI_INT;
2717  op->path_denied = iarg;
2718  break;
2719 
2721  iarg = va_arg(args, int);
2722  *type = CFAPI_INT;
2723  op->material = iarg;
2724  break;
2725 
2727  break;
2728 
2730  iarg = va_arg(args, int);
2731  *type = CFAPI_INT;
2732  op->magic = iarg;
2733  break;
2734 
2736  larg = va_arg(args, long);
2737  *type = CFAPI_LONG;
2738  op->value = larg;
2739  break;
2740 
2742  iarg = va_arg(args, int);
2743  *type = CFAPI_INT;
2744  op->level = iarg;
2745  break;
2746 
2748  iarg = va_arg(args, int);
2749  *type = CFAPI_INT;
2750  op->last_heal = iarg;
2751  break;
2752 
2754  iarg = va_arg(args, int);
2755  *type = CFAPI_INT;
2756  op->last_sp = iarg;
2757  break;
2758 
2760  iarg = va_arg(args, int);
2761  *type = CFAPI_INT;
2762  op->last_grace = iarg;
2763  break;
2764 
2766  iarg = va_arg(args, int);
2767  *type = CFAPI_INT;
2768  op->last_eat = iarg;
2769  break;
2770 
2772  iarg = va_arg(args, int);
2773  *type = CFAPI_INT;
2774  op->invisible = iarg;
2775  break;
2776 
2778  iarg = va_arg(args, int);
2779  *type = CFAPI_INT;
2780  op->pick_up = iarg;
2781  break;
2782 
2784  iarg = va_arg(args, int);
2785  *type = CFAPI_INT;
2786  op->item_power = iarg;
2787  break;
2788 
2790  iarg = va_arg(args, int);
2791  *type = CFAPI_INT;
2792  op->gen_sp_armour = iarg;
2793  break;
2794 
2796  iarg = va_arg(args, int);
2797  *type = CFAPI_INT;
2798  if (op->weight != iarg) {
2799  object *tmp;
2800  player *pl;
2801 
2802  op->weight = iarg;
2803  if (op->env != NULL) {
2804  tmp = object_get_player_container(op->env);
2805  if (!tmp) {
2806  for (pl = first_player; pl; pl = pl->next)
2807  if (pl->ob->container == op->env)
2808  break;
2809  if (pl)
2810  tmp = pl->ob;
2811  else
2812  tmp = NULL;
2813  } else {
2814  object_sum_weight(tmp);
2815  fix_object(tmp);
2816  }
2817  if (tmp)
2818  esrv_update_item(UPD_WEIGHT, tmp, op);
2819  } else {
2820  FOR_ABOVE_PREPARE(op, tmp)
2821  if (tmp->type == PLAYER)
2822  esrv_update_item(UPD_WEIGHT, tmp, op);
2823  FOR_ABOVE_FINISH();
2824  }
2825  }
2826  break;
2827 
2829  iarg = va_arg(args, int);
2830  *type = CFAPI_INT;
2831  op->weight_limit = iarg;
2832  break;
2833 
2835  iarg = va_arg(args, int);
2836  *type = CFAPI_INT;
2837  if (op->glow_radius != iarg) {
2838  object *tmp;
2839 
2840  op->glow_radius = iarg;
2841  tmp = object_get_env_recursive(op);
2842  if (tmp->map != NULL) {
2843  SET_MAP_FLAGS(tmp->map, tmp->x, tmp->y, P_NEED_UPDATE);
2844  update_position(tmp->map, tmp->x, tmp->y);
2845  update_all_los(tmp->map, tmp->x, tmp->y);
2846  }
2847  }
2848  break;
2849 
2851  s64arg = va_arg(args, int64_t);
2852  *type = CFAPI_SINT64;
2853  op->perm_exp = s64arg;
2854  break;
2855 
2857  oparg = va_arg(args, object *);
2858  *type = CFAPI_POBJECT;
2859  object_set_enemy(op, oparg);
2860  break;
2861 
2863  iarg = va_arg(args, int);
2864  *type = CFAPI_INT;
2865  op->run_away = iarg;
2866  break;
2867 
2869  oparg = va_arg(args, object *);
2870  *type = CFAPI_POBJECT;
2871  op->chosen_skill = oparg;
2872  break;
2873 
2875  iarg = va_arg(args, int);
2876  *type = CFAPI_INT;
2877  op->hide = iarg;
2878  break;
2879 
2881  iarg = va_arg(args, int);
2882  *type = CFAPI_INT;
2883  op->move_status = iarg;
2884  break;
2885 
2887  iarg = va_arg(args, int);
2888  *type = CFAPI_INT;
2889  op->attack_movement = iarg;
2890  break;
2891 
2893  oparg = va_arg(args, object *);
2894  *type = CFAPI_POBJECT;
2895  op->spellitem = oparg;
2896  break;
2897 
2899  darg = va_arg(args, double);
2900  *type = CFAPI_DOUBLE;
2901  op->expmul = darg;
2902  break;
2903 
2905  sarg = va_arg(args, char *);
2906  *type = CFAPI_STRING;
2907  FREE_AND_COPY(op->custom_name, sarg);
2908  send_changed_object(op);
2909  break;
2910 
2912  iarg = va_arg(args, int);
2913  *type = CFAPI_INT;
2914  op->anim_speed = iarg;
2915  break;
2916 
2918  iarg = va_arg(args, int);
2919  *type = CFAPI_INT;
2920  if (iarg == 1 && is_friendly(op) == 0)
2921  add_friendly_object(op);
2922  else if (iarg == 0 && is_friendly(op) == 1)
2924  break;
2925 
2927  iarg = va_arg(args, int);
2928  *type = CFAPI_INT;
2929  op->stats.luck = iarg;
2930  break;
2931 
2932  case CFAPI_OBJECT_PROP_EXP:
2933  s64arg = va_arg(args, int64_t);
2934  *type = CFAPI_SINT64;
2935  op->stats.exp = s64arg;
2936  break;
2937 
2939  oparg = va_arg(args, object *);
2940  *type = CFAPI_POBJECT;
2941  object_set_owner(op, oparg);
2942  break;
2943 
2945  object_set_cheat(op);
2946  *type = CFAPI_NONE;
2947  break;
2948 
2949  case CFAPI_OBJECT_PROP_FLAGS: {
2950  int iargbis;
2951 
2952  iarg = va_arg(args, int);
2953  iargbis = va_arg(args, int);
2954  *type = CFAPI_INT;
2955 
2956  if (iargbis == 1)
2957  SET_FLAG(op, iarg);
2958  else
2959  CLEAR_FLAG(op, iarg);
2960  }
2961  break;
2962 
2963  case CFAPI_OBJECT_PROP_STR:
2964  iarg = va_arg(args, int);
2965  *type = CFAPI_INT;
2966  op->stats.Str = iarg;
2967  break;
2968 
2969  case CFAPI_OBJECT_PROP_DEX:
2970  iarg = va_arg(args, int);
2971  *type = CFAPI_INT;
2972  op->stats.Dex = iarg;
2973  break;
2974 
2975  case CFAPI_OBJECT_PROP_CON:
2976  iarg = va_arg(args, int);
2977  *type = CFAPI_INT;
2978  op->stats.Con = iarg;
2979  break;
2980 
2981  case CFAPI_OBJECT_PROP_WIS:
2982  iarg = va_arg(args, int);
2983  *type = CFAPI_INT;
2984  op->stats.Wis = iarg;
2985  break;
2986 
2987  case CFAPI_OBJECT_PROP_INT:
2988  iarg = va_arg(args, int);
2989  *type = CFAPI_INT;
2990  op->stats.Int = iarg;
2991  break;
2992 
2993  case CFAPI_OBJECT_PROP_POW:
2994  iarg = va_arg(args, int);
2995  *type = CFAPI_INT;
2996  op->stats.Pow = iarg;
2997  break;
2998 
2999  case CFAPI_OBJECT_PROP_CHA:
3000  iarg = va_arg(args, int);
3001  *type = CFAPI_INT;
3002  op->stats.Cha = iarg;
3003  break;
3004 
3005  case CFAPI_OBJECT_PROP_WC:
3006  iarg = va_arg(args, int);
3007  *type = CFAPI_INT;
3008  op->stats.wc = iarg;
3009  break;
3010 
3011  case CFAPI_OBJECT_PROP_AC:
3012  iarg = va_arg(args, int);
3013  *type = CFAPI_INT;
3014  op->stats.ac = iarg;
3015  break;
3016 
3017  case CFAPI_OBJECT_PROP_HP:
3018  iarg = va_arg(args, int);
3019  *type = CFAPI_INT;
3020  op->stats.hp = iarg;
3021  break;
3022 
3023  case CFAPI_OBJECT_PROP_SP:
3024  iarg = va_arg(args, int);
3025  *type = CFAPI_INT;
3026  op->stats.sp = iarg;
3027  break;
3028 
3029  case CFAPI_OBJECT_PROP_GP:
3030  iarg = va_arg(args, int);
3031  *type = CFAPI_INT;
3032  op->stats.grace = iarg;
3033  break;
3034 
3035  case CFAPI_OBJECT_PROP_FP:
3036  iarg = va_arg(args, int);
3037  *type = CFAPI_INT;
3038  op->stats.food = iarg;
3039  break;
3040 
3042  iarg = va_arg(args, int);
3043  *type = CFAPI_INT;
3044  op->stats.maxhp = iarg;
3045  break;
3046 
3048  iarg = va_arg(args, int);
3049  *type = CFAPI_INT;
3050  op->stats.maxsp = iarg;
3051  break;
3052 
3054  iarg = va_arg(args, int);
3055  *type = CFAPI_INT;
3056  op->stats.maxgrace = iarg;
3057  break;
3058 
3059  case CFAPI_OBJECT_PROP_DAM:
3060  iarg = va_arg(args, int);
3061  *type = CFAPI_INT;
3062  op->stats.dam = iarg;
3063  break;
3064 
3065  case CFAPI_OBJECT_PROP_FACE: {
3066  sarg = va_arg(args, char *);
3067  ret = va_arg(args, int *);
3068  *type = CFAPI_INT;
3069  *ret = find_face(sarg, 0);
3070  if (*ret != 0) {
3071  op->face = &new_faces[*ret];
3072  op->state = 0;
3074  }
3075  break;
3076  }
3077 
3079  sarg = va_arg(args, char *);
3080  ret = va_arg(args, int *);
3081  *type = CFAPI_INT;
3082  *ret = try_find_animation(sarg);
3083  if (*ret != 0) {
3084  op->animation_id = *ret;
3085  SET_ANIMATION(op, 0);
3087  }
3088  break;
3089 
3091  iarg = va_arg(args, int);
3092  *type = CFAPI_INT;
3093  op->duration = iarg;
3094  break;
3095 
3097  if (op->contr) {
3098  oparg = va_arg(args, object *);
3099  *type = CFAPI_POBJECT;
3100  op->contr->mark = oparg;
3101  if (oparg) {
3102  op->contr->mark_count = oparg->count;
3103  } else {
3104  op->contr->mark_count = 0;
3105  }
3106  }
3107  break;
3108 
3110  if (op->contr) {
3111  partyarg = va_arg(args, partylist *);
3112  *type = CFAPI_PPARTY;
3113  party_join(op, partyarg);
3114  }
3115  break;
3116 
3118  sarg = va_arg(args, char *);
3119  *type = CFAPI_STRING;
3120  safe_strncpy(op->contr->savebed_map, sarg, MAX_BUF);
3121  break;
3122 
3124  iarg = va_arg(args, int);
3125  *type = CFAPI_INT;
3126  op->contr->bed_x = iarg;
3127  break;
3128 
3130  iarg = va_arg(args, int);
3131  *type = CFAPI_INT;
3132  op->contr->bed_y = iarg;
3133  break;
3134 
3136  sarg = va_arg(args, char *);
3137  *type = CFAPI_STRING;
3138  player_set_own_title(op->contr, sarg);
3139  break;
3140 
3142  move = va_arg(args, MoveType *);
3143  op->move_type = *move & MOVE_ALL;
3145  *type = CFAPI_MOVETYPE;
3146  break;
3147 
3149  move = va_arg(args, MoveType *);
3150  op->move_block = *move & MOVE_ALL;
3152  *type = CFAPI_MOVETYPE;
3153  break;
3154 
3156  move = va_arg(args, MoveType *);
3157  op->move_allow = *move & MOVE_ALL;
3159  *type = CFAPI_MOVETYPE;
3160  break;
3161 
3163  move = va_arg(args, MoveType *);
3164  op->move_on = *move & MOVE_ALL;
3166  *type = CFAPI_MOVETYPE;
3167  break;
3168 
3170  move = va_arg(args, MoveType *);
3171  op->move_off = *move & MOVE_ALL;
3173  *type = CFAPI_MOVETYPE;
3174  break;
3175 
3177  move = va_arg(args, MoveType *);
3178  op->move_type = *move & MOVE_ALL;
3180  *type = CFAPI_MOVETYPE;
3181  break;
3182 
3183  default:
3184  break;
3185  }
3186  }
3187  va_end(args);
3188 }
3189 
3196 static void cfapi_object_apply_below(int *type, ...) {
3197  va_list args;
3198  object *applier;
3199 
3200  va_start(args, type);
3201 
3202  applier = va_arg(args, object *);
3203 
3204  va_end(args);
3205 
3206  apply_by_living_below(applier);
3207  *type = CFAPI_NONE;
3208 }
3209 
3216 static void cfapi_object_apply(int *type, ...) {
3217  va_list args;
3218  object *applied;
3219  object *applier;
3220  int aflags;
3221  int *ret;
3222 
3223  va_start(args, type);
3224 
3225  applier = va_arg(args, object *);
3226  applied = va_arg(args, object *);
3227  aflags = va_arg(args, int);
3228  ret = va_arg(args, int *);
3229 
3230  va_end(args);
3231 
3232  *type = CFAPI_INT;
3233  *ret = apply_manual(applier, applied, aflags);
3234 }
3235 
3241 static void cfapi_object_identify(int *type, ...) {
3242  va_list args;
3243  object *op, **result;
3244 
3245  va_start(args, type);
3246 
3247  op = va_arg(args, object *);
3248  result = va_arg(args, object **);
3249 
3250  va_end(args);
3251 
3252  (*result) = identify(op);
3253  *type = CFAPI_POBJECT;
3254 }
3255 
3261 static void cfapi_object_describe(int *type, ...) {
3262  va_list args;
3263  object *op;
3264  object *owner;
3265  char *desc, *final;
3266  int size;
3267 
3268  va_start(args, type);
3269 
3270  op = va_arg(args, object *);
3271  owner = va_arg(args, object *);
3272  desc = va_arg(args, char *);
3273  size = va_arg(args, int);
3274  va_end(args);
3275 
3276  *type = CFAPI_STRING;
3277  final = stringbuffer_finish(describe_item(op, owner, 0, NULL));
3278  strncpy(desc, final, size);
3279  desc[size - 1] = '\0';
3280  free(final);
3281 }
3282 
3283 static void cfapi_object_drain(int *type, ...) {
3284  va_list args;
3285 
3286  object *op;
3287  int ds;
3288 
3289  va_start(args, type);
3290 
3291  op = va_arg(args, object *);
3292  ds = va_arg(args, int);
3293 
3294  va_end(args);
3295 
3296  drain_specific_stat(op, ds);
3297 
3298  *type = CFAPI_NONE;
3299 }
3300 
3301 static void cfapi_object_remove_depletion(int *type, ...) {
3302  va_list args;
3303 
3304  object *op;
3305  int level, *result;
3306 
3307  va_start(args, type);
3308 
3309  op = va_arg(args, object *);
3310  level = va_arg(args, int);
3311  result = va_arg(args, int*);
3312 
3313  va_end(args);
3314 
3315  *result = remove_depletion(op, level);
3316 
3317  *type = CFAPI_INT;
3318 }
3319 
3320 static void cfapi_object_fix(int *type, ...) {
3321  va_list args;
3322  object *op;
3323 
3324  va_start(args, type);
3325 
3326  op = va_arg(args, object *);
3327 
3328  va_end(args);
3329 
3330  fix_object(op);
3331 
3332  *type = CFAPI_NONE;
3333 }
3334 
3336 static void cfapi_object_give_skill(int *type, ...) {
3337  va_list args;
3338 
3339  object *op;
3340  char *skillname;
3341 
3342  va_start(args, type);
3343 
3344  op = va_arg(args, object *);
3345  skillname = va_arg(args, char *);
3346 
3347  va_end(args);
3348 
3349  *type = CFAPI_POBJECT;
3350  give_skill_by_name(op, skillname);
3351 }
3352 
3353 static void cfapi_object_transmute(int *type, ...) {
3354  va_list args;
3355 
3356  object *op;
3357  object *chg;
3358 
3359  va_start(args, type);
3360 
3361  op = va_arg(args, object *);
3362  chg = va_arg(args, object *);
3363 
3364  va_end(args);
3365 
3366  transmute_materialname(op, chg);
3367  *type = CFAPI_NONE;
3368 }
3369 
3370 static void cfapi_object_remove(int *type, ...) {
3371  va_list args;
3372  object *op;
3373 
3374  va_start(args, type);
3375 
3376  op = va_arg(args, object *);
3377 
3378  if (QUERY_FLAG(op, FLAG_REMOVED)) {
3379  LOG(llevError, "Plugin trying to remove removed object %s\n", op->name);
3380  va_end(args);
3381  *type = CFAPI_NONE;
3382  return;
3383  }
3384 
3385  va_end(args);
3386 
3387  object_remove(op);
3388  *type = CFAPI_NONE;
3389 }
3390 
3391 static void cfapi_object_delete(int *type, ...) {
3392  va_list args;
3393  object *op;
3394 
3395  va_start(args, type);
3396 
3397  op = va_arg(args, object *);
3398 
3399  if (QUERY_FLAG(op, FLAG_FREED) || !QUERY_FLAG(op, FLAG_REMOVED)) {
3400  LOG(llevError, "Plugin trying to free freed/non removed object %s\n", op->name);
3401  *type = CFAPI_NONE;
3402  va_end(args);
3403  return;
3404  }
3405 
3406  va_end(args);
3407 
3409 
3410  *type = CFAPI_NONE;
3411 }
3412 
3418 static void cfapi_object_clone(int *type, ...) {
3419  va_list args;
3420  object *op;
3421  int kind;
3422  object **robj;
3423 
3424  va_start(args, type);
3425 
3426  op = va_arg(args, object *);
3427  kind = va_arg(args, int);
3428  robj = va_arg(args, object **);
3429 
3430  va_end(args);
3431 
3432  if (kind == 0) {
3433  *type = CFAPI_POBJECT;
3434  *robj = object_create_clone(op);
3435  } else {
3436  object *tmp;
3437  tmp = object_new();
3438  object_copy(op, tmp);
3439  *type = CFAPI_POBJECT;
3440  *robj = tmp;
3441  }
3442  return;
3443 }
3444 
3450 static void cfapi_object_create(int *type, ...) {
3451  va_list args;
3452  int ival;
3453  object **robj;
3454  va_start(args, type);
3455  ival = va_arg(args, int);
3456 
3457  *type = CFAPI_POBJECT;
3458  switch (ival) {
3459  case 0:
3460  robj = va_arg(args, object **);
3461  *robj = object_new();
3462  break;
3463 
3464  case 1: { /* Named object. Nearly the old plugin behavior, but we don't add artifact suffixes */
3465  const char *sval;
3466  archetype *at;
3467 
3468  sval = va_arg(args, const char *);
3469  robj = va_arg(args, object **);
3470  va_end(args);
3471 
3472  at = try_find_archetype(sval);
3473  if (!at)
3474  at = find_archetype_by_object_name(sval);
3475  if (at) {
3476  *robj = object_create_arch(at);
3477  } else
3478  *robj = NULL;
3479  }
3480  break;
3481 
3482  default:
3483  *type = CFAPI_NONE;
3484  break;
3485  }
3486  va_end(args);
3487 }
3488 
3489 static void cfapi_object_insert(int *type, ...) {
3490  va_list args;
3491  object *op;
3492  object *orig;
3493  mapstruct *map;
3494  int flag, x, y;
3495  int itype;
3496  object **robj;
3497 
3498  va_start(args, type);
3499 
3500  op = va_arg(args, object *);
3501  if (!op) {
3502  LOG(llevError, "cfapi_object_insert: called with NULL object!\n");
3503  va_end(args);
3504  return;
3505  }
3506  if (QUERY_FLAG(op, FLAG_FREED)) {
3507  LOG(llevError, "cfapi_object_insert: called with FREED object!\n");
3508  va_end(args);
3509  return;
3510  }
3511  if (!QUERY_FLAG(op, FLAG_REMOVED)) {
3512  LOG(llevError, "cfapi_object_insert: called with not removed object %s!\n", op->name);
3513  object_remove(op);
3514  }
3515  itype = va_arg(args, int);
3516 
3517  switch (itype) {
3518  case 0:
3519  map = va_arg(args, mapstruct *);
3520  orig = va_arg(args, object *);
3521  flag = va_arg(args, int);
3522  x = va_arg(args, int);
3523  y = va_arg(args, int);
3524  robj = va_arg(args, object **);
3525  if (!map) {
3526  LOG(llevError, "cfapi_object_insert (0): called with NULL map, object %s!\n", op->name);
3528  *robj = NULL;
3529  } else
3530  *robj = object_insert_in_map_at(op, map, orig, flag, x, y);
3531  *type = CFAPI_POBJECT;
3532  break;
3533 
3534  case 1:
3535  map = va_arg(args, mapstruct *);
3536  orig = va_arg(args, object *);
3537  flag = va_arg(args, int);
3538  robj = va_arg(args, object **);
3539  if (!map) {
3540  LOG(llevError, "cfapi_object_insert (1): called with NULL map, object %s!\n", op->name);
3542  *robj = NULL;
3543  } else
3544  *robj = object_insert_in_map_at(op, map, orig, flag, op->x, op->y);
3545  *type = CFAPI_POBJECT;
3546  break;
3547 
3548  case 2:
3549  map = va_arg(args, mapstruct *);
3550  orig = va_arg(args, object *);
3551  flag = va_arg(args, int);
3552  x = va_arg(args, int);
3553  y = va_arg(args, int);
3554  robj = va_arg(args, object **);
3555  if (!map) {
3556  LOG(llevError, "cfapi_object_insert (0): called with NULL map, object %s!\n", op->name);
3558  *robj = NULL;
3559  } else {
3560  int dir = object_find_free_spot(op, map, x, y, 0, SIZEOFFREE);
3561  if (dir != -1) {
3562  *robj = object_insert_in_map_at(op, map, orig, flag, x + freearr_x[dir], y + freearr_y[dir]);
3563  } else {
3565  *robj = NULL;
3566  }
3567  }
3568  *type = CFAPI_POBJECT;
3569  break;
3570 
3571  case 3:
3572  orig = va_arg(args, object *);
3573  robj = va_arg(args, object **);
3574  if (!orig) {
3575  LOG(llevError, "cfapi_object_insert (3): called with NULL orig, object %s!\n", op->name);
3577  *robj = NULL;
3578  } else
3579  *robj = object_insert_in_ob(op, orig);
3580  *type = CFAPI_POBJECT;
3581  break;
3582 
3583  default:
3584  LOG(llevError, "cfapi_object_insert (1): called with itype %d which is not valid, object %s!\n", itype, op->name);
3586  *type = CFAPI_NONE;
3587  break;
3588  }
3589 
3590  va_end(args);
3591 }
3597 static void cfapi_object_split(int *type, ...) {
3598  va_list args;
3599 
3600  int nr, size;
3601  object *op;
3602  char *buf;
3603  object **split;
3604 
3605  va_start(args, type);
3606 
3607  op = va_arg(args, object *);
3608  nr = va_arg(args, int);
3609  buf = va_arg(args, char *);
3610  size = va_arg(args, int);
3611  split = va_arg(args, object **);
3612  va_end(args);
3613 
3614  *split = object_split(op, nr, buf, size);
3615  if (*split != NULL)
3616  {
3617  *type = CFAPI_POBJECT;
3618  }
3619  else
3620  {
3621  *type = CFAPI_NONE;
3622  }
3623 }
3624 
3630 static void cfapi_object_merge(int *type, ...) {
3631  va_list args;
3632  object *op;
3633  object *op2;
3634  object **merge;
3635 
3636  va_start(args, type);
3637 
3638  op = va_arg(args, object *);
3639  op2 = va_arg(args, object *);
3640  merge = va_arg(args, object **);
3641 
3642  va_end(args);
3643 
3644  *type = CFAPI_POBJECT;
3645  *merge = object_merge(op, op2);
3646 }
3647 
3653 static void cfapi_object_distance(int *type, ...) {
3654  va_list args;
3655  object *op;
3656  object *op2;
3657  int *rint;
3658  va_start(args, type);
3659 
3660  op = va_arg(args, object *);
3661  op2 = va_arg(args, object *);
3662  rint = va_arg(args, int *);
3663 
3664  va_end(args);
3665 
3666  *type = CFAPI_INT;
3667  *rint = object_distance(op, op2);
3668 }
3674 static void cfapi_object_update(int *type, ...) {
3675  va_list args;
3676  int action;
3677  object *op;
3678  va_start(args, type);
3679 
3680  op = va_arg(args, object *);
3681  action = va_arg(args, int);
3682 
3683  va_end(args);
3684 
3685  object_update(op, action);
3686  *type = CFAPI_NONE;
3687 }
3688 
3694 static void cfapi_object_clear(int *type, ...) {
3695  va_list args;
3696  object *op;
3697  va_start(args, type);
3698 
3699  op = va_arg(args, object *);
3700 
3701  va_end(args);
3702 
3703  object_clear(op);
3704  *type = CFAPI_NONE;
3705 }
3706 
3712 static void cfapi_object_reset(int *type, ...) {
3713  va_list args;
3714  object *op;
3715 
3716  va_start(args, type);
3717 
3718  op = va_arg(args, object *);
3719 
3720  va_end(args);
3721 
3722  object_reset(op);
3723  *type = CFAPI_NONE;
3724 }
3725 
3726 static void cfapi_object_clean_object(int *type, ...) {
3727  va_list args;
3728  object *op;
3729 
3730  va_start(args, type);
3731  op = va_arg(args, object *);
3732  clean_object(op);
3733  va_end(args);
3734  *type = CFAPI_NONE;
3735 }
3736 
3737 static void cfapi_object_on_same_map(int *type, ...) {
3738  va_list args;
3739  object *op1;
3740  object *op2;
3741  int *rint;
3742 
3743  va_start(args, type);
3744  op1 = va_arg(args, object *);
3745  op2 = va_arg(args, object *);
3746  rint = va_arg(args, int *);
3747  va_end(args);
3748 
3749  *type = CFAPI_INT;
3750  *rint = on_same_map(op1, op2);
3751 }
3752 
3753 static void cfapi_object_spring_trap(int *type, ...) {
3754  object *trap;
3755  object *victim;
3756  va_list args;
3757 
3758  va_start(args, type);
3759  trap = va_arg(args, object *);
3760  victim = va_arg(args, object *);
3761  va_end(args);
3762 
3763  spring_trap(trap, victim);
3764  *type = CFAPI_NONE;
3765 }
3766 
3772 static void cfapi_object_check_trigger(int *type, ...) {
3773  object *op;
3774  object *cause;
3775  va_list args;
3776  int *rint;
3777 
3778  va_start(args, type);
3779  op = va_arg(args, object *);
3780  cause = va_arg(args, object *);
3781  rint = va_arg(args, int *);
3782  va_end(args);
3783 
3784  *rint = check_trigger(op, cause);
3785  *type = CFAPI_INT;
3786 }
3787 
3799 static void cfapi_map_trigger_connected(int *type, ...) {
3800  objectlink *ol;
3801  object *cause;
3802  int state;
3803  va_list args;
3804 
3805  va_start(args, type);
3806  ol = va_arg(args, objectlink *);
3807  cause = va_arg(args, object *);
3808  state = va_arg(args, int);
3809  va_end(args);
3810  trigger_connected(ol, cause, state);
3811  *type = CFAPI_NONE;
3812 }
3813 
3819 static void cfapi_object_query_money(int *type, ...) {
3820  object *op;
3821  va_list args;
3822  int *rint;
3823 
3824  va_start(args, type);
3825  op = va_arg(args, object *);
3826  rint = va_arg(args, int *);
3827  va_end(args);
3828 
3829  *rint = query_money(op);
3830  *type = CFAPI_INT;
3831 }
3832 
3838 static void cfapi_object_cast(int *type, ...) {
3839  object *op;
3840  object *sp;
3841  int dir;
3842  char *str;
3843  object *caster;
3844  va_list args;
3845  int *rint;
3846 
3847  va_start(args, type);
3848  op = va_arg(args, object *);
3849  caster = va_arg(args, object *);
3850  dir = va_arg(args, int);
3851  sp = va_arg(args, object *);
3852  str = va_arg(args, char *);
3853  rint = va_arg(args, int *);
3854  va_end(args);
3855 
3856  *type = CFAPI_INT;
3857 
3858  if (!op->map) {
3859  *rint = -1;
3860  return;
3861  }
3862 
3863  *rint = cast_spell(op, caster, dir, sp, str);
3864 }
3865 
3866 static void cfapi_object_learn_spell(int *type, ...) {
3867  object *op;
3868  object *sp;
3869  int prayer;
3870  va_list args;
3871 
3872  va_start(args, type);
3873  op = va_arg(args, object *);
3874  sp = va_arg(args, object *);
3875  prayer = va_arg(args, int);
3876  va_end(args);
3877  do_learn_spell(op, sp, prayer);
3878  *type = CFAPI_NONE;
3879 }
3880 
3881 static void cfapi_object_forget_spell(int *type, ...) {
3882  object *op;
3883  object *sp;
3884  va_list args;
3885  char name[MAX_BUF];
3886 
3887  va_start(args, type);
3888  op = va_arg(args, object *);
3889  sp = va_arg(args, object *);
3890  va_end(args);
3891  query_name(sp, name, MAX_BUF);
3892  do_forget_spell(op, name);
3893  *type = CFAPI_NONE;
3894 }
3895 
3901 static void cfapi_object_check_spell(int *type, ...) {
3902  object *op;
3903  char *spellname;
3904  va_list args;
3905  object **robj;
3906 
3907  va_start(args, type);
3908  op = va_arg(args, object *);
3909  spellname = va_arg(args, char *);
3910  robj = va_arg(args, object **);
3911  va_end(args);
3912  *robj = check_spell_known(op, spellname);
3913  *type = CFAPI_POBJECT;
3914 }
3915 
3921 static void cfapi_object_pay_amount(int *type, ...) {
3922  object *op;
3923  uint64_t amount;
3924  va_list args;
3925  int *rint;
3926 
3927  va_start(args, type);
3928  op = va_arg(args, object *);
3929  amount = va_arg(args, uint64_t);
3930  rint = va_arg(args, int *);
3931  va_end(args);
3932 
3933  *rint = pay_for_amount(amount, op);
3934  *type = CFAPI_INT;
3935 }
3936 
3942 static void cfapi_object_pay_item(int *type, ...) {
3943  object *op;
3944  object *tobuy;
3945  int *rint;
3946 
3947  va_list args;
3948 
3949  va_start(args, type);
3950  tobuy = va_arg(args, object *);
3951  op = va_arg(args, object *);
3952  rint = va_arg(args, int *);
3953  va_end(args);
3954 
3955  *rint = pay_for_item(tobuy, op);
3956  *type = CFAPI_INT;
3957 }
3958 
3966 static void cfapi_object_transfer(int *type, ...) {
3967  object *op;
3968  object *originator;
3969  int x, y, randompos, ttype, flag;
3970  va_list args;
3971  mapstruct *map;
3972  int *rint;
3973  object **robj;
3974 
3975  va_start(args, type);
3976  op = va_arg(args, object *);
3977  ttype = va_arg(args, int);
3978  switch (ttype) {
3979  case 0:
3980  x = va_arg(args, int);
3981  y = va_arg(args, int);
3982  randompos = va_arg(args, int);
3983  originator = va_arg(args, object *);
3984  rint = va_arg(args, int *);
3985  va_end(args);
3986 
3987  *rint = transfer_ob(op, x, y, randompos, originator);
3988  *type = CFAPI_INT;
3989  return;
3990  break;
3991 
3992  case 1:
3993  map = va_arg(args, mapstruct *);
3994  originator = va_arg(args, object *);
3995  flag = va_arg(args, int);
3996  x = va_arg(args, int);
3997  y = va_arg(args, int);
3998  robj = va_arg(args, object **);
3999  va_end(args);
4000  if (x < 0 || y < 0) {
4001  x = map->enter_x;
4002  y = map->enter_y;
4003  }
4004  *robj = object_insert_in_map_at(op, map, originator, flag, x, y);
4005  *type = CFAPI_POBJECT;
4006  return;
4007  break;
4008 
4009  case 2:
4010  x = va_arg(args, int);
4011  y = va_arg(args, int);
4012  rint = va_arg(args, int *);
4013  va_end(args);
4014 
4015  *rint = move_to(op, x, y);
4016  *type = CFAPI_INT;
4017  return;
4018 
4019  default:
4020  va_end(args);
4021  *type = CFAPI_NONE;
4022  return;
4023  break;
4024  }
4025 }
4026 
4030 static void cfapi_object_find_archetype_inside(int *type, ...) {
4031  object *op;
4032  char *str;
4033  va_list args;
4034  object **robj;
4035 
4036  *type = CFAPI_POBJECT;
4037  va_start(args, type);
4038  op = va_arg(args, object *);
4039 
4040  str = va_arg(args, char *);
4041  robj = va_arg(args, object **);
4042  *robj = arch_present_in_ob(try_find_archetype(str), op);
4043  if (*robj == NULL) {
4044  char name[MAX_BUF];
4045 
4046  /* Search by name or slaying instead */
4047  FOR_INV_PREPARE(op, tmp) {
4048  query_name(tmp, name, MAX_BUF);
4049  if (!strncmp(name, str, strlen(str)))
4050  *robj = tmp;
4051  if (!strncmp(tmp->name, str, strlen(str)))
4052  *robj = tmp;
4053  if (tmp->slaying && !strcmp(tmp->slaying, str))
4054  *robj = tmp;
4055  if (*robj != NULL)
4056  break;
4057  } FOR_INV_FINISH();
4058  }
4059  va_end(args);
4060 }
4061 
4062 static void cfapi_object_find_by_arch_name(int *type, ...) {
4063  const object *who;
4064  object **result;
4065  const char *name;
4066  va_list args;
4067 
4068  va_start(args, type);
4069  who = va_arg(args, const object *);
4070  name = va_arg(args, const char *);
4071  result = va_arg(args, object **);
4072  va_end(args);
4073  *type = CFAPI_POBJECT;
4074 
4075  *result = object_find_by_arch_name(who, name);
4076 }
4077 
4078 static void cfapi_object_find_by_name(int *type, ...) {
4079  const object *who;
4080  object **result;
4081  const char *name;
4082  va_list args;
4083 
4084  va_start(args, type);
4085  who = va_arg(args, const object *);
4086  name = va_arg(args, const char *);
4087  result = va_arg(args, object **);
4088  va_end(args);
4089  *type = CFAPI_POBJECT;
4090 
4091  *result = object_find_by_name(who, name);
4092 }
4093 
4099 static void cfapi_object_drop(int *type, ...) {
4100  object *op;
4101  object *author;
4102  va_list args;
4103 
4104  va_start(args, type);
4105  op = va_arg(args, object *);
4106  author = va_arg(args, object *);
4107  va_end(args);
4108  *type = CFAPI_NONE;
4109 
4110  if (QUERY_FLAG(op, FLAG_NO_DROP))
4111  return;
4112  drop(author, op);
4113 
4114  if (author->type == PLAYER) {
4115  author->contr->count = 0;
4116  author->contr->socket.update_look = 1;
4117  }
4118 }
4119 
4123 static void cfapi_object_change_abil(int *type, ...) {
4124  object *op, *tmp;
4125  int *rint;
4126  va_list args;
4127 
4128  va_start(args, type);
4129  op = va_arg(args, object *);
4130  tmp = va_arg(args, object *);
4131  rint = va_arg(args, int *);
4132  va_end(args);
4133 
4134  *type = CFAPI_INT;
4135  *rint = change_abil(op, tmp);
4136 }
4137 
4138 static void cfapi_object_say(int *type, ...) {
4139  object *op;
4140  char *msg;
4141  va_list args;
4142  int *rint;
4143  char empty[] = "";
4144 
4145  va_start(args, type);
4146  op = va_arg(args, object *);
4147  msg = va_arg(args, char *);
4148  rint = va_arg(args, int *);
4149  va_end(args);
4150 
4151  if (op->type == PLAYER) {
4152  command_say(op, msg == NULL ? empty : msg);
4153  } else {
4154  monster_npc_say(op, msg);
4155  }
4156  *rint = 0;
4157  *type = CFAPI_INT;
4158 }
4159 
4160 /* PLAYER SUBCLASS */
4161 
4167 static void cfapi_player_find(int *type, ...) {
4168  va_list args;
4169  char *sval;
4170  player **rpl;
4171  va_start(args, type);
4172 
4173  sval = va_arg(args, char *);
4174  rpl = va_arg(args, player **);
4175  va_end(args);
4176 
4177  *rpl = find_player_partial_name(sval);
4178 
4179  *type = CFAPI_PPLAYER;
4180 }
4181 
4182 static void cfapi_player_message(int *type, ...) {
4183  va_list args;
4184  int flags;
4185  int pri;
4186  object *pl;
4187  char *buf;
4188 
4189  va_start(args, type);
4190 
4191  flags = va_arg(args, int);
4192  pri = va_arg(args, int);
4193  pl = va_arg(args, object *);
4194  buf = va_arg(args, char *);
4195  va_end(args);
4196 
4197  draw_ext_info(flags, pri, pl, MSG_TYPE_MISC, MSG_SUBTYPE_NONE,
4198  buf);
4199  *type = CFAPI_NONE;
4200 }
4201 
4207 static void cfapi_object_change_exp(int *type, ...) {
4208  va_list args;
4209  int flag;
4210  object *ob;
4211  const char *skill;
4212  int64_t exp;
4213 
4214  va_start(args, type);
4215  ob = va_arg(args, object *);
4216  exp = va_arg(args, int64_t);
4217  skill = va_arg(args, const char *);
4218  flag = va_arg(args, int);
4219  va_end(args);
4220 
4221  *type = CFAPI_NONE;
4222  change_exp(ob, exp, skill, flag);
4223 }
4224 
4230 static void cfapi_player_can_pay(int *type, ...) {
4231  va_list args;
4232  object *pl;
4233  int *rint;
4234 
4235  va_start(args, type);
4236  pl = va_arg(args, object *);
4237  rint = va_arg(args, int *);
4238  va_end(args);
4239 
4240  *rint = can_pay(pl);
4241  *type = CFAPI_INT;
4242 }
4243 
4249 static void cfapi_player_knowledge(int *type, ...) {
4250  va_list args;
4251  object *pl;
4252  int *rint, what;
4253  const char *knowledge;
4254 
4255  va_start(args, type);
4256  what = va_arg(args, int);
4257 
4258  switch(what)
4259  {
4260  case 1:
4261  pl = va_arg(args, object *);
4262  knowledge = va_arg(args, const char *);
4263  rint = va_arg(args, int *);
4264 
4265  *type = CFAPI_INT;
4266 
4267  if (pl->contr == NULL) {
4268  LOG(llevError, "cfapi_player_knowledge: 'has' called for non player object %s", pl->name);
4269  *rint = 0;
4270  va_end(args);
4271  return;
4272  }
4273 
4274  *rint = knowledge_player_knows(pl->contr, knowledge);
4275  break;
4276 
4277  case 2:
4278  pl = va_arg(args, object *);
4279  knowledge = va_arg(args, const char *);
4280  *type = CFAPI_NONE;
4281  if (pl->contr != NULL)
4282  knowledge_give(pl->contr, knowledge, NULL);
4283 
4284  break;
4285 
4286  default:
4287  LOG(llevError, "cfapi_player_knowledge: invalid what %d", what);
4288  }
4289 
4290  va_end(args);
4291 }
4292 
4298 static void cfapi_object_teleport(int *type, ...) {
4299  mapstruct *map;
4300  int x, y;
4301  object *who;
4302  int *res;
4303  va_list args;
4304 
4305  va_start(args, type);
4306  who = va_arg(args, object *);
4307  map = va_arg(args, mapstruct *);
4308  x = va_arg(args, int);
4309  y = va_arg(args, int);
4310  res = va_arg(args, int *);
4311  *type = CFAPI_INT;
4312 
4313  if (!out_of_map(map, x, y)) {
4314  int k;
4315  k = object_find_first_free_spot(who, map, x, y);
4316  if (k == -1) {
4317  *res = 1;
4318  va_end(args);
4319  return;
4320  }
4321 
4322  if (!QUERY_FLAG(who, FLAG_REMOVED)) {
4323  object_remove(who);
4324  }
4325 
4326  object_insert_in_map_at(who, map, NULL, 0, x, y);
4327  if (who->type == PLAYER) {
4328  map_newmap_cmd(&who->contr->socket);
4330  }
4331  *res = 0;
4332  }
4333 
4334  va_end(args);
4335 }
4336 
4337 static void cfapi_object_pickup(int *type, ...) {
4338  object *who;
4339  object *what;
4340  va_list args;
4341 
4342  va_start(args, type);
4343  who = va_arg(args, object *);
4344  what = va_arg(args, object *);
4345  va_end(args);
4346 
4347  pick_up(who, what);
4348  *type = CFAPI_NONE;
4349 }
4350 
4351 /* Archetype-related functions */
4352 static void cfapi_archetype_get_property(int *type, ...) {
4353  int prop;
4354  archetype *arch;
4355  va_list args;
4356  sstring *rsstring;
4357  archetype **rarch;
4358  object **robject;
4359 
4360  va_start(args, type);
4361  arch = va_arg(args, archetype *);
4362  prop = va_arg(args, int);
4363  switch (prop) {
4364  case CFAPI_ARCH_PROP_NAME:
4365  *type = CFAPI_SSTRING;
4366  rsstring = va_arg(args, sstring *);
4367  *rsstring = arch->name;
4368  break;
4369 
4370  case CFAPI_ARCH_PROP_NEXT:
4371  *type = CFAPI_PARCH;
4372  rarch = va_arg(args, archetype **);
4373  *rarch = arch ? arch->next : first_archetype;
4374  break;
4375 
4376  case CFAPI_ARCH_PROP_HEAD:
4377  *type = CFAPI_PARCH;
4378  rarch = va_arg(args, archetype **);
4379  *rarch = arch->head;
4380  break;
4381 
4382  case CFAPI_ARCH_PROP_MORE:
4383  *type = CFAPI_PARCH;
4384  rarch = va_arg(args, archetype **);
4385  *rarch = arch->more;
4386  break;
4387 
4388  case CFAPI_ARCH_PROP_CLONE:
4389  *type = CFAPI_POBJECT;
4390  robject = va_arg(args, object **);
4391  *robject = &arch->clone;
4392  break;
4393 
4394  default:
4395  *type = CFAPI_NONE;
4396  break;
4397  }
4398  va_end(args);
4399 }
4400 
4407 static void cfapi_party_get_property(int *type, ...) {
4408  partylist *party;
4409  int prop;
4410  va_list args;
4411  object *obarg;
4412  sstring *rsstring;
4413  player **rplayer;
4414  partylist **rparty;
4415 
4416  va_start(args, type);
4417  party = va_arg(args, partylist *);
4418  prop = va_arg(args, int);
4419  switch (prop) {
4420  case CFAPI_PARTY_PROP_NAME:
4421  rsstring = va_arg(args, sstring *);
4422  *rsstring = party->partyname;
4423  *type = CFAPI_SSTRING;
4424  break;
4425 
4426  case CFAPI_PARTY_PROP_NEXT:
4427  rparty = va_arg(args, partylist **);
4428  *rparty = (party ? party_get_next(party) : party_get_first());
4429  *type = CFAPI_PPARTY;
4430  break;
4431 
4433  rsstring = va_arg(args, sstring *);
4434  *rsstring = party_get_password(party);
4435  *type = CFAPI_SSTRING;
4436  break;
4437 
4439  *type = CFAPI_PPLAYER;
4440  obarg = va_arg(args, object *);
4441  rplayer = va_arg(args, player **);
4442  *rplayer = (obarg ? obarg->contr : first_player);
4443  for (; *rplayer != NULL; (*rplayer) = (*rplayer)->next)
4444  if ((*rplayer)->ob->contr->party == party) {
4445  break;
4446  }
4447  break;
4448 
4449  default:
4450  *type = CFAPI_NONE;
4451  break;
4452  }
4453  va_end(args);
4454 }
4455 
4462 static void cfapi_region_get_property(int *type, ...) {
4463  region *reg;
4464  int prop, *rint;
4465  va_list args;
4467  sstring *rsstring;
4468  region **rregion;
4469 
4470  va_start(args, type);
4471  reg = va_arg(args, region *);
4472  prop = va_arg(args, int);
4473  switch (prop) {
4475  rsstring = va_arg(args, sstring *);
4476  *rsstring = reg->name;
4477  *type = CFAPI_SSTRING;
4478  break;
4479 
4481  rregion = va_arg(args, region **);
4482  *rregion = (reg ? reg->next : first_region);
4483  *type = CFAPI_PREGION;
4484  break;
4485 
4487  rregion = va_arg(args, region **);
4488  *rregion = reg->parent;
4489  *type = CFAPI_PREGION;
4490  break;
4491 
4493  rsstring = va_arg(args, sstring *);
4494  *rsstring = reg->longname;
4495  *type = CFAPI_SSTRING;
4496  break;
4497 
4499  rsstring = va_arg(args, sstring *);
4500  *rsstring = reg->msg;
4501  *type = CFAPI_SSTRING;
4502  break;
4503 
4506  rint = va_arg(args, int*);
4507  *rint = (prop == CFAPI_REGION_PROP_JAIL_X ? reg->jailx : reg->jaily);
4508  *type = CFAPI_INT;
4509  break;
4510 
4512  rsstring = va_arg(args, sstring *);
4513  *rsstring = reg->jailmap;
4514  *type = CFAPI_SSTRING;
4515  break;
4516 
4517  default:
4518  *type = CFAPI_NONE;
4519  break;
4520  }
4521  va_end(args);
4522 }
4523 
4535 static void cfapi_friendlylist_get_next(int *type, ...) {
4536  object *ob;
4537  va_list args;
4538  objectlink *link;
4539  object **robject;
4540 
4541  va_start(args, type);
4542  ob = va_arg(args, object *);
4543  robject = va_arg(args, object **);
4544  va_end(args);
4545 
4546  *type = CFAPI_POBJECT;
4547  *robject = NULL;
4548 
4549  if (ob) {
4550  for (link = first_friendly_object; link; link = link->next) {
4551  if (ob == link->ob) {
4552  if (link->next) {
4553  *robject = link->next->ob;
4554  return;
4555  } else {
4556  return;
4557  }
4558  }
4559  }
4560  return;
4561  }
4562 
4564  *robject = first_friendly_object->ob;
4565 }
4566 
4567 /*
4568  * Random-map related stuff.
4569  */
4570 
4577 static void cfapi_set_random_map_variable(int *type, ...) {
4578  va_list args;
4579  RMParms *rp;
4580  const char *buf;
4581  int *ret;
4582 
4583  va_start(args, type);
4584  rp = va_arg(args, RMParms *);
4585  buf = va_arg(args, const char *);
4586  ret = va_arg(args, int *);
4587  va_end(args);
4588 
4589  *ret = set_random_map_variable(rp, buf);
4590  *type = CFAPI_INT;
4591 }
4592 
4599 static void cfapi_generate_random_map(int *type, ...) {
4600  va_list args;
4601  const char *name;
4602  RMParms *rp;
4603  char **use_layout;
4604  mapstruct **ret;
4605 
4606  va_start(args, type);
4607  name = va_arg(args, const char *);
4608  rp = va_arg(args, RMParms *);
4609  use_layout = va_arg(args, char **);
4610  ret = va_arg(args, mapstruct **);
4611  va_end(args);
4612 
4613  *ret = generate_random_map(name, rp, use_layout);
4614 }
4615 
4616 static void cfapi_object_user_event(int *type, ...) {
4617  object *op;
4618  object *activator;
4619  object *third;
4620  const char *message;
4621  int fix;
4622  int *ret;
4623  va_list args;
4624 
4625  va_start(args, type);
4626  op = va_arg(args, object *);
4627  activator = va_arg(args, object *);
4628  third = va_arg(args, object *);
4629  message = va_arg(args, const char *);
4630  fix = va_arg(args, int);
4631  ret = va_arg(args, int *);
4632  va_end(args);
4633 
4634  *ret = user_event(op, activator, third, message, fix);
4635  *type = CFAPI_INT;
4636 }
4637 
4640 static void cfapi_player_quest(int *type, ...) {
4641  int op;
4642  va_list args;
4643  object *player;
4644  sstring code;
4645 
4646  va_start(args, type);
4647  op = va_arg(args, int);
4648  player = va_arg(args, object *);
4649  code = va_arg(args, sstring);
4650 
4651  if (player->contr == NULL) {
4652  LOG(llevError, "cfapi_player_quest called with non player object %s!\n", player->name);
4653  va_end(args);
4654  /* crash/quit? */
4655  return;
4656  }
4657 
4658  switch(op) {
4659  case CFAPI_PLAYER_QUEST_START: {
4660  int state = va_arg(args, int);
4661  quest_start(player->contr, code, state);
4662  *type = CFAPI_NONE;
4663  break;
4664  }
4666  int *ret = va_arg(args, int *);
4667  *ret = quest_get_player_state(player->contr, code);
4668  *type = CFAPI_INT;
4669  break;
4670  }
4672  int state = va_arg(args, int);
4673  quest_set_player_state(player->contr, code, state);
4674  *type = CFAPI_NONE;
4675  break;
4676  }
4678  int *ret = va_arg(args, int*);
4679  *ret = quest_was_completed(player->contr, code);
4680  *type = CFAPI_INT;
4681  break;
4682  }
4683  default:
4684  LOG(llevError, "invalid quest type: %d\n", op);
4685  *type = CFAPI_NONE;
4686  }
4687 
4688  va_end(args);
4689 }
4690 
4691 /*****************************************************************************/
4692 /* NEW PLUGIN STUFF ENDS HERE */
4693 /*****************************************************************************/
4694 
4695 
4708  int i;
4709  crossfire_plugin *cp;
4710 
4711  assert(cmd != NULL);
4712  assert(command != NULL);
4713 
4714  if (plugins_list == NULL)
4715  return NULL;
4716 
4717  for (cp = plugins_list; cp != NULL; cp = cp->next) {
4718  if (cp->propfunc(&i, "command?", cmd, command) != NULL)
4719  return command;
4720  }
4721  return NULL;
4722 }
4723 
4728 void initPlugins(void) {
4729  struct dirent *currentfile;
4730  DIR *plugdir;
4731  size_t l;
4732  char buf[MAX_BUF];
4733 
4734  snprintf(buf, sizeof(buf), "%s/plugins/", LIBDIR);
4735  LOG(llevDebug, "plugins: loading from %s\n", buf);
4736 
4737  plugdir = opendir(buf);
4738  if (plugdir == NULL)
4739  return;
4740 
4741  while ((currentfile = readdir(plugdir)) != NULL) {
4742  l = strlen(currentfile->d_name);
4743  if (l > strlen(PLUGIN_SUFFIX)) {
4745  int ignore = 0;
4746 
4747  if (strcmp(currentfile->d_name+l-strlen(PLUGIN_SUFFIX), PLUGIN_SUFFIX) != 0)
4748  continue;
4749 
4750  while (disable) {
4751  if (strcmp(disable->name, "All") == 0) {
4752  LOG(llevInfo, "plugins: disabling (all) %s\n", currentfile->d_name);
4753  ignore = 1;
4754  break;
4755  }
4756  if (strncmp(disable->name, currentfile->d_name, strlen(disable->name)) == 0 && strlen(currentfile->d_name) == strlen(PLUGIN_SUFFIX) + strlen(disable->name)) {
4757  LOG(llevInfo, "plugins: disabling %s\n", currentfile->d_name);
4758  ignore = 1;
4759  break;
4760  }
4761  disable = disable->next;
4762  }
4763  if (ignore == 0) {
4764  snprintf(buf, sizeof(buf), "%s/plugins/%s", LIBDIR, currentfile->d_name);
4765  LOG(llevInfo, "plugins: loading %s\n", currentfile->d_name);
4766  plugins_init_plugin(buf);
4767  }
4768  }
4769  }
4770 
4771  closedir(plugdir);
4772 }
4773 
4778 void cleanupPlugins(void) {
4779  crossfire_plugin *cp;
4780 
4781  if (!plugins_list)
4782  return;
4783 
4784  for (cp = plugins_list; cp != NULL; ) {
4785  crossfire_plugin *next = cp->next;
4786  if (cp->closefunc)
4787  cp->closefunc();
4788  /* Don't actually unload plugins, it makes backtraces for memory
4789  * debugging (printed at exit) messed up. And it doesn't matter if we
4790  * don't free it here. The OS will do it for us.
4791  */
4792  /* plugins_dlclose(cp->libptr); */
4793  free(cp);
4794  cp = next;
4795  }
4796  plugins_list = NULL;
4797 }
#define CFAPI_OBJECT_PROP_STR
Definition: plugin.h:248
#define CFAPI_OBJECT_PROP_MAP
Definition: plugin.h:179
#define CFAPI_OBJECT_PROP_RUN_AWAY
Definition: plugin.h:225
static void cfapi_object_clear(int *type,...)
Wrapper for object_clear().
Definition: plugins.c:3694
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Sends message to player(s).
Definition: main.c:315
Error, serious thing.
Definition: logger.h:11
int object_distance(const object *ob1, const object *ob2)
Return the square of the distance between the two given objects.
Definition: object.c:3584
void spring_trap(object *trap, object *victim)
This function generalizes attacks by runes/traps.
Definition: rune.c:205
static void cfapi_map_trigger_connected(int *type,...)
Wrapper for trigger_connected().
Definition: plugins.c:3799
static void copy_message(object *op, const char *msg)
Utility function to copy the string to op->msg and ensure there is a final newline.
Definition: plugins.c:2519
static void cfapi_set_random_map_variable(int *type,...)
Wrapper for set_random_map_variable().
Definition: plugins.c:4577
char path[HUGE_BUF]
Filename of the map.
Definition: map.h:365
#define CFAPI_OBJECT_PROP_MAGIC
Definition: plugin.h:206
void apply_by_living_below(object *pl)
Attempt to apply the object 'below' the player.
Definition: apply.c:618
#define CFAPI_PLAYER_QUEST_GET_STATE
Definition: plugin.h:291
#define MSG_TYPE_MISC
Messages that don't go elsewhere.
Definition: newclient.h:389
#define FLAG_NO_DROP
Object can't be dropped.
Definition: define.h:289
int8_t Int
Definition: living.h:35
#define CFAPI_PARTY_PROP_PASSWORD
Definition: plugin.h:322
One player.
Definition: player.h:92
int apply_manual(object *op, object *tmp, int aflag)
Main apply handler.
Definition: apply.c:510
#define CFAPI_OBJECT_PROP_MATERIAL
Definition: plugin.h:204
const char * determine_god(object *op)
Determines if op worships a god.
Definition: gods.c:106
Random map parameters.
Definition: random_map.h:14
#define CFAPI_OBJECT_PROP_ANIMATION
Definition: plugin.h:269
mapstruct * generate_random_map(const char *OutFileName, RMParms *RP, char **use_layout)
Main random map routine.
Definition: random_map.c:74
int8_t ac
Armour Class, how hard to hit, the lower the better.
Definition: living.h:37
#define CFAPI_OBJECT_PROP_SP
Definition: plugin.h:258
int32_t weight_limit
Weight-limit of object.
Definition: object.h:366
#define UP_OBJ_FACE
Only thing that changed was the face.
Definition: object.h:519
void(* f_plug_api)(int *type,...)
General API function.
Definition: plugin.h:125
#define CFAPI_OBJECT_PROP_CARRYING
Definition: plugin.h:219
MoveType move_type
Type of movement this object uses.
Definition: object.h:424
#define plugins_dlopen(fname)
Load a shared library.
Definition: plugin.h:163
#define EVENT_REMOVE
A Player character has been removed.
Definition: plugin.h:93
#define CFAPI_OBJECT_PROP_NAME
Definition: plugin.h:181
#define CFAPI_OBJECT_PROP_OB_BELOW
Definition: plugin.h:172
#define CFAPI_PREGION
Definition: plugin.h:117
#define CFAPI_PLAYER_PROP_TITLE
Definition: plugin.h:288
#define EVENT_SHOUT
A player 'shout' something.
Definition: plugin.h:94
#define CFAPI_MAP_PROP_NAME
Definition: plugin.h:299
int16_t jaily
The coodinates in jailmap to which the player should be sent.
Definition: map.h:298
int move_player(object *op, int dir)
Player gave us a direction, check whether to move or fire.
Definition: player.c:3019
MoveType move_on
Move types affected moving on to this space.
Definition: object.h:427
Information.
Definition: logger.h:12
static void cfapi_object_drain(int *type,...)
Definition: plugins.c:3283
static void cfapi_system_register_global_event(int *type,...)
Definition: plugins.c:847
void quest_start(player *pl, sstring quest_code, int state)
Start a quest for a player.
Definition: quest.c:1096
static void cfapi_system_find_animation(int *type,...)
Wrapper for find_animation().
Definition: plugins.c:793
static void cfapi_object_move(int *type,...)
Moves an object.
Definition: plugins.c:1622
#define CFAPI_OBJECT_PROP_RACE
Definition: plugin.h:184
object * check_spell_known(object *op, const char *name)
Checks to see if player knows the spell.
Definition: spell_util.c:435
#define CFAPI_MAP_PROP_ENTER_Y
Definition: plugin.h:308
static void cfapi_object_check_spell(int *type,...)
Wrapper for check_spell_known().
Definition: plugins.c:3901
Used to link together several objects.
Definition: object.h:442
#define CFAPI_REGION_PROP_MESSAGE
Definition: plugin.h:329
const char * race
Human, goblin, dragon, etc.
Definition: object.h:318
#define P_NEED_UPDATE
This space is out of date.
Definition: map.h:239
int is_magical(const object *op)
Checks whether object is magical.
Definition: item.c:1243
#define CFAPI_MAP_PROP_FLAGS
Definition: plugin.h:295
#define CFAPI_MAP_PROP_DARKNESS
Definition: plugin.h:304
#define CFAPI_OBJECT_PROP_ARCHETYPE
Definition: plugin.h:232
#define CFAPI_OBJECT_PROP_WEIGHT
Definition: plugin.h:217
static void cfapi_get_month_name(int *type,...)
Wrapper for get_season_name().
Definition: plugins.c:1095
uint16_t attack_movement
What kind of attack movement.
Definition: object.h:391
#define CFAPI_OBJECT_PROP_ATTACK_TYPE
Definition: plugin.h:200
static void cfapi_object_pickup(int *type,...)
Definition: plugins.c:4337
#define CFAPI_OBJECT_PROP_FACE
Definition: plugin.h:268
mapstruct * get_empty_map(int sizex, int sizey)
Creates and returns a map of the specific size.
Definition: map.c:874
static void cfapi_archetype_get_property(int *type,...)
Definition: plugins.c:4352
static void cfapi_object_pay_amount(int *type,...)
Wrapper for pay_for_amount().
Definition: plugins.c:3921
#define SET_FLAG(xyz, p)
Definition: define.h:223
#define NR_OF_HOOKS
Number of hooked functions a plugin can call.
Definition: plugins.c:43
#define EVENT_KICK
A player was Kicked by a DM.
Definition: plugin.h:97
void do_forget_spell(object *op, const char *spell)
Erases spell from player's inventory.
Definition: apply.c:432
MoveType move_allow
What movement types explicitly allowed.
Definition: object.h:426
int16_t bed_x
Definition: player.h:98
linked_char * disabled_plugins
List of disabled plugins, 'All' means all.
Definition: global.h:322
static void cfapi_object_get_property(int *type,...)
Main object property getter.
Definition: plugins.c:1717
#define plugins_dlsym(lib, name)
Get a function from a shared library.
Definition: plugin.h:165
#define CFAPI_FUNC
Definition: plugin.h:114
#define PLUGIN_SUFFIX
Definition: win32.h:106
static void cfapi_object_spring_trap(int *type,...)
Definition: plugins.c:3753
New_Face * new_faces
Contains face information, with names, numbers, magicmap color and such.
Definition: image.c:33
#define CFAPI_OBJECT_PROP_GOD
Definition: plugin.h:265
#define CFAPI_OBJECT_PROP_PICK_UP
Definition: plugin.h:214
#define CFAPI_MAP_PROP_DIFFICULTY
Definition: plugin.h:296
void player_get_title(const struct pl *pl, char *buf, size_t bufsize)
Returns the player's title.
Definition: player.c:224
uint16_t animation_id
An index into the animation array.
Definition: object.h:416
#define CFAPI_MAP_PROP_HEIGHT
Definition: plugin.h:306
uint16_t material
What materials this object consist of.
Definition: object.h:347
#define CFAPI_OBJECT_PROP_DIRECTION
Definition: plugin.h:194
const char * name
Name of the animation sequence.
Definition: face.h:27
#define strdup_local
Definition: compat.h:25
uint8_t anim_speed
Ticks between animation-frames.
Definition: object.h:417
object * object_get_env_recursive(object *op)
Utility function.
Definition: object.c:333
One party.
Definition: party.h:10
EXTERN objectlink * first_friendly_object
Objects monsters will go after.
Definition: global.h:123
#define CFAPI_OBJECT_PROP_NEXT_ACTIVE_OB
Definition: plugin.h:173
struct obj * container
Current container being used.
Definition: object.h:291
#define CFAPI_OBJECT_PROP_MAXGP
Definition: plugin.h:263
#define EVENT_LOGIN
Player login.
Definition: plugin.h:88
int player_arrest(object *who)
Put a player into jail, taking into account cursed exits and player's region.
Definition: c_wiz.c:806
#define CFAPI_OBJECT_PROP_HIDDEN
Definition: plugin.h:227
static void cfapi_region_get_property(int *type,...)
Regions-related functions.
Definition: plugins.c:4462
static void cfapi_object_on_same_map(int *type,...)
Definition: plugins.c:3737
static void cfapi_system_find_face(int *type,...)
Wrapper for find_face().
Definition: plugins.c:812
int16_t players
How many players are on this level right now.
Definition: map.h:344
void player_update_bg_music(object player[static 1])
Definition: sounds.c:152
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
Definition: utils.c:596
struct obj * who
Player saying something.
Definition: dialog.h:52
static void cfapi_object_give_skill(int *type,...)
Definition: plugins.c:3336
#define CFAPI_OBJECT_PROP_MOVE_STATUS
Definition: plugin.h:228
const char * get_season_name(const int index)
give access to season names
Definition: time.c:123
int pay_for_item(object *op, object *pl)
DAMN: This is now a wrapper for pay_from_container, which is called for the player, then for each active container that can hold money until op is paid for.
Definition: shop.c:548
char * create_pathname(const char *name, char *buf, size_t size)
Get the full path to a map file.
Definition: map.c:104
void knowledge_give(player *pl, const char *marker, const object *book)
Give a knowledge item from its code.
Definition: knowledge.c:1009
mapstruct * ready_map_name(const char *name, int flags)
Makes sure the given map is loaded and swapped in.
Definition: map.c:1803
const char * playerdir
Where the player files are.
Definition: global.h:244
unsigned char MoveType
Typdef here to define type large enough to hold bitmask of all movement types.
Definition: define.h:432
int32_t last_heal
Last healed.
Definition: object.h:357
#define CFAPI_OBJECT_PROP_SUBTYPE
Definition: plugin.h:197
partylist * party_get_next(const partylist *party)
Returns the next party from the list of all parties.
Definition: party.c:229
int16_t maxgrace
Maximum grace.
Definition: living.h:44
void free_string(sstring str)
This will reduce the refcount, and if it has reached 0, str will be freed.
Definition: shstr.c:280
#define UP_OBJ_INSERT
Object was inserted.
Definition: object.h:516
signed long object_sum_weight(object *op)
object_sum_weight() is a recursive function which calculates the weight an object is carrying...
Definition: object.c:311
#define TIMER_ERR_ID
Invalid timer id.
Definition: timers.h:67
#define CFAPI_REGION_PROP_JAIL_X
Definition: plugin.h:330
static void cfapi_get_periodofday_name(int *type,...)
Wrapper for get_season_name().
Definition: plugins.c:1107
#define CFAPI_ARCH_PROP_MORE
Definition: plugin.h:317
#define SET_ANIMATION(ob, newanim)
Definition: global.h:169
static void cfapi_object_find_by_arch_name(int *type,...)
Definition: plugins.c:4062
mapstruct * get_map_from_coord(mapstruct *m, int16_t *x, int16_t *y)
This is basically the same as out_of_map above(), but instead we return NULL if no map is valid (coor...
Definition: map.c:2368
#define NR_EVENTS
Definition: plugin.h:100
#define EVENT_MAPLEAVE
A player left a map.
Definition: plugin.h:91
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
Definition: main.c:342
#define CFAPI_OBJECT_PROP_CONTAINER
Definition: plugin.h:178
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.c:4246
#define CFAPI_INT16
Definition: plugin.h:118
void pick_up(object *op, object *alt)
Try to pick up an item.
Definition: c_object.c:446
f_plug_api func
Function itself.
Definition: plugin.h:351
#define CFAPI_OBJECT_PROP_INVENTORY
Definition: plugin.h:175
void query_base_name(const object *op, int plural, char *buf, size_t size)
Query a short name for the item.
Definition: item.c:723
struct pl player
One player.
static void cfapi_object_set_property(int *type,...)
Sets the property of an object.
Definition: plugins.c:2552
object clone
An object from which to do object_copy()
Definition: object.h:470
int16_t duration
How long the spell lasts.
Definition: object.h:403
#define CFAPI_OBJECT_PROP_FLAGS
Definition: plugin.h:247
static void cfapi_get_season_name(int *type,...)
Wrapper for get_season_name().
Definition: plugins.c:1071
socket_struct socket
Socket information for this player.
Definition: player.h:94
int16_t invisible
How much longer the object will be invis.
Definition: object.h:360
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.c:65
#define EVENT_LOGOUT
Player logout.
Definition: plugin.h:89
uint32_t reset_time
When this map should reset.
Definition: map.h:332
int calculate_difficulty(mapstruct *m)
This routine is supposed to find out the difficulty of the map.
Definition: map.c:1913
#define CFAPI_SINT64
Definition: plugin.h:120
#define CFAPI_OBJECT_PROP_NAME_PLURAL
Definition: plugin.h:182
static void cfapi_log(int *type,...)
Wrapper for LOG().
Definition: plugins.c:1174
const char * get_weekday(const int index)
give access to weekday names
Definition: time.c:116
const char * slaying
Which race to do double damage to.
Definition: object.h:319
region * get_region_by_map(mapstruct *m)
Gets a region from a map.
Definition: region.c:74
static void cfapi_object_find_archetype_inside(int *type,...)
Kinda wrapper for arch__present_in_ob().
Definition: plugins.c:4030
Definitions for the plugin system.
DIR * opendir(const char *)
Opens a directory for reading.
Definition: win32.c:37
int32_t last_sp
As last_heal, but for spell points.
Definition: object.h:358
#define CFAPI_OBJECT_PROP_OWNER
Definition: plugin.h:242
static void cfapi_object_teleport(int *type,...)
Teleports an object at a specified destination if possible.
Definition: plugins.c:4298
static void cfapi_system_re_cmp(int *type,...)
Wrapper for re_cmp().
Definition: plugins.c:969
static int do_execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix, talk_info *talk)
Definition: plugins.c:312
const char * party_get_password(const partylist *party)
Returns the party's password.
Definition: party.c:263
uint8_t subtype
Subtype of object.
Definition: object.h:339
crossfire_plugin * plugins_list
Linked list of loaded plugins.
Definition: plugins.c:235
uint32_t mark_count
Count of marked object.
Definition: player.h:193
#define CFAPI_OBJECT_PROP_MOVE_ON
Definition: plugin.h:274
static void cfapi_map_get_map_property(int *type,...)
Definition: plugins.c:1301
uint8_t hide
The object is hidden, not invisible.
Definition: object.h:387
int64_t exp
Experience.
Definition: living.h:46
#define CFAPI_OBJECT_PROP_MESSAGE
Definition: plugin.h:187
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
Definition: object.h:533
static void cfapi_map_delete_map(int *type,...)
Definition: plugins.c:1501
#define CFAPI_OBJECT_PROP_EXP_MULTIPLIER
Definition: plugin.h:231
struct obj * above
Pointer to the object stacked above this one.
Definition: object.h:288
double expmul
needed experience = (calc_exp*expmul) - means some races/classes can need less/more exp to gain level...
Definition: object.h:395
#define plugins_dlclose(lib)
Unload a shared library.
Definition: plugin.h:164
#define CFAPI_MAP_PROP_RESET_TIMEOUT
Definition: plugin.h:301
char id[MAX_BUF]
Plugin identification string.
Definition: plugin.h:148
void initPlugins(void)
Plugins initialization.
Definition: plugins.c:4728
object * arch_present_in_ob(const archetype *at, const object *op)
Searches for any objects with a matching archetype in the inventory of the given object.
Definition: object.c:3061
#define CFAPI_PLAYER_QUEST_START
Definition: plugin.h:290
#define CFAPI_DOUBLE
Definition: plugin.h:112
static void cfapi_object_insert(int *type,...)
Definition: plugins.c:3489
void remove_friendly_object(object *op)
Removes the specified object from the linked list of friendly objects.
Definition: friend.c:56
#define CFAPI_REGION_PROP_NEXT
Definition: plugin.h:326
uint32_t path_attuned
Paths the object is attuned to.
Definition: object.h:343
void object_update(object *op, int action)
object_update() updates the array which represents the map.
Definition: object.c:1239
static void cfapi_object_drop(int *type,...)
Wrapper for drop().
Definition: plugins.c:4099
static void cfapi_object_fix(int *type,...)
Definition: plugins.c:3320
int16_t sp
Spell points.
Definition: living.h:41
static void cfapi_map_set_map_property(int *type,...)
Definition: plugins.c:1433
#define EVENT_TELL
A player 'tell' something.
Definition: plugin.h:95
static void cfapi_object_set_key(int *type,...)
Write a key/value for an object.
Definition: plugins.c:1694
#define EVENT_CRASH
Triggered when the server crashes.
Definition: plugin.h:85
#define CFAPI_MAP_PROP_NEXT
Definition: plugin.h:310
static void cfapi_party_get_property(int *type,...)
Party-related functions.
Definition: plugins.c:4407
int object_can_merge(object *ob1, object *ob2)
Examines the 2 objects given to it, and returns true if they can be merged together, including inventory.
Definition: object.c:171
#define CFAPI_OBJECT_PROP_SLAYING
Definition: plugin.h:185
static void cfapi_map_create_path(int *type,...)
Wrapper for create_pathname() and create_overlay_pathname().
Definition: plugins.c:1267
int plugin_event_say(object *npc, talk_info *talk)
Definition: plugins.c:375
Definition: win32.h:110
uint32_t path_repelled
Paths the object is repelled from.
Definition: object.h:344
#define safe_strncpy
Definition: compat.h:23
int(* f_plug_postinit)(void)
Function called after the plugin was initialized.
Definition: plugin.h:127
#define SCRIPT_FIX_ALL
Definition: global.h:359
void free_dialog_information(object *op)
Frees obj::dialog_information.
Definition: dialog.c:32
char * partyname
Party name.
Definition: party.h:14
struct obj * enemy
Monster/player to follow even if not closest.
Definition: object.h:381
struct archt * other_arch
Pointer used for various things - mostly used for what this objects turns into or what this object cr...
Definition: object.h:413
static void cfapi_system_find_string(int *type,...)
Wrapper for find_string().
Definition: plugins.c:927
object * object_find_by_name(const object *who, const char *name)
Finds an object in inventory name.
Definition: object.c:3879
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
Definition: main.c:310
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
Definition: object.h:465
#define CFAPI_PMAP
Definition: plugin.h:110
static void cfapi_object_apply_below(int *type,...)
Applies an object below.
Definition: plugins.c:3196
void transmute_materialname(object *op, const object *change)
When doing transmutation of objects, we have to recheck the resistances, as some that did not apply p...
Definition: utils.c:266
char savebed_map[MAX_BUF]
Map where player will respawn after death.
Definition: player.h:97
static void cfapi_timer_create(int *type,...)
Wrapper for cfapi_timer_create().
Definition: plugins.c:1122
One function the server exposes to plugins.
Definition: plugin.h:350
char * host
Which host it is connected from (ip address).
Definition: newserver.h:110
static void cfapi_player_quest(int *type,...)
Quest-related wrappers, for all quest-related operations.
Definition: plugins.c:4640
#define CFAPI_POBJECT
Definition: plugin.h:109
static void cfapi_object_split(int *type,...)
Wrapper for object_split().
Definition: plugins.c:3597
#define CFAPI_OBJECT_PROP_CHOSEN_SKILL
Definition: plugin.h:226
#define CFAPI_OBJECT_PROP_OTHER_ARCH
Definition: plugin.h:233
int16_t maxsp
Max spell points.
Definition: living.h:42
#define CFAPI_OBJECT_PROP_LAST_SP
Definition: plugin.h:210
int8_t Con
Definition: living.h:35
int change_map_light(mapstruct *m, int change)
Used to change map light level (darkness) up or down.
Definition: map.c:1995
#define CFAPI_REGION_PROP_JAIL_PATH
Definition: plugin.h:332
#define FLAG_REMOVED
Object is not in any map or invenory.
Definition: define.h:232
static void cfapi_object_delete(int *type,...)
Definition: plugins.c:3391
int16_t hp
Hit Points.
Definition: living.h:39
#define CFAPI_OBJECT_PROP_LAST_GRACE
Definition: plugin.h:211
static void cfapi_object_find_by_name(int *type,...)
Definition: plugins.c:4078
#define CFAPI_OBJECT_PROP_COUNT
Definition: plugin.h:180
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.c:71
partylist * party
Party this player is part of.
Definition: player.h:186
static void cfapi_object_remove(int *type,...)
Definition: plugins.c:3370
#define CFAPI_NONE
Definition: plugin.h:104
#define UPD_ALL
Definition: newclient.h:297
void command_say(object *op, const char *params)
'say' command.
Definition: c_chat.c:34
object * ob
Item to link to.
Definition: object.h:443
#define MOVE_ALL
Mask of all movement types.
Definition: define.h:413
uint16_t height
Width and height of map.
Definition: map.h:347
object * give_skill_by_name(object *op, const char *skill_name)
Given the skill name skill_name, we find the skill archetype/object, set appropriate values...
Definition: living.c:1750
static void cfapi_object_transmute(int *type,...)
Definition: plugins.c:3353
const char * get_month_name(const int index)
give access to month names
Definition: time.c:109
#define CFAPI_FLOAT
Definition: plugin.h:111
void map_newmap_cmd(socket_struct *ns)
Sound related function.
Definition: request.c:615
struct _crossfire_plugin * next
Next plugin in list.
Definition: plugin.h:151
void object_set_owner(object *op, object *owner)
Sets the owner and sets the skill and exp pointers to owner's current skill and experience objects...
Definition: object.c:601
#define CFAPI_PLAYER_PROP_BED_X
Definition: plugin.h:285
char * name
Name of map as given by its creator.
Definition: map.h:328
#define CFAPI_PARCH
Definition: plugin.h:113
const char * lore
Obscure information about this object, to get put into books and the like.
Definition: object.h:323
static void cfapi_object_identify(int *type,...)
Wrapper for identify().
Definition: plugins.c:3241
struct obj * chosen_skill
The skill chosen to use.
Definition: object.h:386
int object_set_value(object *op, const char *key, const char *value, int add_key)
Updates the key in op to value.
Definition: object.c:4375
uint32_t update_look
If true, we need to send the look window.
Definition: newserver.h:115
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1368
int change_abil(object *op, object *tmp)
Permanently alters an object's stats/flags based on another object.
Definition: living.c:394
const char * name
Face name, as used by archetypes and such.
Definition: face.h:20
const char * title
Of foo, etc.
Definition: object.h:317
int16_t y
Position in the map for this object.
Definition: object.h:326
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.c:1921
#define CFAPI_MAP_PROP_PLAYERS
Definition: plugin.h:302
int move_to(object *op, int x, int y)
Move an object one square toward a specified destination on the same map.
Definition: move.c:545
int is_friendly(const object *op)
Checks if the given object is already in the friendly list or not Lauwenmark - 31/07/05.
Definition: friend.c:144
int16_t maxhp
Max hit points.
Definition: living.h:40
sstring find_string(const char *str)
Searches a string in the shared strings.
Definition: shstr.c:236
char * name
Shortend name of the region as maps refer to it.
Definition: map.h:278
#define CFAPI_OBJECT_PROP_FACING
Definition: plugin.h:195
int user_event(object *op, object *activator, object *third, const char *message, int fix)
Definition: plugins.c:308
#define MSG_TYPE_COMMAND
Responses to commands, eg, who.
Definition: newclient.h:379
static void cfapi_object_say(int *type,...)
Definition: plugins.c:4138
#define EVENT_MAPENTER
A player entered a map.
Definition: plugin.h:90
static void cfapi_system_remove_string(int *type,...)
Wrapper for free_string().
Definition: plugins.c:909
uint32_t path_denied
Paths the object is denied access to.
Definition: object.h:345
static void cfapi_object_change_exp(int *type,...)
Wrapper for change_exp().
Definition: plugins.c:4207
#define CFAPI_PLAYER_PROP_IP
Definition: plugin.h:281
#define CFAPI_OBJECT_PROP_ENVIRONMENT
Definition: plugin.h:176
Definition: win32.h:120
static void cfapi_object_merge(int *type,...)
Wrapper for object_merge().
Definition: plugins.c:3630
#define CFAPI_OBJECT_PROP_GP
Definition: plugin.h:259
LIBPTRTYPE libptr
Pointer to the plugin library.
Definition: plugin.h:147
#define CFAPI_OBJECT_PROP_CHA
Definition: plugin.h:254
#define CFAPI_PARTY_PROP_PLAYER
Definition: plugin.h:323
object * object_new(void)
Grabs an object from the list of unused objects, makes sure it is initialised, and returns it...
Definition: object.c:1037
const char * name_pl
The plural name of the object.
Definition: object.h:315
static void cfapi_player_knowledge(int *type,...)
Wrapper for knowledge-related functions().
Definition: plugins.c:4249
#define LIBDIR
Definition: win32.h:99
#define CFAPI_OBJECT_PROP_ATTACKED_BY
Definition: plugin.h:224
#define CFAPI_STRING
Definition: plugin.h:108
void player_set_own_title(struct pl *pl, const char *title)
Sets the custom title.
Definition: player.c:264
int object_can_pick(const object *who, const object *item)
Finds out if an object can be picked up.
Definition: object.c:3793
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.c:2690
#define CFAPI_OBJECT_PROP_MOVE_SLOW_PENALTY
Definition: plugin.h:277
#define CFAPI_MAP_PROP_UNIQUE
Definition: plugin.h:312
float speed_left
How much speed is left to spend this round.
Definition: object.h:329
int knowledge_player_knows(const player *pl, const char *knowledge)
Determines whether a player knows a specific knowledge or not.
Definition: knowledge.c:1306
#define CFAPI_OBJECT_PROP_INT
Definition: plugin.h:252
signed short int16_t
Definition: win32.h:160
#define CFAPI_MAP_PROP_RESET_TIME
Definition: plugin.h:300
#define CFAPI_ARCH_PROP_HEAD
Definition: plugin.h:316
void monster_npc_say(object *npc, const char *cp)
Simple function to have some NPC say something.
Definition: monster.c:2301
static void cfapi_timer_destroy(int *type,...)
Wrapper for cftimer_destroy().
Definition: plugins.c:1155
const char * materialname
Specific material name.
Definition: object.h:346
int16_t enter_x
Definition: map.h:348
int32_t weight
Attributes of the object.
Definition: object.h:365
uint32_t unique
If set, this is a per player unique map.
Definition: map.h:337
#define CFAPI_OBJECT_PROP_LEVEL
Definition: plugin.h:208
Structure used to build up dialog information when a player says something.
Definition: dialog.h:51
#define FOR_ABOVE_FINISH()
Finishes FOR_ABOVE_PREPARE().
Definition: define.h:729
void update_all_los(const mapstruct *map, int x, int y)
This function makes sure that update_los() will be called for all players on the given map within the...
Definition: los.c:532
const char * tmpdir
Directory to use for temporary files.
Definition: global.h:251
int8_t Wis
Definition: living.h:35
const char * text
What the player actually said.
Definition: dialog.h:53
#define CFAPI_OBJECT_PROP_HEAD
Definition: plugin.h:177
#define CFAPI_PLAYER_PROP_BED_MAP
Definition: plugin.h:284
#define CFAPI_OBJECT_PROP_MOVE_ALLOW
Definition: plugin.h:273
static void cfapi_player_message(int *type,...)
Definition: plugins.c:4182
struct mapdef * map
Pointer to the map in which this object is present.
Definition: object.h:297
struct regiondef * next
Pointer to next region, NULL for the last one.
Definition: map.h:277
This is a game region.
Definition: map.h:276
#define CFAPI_OBJECT_PROP_RAW_NAME
Definition: plugin.h:279
#define snprintf
Definition: win32.h:46
struct obj * active_prev
Previous object in the 'active list This is used in process_events so that the entire object list doe...
Definition: object.h:283
void drain_specific_stat(object *op, int deplete_stats)
Drain a specified stat from op.
Definition: living.c:724
static void cfapi_object_user_event(int *type,...)
Definition: plugins.c:4616
#define CFAPI_ARCH_PROP_NEXT
Definition: plugin.h:315
f_plug_postinit closefunc
Plugin Termination function.
Definition: plugin.h:146
struct linked_char * next
Definition: global.h:88
int plugins_init_plugin(const char *libfile)
Try to load the specified plugin.
Definition: plugins.c:607
uint64_t query_money(const object *op)
Determine the amount of money the given object contains, including what is inside containers...
Definition: shop.c:478
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:712
char * msg
Message map creator may have left.
Definition: map.h:361
void update_position(mapstruct *m, int x, int y)
This function updates various attributes about a specific space on the map (what it looks like...
Definition: map.c:2119
int16_t dam
How much damage this object does when hitting.
Definition: living.h:45
int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix)
Definition: plugins.c:371
void add_friendly_object(object *op)
Add a new friendly object to the linked list of friendly objects.
Definition: friend.c:30
#define CFAPI_OBJECT_PROP_FP
Definition: plugin.h:260
int32_t carrying
How much weight this object contains.
Definition: object.h:367
const char * name
The name of the object, obviously...
Definition: object.h:311
int16_t bed_y
x,y - coordinates of respawn (savebed).
Definition: player.h:98
struct obj * env
Pointer to the object which is the environment.
Definition: object.h:293
#define FOR_ABOVE_PREPARE(op_, it_)
Constructs a loop iterating over all objects above an object.
Definition: define.h:722
#define CFAPI_OBJECT_PROP_MAGICAL
Definition: plugin.h:239
int64_t perm_exp
Permanent exp.
Definition: object.h:369
int8_t gen_sp_armour
Sp regen penalty this object has (was last_heal)
Definition: object.h:363
static void cfapi_map_find_by_archetype_name(int *type,...)
Kinda wrapper for map_find_by_archetype() (but uses a string, not an archetype*). ...
Definition: plugins.c:1565
#define LIBPTRTYPE
Definition: plugin.h:136
uint8_t state
How the object was last drawn (animation)
Definition: object.h:349
struct obj * below
Pointer to the object stacked below this one.
Definition: object.h:287
struct archt * more
Next part of a linked object.
Definition: object.h:469
static void cfapi_object_pay_item(int *type,...)
Wrapper for pay_for_item().
Definition: plugins.c:3942
archetype * find_archetype_by_object_name(const char *name)
This function retrieves an archetype given the name that appears during the game (for example...
Definition: arch.c:57
#define CFAPI_OBJECT_PROP_LAST_EAT
Definition: plugin.h:212
object * object_present_in_ob(uint8_t type, const object *op)
Searches for any objects with a matching type variable in the inventory of the given object...
Definition: object.c:3001
void trigger_connected(objectlink *ol, object *cause, const int state)
Trigger every object in an objectlink.
Definition: button.c:41
int16_t last_grace
As last_sp, except for grace.
Definition: object.h:359
void object_reset(object *op)
Sets to 0 vital variables in an object.
Definition: object.c:704
int pay_for_amount(uint64_t to_pay, object *pl)
Takes the amount of money from the the player inventory and from it's various pouches using the pay_f...
Definition: shop.c:509
#define CFAPI_OBJECT_PROP_MOVE_OFF
Definition: plugin.h:275
#define CFAPI_OBJECT_PROP_WEIGHT_LIMIT
Definition: plugin.h:218
#define CFAPI_PLAYER_QUEST_SET_STATE
Definition: plugin.h:292
struct obj * current_weapon
Pointer to the weapon currently used.
Definition: object.h:370
int8_t direction
Means the object is moving that way.
Definition: object.h:334
#define CFAPI_LONG
Definition: plugin.h:106
object * object_create_clone(object *asrc)
Create clone from object to another.
Definition: object.c:3832
uint32_t nrof
How many of the objects.
Definition: object.h:333
#define string_get_int(name)
Definition: plugins.c:1052
#define CFAPI_OBJECT_PROP_CURRENT_WEAPON
Definition: plugin.h:222
#define CFAPI_SSTRING
Definition: plugin.h:121
int8_t Cha
Definition: living.h:35
struct archt * head
The main part of a linked object.
Definition: object.h:468
int find_animation(const char *name)
Finds the animation id that matches name.
Definition: anim.c:170
static void cfapi_player_can_pay(int *type,...)
Wrapper for can_pay().
Definition: plugins.c:4230
static void cfapi_system_check_path(int *type,...)
Wrapper for check_path().
Definition: plugins.c:946
#define CFAPI_PPLAYER
Definition: plugin.h:115
#define SIZEOFFREE
Definition: define.h:154
#define P_OUT_OF_MAP
This space is outside the map.
Definition: map.h:251
MoveType move_off
Move types affected moving off this space.
Definition: object.h:428
int move_ob(object *op, int dir, object *originator)
Op is trying to move in direction dir.
Definition: move.c:58
int cftimer_destroy(int id)
Destroys an existing timer.
Definition: timers.c:128
#define CFAPI_OBJECT_PROP_X
Definition: plugin.h:189
EXTERN Animations * animations
Definition: global.h:163
void do_learn_spell(object *op, object *spell, int special_prayer)
Actually makes op learn spell.
Definition: apply.c:391
static void cfapi_map_out_of_map(int *type,...)
Wrapper for out_of_map().
Definition: plugins.c:1463
struct pl * contr
Pointer to the player which control this object.
Definition: object.h:276
#define CFAPI_OBJECT_PROP_CHEATER
Definition: plugin.h:244
static void cfapi_object_get_key(int *type,...)
Gets a key/value value for an object.
Definition: plugins.c:1672
#define CFAPI_OBJECT_PROP_PICKABLE
Definition: plugin.h:246
int8_t item_power
Power rating of the object.
Definition: object.h:362
static void cfapi_system_directory(int *type,...)
Definition: plugins.c:987
void cleanupPlugins(void)
Call the crossfire_plugin::closefunc on the various plugins, used at server shutdown.
Definition: plugins.c:4778
uint8_t ignore_plugin_compatibility
If set, don't check plugin version.
Definition: global.h:323
uint8_t darkness
Indicates level of darkness of map.
Definition: map.h:346
#define CFAPI_MAP_PROP_MESSAGE
Definition: plugin.h:309
int try_find_animation(const char *name)
Tries to find the animation id that matches name, don't LOG() an error if not found.
Definition: anim.c:185
void object_clear(object *op)
Frees everything allocated by an object, and also clears all variables and flags to default settings...
Definition: object.c:759
command_array_struct * find_plugin_command(const char *cmd, command_array_struct *command)
Tries to find if a given command is handled by a plugin.
Definition: plugins.c:4707
static crossfire_plugin * plugins_find_plugin(const char *id)
Find a plugin from its internal name.
Definition: plugins.c:246
#define CFAPI_OBJECT_PROP_ENEMY
Definition: plugin.h:223
#define CFAPI_REGION_PROP_JAIL_Y
Definition: plugin.h:331
object * find_marked_object(object *op)
Return the object the player has marked with the 'mark' command below.
Definition: c_object.c:1256
#define CFAPI_OBJECT_PROP_PATH_REPELLED
Definition: plugin.h:202
void plugins_display_list(object *op)
Displays a list of loaded plugins (keystrings and description) in the game log window.
Definition: plugins.c:740
static void cfapi_object_learn_spell(int *type,...)
Definition: plugins.c:3866
archetype * try_find_archetype(const char *name)
Finds, using the hashtable, which archetype matches the given name.
Definition: arch.c:663
#define UPD_WEIGHT
Definition: newclient.h:291
#define EVENT_SAY
Someone speaks.
Definition: plugin.h:70
char d_name[_MAX_FNAME+1]
Definition: win32.h:114
static void cfapi_object_create(int *type,...)
Wrapper for object_new(), create_archetype() and create_archetype_by_object_name().
Definition: plugins.c:3450
int8_t luck
Affects thaco and ac from time to time.
Definition: living.h:38
#define CFAPI_MAP_PROP_TMPNAME
Definition: plugin.h:298
float speed
The overall speed of this object.
Definition: object.h:328
unsigned __int64 uint64_t
Definition: win32.h:167
char fullname[MAX_BUF]
Plugin full name.
Definition: plugin.h:149
struct regiondef * parent
Pointer to the region that is a parent of the current region, if a value isn't defined in the current...
Definition: map.h:286
int on_same_map(const object *op1, const object *op2)
Checks whether 2 objects are on the same map or not.
Definition: map.c:2638
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
f_plug_property propfunc
Plugin getProperty function.
Definition: plugin.h:145
#define CLEAR_FLAG(xyz, p)
Definition: define.h:224
#define CFAPI_OBJECT_PROP_LORE
Definition: plugin.h:188
static void cfapi_player_find(int *type,...)
Wrapper for find_player_partial_name().
Definition: plugins.c:4167
#define EVENT_MAPLOAD
A map is loaded.
Definition: plugin.h:99
partylist * party_get_first(void)
Returns the first party from the list of all parties.
Definition: party.c:217
void change_exp(object *op, int64_t exp, const char *skill_name, int flag)
Changes experience to a player/monster.
Definition: living.c:2100
#define CFAPI_OBJECT_PROP_ITEM_POWER
Definition: plugin.h:215
#define CFAPI_REGION_PROP_LONGNAME
Definition: plugin.h:328
#define MSG_TYPE_COMMAND_DEBUG
Various debug type commands.
Definition: newclient.h:508
static void cfapi_object_apply(int *type,...)
Applies an object.
Definition: plugins.c:3216
static void cfapi_system_unregister_global_event(int *type,...)
Definition: plugins.c:866
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
int quest_get_player_state(player *pl, sstring quest_code)
Get the quest state for a player.
Definition: quest.c:1076
#define CFAPI_PARTY_PROP_NAME
Definition: plugin.h:320
struct obj * active_next
Next object in the 'active' list This is used in process_events so that the entire object list does n...
Definition: object.h:279
#define CFAPI_PLAYER_PROP_PARTY
Definition: plugin.h:283
LogLevel
Log levels for the LOG() function.
Definition: logger.h:10
object * object_create_arch(archetype *at)
Create a full object using the given archetype.
Definition: arch.c:733
int16_t jailx
Definition: map.h:298
int16_t enter_y
Enter_x and enter_y are default entrance coordinates to use for a map such that when an exit specifie...
Definition: map.h:348
int16_t x
Definition: object.h:326
#define EVENT_MAPUNLOAD
A map is freed (includes swapping out)
Definition: plugin.h:98
void drop(object *op, object *tmp)
Drop an item, either on the floor or in a container.
Definition: c_object.c:910
#define CFAPI_OBJECT_PROP_EXP
Definition: plugin.h:241
const char * skill
Name of the skill this object uses/grants.
Definition: object.h:321
int32_t last_eat
How long since we last ate.
Definition: object.h:356
static void cfapi_object_describe(int *type,...)
Wrapper for describe_item().
Definition: plugins.c:3261
#define plugins_dlerror()
Library error.
Definition: plugin.h:166
#define EVENT_MAPRESET
A map is resetting.
Definition: plugin.h:92
const char * re_cmp(const char *, const char *)
re-cmp - get regular expression match.
Definition: re-cmp.c:69
int8_t wc
Weapon Class, how skilled, the lower the better.
Definition: living.h:36
int(* f_plug_init)(const char *iversion, f_plug_api gethooksptr)
First function called in a plugin.
Definition: plugin.h:129
const char * confdir
Configuration files.
Definition: global.h:241
int object_find_first_free_spot(const object *ob, mapstruct *m, int x, int y)
object_find_first_free_spot(archetype, mapstruct, x, y) works like object_find_free_spot(), but it will search max number of squares.
Definition: object.c:3458
signed __int64 int64_t
Definition: win32.h:168
static const flag_definition flags[]
Flag mapping.
#define EVENT_GKILL
Triggered when anything got killed by anyone.
Definition: plugin.h:87
static void cfapi_system_strdup_local(int *type,...)
Wrapper for strdup_local().
Definition: plugins.c:833
#define CFAPI_OBJECT_PROP_PERM_EXP
Definition: plugin.h:221
const char * uniquedir
Directory for the unique items.
Definition: global.h:249
int8_t Str
Definition: living.h:35
char * tmpname
Name of temporary file.
Definition: map.h:327
int16_t resist[NROFATTACKS]
Resistance adjustments for attacks.
Definition: object.h:341
object * ob
The object representing the player.
Definition: player.h:158
const char * sstring
Strings that should be manipulated through add_string() and free_string().
Definition: global.h:40
#define EVENT_CLOCK
Global time event.
Definition: plugin.h:84
#define CFAPI_OBJECT_PROP_DAM
Definition: plugin.h:264
unsigned int uint32_t
Definition: win32.h:162
#define CFAPI_OBJECT_PROP_MOVE_TYPE
Definition: plugin.h:271
See Player.
Definition: object.h:107
const char * datadir
Read only data files.
Definition: global.h:242
#define CFAPI_OBJECT_PROP_SKILL
Definition: plugin.h:186
#define CFAPI_PLAYER_PROP_NEXT
Definition: plugin.h:287
#define CFAPI_OBJECT_PROP_AC
Definition: plugin.h:256
static void cfapi_object_check_trigger(int *type,...)
Wrapper for check_trigger().
Definition: plugins.c:3772
#define SET_MAP_FLAGS(M, X, Y, C)
Sets map flags.
Definition: map.h:163
#define CFAPI_OBJECT_PROP_BASE_NAME
Definition: plugin.h:238
Represents one command.
Definition: commands.h:37
#define TIMER_ERR_NONE
No error.
Definition: timers.h:66
const char * name
Definition: global.h:87
#define CFAPI_REGION_PROP_PARENT
Definition: plugin.h:327
#define CFAPI_INT
Definition: plugin.h:105
uint32_t attacktype
Bitmask of attacks this object does.
Definition: object.h:342
struct obj * spellitem
Spell ability monster is choosing to use.
Definition: object.h:394
static void cfapi_friendlylist_get_next(int *type,...)
Friend list access, to get objects on it.
Definition: plugins.c:4535
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
object_split(ob,nr) splits up ob into two parts.
Definition: object.c:2463
#define CFAPI_ARCH_PROP_NAME
Definition: plugin.h:314
StringBuffer * describe_item(const object *op, const object *owner, int use_media_tags, StringBuffer *buf)
Describes an item, in all its details.
Definition: item.c:981
void quest_set_player_state(player *pl, sstring quest_code, int state)
Set the state of a quest for a player.
Definition: quest.c:1132
Variables for the custom timers.
object * object_decrease_nrof(object *op, uint32_t i)
Decreases a specified number from the amount of an object.
Definition: object.c:2505
int set_random_map_variable(RMParms *rp, const char *buf)
#define CFAPI_OBJECT_PROP_SPEED_LEFT
Definition: plugin.h:192
#define FREE_AND_COPY(sv, nv)
Release the shared string if not NULL, and make it a reference to nv.
Definition: global.h:211
int16_t grace
Grace.
Definition: living.h:43
#define UPD_NROF
Definition: newclient.h:296
void get_tod(timeofday_t *tod)
Computes the ingame time of the day.
Definition: time.c:215
static void cfapi_object_query_money(int *type,...)
Wrapper for query_money().
Definition: plugins.c:3819
const char * custom_name
Custom name assigned by player.
Definition: object.h:432
int cftimer_create(int id, long delay, object *ob, int mode)
Creates a new timer.
Definition: timers.c:97
const char * localdir
Read/write data files.
Definition: global.h:243
tag_t count
Unique object number for this object.
Definition: object.h:299
living stats
Str, Con, Dex, etc.
Definition: object.h:368
static void cfapi_map_has_been_loaded(int *type,...)
Wrapper for has_been_loaded().
Definition: plugins.c:1249
uint16_t client_type
Public type information.
Definition: object.h:340
mapstruct * has_been_loaded(const char *name)
Checks whether map has been loaded.
Definition: map.c:79
int8_t Dex
Definition: living.h:35
char * jailmap
Where a player that is arrested in this region should be imprisoned.
Definition: map.h:297
struct archt * arch
Pointer to archetype.
Definition: object.h:412
#define CFAPI_OBJECT_PROP_HP
Definition: plugin.h:257
struct oblnk * next
Next item to link to.
Definition: object.h:444
Only for debugging purposes.
Definition: logger.h:13
static void cfapi_object_cast(int *type,...)
Wrapper for query_money().
Definition: plugins.c:3838
#define CFAPI_OBJECT_PROP_TITLE
Definition: plugin.h:183
int cftimer_find_free_id(void)
Finds a free ID for a new timer.
Definition: timers.c:144
const char * mapdir
Where the map files are.
Definition: global.h:245
uint32_t reset_timeout
How many seconds must elapse before this map should be reset.
Definition: map.h:333
#define CFAPI_PLAYER_PROP_BED_Y
Definition: plugin.h:286
uint16_t width
Definition: map.h:347
#define CFAPI_OBJECT_PROP_SPEED
Definition: plugin.h:191
Represents the ingame time.
Definition: tod.h:32
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:338
struct Settings settings
Server settings.
Definition: init.c:40
#define CFAPI_MAP_PROP_PATH
Definition: plugin.h:297
static void cfapi_get_hooks(int *type,...)
Definition: plugins.c:561
void object_set_enemy(object *op, object *enemy)
Sets the enemy of an object.
Definition: object.c:679
int remove_depletion(object *op, int level)
Remove depletion from op, if present, and warn player of such restorations.
Definition: living.c:751
#define CFAPI_OBJECT_PROP_FRIENDLY
Definition: plugin.h:236
void object_free2(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
Definition: object.c:1391
#define CFAPI_OBJECT_PROP_ANIM_SPEED
Definition: plugin.h:235
struct archt * next
Next archetype in a linked list.
Definition: object.h:467
#define CFAPI_OBJECT_PROP_LUCK
Definition: plugin.h:240
void party_join(object *op, partylist *party)
Makes a player join a party.
Definition: party.c:84
struct dirent * readdir(DIR *)
Returns the next file/directory for specified directory handle, obtained through a call to opendir()...
Definition: win32.c:75
const char * get_periodofday(const int index)
give access to weekday names
Definition: time.c:102
object * object_merge(object *op, object *top)
This function goes through all objects below and including top, and merges op to the first matching o...
Definition: object.c:1869
#define CFAPI_OBJECT_PROP_ARCH_NAME
Definition: plugin.h:266
void query_short_name(const object *op, char *buf, size_t size)
query_short_name(object) is similar to query_name(), but doesn't contain any information about object...
Definition: item.c:548
object * object_get_player_container(object *op)
Finds the player carrying an object.
Definition: object.c:353
static void cfapi_system_add_string(int *type,...)
Wrapper for add_string().
Definition: plugins.c:889
int out_of_map(mapstruct *m, int x, int y)
this returns TRUE if the coordinates (x,y) are out of map m.
Definition: map.c:2294
#define CFAPI_OBJECT_PROP_INVISIBLE_TIME
Definition: plugin.h:213
static void cfapi_get_time(int *type,...)
Wrapper for get_tod().
Definition: plugins.c:1040
static void cfapi_map_get_object_at(int *type,...)
Wrapper for GET_MAP_OB().
Definition: plugins.c:1536
#define CFAPI_OBJECT_PROP_DEX
Definition: plugin.h:249
#define CFAPI_MOVETYPE
Definition: plugin.h:122
#define CFAPI_OBJECT_PROP_ATTACK_MOVEMENT
Definition: plugin.h:229
#define CFAPI_MAP_PROP_REGION
Definition: plugin.h:311
static void cfapi_object_change_abil(int *type,...)
Wrapper for change_abil().
Definition: plugins.c:4123
void delete_map(mapstruct *m)
Frees the map, including the mapstruct.
Definition: map.c:1741
const char * msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:322
#define CFAPI_MAP_PROP_WIDTH
Definition: plugin.h:305
#define CFAPI_OBJECT_PROP_CON
Definition: plugin.h:250
sstring add_string(const char *str)
This will add 'str' to the hash table.
Definition: shstr.c:124
#define CFAPI_PLAYER_QUEST_WAS_COMPLETED
Definition: plugin.h:293
EXTERN player * first_player
First player.
Definition: global.h:117
char * cost_string_from_value(uint64_t cost, int largest_coin)
Return the textual representation of a cost in a newly-allocated string.
Definition: shop.c:330
Lauwenmark: an invisible object holding a plugin event hook.
Definition: object.h:227
#define CFAPI_PARTY_PROP_NEXT
Definition: plugin.h:321
object * identify(object *op)
Identifies an item.
Definition: item.c:1438
struct pl * next
Pointer to next player, NULL if this is last.
Definition: player.h:93
static void cfapi_object_clean_object(int *type,...)
Definition: plugins.c:3726
#define GET_MAP_OB(M, X, Y)
Gets the bottom object on a map.
Definition: map.h:172
int check_path(const char *name, int prepend_dir)
This function checks if a file with the given path exists.
Definition: map.c:203
int(* f_plug_event)(int *type,...)
Function to call to handle global or object-related events.
Definition: plugin.h:131
#define CFAPI_OBJECT_PROP_NROF
Definition: plugin.h:193
int8_t glow_radius
indicates the glow radius of the object
Definition: object.h:364
#define CFAPI_OBJECT_PROP_MAXSP
Definition: plugin.h:262
f_plug_event eventfunc
Event Handler function.
Definition: plugin.h:144
void object_copy(const object *src_ob, object *dest_ob)
Copy object first frees everything allocated by the second object, and then copies the contents of th...
Definition: object.c:838
#define CFAPI_ARCH_PROP_CLONE
Definition: plugin.h:318
struct _crossfire_plugin * prev
Previous plugin in list.
Definition: plugin.h:152
static void cfapi_object_transfer(int *type,...)
Object transfer.
Definition: plugins.c:3966
#define EVENT_PLAYER_DEATH
Global Death event.
Definition: plugin.h:86
static void cfapi_object_remove_depletion(int *type,...)
Definition: plugins.c:3301
int8_t Pow
Definition: living.h:35
int closedir(DIR *)
Dispose of a directory handle.
Definition: win32.c:108
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
This rolls up wall, blocks_magic, blocks_view, etc, all into one function that just returns a P_...
Definition: map.c:302
struct obj * inv
Pointer to the first object in the inventory.
Definition: object.h:290
void object_set_cheat(object *op)
object_set_cheat(object) sets the cheat flag (WAS_WIZ) in the object and in all it's inventory (recur...
Definition: object.c:3122
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:245
#define CFAPI_PLAYER_PROP_MARKED_ITEM
Definition: plugin.h:282
static void cfapi_map_get_map(int *type,...)
Gets map information.
Definition: plugins.c:1198
struct obj * head
Points to the main object of a large body.
Definition: object.h:296
#define MSG_SUBTYPE_NONE
Definition: newclient.h:398
static void cfapi_object_distance(int *type,...)
Wrapper for object_distance().
Definition: plugins.c:3653
#define CFAPI_OBJECT_PROP_LAST_HEAL
Definition: plugin.h:209
#define CFAPI_OBJECT_PROP_CLIENT_TYPE
Definition: plugin.h:198
#define CFAPI_OBJECT_PROP_INVISIBLE
Definition: plugin.h:267
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
#define CFAPI_OBJECT_PROP_TYPE
Definition: plugin.h:196
static const hook_entry plug_hooks[]
All hooked functions plugins can call.
Definition: plugins.c:140
char * msg
The description of the region.
Definition: map.h:293
static void cfapi_object_forget_spell(int *type,...)
Definition: plugins.c:3881
#define CFAPI_OBJECT_PROP_POW
Definition: plugin.h:253
static void cfapi_get_weekday_name(int *type,...)
Wrapper for get_season_name().
Definition: plugins.c:1083
static void cfapi_map_message(int *type,...)
Definition: plugins.c:1514
static void cfapi_object_update(int *type,...)
Wrapper for object_update().
Definition: plugins.c:3674
object * mark
Marked object.
Definition: player.h:194
void *(* f_plug_property)(int *type,...)
Get various plugin properties.
Definition: plugin.h:133
#define FLAG_WAS_WIZ
Player was once a wiz.
Definition: define.h:234
EXTERN region * first_region
First region.
Definition: global.h:119
uint8_t pick_up
See crossfire.doc.
Definition: object.h:361
#define CFAPI_OBJECT_PROP_GEN_SP_ARMOUR
Definition: plugin.h:216
int transfer_ob(object *op, int x, int y, int randomly, object *originator)
Move an object (even linked objects) to another spot on the same map.
Definition: move.c:144
MoveType move_block
What movement types this blocks.
Definition: object.h:425
uint8_t run_away
Monster runs away if it's hp goes below this percentage.
Definition: object.h:384
#define CFAPI_OBJECT_PROP_GLOW_RADIUS
Definition: plugin.h:220
struct mapdef * next
Next map, linked list.
Definition: map.h:326
static void cfapi_object_clone(int *type,...)
Clone an object, either through object_create_clone() or object_copy().
Definition: plugins.c:3418
static void cfapi_object_reset(int *type,...)
Wrapper for clear_reset().
Definition: plugins.c:3712
void object_set_msg(object *op, const char *msg)
Set the message field of an object.
Definition: object.c:4695
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
object_find_free_spot(object, map, x, y, start, stop) will search for a spot at the given map and coo...
Definition: object.c:3415
int check_trigger(object *op, object *cause)
Definition: button.c:523
#define CFAPI_OBJECT_PROP_PRESENT
Definition: plugin.h:243
float move_slow_penalty
How much this slows down the object.
Definition: object.h:430
#define CFAPI_OBJECT_PROP_MERGEABLE
Definition: plugin.h:245
#define CFAPI_OBJECT_PROP_WC
Definition: plugin.h:255
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.c:626
#define CFAPI_OBJECT_PROP_RESIST
Definition: plugin.h:199
#define CFAPI_OBJECT_PROP_SHORT_NAME
Definition: plugin.h:237
#define CFAPI_OBJECT_PROP_MOVE_SLOW
Definition: plugin.h:276
#define CFAPI_OBJECT_PROP_MATERIAL_NAME
Definition: plugin.h:205
void create_overlay_pathname(const char *name, char *buf, size_t size)
Same as create_pathname(), but for the overlay maps.
Definition: map.c:125
object * map_find_by_archetype(mapstruct *m, int x, int y, const archetype *at)
Searches for any objects with a matching archetype at the given map and coordinates.
Definition: object.c:2944
This is a game-map.
Definition: map.h:325
const New_Face * face
Face with colors.
Definition: object.h:332
#define CFAPI_OBJECT_PROP_MAXHP
Definition: plugin.h:261
int can_pay(object *pl)
Checks all unpaid items in op's inventory, adds up all the money they have, and checks that they can ...
Definition: shop.c:831
#define FLAG_UNIQUE
Item is really unique (UNIQUE_ITEMS)
Definition: define.h:288
#define CFAPI_OBJECT_PROP_VALUE
Definition: plugin.h:207
static void cfapi_cost_string_from_value(int *type,...)
Wrapper for cost_string_from_value, modified to take a buffer and length instead of a StringBuffer...
Definition: plugins.c:763
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Writes to everyone on the specified map.
Definition: main.c:325
#define CFAPI_OBJECT_PROP_SPELL_ITEM
Definition: plugin.h:230
#define CFAPI_OBJECT_PROP_PATH_ATTUNED
Definition: plugin.h:201
int32_t move_status
What stage in attack mode.
Definition: object.h:390
int16_t level
Level of creature or object.
Definition: object.h:351
int8_t facing
Object is oriented/facing that way.
Definition: object.h:335
void fix_object(object *op)
Updates all abilities given by applied objects in the inventory of the given object.
Definition: living.c:1118
static void send_changed_object(object *op)
Notify clients about a changed object.
Definition: plugins.c:282
unsigned find_face(const char *name, unsigned error)
This returns an the face number of face 'name'.
Definition: image.c:303
player * find_player_partial_name(const char *plname)
Find a player by a partial name.
Definition: player.c:109
#define CFAPI_OBJECT_PROP_WIS
Definition: plugin.h:251
EXTERN mapstruct * first_map
First map.
Definition: global.h:118
int quest_was_completed(player *pl, sstring quest_code)
Check if a quest was completed once for a player, without taking account the current state...
Definition: quest.c:1142
#define CFAPI_OBJECT_PROP_DURATION
Definition: plugin.h:278
EXTERN archetype * first_archetype
First archetype.
Definition: global.h:122
char * longname
Official title of the region, this might be defined to be the same as name.
Definition: map.h:291
void object_update_speed(object *op)
Updates the speed of an object.
Definition: object.c:1129
#define CFAPI_MAP_PROP_ENTER_X
Definition: plugin.h:307
void clean_object(object *op)
Remove and free all objects in the inventory of the given object.
Definition: map.c:1631
int32_t value
How much money it is worth (or contains)
Definition: object.h:350
object * object_get_owner(object *op)
Returns the object which this object marks as being the owner.
Definition: object.c:559
#define CFAPI_OBJECT_PROP_OB_ABOVE
Definition: plugin.h:171
int8_t magic
Any magical bonuses to this item.
Definition: object.h:348
#define CFAPI_OBJECT_PROP_Y
Definition: plugin.h:190
#define CFAPI_OBJECT_PROP_CUSTOM_NAME
Definition: plugin.h:234
const char * name
More definite name, like "generate_kobold".
Definition: object.h:466
#define EVENT_BORN
A new character has been created.
Definition: plugin.h:83
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
Definition: stringbuffer.c:76
f_plug_event gevent[NR_EVENTS]
Global events registered.
Definition: plugin.h:150
int plugins_remove_plugin(const char *id)
Unload the specified plugin.
Definition: plugins.c:698
One loaded plugin.
Definition: plugin.h:143
int execute_global_event(int eventcode,...)
Definition: plugins.c:379
object * object_find_by_arch_name(const object *who, const char *name)
Find object in inventory by archetype name.
Definition: object.c:4143
object * object_present_in_ob_by_name(int type, const char *str, const object *op)
Searches for any objects with a matching type & name variable in the inventory of the given object...
Definition: object.c:3039
#define CFAPI_OBJECT_PROP_PREV_ACTIVE_OB
Definition: plugin.h:174
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:705
int cast_spell(object *op, object *caster, int dir, object *spell_ob, char *stringarg)
Main dispatch when someone casts a spell.
Definition: spell_util.c:1471
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
Definition: object.c:1654
#define EVENT_USER
User-defined event.
Definition: plugin.h:78
static void cfapi_generate_random_map(int *type,...)
Wrapper for generate_random_map().
Definition: plugins.c:4599
#define CFAPI_OBJECT_PROP_PATH_DENIED
Definition: plugin.h:203
static void cfapi_map_update_position(int *type,...)
Wrapper for update_position().
Definition: plugins.c:1485
#define CFAPI_OBJECT_PROP_MOVE_BLOCK
Definition: plugin.h:272
#define CFAPI_REGION_PROP_NAME
Definition: plugin.h:325
struct obj * attacked_by
This object start to attack us! only player & monster.
Definition: object.h:382
#define CFAPI_PPARTY
Definition: plugin.h:116
static void cfapi_map_change_light(int *type,...)
Wrapper for change_map_light().
Definition: plugins.c:1591
int32_t food
How much food in stomach.
Definition: living.h:47
#define FLAG_FREED
Object is in the list of free objects.
Definition: define.h:233
#define EVENT_MUZZLE
A player was Muzzled (no_shout set).
Definition: plugin.h:96
uint32_t count
Any numbers typed before a command.
Definition: player.h:109