ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.10
Committed: Tue Mar 28 16:08:38 2006 UTC (18 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.9: +1 -1 lines
Log Message:
decrossfirefy global event calling conventions

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *rcsid_plugins_c =
3 elmex 1.5 * "$Id$";
4 root 1.1 */
5    
6     /*****************************************************************************/
7     /* CrossFire, A Multiplayer game for X-windows */
8     /* */
9     /* Copyright (C) 2000 Mark Wedel */
10     /* Copyright (C) 1992 Frank Tore Johansen */
11     /* */
12     /* This program is free software; you can redistribute it and/or modify */
13     /* it under the terms of the GNU General Public License as published by */
14     /* the Free Software Foundation; either version 2 of the License, or */
15     /* (at your option) any later version. */
16     /* */
17     /* This program is distributed in the hope that it will be useful, */
18     /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19     /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20     /* GNU General Public License for more details. */
21     /* */
22     /* You should have received a copy of the GNU General Public License */
23     /* along with this program; if not, write to the Free Software */
24     /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
25     /* */
26     /*****************************************************************************/
27     /* This is the server-side plugin management part. */
28     /*****************************************************************************/
29     /* Original code by Yann Chachkoff (yann.chachkoff@mailandnews.com). */
30     /* Special thanks to: */
31     /* David Delbecq (david.delbecq@mailandnews.com); */
32     /* Joris Bontje (jbontje@suespammers.org); */
33     /* Philip Currlin (?); */
34     /*****************************************************************************/
35    
36     /*****************************************************************************/
37     /* First, the headers. We only include plugin.h, because all other includes */
38     /* are done into it, and plugproto.h (which is used only by this file). */
39     /*****************************************************************************/
40     #include <plugin.h>
41    
42     #ifndef __CEXTRACT__
43     #include <sproto.h>
44     #endif
45    
46     #define NR_OF_HOOKS 74
47    
48     static const hook_entry plug_hooks[NR_OF_HOOKS] =
49     {
50     {cfapi_system_add_string, 0, "cfapi_system_add_string"},
51     {cfapi_system_register_global_event, 1, "cfapi_system_register_global_event"},
52     {cfapi_system_remove_string, 2, "cfapi_system_remove_string"},
53     {cfapi_system_unregister_global_event, 3, "cfapi_system_unregister_global_event"},
54     {cfapi_system_check_path, 4, "cfapi_system_check_path"},
55     {cfapi_system_re_cmp, 5, "cfapi_system_re_cmp"},
56     {cfapi_system_strdup_local, 6, "cfapi_system_strdup_local"},
57     {cfapi_system_directory, 7, "cfapi_system_directory"},
58     {cfapi_system_find_animation, 8, "cfapi_system_find_animation"},
59     {cfapi_object_clean_object, 9, "cfapi_object_clean_object"},
60     {cfapi_object_on_same_map, 10, "cfapi_object_on_same_map"},
61     {cfapi_object_get_key, 11, "cfapi_object_get_key"},
62     {cfapi_object_set_key, 12, "cfapi_object_set_key"},
63     {cfapi_object_get_property, 13, "cfapi_object_get_property"},
64     {cfapi_object_set_property, 14,"cfapi_object_set_property"},
65     {cfapi_object_apply, 15, "cfapi_object_apply"},
66     {cfapi_object_identify, 16, "cfapi_object_identify"},
67     {cfapi_object_describe, 17, "cfapi_object_describe"},
68     {cfapi_object_drain, 18, "cfapi_object_drain"},
69     {cfapi_object_fix, 19, "cfapi_object_fix"},
70     {cfapi_object_give_skill, 20, "cfapi_object_give_skill"},
71     {cfapi_object_transmute, 21, "cfapi_object_transmute"},
72     {cfapi_object_remove, 22, "cfapi_object_remove"},
73     {cfapi_object_delete, 23, "cfapi_object_delete"},
74     {cfapi_object_clone, 24, "cfapi_object_clone"},
75     {cfapi_object_find, 25, "cfapi_object_find"},
76     {cfapi_object_create, 26, "cfapi_object_create"},
77     {cfapi_object_insert, 27, "cfapi_object_insert"},
78     {cfapi_object_split, 28, "cfapi_object_split"},
79     {cfapi_object_merge, 29, "cfapi_object_merge"},
80     {cfapi_object_distance, 30, "cfapi_object_distance"},
81     {cfapi_object_update, 31, "cfapi_object_update"},
82     {cfapi_object_clear, 32, "cfapi_object_clear"},
83     {cfapi_object_reset, 33, "cfapi_object_reset"},
84     {cfapi_object_check_inventory, 34, "cfapi_object_check_inventory"},
85     {cfapi_object_spring_trap, 35, "cfapi_object_spring_trap"},
86     {cfapi_object_check_trigger, 36, "cfapi_object_check_trigger"},
87     {cfapi_object_query_cost, 37, "cfapi_object_query_cost"},
88     {cfapi_object_query_money, 38, "cfapi_object_query_money"},
89     {cfapi_object_cast, 39, "cfapi_object_cast"},
90     {cfapi_object_learn_spell, 40, "cfapi_object_learn_spell"},
91     {cfapi_object_forget_spell, 41, "cfapi_object_forget_spell"},
92     {cfapi_object_check_spell, 42, "cfapi_object_check_spell"},
93     {cfapi_object_pay_amount, 43, "cfapi_object_pay_amount"},
94     {cfapi_object_pay_item, 44, "cfapi_object_pay_item"},
95     {cfapi_object_transfer, 45, "cfapi_object_transfer"},
96     {cfapi_object_drop, 46, "cfapi_object_drop"},
97     {cfapi_object_take, 47, "cfapi_object_take"},
98     {cfapi_object_find_archetype_inside, 48, "cfapi_object_find_archetype_inside"},
99     {cfapi_object_say, 49, "cfapi_object_say"},
100     {cfapi_map_get_map, 50, "cfapi_map_get_map"},
101     {cfapi_map_has_been_loaded, 51, "cfapi_map_has_been_loaded"},
102     {cfapi_map_create_path, 52, "cfapi_map_create_path"},
103     {cfapi_map_get_map_property, 53, "cfapi_map_get_property"},
104     {cfapi_map_set_map_property, 54, "cfapi_map_set_property"},
105     {cfapi_map_out_of_map, 55, "cfapi_map_out_of_map"},
106     {cfapi_map_update_position, 56, "cfapi_map_update_position"},
107     {cfapi_map_delete_map, 57, "cfapi_map_delete_map"},
108     {cfapi_map_message, 58, "cfapi_map_message"},
109     {cfapi_map_get_object_at, 59, "cfapi_map_get_object_at"},
110     {cfapi_map_get_flags, 60, "cfapi_map_get_flags"},
111     {cfapi_map_present_arch_by_name,61, "cfapi_map_present_arch_by_name"},
112     {cfapi_player_find, 62, "cfapi_player_find"},
113     {cfapi_player_message, 63, "cfapi_player_message"},
114     {cfapi_player_send_inventory, 64, "cfapi_player_send_inventory"},
115     {cfapi_object_teleport, 65, "cfapi_object_teleport"},
116     {cfapi_object_speak, 66, "cfapi_object_speak"},
117     {cfapi_object_pickup, 67, "cfapi_object_pickup"},
118     {cfapi_object_move, 68, "cfapi_object_move"},
119     {cfapi_object_apply_below, 69, "cfapi_object_apply_below"},
120     {cfapi_archetype_get_first, 70, "cfapi_archetype_get_first"},
121     {cfapi_archetype_get_property, 71, "cfapi_archetype_get_property"},
122     {cfapi_party_get_property, 72, "cfapi_party_get_property"},
123     {cfapi_region_get_property, 73, "cfapi_region_get_property"},
124     };
125     int plugin_number = 0;
126     crossfire_plugin* plugins_list = NULL;
127    
128     /*****************************************************************************/
129     /* NEW PLUGIN STUFF STARTS HERE */
130     /*****************************************************************************/
131    
132 root 1.6 static void plugin_load_original_map(mapstruct *map)
133     {
134     execute_global_event (EVENT_MAPLOAD, map);
135     }
136    
137     static void plugin_load_temporary_map(mapstruct *map)
138     {
139     execute_global_event (EVENT_MAPIN, map);
140     }
141    
142 root 1.7 static void plugin_clean_temporary_map(mapstruct *map)
143     {
144     execute_global_event (EVENT_MAPCLEAN, map);
145     }
146    
147 root 1.2 static void plugin_object_free(object *ob)
148     {
149     execute_global_event (EVENT_FREE_OB, ob);
150     }
151    
152 root 1.1 #ifdef WIN32
153     static const char *plugins_dlerror(void)
154     {
155     static char buf[256];
156     DWORD err;
157     char* p;
158     err = GetLastError();
159     if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL) == 0)
160     snprintf(buf, sizeof(buf), "error %lu", err);
161     p = strchr(buf, '\0');
162     while (p > buf && (p[-1] == '\r' || p[-1] == '\n'))
163     p--;
164     *p = '\0';
165     return buf;
166     }
167     #endif /* WIN32 */
168    
169     /**
170     * Notify clients about a changed object.
171     *
172     * @param op the object that has changed
173     */
174     static void send_changed_object(object *op)
175     {
176     object* tmp;
177     player *pl;
178    
179     if (op->env != NULL) {
180     tmp = is_player_inv(op->env);
181     if (!tmp) {
182     for (pl = first_player; pl; pl = pl->next)
183     if (pl->ob->container == op->env)
184     break;
185     if (pl)
186     tmp = pl->ob;
187     else
188     tmp = NULL;
189     }
190     if (tmp)
191     esrv_send_item(tmp, op);
192     } else {
193     for (tmp = op->above; tmp != NULL; tmp = tmp->above)
194     if (tmp->type == PLAYER)
195     esrv_send_item(tmp, op);
196     }
197     }
198    
199     /**
200     * Notify clients about a removed object.
201     *
202     * @param op the object about to be removed from its environment; it must still
203     * be present in its environment
204     */
205     static void send_removed_object(object *op)
206     {
207     object* tmp;
208     player *pl;
209    
210     if (op->env == NULL) {
211     /* no action necessary: remove_ob() notifies the client */
212     return;
213     }
214    
215     tmp = is_player_inv(op->env);
216     if (!tmp) {
217     for (pl = first_player; pl; pl = pl->next)
218     if (pl->ob->container == op->env)
219     break;
220     if (pl)
221     tmp = pl->ob;
222     else
223     tmp = NULL;
224     }
225     if (tmp)
226     esrv_del_item(tmp->contr, op->count);
227     }
228    
229     int execute_event(object* op, int eventcode, object* activator, object* third, const char* message, int fix)
230     {
231     object *tmp, *next;
232     crossfire_plugin* plugin;
233     int rv = 0;
234     for (tmp = op->inv; tmp != NULL; tmp = next) {
235     next = tmp->below;
236     if (tmp->type == EVENT_CONNECTOR && tmp->subtype == eventcode) {
237 root 1.4 #if 0
238 root 1.1 LOG(llevDebug, "********** EVENT HANDLER **********\n");
239     LOG(llevDebug, " - Who am I :%s\n", op->name);
240     if (activator != NULL)
241     LOG(llevDebug, " - Activator :%s\n", activator->name);
242     if (third != NULL)
243     LOG(llevDebug, " - Other object :%s\n", third->name);
244     LOG(llevDebug, " - Event code :%d\n", tmp->subtype);
245     if (tmp->title != NULL)
246     LOG(llevDebug, " - Event plugin :%s\n", tmp->title);
247     if (tmp->slaying != NULL)
248     LOG(llevDebug, " - Event hook :%s\n", tmp->slaying);
249     if (tmp->name != NULL)
250     LOG(llevDebug, " - Event options :%s\n", tmp->name);
251 root 1.4 #endif
252 root 1.1
253     if (tmp->title == NULL) {
254     object *env = object_get_env_recursive(tmp);
255     LOG(llevError, "Event object without title at %d/%d in map %s\n", env->x, env->y, env->map->name);
256     send_removed_object(tmp);
257     remove_ob(tmp);
258     free_object(tmp);
259     } else if (tmp->slaying == NULL) {
260     object *env = object_get_env_recursive(tmp);
261     LOG(llevError, "Event object without slaying at %d/%d in map %s\n", env->x, env->y, env->map->name);
262     send_removed_object(tmp);
263     remove_ob(tmp);
264     free_object(tmp);
265     } else {
266     plugin = plugins_find_plugin(tmp->title);
267     if (plugin == NULL) {
268     object *env = object_get_env_recursive(tmp);
269 root 1.3 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);
270 root 1.1 send_removed_object(tmp);
271     remove_ob(tmp);
272     free_object(tmp);
273     } else {
274     int rvt = 0;
275     int *rv;
276    
277 root 1.10 rv = plugin->eventfunc(&rvt, op, eventcode, activator, third, message, fix, tmp->slaying, tmp->name, tmp);
278 root 1.1 return *rv;
279     }
280     }
281     }
282     }
283     return rv;
284     }
285    
286     int execute_global_event(int eventcode, ...)
287     {
288     va_list args;
289     object* op;
290     object* op2;
291 root 1.6 mapstruct *map;
292 root 1.1 player* pl;
293     char* buf;
294     int i, rt;
295     crossfire_plugin* cp;
296     if (plugins_list == NULL)
297     return -1;
298    
299     va_start(args, eventcode);
300    
301     switch (eventcode) {
302    
303     case EVENT_CLOCK:
304     case EVENT_CRASH:
305 root 1.2 case EVENT_TELL:
306     /* no additional arguments */
307 root 1.1 for (cp = plugins_list; cp != NULL; cp = cp->next) {
308     if (cp->gevent[eventcode] != NULL)
309     cp->gevent[eventcode](&rt, eventcode);
310     }
311     break;
312    
313 root 1.8 case EVENT_PLAYER_LOAD:
314     case EVENT_PLAYER_SAVE:
315     /* object, filename */
316     op = va_arg(args, object*);
317     buf = va_arg(args, char*);
318     for (cp = plugins_list; cp != NULL; cp = cp->next) {
319     if (cp->gevent[eventcode] != NULL)
320     cp->gevent[eventcode](&rt, eventcode, op, buf);
321     }
322     break;
323    
324 root 1.6 case EVENT_MAPLOAD:
325     case EVENT_MAPOUT:
326     case EVENT_MAPIN:
327 root 1.7 case EVENT_MAPCLEAN:
328 root 1.6 /* map argument */
329     map = va_arg(args, mapstruct*);
330     for (cp = plugins_list; cp != NULL; cp = cp->next) {
331     if (cp->gevent[eventcode] != NULL)
332     cp->gevent[eventcode](&rt, eventcode, map);
333     }
334     break;
335    
336 root 1.2 case EVENT_REMOVE:
337     case EVENT_MAPENTER:
338     case EVENT_MAPLEAVE:
339     case EVENT_BORN:
340 root 1.1 case EVENT_PLAYER_DEATH:
341 root 1.2 case EVENT_FREE_OB:
342     /* op argument */
343 root 1.1 op = va_arg(args, object*);
344     for (cp = plugins_list; cp != NULL; cp = cp->next) {
345     if (cp->gevent[eventcode] != NULL)
346     cp->gevent[eventcode](&rt, eventcode, op);
347     }
348     break;
349    
350     case EVENT_GKILL:
351     /*GKILL: op, hitter*/
352     op = va_arg(args, object*);
353     op2 = va_arg(args, object*);
354     for (cp = plugins_list; cp != NULL; cp = cp->next) {
355     if (cp->gevent[eventcode] != NULL)
356     cp->gevent[eventcode](&rt, eventcode, op, op2);
357     }
358     break;
359    
360     case EVENT_LOGIN:
361     /*LOGIN: pl, pl->socket.host*/
362     pl = va_arg(args, player*);
363     buf = va_arg(args, char*);
364     for (cp = plugins_list; cp != NULL; cp = cp->next) {
365     if (cp->gevent[eventcode] != NULL)
366     cp->gevent[eventcode](&rt, eventcode, pl, buf);
367     }
368     break;
369    
370     case EVENT_LOGOUT:
371     /*LOGOUT: pl, pl->socket.host*/
372     pl = va_arg(args, player*);
373     buf = va_arg(args, char*);
374     for (cp = plugins_list; cp != NULL; cp = cp->next) {
375     if (cp->gevent[eventcode] != NULL)
376     cp->gevent[eventcode](&rt, eventcode, pl, buf);
377     }
378     break;
379    
380     case EVENT_MAPRESET:
381     /*MAPRESET: map->path*/
382     buf = va_arg(args, char*);
383     for (cp = plugins_list; cp != NULL; cp = cp->next) {
384     if (cp->gevent[eventcode] != NULL)
385     cp->gevent[eventcode](&rt, eventcode, buf);
386     }
387     break;
388    
389     case EVENT_SHOUT:
390     /*SHOUT: op, parms, priority*/
391     op = va_arg(args, object*);
392     buf = va_arg(args, char*);
393     i = va_arg(args, int);
394     for (cp = plugins_list; cp != NULL; cp = cp->next) {
395     if (cp->gevent[eventcode] != NULL)
396     cp->gevent[eventcode](&rt, eventcode, op, buf, i);
397     }
398     break;
399    
400     case EVENT_MUZZLE:
401     /*MUZZLE: op, parms*/
402     op = va_arg(args, object*);
403     buf = va_arg(args, char*);
404     for (cp = plugins_list; cp != NULL; cp = cp->next) {
405     if (cp->gevent[eventcode] != NULL)
406     cp->gevent[eventcode](&rt, eventcode, op, buf);
407     }
408     break;
409    
410     case EVENT_KICK:
411     /*KICK: op, parms*/
412     op = va_arg(args, object*);
413     buf = va_arg(args, char*);
414     for (cp = plugins_list; cp != NULL; cp = cp->next) {
415     if (cp->gevent[eventcode] != NULL)
416     cp->gevent[eventcode](&rt, eventcode, op, buf);
417     }
418     break;
419     }
420     va_end(args);
421     return 0;
422     }
423    
424     int plugins_init_plugin(const char* libfile)
425     {
426     LIBPTRTYPE ptr;
427     f_plug_init initfunc;
428     f_plug_api propfunc;
429     f_plug_api eventfunc;
430     f_plug_postinit postfunc;
431     f_plug_postinit closefunc;
432     int i;
433     crossfire_plugin* cp;
434     crossfire_plugin* ccp;
435    
436 root 1.6 load_original_map_callback = plugin_load_original_map;
437     load_temporary_map_callback = plugin_load_temporary_map;
438 root 1.7 clean_temporary_map_callback = plugin_clean_temporary_map;
439 root 1.2 object_free_callback = plugin_object_free;
440    
441 root 1.1 /* Open the plugin lib and load the required functions */
442     ptr = plugins_dlopen(libfile);
443     if (ptr == NULL) {
444     LOG(llevError, "Error trying to load %s: %s\n", libfile, plugins_dlerror());
445     return -1;
446     }
447     initfunc = (f_plug_init)plugins_dlsym(ptr, "initPlugin");
448     if (initfunc == NULL) {
449     LOG(llevError, "Plugin error while requesting %s.initPlugin: %s\n",
450     libfile, plugins_dlerror());
451     plugins_dlclose(ptr);
452     return -1;
453     }
454     propfunc = (f_plug_api)plugins_dlsym(ptr, "getPluginProperty");
455     if (propfunc == NULL) {
456     LOG(llevError, "Plugin error while requesting %s.getPluginProperty: %s\n",
457     libfile, plugins_dlerror());
458     plugins_dlclose(ptr);
459     return -1;
460     }
461     eventfunc = (f_plug_api)plugins_dlsym(ptr, "eventListener");
462     if (eventfunc == NULL) {
463     LOG(llevError, "Plugin error while requesting %s.eventListener: %s\n",
464     libfile, plugins_dlerror());
465     plugins_dlclose(ptr);
466     return -1;
467     }
468     postfunc = (f_plug_postinit)plugins_dlsym(ptr, "postInitPlugin");
469     if (postfunc == NULL) {
470     LOG(llevError, "Plugin error while requesting %s.postInitPlugin: %s\n",
471     libfile, plugins_dlerror());
472     plugins_dlclose(ptr);
473     return -1;
474     }
475     closefunc = (f_plug_postinit)plugins_dlsym(ptr, "closePlugin");
476     if (postfunc == NULL) {
477     LOG(llevError, "Plugin error while requesting %s.closePlugin: %s\n",
478     libfile, plugins_dlerror());
479     plugins_dlclose(ptr);
480     return -1;
481     }
482     if (postfunc == NULL) {
483     LOG(llevError, "Plugin error while requesting %s.closePlugin: %s\n",
484     libfile, plugins_dlerror());
485     plugins_dlclose(ptr);
486     return -1;
487     }
488     i = initfunc("2.0", cfapi_get_hooks);
489     cp = malloc(sizeof(crossfire_plugin));
490     for (i = 0; i < NR_EVENTS; i++)
491     cp->gevent[i] = NULL;
492     cp->eventfunc = eventfunc;
493     cp->propfunc = propfunc;
494     cp->closefunc = closefunc;
495     cp->libptr = ptr;
496     strcpy(cp->id, propfunc(&i, "Identification"));
497     strcpy(cp->fullname, propfunc(&i, "FullName"));
498     cp->next = NULL;
499     cp->prev = NULL;
500     if (plugins_list == NULL) {
501     plugins_list = cp;
502     } else {
503     for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next)
504     ;
505     ccp->next = cp;
506     cp->prev = ccp;
507     }
508     postfunc();
509     plugin_number++;
510     return 0;
511     }
512    
513     void* cfapi_get_hooks(int* type, ...)
514     {
515     va_list args;
516     int request_type;
517     char* buf;
518     int fid;
519     f_plug_api rv;
520     int i;
521    
522     va_start(args, type);
523     request_type = va_arg(args, int);
524     if (request_type == 0) { /* By nr */
525     fid = va_arg(args, int);
526     if (fid < 0 || fid >= NR_OF_HOOKS) {
527     rv = NULL;
528     *type = CFAPI_NONE;
529     } else {
530     rv = plug_hooks[fid].func;
531     *type = CFAPI_FUNC;
532     }
533     } else { /* by name */
534     buf = va_arg(args, char*);
535     rv = NULL;
536     for (i = 0; i < NR_OF_HOOKS; i++) {
537     if (!strcmp(buf, plug_hooks[i].fname)) {
538     rv = plug_hooks[i].func;
539     *type = CFAPI_FUNC;
540     break;
541     }
542     }
543     if (rv == NULL) {
544     *type = CFAPI_NONE;
545     }
546     }
547     va_end(args);
548     return rv;
549     }
550    
551     int plugins_remove_plugin(const char* id)
552     {
553     crossfire_plugin* cp;
554    
555     if (plugins_list == NULL)
556     return -1;
557    
558     for (cp = plugins_list; cp != NULL; cp = cp->next) {
559     if (!strcmp(id, cp->id)) {
560     crossfire_plugin* n;
561     crossfire_plugin* p;
562     n = cp->next;
563     p = cp->prev;
564     plugins_dlclose(cp->libptr);
565     if (n != NULL) {
566     if (p != NULL) {
567     n->prev = p;
568     p->next = n;
569     } else {
570     n->prev = NULL;
571     plugins_list = n;
572     }
573     } else {
574     if (p != NULL)
575     p->next = NULL;
576     else
577     plugins_list = NULL;
578     }
579     free(cp);
580     plugin_number --;
581     return 0;
582     }
583     }
584     return -1;
585     }
586    
587     crossfire_plugin* plugins_find_plugin(const char* id)
588     {
589     crossfire_plugin* cp;
590    
591     if (plugins_list == NULL)
592     return NULL;
593    
594     for (cp = plugins_list; cp != NULL; cp = cp->next) {
595     if (!strcmp(id, cp->id)) {
596     return cp;
597     }
598     }
599     return NULL;
600     }
601    
602     /*****************************************************************************/
603     /* Displays a list of loaded plugins (keystrings and description) in the */
604     /* game log window. */
605     /*****************************************************************************/
606     void plugins_display_list(object *op)
607     {
608     crossfire_plugin* cp;
609    
610     new_draw_info(NDI_UNIQUE, 0, op, "List of loaded plugins:");
611     new_draw_info(NDI_UNIQUE, 0, op, "-----------------------");
612    
613     if (plugins_list == NULL)
614     return;
615    
616     for (cp = plugins_list; cp != NULL; cp = cp->next) {
617     new_draw_info_format(NDI_UNIQUE, 0, op, "%s, %s", cp->id, cp->fullname);
618     }
619     }
620    
621     /* SYSTEM-RELATED HOOKS */
622    
623     void* cfapi_system_find_animation(int *type, ...)
624     {
625     va_list args;
626     static int rv;
627     char* anim;
628     va_start(args, type);
629     anim = va_arg(args, char*);
630     va_end(args);
631    
632     rv = find_animation(anim);
633     *type = CFAPI_INT;
634     return &rv;
635     }
636    
637     void* cfapi_system_strdup_local(int *type, ...)
638     {
639     va_list args;
640     char* txt;
641     va_start(args, type);
642     txt = va_arg(args, char*);
643     va_end(args);
644     *type = CFAPI_STRING;
645     return strdup_local(txt);
646     }
647    
648     void* cfapi_system_register_global_event(int *type, ...)
649     {
650     va_list args;
651     int eventcode;
652     char* pname;
653     f_plug_api hook;
654     crossfire_plugin* cp;
655    
656     va_start(args, type);
657     eventcode = va_arg(args, int);
658     pname = va_arg(args, char*);
659     hook = va_arg(args, f_plug_api);
660    
661     va_end(args);
662     cp = plugins_find_plugin(pname);
663     cp->gevent[eventcode] = hook;
664     return NULL;
665     }
666    
667     void* cfapi_system_unregister_global_event(int *type, ...)
668     {
669     va_list args;
670     int eventcode;
671     char* pname;
672     crossfire_plugin* cp;
673    
674     va_start(args, type);
675     eventcode = va_arg(args, int);
676     pname = va_arg(args, char*);
677    
678     cp = plugins_find_plugin(pname);
679     cp->gevent[eventcode] = NULL;
680    
681     va_end(args);
682     return NULL;
683     }
684    
685     void* cfapi_system_add_string(int *type, ...)
686     {
687     va_list args;
688     const char* str;
689     char* rv;
690    
691     va_start(args, type);
692     str = va_arg(args, char*);
693     va_end(args);
694    
695     rv = (char*)add_string(str);
696     *type = CFAPI_STRING;
697     return rv;
698     }
699    
700     void* cfapi_system_remove_string(int *type, ...)
701     {
702     va_list args;
703     char* str;
704    
705     va_start(args, type);
706     str = va_arg(args, char*);
707     va_end(args);
708    
709     free_string(str);
710     *type = CFAPI_NONE;
711     return NULL;
712     }
713     void* cfapi_system_check_path(int* type, ...)
714     {
715     va_list args;
716     static int rv;
717     char* name;
718     int prepend_dir;
719    
720     va_start(args, type);
721    
722     name = va_arg(args, char*);
723     prepend_dir = va_arg(args, int);
724    
725     rv = check_path(name, prepend_dir);
726    
727     va_end(args);
728     *type = CFAPI_INT;
729     return &rv;
730     }
731    
732     void* cfapi_system_re_cmp(int* type, ...)
733     {
734     va_list args;
735     char* rv;
736     const char* str;
737     const char* regexp;
738    
739     va_start(args, type);
740    
741     str = va_arg(args, char*);
742     regexp = va_arg(args, char*);
743    
744     rv = (char*)re_cmp(str, regexp);
745    
746     va_end(args);
747     *type = CFAPI_STRING;
748     return rv;
749     }
750    
751     void* cfapi_system_directory(int* type, ...)
752     {
753     va_list args;
754     int dirtype;
755    
756     va_start(args, type);
757    
758     dirtype = va_arg(args, int);
759     va_end(args);
760    
761     *type = CFAPI_STRING;
762    
763     switch (dirtype)
764     {
765     case 0:
766     return settings.mapdir;
767     break;
768    
769     case 1:
770     return settings.uniquedir;
771     break;
772    
773     case 2:
774     return settings.tmpdir;
775     break;
776    
777     case 3:
778     return settings.confdir;
779     break;
780    
781     case 4:
782     return settings.localdir;
783     break;
784    
785     case 5:
786     return settings.playerdir;
787     break;
788    
789     case 6:
790     return settings.datadir;
791     break;
792     }
793    
794     *type = CFAPI_NONE;
795     return NULL;
796     }
797    
798    
799     /* MAP RELATED HOOKS */
800    
801     void* cfapi_map_get_map(int* type, ...)
802     {
803     va_list args;
804     mapstruct* rv;
805     int ctype;
806     int x, y;
807     sint16 nx, ny;
808     char* name;
809     mapstruct* m;
810    
811     va_start(args, type);
812    
813     ctype = va_arg(args, int);
814    
815     switch (ctype)
816     {
817     case 0:
818     x = va_arg(args, int);
819     y = va_arg(args, int);
820     rv = get_empty_map(x, y);
821     break;
822    
823     case 1:
824     name = va_arg(args, char*);
825     x = va_arg(args, int);
826     rv = ready_map_name(name, x);
827     break;
828    
829     case 2:
830     m = va_arg(args, mapstruct*);
831     nx = va_arg(args, int);
832     ny = va_arg(args, int);
833     rv = get_map_from_coord(m, &nx, &ny);
834     break;
835    
836     case 3:
837     rv = first_map;
838     break;
839    
840     default:
841     *type = CFAPI_NONE;
842     va_end(args);
843     return NULL;
844     break;
845     }
846     va_end(args);
847     *type = CFAPI_PMAP;
848     return rv;
849     }
850     void* cfapi_map_has_been_loaded(int* type, ...)
851     {
852     va_list args;
853     mapstruct* map;
854     char* string;
855    
856     va_start(args, type);
857     string = va_arg(args, char*);
858     map = has_been_loaded(string);
859     va_end(args);
860     *type = CFAPI_PMAP;
861     return map;
862     }
863     void* cfapi_map_create_path(int* type, ...)
864     {
865     va_list args;
866     int ctype;
867     const char* str;
868     char* rv;
869     va_start(args, type);
870    
871     ctype = va_arg(args, int);
872     str = va_arg(args, char*);
873     *type = CFAPI_STRING;
874    
875     switch (ctype)
876     {
877     case 0:
878     rv = (char*)create_pathname(str);
879     break;
880    
881     case 1:
882     rv = (char*)create_overlay_pathname(str);
883     break;
884    
885     /*case 2:
886     rv = create_items_path(str);
887     break;*/
888    
889     default:
890     rv = NULL;
891     *type = CFAPI_NONE;
892     break;
893     }
894     va_end(args);
895     return rv;
896     }
897     void* cfapi_map_get_map_property(int* type, ...)
898     {
899     va_list args;
900     int x, y;
901     sint16 nx, ny;
902     mapstruct* map;
903     mapstruct* newmap;
904     static int rv;
905     int property;
906     char* buf;
907    
908     va_start(args, type);
909    
910     property = va_arg(args, int);
911     switch (property)
912     {
913     case CFAPI_MAP_PROP_FLAGS:
914     map = va_arg(args, mapstruct*);
915     newmap = va_arg(args, mapstruct*);
916     x = va_arg(args, int);
917     y = va_arg(args, int);
918     nx = va_arg(args, int);
919     ny = va_arg(args, int);
920     rv = get_map_flags(map, &newmap, x, y, &nx, &ny);
921     va_end(args);
922     *type = CFAPI_INT;
923     return &rv;
924     break;
925    
926     case CFAPI_MAP_PROP_DIFFICULTY:
927     map = va_arg(args, mapstruct*);
928     rv = calculate_difficulty(map);
929     va_end(args);
930     *type = CFAPI_INT;
931     return &rv;
932     break;
933    
934     case CFAPI_MAP_PROP_PATH:
935     map = va_arg(args, mapstruct*);
936     buf = map->path;
937     *type = CFAPI_STRING;
938     va_end(args);
939     return buf;
940     break;
941    
942     case CFAPI_MAP_PROP_TMPNAME:
943     map = va_arg(args, mapstruct*);
944     buf = map->tmpname;
945     *type = CFAPI_STRING;
946     va_end(args);
947     return buf;
948     break;
949    
950     case CFAPI_MAP_PROP_NAME:
951     map = va_arg(args, mapstruct*);
952     buf = map->name;
953     *type = CFAPI_STRING;
954     va_end(args);
955     return buf;
956     break;
957    
958     case CFAPI_MAP_PROP_RESET_TIME:
959     map = va_arg(args, mapstruct*);
960     rv = map->reset_time;
961     *type = CFAPI_INT;
962     va_end(args);
963     return &rv;
964     break;
965    
966     case CFAPI_MAP_PROP_RESET_TIMEOUT:
967     map = va_arg(args, mapstruct*);
968     rv = map->reset_timeout;
969     *type = CFAPI_INT;
970     va_end(args);
971     return &rv;
972     break;
973    
974     case CFAPI_MAP_PROP_PLAYERS:
975     map = va_arg(args, mapstruct*);
976     rv = map->players;
977     *type = CFAPI_INT;
978     va_end(args);
979     return &rv;
980     break;
981    
982     case CFAPI_MAP_PROP_DARKNESS:
983     map = va_arg(args, mapstruct*);
984     rv = map->darkness;
985     *type = CFAPI_INT;
986     va_end(args);
987     return &rv;
988     break;
989    
990     case CFAPI_MAP_PROP_WIDTH:
991     map = va_arg(args, mapstruct*);
992     rv = map->width;
993     *type = CFAPI_INT;
994     va_end(args);
995     return &rv;
996     break;
997    
998     case CFAPI_MAP_PROP_HEIGHT:
999     map = va_arg(args, mapstruct*);
1000     rv = map->height;
1001     *type = CFAPI_INT;
1002     va_end(args);
1003     return &rv;
1004     break;
1005    
1006     case CFAPI_MAP_PROP_ENTER_X:
1007     map = va_arg(args, mapstruct*);
1008     rv = map->enter_x;
1009     *type = CFAPI_INT;
1010     va_end(args);
1011     return &rv;
1012     break;
1013    
1014     case CFAPI_MAP_PROP_ENTER_Y:
1015     map = va_arg(args, mapstruct*);
1016     rv = map->enter_y;
1017     *type = CFAPI_INT;
1018     va_end(args);
1019     return &rv;
1020     break;
1021    
1022     case CFAPI_MAP_PROP_TEMPERATURE:
1023     map = va_arg(args, mapstruct*);
1024     rv = map->temp;
1025     *type = CFAPI_INT;
1026     va_end(args);
1027     return &rv;
1028     break;
1029    
1030     case CFAPI_MAP_PROP_PRESSURE:
1031     map = va_arg(args, mapstruct*);
1032     rv = map->pressure;
1033     *type = CFAPI_INT;
1034     va_end(args);
1035     return &rv;
1036     break;
1037    
1038     case CFAPI_MAP_PROP_HUMIDITY:
1039     map = va_arg(args, mapstruct*);
1040     rv = map->humid;
1041     *type = CFAPI_INT;
1042     va_end(args);
1043     return &rv;
1044     break;
1045    
1046     case CFAPI_MAP_PROP_WINDSPEED:
1047     map = va_arg(args, mapstruct*);
1048     rv = map->windspeed;
1049     *type = CFAPI_INT;
1050     va_end(args);
1051     return &rv;
1052     break;
1053    
1054     case CFAPI_MAP_PROP_WINDDIR:
1055     map = va_arg(args, mapstruct*);
1056     rv = map->winddir;
1057     *type = CFAPI_INT;
1058     va_end(args);
1059     return &rv;
1060     break;
1061    
1062     case CFAPI_MAP_PROP_SKY:
1063     map = va_arg(args, mapstruct*);
1064     rv = map->sky;
1065     *type = CFAPI_INT;
1066     va_end(args);
1067     return &rv;
1068     break;
1069    
1070     case CFAPI_MAP_PROP_WPARTX:
1071     map = va_arg(args, mapstruct*);
1072     rv = map->wpartx;
1073     *type = CFAPI_INT;
1074     va_end(args);
1075     return &rv;
1076     break;
1077    
1078     case CFAPI_MAP_PROP_WPARTY:
1079     map = va_arg(args, mapstruct*);
1080     rv = map->wparty;
1081     *type = CFAPI_INT;
1082     va_end(args);
1083     return &rv;
1084     break;
1085    
1086     case CFAPI_MAP_PROP_MESSAGE:
1087     map = va_arg(args, mapstruct*);
1088     buf = map->msg;
1089     *type = CFAPI_STRING;
1090     va_end(args);
1091     return buf;
1092     break;
1093    
1094     case CFAPI_MAP_PROP_NEXT:
1095     map = va_arg(args, mapstruct*);
1096     *type = CFAPI_PMAP;
1097     va_end(args);
1098     return map->next;
1099     break;
1100    
1101     case CFAPI_MAP_PROP_REGION:
1102     map = va_arg(args, mapstruct*);
1103     *type = CFAPI_PREGION;
1104     va_end(args);
1105     return get_region_by_map(map);
1106     break;
1107    
1108     default:
1109     *type = CFAPI_NONE;
1110     va_end(args);
1111     return NULL;
1112     break;
1113     }
1114     }
1115    
1116     void* cfapi_map_set_map_property(int* type, ...)
1117     {
1118     va_list args;
1119     static int rv;
1120     mapstruct* map;
1121     int val;
1122     int property;
1123    
1124     va_start(args, type);
1125    
1126     property = va_arg(args, int);
1127    
1128     switch (property)
1129     {
1130     case CFAPI_MAP_PROP_LIGHT:
1131     map = va_arg(args, mapstruct*);
1132     val = va_arg(args, int);
1133     rv = change_map_light(map, val);
1134     *type = CFAPI_INT;
1135     va_end(args);
1136     return &rv;
1137     break;
1138    
1139     case CFAPI_MAP_PROP_RESET_TIME:
1140     map = va_arg(args, mapstruct*);
1141     *type = CFAPI_NONE;
1142     va_end(args);
1143     return NULL;
1144     break;
1145    
1146     default:
1147     *type = CFAPI_NONE;
1148     va_end(args);
1149     return NULL;
1150     break;
1151     }
1152     }
1153     void* cfapi_map_out_of_map(int* type, ...)
1154     {
1155     va_list args;
1156     static int rv;
1157     mapstruct* map;
1158     int x, y;
1159    
1160     va_start(args, type);
1161     map = va_arg(args, mapstruct*);
1162     x = va_arg(args, int);
1163     y = va_arg(args, int);
1164    
1165     rv = out_of_map(map, x, y);
1166     va_end(args);
1167     *type = CFAPI_INT;
1168     return &rv;
1169     }
1170     void* cfapi_map_update_position(int* type, ...)
1171     {
1172     va_list args;
1173     mapstruct* map;
1174     int x, y;
1175    
1176     va_start(args, type);
1177    
1178     map = va_arg(args, mapstruct*);
1179     x = va_arg(args, int);
1180     y = va_arg(args, int);
1181    
1182     update_position(map, x, y);
1183     va_end(args);
1184     *type = CFAPI_NONE;
1185     return NULL;
1186     }
1187     void* cfapi_map_delete_map(int* type, ...)
1188     {
1189     va_list args;
1190     mapstruct* map;
1191     va_start(args, type);
1192    
1193     map = va_arg(args, mapstruct*);
1194    
1195     delete_map(map);
1196    
1197     va_end(args);
1198     *type = CFAPI_NONE;
1199     return NULL;
1200     }
1201     void* cfapi_map_message(int* type, ...)
1202     {
1203     va_list args;
1204     mapstruct* map;
1205     char* string;
1206     int color;
1207    
1208     va_start(args, type);
1209     map = va_arg(args, mapstruct*);
1210     string = va_arg(args, char*);
1211     color = va_arg(args, int);
1212     va_end(args);
1213    
1214     new_info_map(color, map, string);
1215     *type = CFAPI_NONE;
1216     return NULL;
1217     }
1218     void* cfapi_map_get_object_at(int* type, ...)
1219     {
1220     va_list args;
1221     mapstruct* map;
1222     int x, y;
1223     object* rv;
1224    
1225     va_start(args, type);
1226     map = va_arg(args, mapstruct*);
1227     x = va_arg(args, int);
1228     y = va_arg(args, int);
1229     va_end(args);
1230    
1231     rv = get_map_ob(map, x, y);
1232     *type = CFAPI_POBJECT;
1233     return rv;
1234     }
1235     void* cfapi_map_get_flags(int* type, ...)
1236     {
1237     va_list args;
1238     sint16 x, y;
1239     sint16 *nx, *ny;
1240     static mapstruct* map;
1241     mapstruct** newmap;
1242     static int rv;
1243    
1244     va_start(args, type);
1245    
1246     map = va_arg(args, mapstruct*);
1247     newmap = va_arg(args, mapstruct**);
1248     x = va_arg(args, int);
1249     y = va_arg(args, int);
1250     nx = va_arg(args, sint16*);
1251     ny = va_arg(args, sint16*);
1252     va_end(args);
1253    
1254     rv = get_map_flags(map, newmap, x, y, nx, ny);
1255    
1256     *type = CFAPI_INT;
1257     return &rv;
1258     }
1259     void* cfapi_map_present_arch_by_name(int* type, ...)
1260     {
1261     va_list args;
1262     object* rv;
1263     int x, y;
1264     mapstruct* map;
1265     char* msg;
1266    
1267     va_start(args, type);
1268    
1269     msg = va_arg(args, char*);
1270     map = va_arg(args, mapstruct*);
1271     x = va_arg(args, int);
1272     y = va_arg(args, int);
1273    
1274     va_end(args);
1275    
1276     rv = present_arch(find_archetype(msg), map, x, y);
1277     *type = CFAPI_POBJECT;
1278     return rv;
1279     }
1280    
1281     /* OBJECT-RELATED HOOKS */
1282    
1283     void* cfapi_object_move(int* type, ...)
1284     {
1285     va_list args;
1286     int kind;
1287     object* op;
1288     object* activator;
1289     player* pl;
1290     int direction;
1291     static int rv=0;
1292    
1293     va_start(args, type);
1294     kind = va_arg(args, int);
1295     switch (kind)
1296     {
1297     case 0:
1298     op = va_arg(args, object*);
1299     direction = va_arg(args, int);
1300     activator = va_arg(args, object*);
1301     va_end(args);
1302     rv = move_ob(op, direction, activator);
1303     break;
1304    
1305     case 1:
1306     pl = va_arg(args, player*);
1307     direction = va_arg(args, int);
1308     va_end(args);
1309     rv = move_player(pl->ob, direction);
1310     break;
1311     }
1312     *type = CFAPI_INT;
1313     return &rv;
1314     }
1315    
1316     void* cfapi_object_get_key(int* type, ...)
1317     {
1318     va_list args;
1319     char* rv;
1320     char* keyname;
1321     object* op;
1322    
1323     va_start(args, type);
1324     op = va_arg(args, object*);
1325     keyname = va_arg(args, char*);
1326     va_end(args);
1327    
1328     rv = (char*)get_ob_key_value(op, keyname);
1329     *type = CFAPI_STRING;
1330     return rv;
1331     }
1332     void* cfapi_object_set_key(int* type, ...)
1333     {
1334     va_list args;
1335     char* keyname;
1336     char* value;
1337     object* op;
1338    
1339     va_start(args, type);
1340     op = va_arg(args, object*);
1341     keyname = va_arg(args, char*);
1342     value = va_arg(args, char*);
1343     va_end(args);
1344    
1345     set_ob_key_value(op, keyname, value, 0);
1346     *type = CFAPI_NONE;
1347     return NULL;
1348     }
1349     void* cfapi_object_get_property(int* type, ...)
1350     {
1351     va_list args;
1352     int property;
1353     object* op;
1354     void* rv;
1355     static int ri;
1356    
1357     va_start(args, type);
1358    
1359     op = va_arg(args, object*);
1360     property = va_arg(args, int);
1361     rv = NULL;
1362     if (op != NULL) {
1363     switch (property)
1364     {
1365     case CFAPI_OBJECT_PROP_OB_ABOVE:
1366     rv = op->above;
1367     *type = CFAPI_POBJECT;
1368     break;
1369    
1370     case CFAPI_OBJECT_PROP_OB_BELOW:
1371     rv = op->below;
1372     *type = CFAPI_POBJECT;
1373     break;
1374    
1375     case CFAPI_OBJECT_PROP_NEXT_ACTIVE_OB:
1376     rv = op->active_next;
1377     *type = CFAPI_POBJECT;
1378     break;
1379    
1380     case CFAPI_OBJECT_PROP_PREV_ACTIVE_OB:
1381     rv = op->active_prev;
1382     *type = CFAPI_POBJECT;
1383     break;
1384    
1385     case CFAPI_OBJECT_PROP_INVENTORY:
1386     rv = op->inv;
1387     *type = CFAPI_POBJECT;
1388     break;
1389    
1390     case CFAPI_OBJECT_PROP_ENVIRONMENT:
1391     rv = op->env;
1392     *type = CFAPI_POBJECT;
1393     break;
1394    
1395     case CFAPI_OBJECT_PROP_HEAD:
1396     rv = op->head;
1397     *type = CFAPI_POBJECT;
1398     break;
1399    
1400     case CFAPI_OBJECT_PROP_CONTAINER:
1401     rv = op->container;
1402     *type = CFAPI_POBJECT;
1403     break;
1404    
1405     case CFAPI_OBJECT_PROP_MAP:
1406     rv = op->map;
1407     *type = CFAPI_PMAP;
1408     break;
1409    
1410     case CFAPI_OBJECT_PROP_COUNT:
1411 root 1.9 ri = op->count; rv = &ri;
1412 root 1.1 *type = CFAPI_INT;
1413     break;
1414    
1415     case CFAPI_OBJECT_PROP_REFCOUNT:
1416 root 1.9 ri = op->refcount; rv = &ri;
1417 root 1.1 *type = CFAPI_INT;
1418     break;
1419    
1420     case CFAPI_OBJECT_PROP_NAME:
1421     rv = query_name(op);
1422     *type = CFAPI_STRING;
1423     break;
1424    
1425     case CFAPI_OBJECT_PROP_NAME_PLURAL:
1426     rv = (char*)op->name_pl;
1427     *type = CFAPI_STRING;
1428     break;
1429    
1430     case CFAPI_OBJECT_PROP_TITLE:
1431     rv = (char*)op->title;
1432     *type = CFAPI_STRING;
1433     break;
1434    
1435     case CFAPI_OBJECT_PROP_RACE:
1436     rv = (char*)op->race;
1437     *type = CFAPI_STRING;
1438     break;
1439    
1440     case CFAPI_OBJECT_PROP_SLAYING:
1441     rv = (char*)op->slaying;
1442     *type = CFAPI_STRING;
1443     break;
1444    
1445     case CFAPI_OBJECT_PROP_SKILL:
1446     rv = (char*)op->skill;
1447     *type = CFAPI_STRING;
1448     break;
1449    
1450     case CFAPI_OBJECT_PROP_MESSAGE:
1451     rv = (char*)op->msg;
1452     if (rv == NULL)
1453     rv = "";
1454     *type = CFAPI_STRING;
1455     break;
1456    
1457     case CFAPI_OBJECT_PROP_LORE:
1458     rv = (char*)op->lore;
1459     *type = CFAPI_STRING;
1460     break;
1461    
1462     case CFAPI_OBJECT_PROP_X:
1463     ri = op->x;
1464     rv = &ri;
1465     *type = CFAPI_INT;
1466     break;
1467    
1468     case CFAPI_OBJECT_PROP_Y:
1469     ri = op->y;
1470     rv = &ri;
1471     *type = CFAPI_INT;
1472     break;
1473    
1474     case CFAPI_OBJECT_PROP_SPEED:
1475     rv = &op->speed;
1476     *type = CFAPI_DOUBLE;
1477     break;
1478    
1479     case CFAPI_OBJECT_PROP_SPEED_LEFT:
1480     rv = &op->speed_left;
1481     *type = CFAPI_DOUBLE;
1482     break;
1483    
1484     case CFAPI_OBJECT_PROP_NROF:
1485 root 1.9 ri = op->nrof; rv = &ri;
1486 root 1.1 *type = CFAPI_INT;
1487     break;
1488    
1489     case CFAPI_OBJECT_PROP_DIRECTION:
1490 root 1.9 ri = op->direction; rv = &ri;
1491 root 1.1 *type = CFAPI_INT;
1492     break;
1493    
1494     case CFAPI_OBJECT_PROP_FACING:
1495 root 1.9 ri = op->facing; rv = &ri;
1496 root 1.1 *type = CFAPI_INT;
1497     break;
1498    
1499     case CFAPI_OBJECT_PROP_TYPE:
1500 root 1.9 ri = op->type; rv = &ri;
1501 root 1.1 *type = CFAPI_INT;
1502     break;
1503    
1504     case CFAPI_OBJECT_PROP_SUBTYPE:
1505 root 1.9 ri = op->subtype; rv = &ri;
1506 root 1.1 *type = CFAPI_INT;
1507     break;
1508    
1509     case CFAPI_OBJECT_PROP_CLIENT_TYPE:
1510 root 1.9 ri = op->client_type; rv = &ri;
1511 root 1.1 *type = CFAPI_INT;
1512     break;
1513    
1514     case CFAPI_OBJECT_PROP_RESIST:
1515     {
1516     int idx;
1517     idx = va_arg(args, int);
1518 root 1.9 ri = op->resist[idx]; rv = &ri;
1519 root 1.1 }
1520 root 1.9 *type = CFAPI_INT;
1521 root 1.1 break;
1522    
1523     case CFAPI_OBJECT_PROP_ATTACK_TYPE:
1524 root 1.9 ri = op->attacktype; rv = &ri;
1525 root 1.1 *type = CFAPI_INT;
1526     break;
1527    
1528     case CFAPI_OBJECT_PROP_PATH_ATTUNED:
1529 root 1.9 ri = op->path_attuned; rv = &ri;
1530 root 1.1 *type = CFAPI_INT;
1531     break;
1532    
1533     case CFAPI_OBJECT_PROP_PATH_REPELLED:
1534 root 1.9 ri = op->path_repelled; rv = &ri;
1535 root 1.1 *type = CFAPI_INT;
1536     break;
1537    
1538     case CFAPI_OBJECT_PROP_PATH_DENIED:
1539 root 1.9 ri = op->path_denied; rv = &ri;
1540 root 1.1 *type = CFAPI_INT;
1541     break;
1542    
1543     case CFAPI_OBJECT_PROP_MATERIAL:
1544 root 1.9 ri = op->material; rv = &ri;
1545 root 1.1 *type = CFAPI_INT;
1546     break;
1547    
1548     case CFAPI_OBJECT_PROP_MATERIAL_NAME:
1549     rv = (char*)op->materialname;
1550     *type = CFAPI_STRING;
1551     break;
1552    
1553     case CFAPI_OBJECT_PROP_MAGIC:
1554 root 1.9 ri = op->magic; rv = &ri;
1555 root 1.1 *type = CFAPI_INT;
1556     break;
1557    
1558     case CFAPI_OBJECT_PROP_VALUE:
1559 root 1.9 ri = op->value; rv = &ri;
1560 root 1.1 *type = CFAPI_INT;
1561     break;
1562    
1563     case CFAPI_OBJECT_PROP_LEVEL:
1564 root 1.9 ri = op->level; rv = &ri;
1565 root 1.1 *type = CFAPI_INT;
1566     break;
1567    
1568     case CFAPI_OBJECT_PROP_LAST_HEAL:
1569 root 1.9 ri = op->last_heal; rv = &ri;
1570 root 1.1 *type = CFAPI_INT;
1571     break;
1572    
1573     case CFAPI_OBJECT_PROP_LAST_SP:
1574 root 1.9 ri = op->last_sp; rv = &ri;
1575 root 1.1 *type = CFAPI_INT;
1576     break;
1577    
1578     case CFAPI_OBJECT_PROP_LAST_GRACE:
1579 root 1.9 ri = op->last_grace; rv = &ri;
1580 root 1.1 *type = CFAPI_INT;
1581     break;
1582    
1583     case CFAPI_OBJECT_PROP_LAST_EAT:
1584 root 1.9 ri = op->last_eat; rv = &ri;
1585 root 1.1 *type = CFAPI_INT;
1586     break;
1587    
1588     case CFAPI_OBJECT_PROP_INVISIBLE_TIME:
1589 root 1.9 ri = op->invisible; rv = &ri;
1590 root 1.1 *type = CFAPI_INT;
1591     break;
1592    
1593     case CFAPI_OBJECT_PROP_PICK_UP:
1594 root 1.9 ri = op->pick_up; rv = &ri;
1595 root 1.1 *type = CFAPI_INT;
1596     break;
1597    
1598     case CFAPI_OBJECT_PROP_ITEM_POWER:
1599 root 1.9 ri = op->item_power; rv = &ri;
1600 root 1.1 *type = CFAPI_INT;
1601     break;
1602    
1603     case CFAPI_OBJECT_PROP_GEN_SP_ARMOUR:
1604 root 1.9 ri = op->gen_sp_armour; rv = &ri;
1605 root 1.1 *type = CFAPI_INT;
1606     break;
1607    
1608     case CFAPI_OBJECT_PROP_WEIGHT:
1609 root 1.9 ri = op->weight; rv = &ri;
1610 root 1.1 *type = CFAPI_INT;
1611     break;
1612    
1613     case CFAPI_OBJECT_PROP_WEIGHT_LIMIT:
1614 root 1.9 ri = op->weight_limit; rv = &ri;
1615 root 1.1 *type = CFAPI_INT;
1616     break;
1617    
1618     case CFAPI_OBJECT_PROP_CARRYING:
1619 root 1.9 ri = op->carrying; rv = &ri;
1620 root 1.1 *type = CFAPI_INT;
1621     break;
1622    
1623     case CFAPI_OBJECT_PROP_GLOW_RADIUS:
1624 root 1.9 ri = op->glow_radius; rv = &ri;
1625 root 1.1 *type = CFAPI_INT;
1626     break;
1627    
1628     case CFAPI_OBJECT_PROP_PERM_EXP:
1629     rv = &op->perm_exp;
1630     *type = CFAPI_LONG;
1631     break;
1632    
1633     case CFAPI_OBJECT_PROP_CURRENT_WEAPON:
1634     rv = op->current_weapon;
1635     *type = CFAPI_POBJECT;
1636     break;
1637    
1638     case CFAPI_OBJECT_PROP_ENEMY:
1639     rv = op->enemy;
1640     *type = CFAPI_POBJECT;
1641     break;
1642    
1643     case CFAPI_OBJECT_PROP_ATTACKED_BY:
1644     rv = op->attacked_by;
1645     *type = CFAPI_POBJECT;
1646     break;
1647    
1648     case CFAPI_OBJECT_PROP_RUN_AWAY:
1649 root 1.9 ri = op->run_away; rv = &ri;
1650 root 1.1 *type = CFAPI_INT;
1651     break;
1652    
1653     case CFAPI_OBJECT_PROP_CHOSEN_SKILL:
1654     rv = op->chosen_skill;
1655     *type = CFAPI_POBJECT;
1656     break;
1657    
1658     case CFAPI_OBJECT_PROP_HIDDEN:
1659 root 1.9 ri = op->hide; rv = &ri;
1660 root 1.1 *type = CFAPI_INT;
1661     break;
1662    
1663     case CFAPI_OBJECT_PROP_MOVE_STATUS:
1664 root 1.9 ri = op->move_status; rv = &ri;
1665 root 1.1 *type = CFAPI_INT;
1666     break;
1667    
1668     case CFAPI_OBJECT_PROP_MOVE_TYPE:
1669 root 1.9 ri = op->attack_movement; rv = &ri;
1670 root 1.1 *type = CFAPI_INT;
1671     break;
1672    
1673     case CFAPI_OBJECT_PROP_SPELL_ITEM:
1674     rv = op->spellitem;
1675     *type = CFAPI_POBJECT;
1676     break;
1677    
1678     case CFAPI_OBJECT_PROP_EXP_MULTIPLIER:
1679     rv = &op->expmul;
1680     *type = CFAPI_DOUBLE;
1681     break;
1682    
1683     case CFAPI_OBJECT_PROP_ARCHETYPE:
1684     rv = op->arch;
1685     *type = CFAPI_PARCH;
1686     break;
1687    
1688     case CFAPI_OBJECT_PROP_OTHER_ARCH:
1689     rv = op->other_arch;
1690     *type = CFAPI_PARCH;
1691     break;
1692    
1693     case CFAPI_OBJECT_PROP_CUSTOM_NAME:
1694     rv = (char*)op->custom_name;
1695     *type = CFAPI_STRING;
1696     break;
1697    
1698     case CFAPI_OBJECT_PROP_ANIM_SPEED:
1699 root 1.9 ri = op->anim_speed; rv = &ri;
1700 root 1.1 *type = CFAPI_INT;
1701     break;
1702    
1703     case CFAPI_OBJECT_PROP_FRIENDLY:
1704     ri = is_friendly(op);
1705     rv = &ri;
1706     *type = CFAPI_INT;
1707     break;
1708    
1709     case CFAPI_OBJECT_PROP_SHORT_NAME:
1710     rv = (char*)query_short_name(op);
1711     *type = CFAPI_STRING;
1712     break;
1713    
1714     case CFAPI_OBJECT_PROP_BASE_NAME:
1715     {
1716     int i;
1717     i = va_arg(args, int);
1718     rv = (char*)query_base_name(op, i);
1719     *type = CFAPI_STRING;
1720     }
1721     break;
1722    
1723     case CFAPI_OBJECT_PROP_MAGICAL:
1724     ri = is_magical(op);
1725     rv = &ri;
1726     *type = CFAPI_INT;
1727     break;
1728    
1729     case CFAPI_OBJECT_PROP_LUCK:
1730 root 1.9 ri = op->stats.luck; rv = &ri;
1731 root 1.1 *type = CFAPI_INT;
1732     break;
1733    
1734     case CFAPI_OBJECT_PROP_EXP:
1735     rv = &op->stats.exp;
1736     *type = CFAPI_LONG;
1737     break;
1738    
1739     case CFAPI_OBJECT_PROP_OWNER:
1740     rv = get_owner(op);
1741     *type = CFAPI_POBJECT;
1742     break;
1743    
1744     case CFAPI_OBJECT_PROP_PRESENT:
1745     {
1746     int stype;
1747     rv = 0;
1748     stype = va_arg(args, int);
1749     switch (stype) {
1750    
1751     unsigned char ptype;
1752     char* buf;
1753     archetype* at;
1754    
1755     case 0: /* present_in_ob */
1756     ptype = (unsigned char)(va_arg(args, int));
1757     rv = present_in_ob(ptype, op);
1758     break;
1759    
1760     case 1: /* present_in_ob_by_name */
1761     ptype = (unsigned char)(va_arg(args, int));
1762     buf = va_arg(args, char*);
1763     rv = present_in_ob_by_name(ptype, buf, op);
1764     break;
1765    
1766     case 2: /* present_arch_in_ob */
1767     at = va_arg(args, archetype*);
1768     rv = present_arch_in_ob(at, op);
1769     break;
1770     }
1771     }
1772     *type = CFAPI_POBJECT;
1773     break;
1774    
1775     case CFAPI_OBJECT_PROP_CHEATER:
1776     ri = (QUERY_FLAG(op, FLAG_WAS_WIZ));
1777 root 1.9 rv = &ri;
1778 root 1.1 *type = CFAPI_INT;
1779     break;
1780    
1781     case CFAPI_OBJECT_PROP_MERGEABLE:
1782     {
1783     object* op2;
1784     op2 = va_arg(args, object*);
1785     ri = CAN_MERGE(op, op2);
1786     rv = &ri;
1787     }
1788     *type = CFAPI_INT;
1789     break;
1790    
1791     case CFAPI_OBJECT_PROP_PICKABLE:
1792     {
1793     object* op2;
1794     rv = 0;
1795     op2 = va_arg(args, object*);
1796     ri = can_pick(op2, op);
1797     rv = &ri;
1798     }
1799     *type = CFAPI_INT;
1800     break;
1801    
1802     case CFAPI_OBJECT_PROP_FLAGS:
1803     {
1804     int fl;
1805     ri = 0;
1806     fl = va_arg(args, int);
1807     ri = QUERY_FLAG(op, fl);
1808     rv = &ri;
1809     }
1810     *type = CFAPI_INT;
1811     break;
1812    
1813     case CFAPI_OBJECT_PROP_STR:
1814     ri = op->stats.Str;
1815     rv = &ri;
1816     *type = CFAPI_INT;
1817     break;
1818    
1819     case CFAPI_OBJECT_PROP_DEX:
1820     ri = op->stats.Dex;
1821     rv = &ri;
1822     *type = CFAPI_INT;
1823     break;
1824    
1825     case CFAPI_OBJECT_PROP_CON:
1826     ri = op->stats.Con;
1827     rv = &ri;
1828     *type = CFAPI_INT;
1829     break;
1830    
1831     case CFAPI_OBJECT_PROP_WIS:
1832     ri = op->stats.Wis;
1833     rv = &ri;
1834     *type = CFAPI_INT;
1835     break;
1836    
1837     case CFAPI_OBJECT_PROP_INT:
1838     ri = op->stats.Int;
1839     rv = &ri;
1840     *type = CFAPI_INT;
1841     break;
1842    
1843     case CFAPI_OBJECT_PROP_POW:
1844     ri = op->stats.Pow;
1845     rv = &ri;
1846     *type = CFAPI_INT;
1847     break;
1848    
1849     case CFAPI_OBJECT_PROP_CHA:
1850     ri = op->stats.Cha;
1851     rv = &ri;
1852     *type = CFAPI_INT;
1853     break;
1854    
1855     case CFAPI_OBJECT_PROP_WC:
1856     ri = op->stats.wc;
1857     rv = &ri;
1858     *type = CFAPI_INT;
1859     break;
1860    
1861     case CFAPI_OBJECT_PROP_AC:
1862     ri = op->stats.ac;
1863     rv = &ri;
1864     *type = CFAPI_INT;
1865     break;
1866    
1867     case CFAPI_OBJECT_PROP_HP:
1868     ri = op->stats.hp;
1869     rv = &ri;
1870     *type = CFAPI_INT;
1871     break;
1872    
1873     case CFAPI_OBJECT_PROP_SP:
1874     ri = op->stats.sp;
1875     rv = &ri;
1876     *type = CFAPI_INT;
1877     break;
1878    
1879     case CFAPI_OBJECT_PROP_GP:
1880     ri = op->stats.grace;
1881     rv = &ri;
1882     *type = CFAPI_INT;
1883     break;
1884    
1885     case CFAPI_OBJECT_PROP_FP:
1886     ri = op->stats.food;
1887     rv = &ri;
1888     *type = CFAPI_INT;
1889     break;
1890    
1891     case CFAPI_OBJECT_PROP_MAXHP:
1892     ri = op->stats.maxhp;
1893     rv = &ri;
1894     *type = CFAPI_INT;
1895     break;
1896    
1897     case CFAPI_OBJECT_PROP_MAXSP:
1898     ri = op->stats.maxsp;
1899     rv = &ri;
1900     *type = CFAPI_INT;
1901     break;
1902    
1903     case CFAPI_OBJECT_PROP_MAXGP:
1904     ri = op->stats.maxgrace;
1905     rv = &ri;
1906     *type = CFAPI_INT;
1907     break;
1908    
1909     case CFAPI_OBJECT_PROP_DAM:
1910     ri = op->stats.dam;
1911     rv = &ri;
1912     *type = CFAPI_INT;
1913     break;
1914    
1915     case CFAPI_OBJECT_PROP_GOD:
1916     rv = (char*)determine_god(op);
1917     *type = CFAPI_STRING;
1918     break;
1919    
1920     case CFAPI_OBJECT_PROP_ARCH_NAME:
1921     rv = (char*)op->arch->name;
1922     *type = CFAPI_STRING;
1923     break;
1924    
1925     case CFAPI_OBJECT_PROP_INVISIBLE:
1926     ri = op->invisible;
1927     rv = &ri;
1928     *type = CFAPI_INT;
1929     break;
1930    
1931     case CFAPI_OBJECT_PROP_FACE:
1932     ri = op->animation_id;
1933     rv = &ri;
1934     *type = CFAPI_INT;
1935     break;
1936    
1937     case CFAPI_PLAYER_PROP_IP:
1938     rv = op->contr->socket.host;
1939     *type = CFAPI_STRING;
1940     break;
1941    
1942     case CFAPI_PLAYER_PROP_MARKED_ITEM:
1943     rv = find_marked_object(op);
1944     *type = CFAPI_POBJECT;
1945     break;
1946    
1947     case CFAPI_PLAYER_PROP_PARTY:
1948     rv = (op->contr ? op->contr->party : NULL);
1949     *type = CFAPI_PPARTY;
1950     break;
1951     default:
1952     *type = CFAPI_NONE;
1953     break;
1954     }
1955     }
1956     va_end(args);
1957     return rv;
1958     }
1959    
1960     void* cfapi_object_set_property(int* type, ...)
1961     {
1962     va_list args;
1963     int iarg;
1964     long larg;
1965     char* sarg;
1966     double darg;
1967     object* oparg;
1968     object* op;
1969     int property;
1970     void* rv;
1971     partylist* partyarg;
1972     va_start(args, type);
1973    
1974     op = va_arg(args, object*);
1975     property = va_arg(args, int);
1976     rv = NULL;
1977    
1978     if (op != NULL && (!op->arch || (op != &op->arch->clone))) {
1979     switch (property)
1980     {
1981     case CFAPI_OBJECT_PROP_NAME:
1982     sarg = va_arg(args, char*);
1983     FREE_AND_COPY(op->name, sarg);
1984     send_changed_object(op);
1985     break;
1986    
1987     case CFAPI_OBJECT_PROP_NAME_PLURAL:
1988     sarg = va_arg(args, char*);
1989     FREE_AND_COPY(op->name_pl, sarg);
1990     send_changed_object(op);
1991     break;
1992    
1993     case CFAPI_OBJECT_PROP_TITLE:
1994     sarg = va_arg(args, char*);
1995     FREE_AND_COPY(op->title, sarg);
1996     break;
1997    
1998     case CFAPI_OBJECT_PROP_RACE:
1999     sarg = va_arg(args, char*);
2000     FREE_AND_COPY(op->race, sarg);
2001     break;
2002    
2003     case CFAPI_OBJECT_PROP_SLAYING:
2004     sarg = va_arg(args, char*);
2005     FREE_AND_COPY(op->slaying, sarg);
2006     break;
2007    
2008     case CFAPI_OBJECT_PROP_SKILL:
2009     sarg = va_arg(args, char*);
2010     FREE_AND_COPY(op->skill, sarg);
2011     break;
2012    
2013     case CFAPI_OBJECT_PROP_MESSAGE:
2014     sarg = va_arg(args, char*);
2015     FREE_AND_COPY(op->msg, sarg);
2016     break;
2017    
2018     case CFAPI_OBJECT_PROP_LORE:
2019     sarg = va_arg(args, char*);
2020     FREE_AND_COPY(op->lore, sarg);
2021     break;
2022    
2023     case CFAPI_OBJECT_PROP_SPEED:
2024     darg = va_arg(args, double);
2025     op->speed = darg;
2026     break;
2027    
2028     case CFAPI_OBJECT_PROP_SPEED_LEFT:
2029     darg = va_arg(args, double);
2030     op->speed_left = darg;
2031     break;
2032    
2033     case CFAPI_OBJECT_PROP_NROF:
2034     iarg = va_arg(args, int);
2035     if (iarg < 0)
2036     iarg = 0;
2037     if (op->nrof > (uint32)iarg)
2038     decrease_ob_nr(op, op->nrof-iarg);
2039     else if (op->nrof < (uint32)iarg) {
2040     object* tmp;
2041     player *pl;
2042     op->nrof = iarg;
2043     if (op->env != NULL) {
2044     tmp = is_player_inv(op->env);
2045     if (!tmp) {
2046     for (pl = first_player; pl; pl = pl->next)
2047     if (pl->ob->container == op->env)
2048     break;
2049     if (pl)
2050     tmp = pl->ob;
2051     else
2052     tmp = NULL;
2053     }
2054     else {
2055     sum_weight(tmp);
2056     fix_player(tmp);
2057     }
2058     if (tmp)
2059     esrv_send_item(tmp, op);
2060     }
2061     else
2062     {
2063     object *above = op->above;
2064    
2065     for (tmp = above; tmp != NULL; tmp = tmp->above)
2066     if (tmp->type == PLAYER)
2067     esrv_send_item(tmp, op);
2068     }
2069     }
2070     break;
2071    
2072     case CFAPI_OBJECT_PROP_DIRECTION:
2073     iarg = va_arg(args, int);
2074     op->direction = iarg;
2075     break;
2076    
2077     case CFAPI_OBJECT_PROP_FACING:
2078     iarg = va_arg(args, int);
2079     op->facing = iarg;
2080     break;
2081    
2082     case CFAPI_OBJECT_PROP_RESIST:
2083     {
2084     int iargbis = va_arg(args, int);
2085     iarg = va_arg(args, int);
2086     op->resist[iargbis] = iarg;
2087     }
2088     break;
2089    
2090     case CFAPI_OBJECT_PROP_ATTACK_TYPE:
2091     iarg = va_arg(args, int);
2092     op->attacktype = iarg;
2093     break;
2094    
2095     case CFAPI_OBJECT_PROP_PATH_ATTUNED:
2096     iarg = va_arg(args, int);
2097     op->path_attuned = iarg;
2098     break;
2099    
2100     case CFAPI_OBJECT_PROP_PATH_REPELLED:
2101     iarg = va_arg(args, int);
2102     op->path_repelled = iarg;
2103     break;
2104    
2105     case CFAPI_OBJECT_PROP_PATH_DENIED:
2106     iarg = va_arg(args, int);
2107     op->path_denied = iarg;
2108     break;
2109    
2110     case CFAPI_OBJECT_PROP_MATERIAL:
2111     iarg = va_arg(args, int);
2112     op->material = iarg;
2113     break;
2114    
2115     case CFAPI_OBJECT_PROP_MATERIAL_NAME:
2116     break;
2117    
2118     case CFAPI_OBJECT_PROP_MAGIC:
2119     iarg = va_arg(args, int);
2120     op->magic = iarg;
2121     break;
2122    
2123     case CFAPI_OBJECT_PROP_VALUE:
2124     iarg = va_arg(args, int);
2125     op->value = iarg;
2126     break;
2127    
2128     case CFAPI_OBJECT_PROP_LEVEL:
2129     iarg = va_arg(args, int);
2130     op->level = iarg;
2131     break;
2132    
2133     case CFAPI_OBJECT_PROP_LAST_HEAL:
2134     iarg = va_arg(args, int);
2135     op->last_heal = iarg;
2136     break;
2137    
2138     case CFAPI_OBJECT_PROP_LAST_SP:
2139     iarg = va_arg(args, int);
2140     op->last_sp = iarg;
2141     break;
2142    
2143     case CFAPI_OBJECT_PROP_LAST_GRACE:
2144     iarg = va_arg(args, int);
2145     op->last_grace = iarg;
2146     break;
2147    
2148     case CFAPI_OBJECT_PROP_LAST_EAT:
2149     iarg = va_arg(args, int);
2150     op->last_eat = iarg;
2151     break;
2152    
2153     case CFAPI_OBJECT_PROP_INVISIBLE_TIME:
2154     iarg = va_arg(args, int);
2155     op->invisible = iarg;
2156     break;
2157    
2158     case CFAPI_OBJECT_PROP_PICK_UP:
2159     iarg = va_arg(args, int);
2160     op->pick_up = iarg;
2161     break;
2162    
2163     case CFAPI_OBJECT_PROP_ITEM_POWER:
2164     iarg = va_arg(args, int);
2165     op->item_power = iarg;
2166     break;
2167    
2168     case CFAPI_OBJECT_PROP_GEN_SP_ARMOUR:
2169     iarg = va_arg(args, int);
2170     op->gen_sp_armour = iarg;
2171     break;
2172    
2173     case CFAPI_OBJECT_PROP_WEIGHT:
2174     iarg = va_arg(args, int);
2175     if (op->weight != iarg) {
2176     object* tmp;
2177     player *pl;
2178     op->weight = iarg;
2179     if (op->env != NULL) {
2180     tmp = is_player_inv(op->env);
2181     if (!tmp) {
2182     for (pl = first_player; pl; pl = pl->next)
2183     if (pl->ob->container == op->env)
2184     break;
2185     if (pl)
2186     tmp = pl->ob;
2187     else
2188     tmp = NULL;
2189     } else {
2190     sum_weight(tmp);
2191     fix_player(tmp);
2192     }
2193     if (tmp)
2194     esrv_send_item(tmp, op);
2195     }
2196     else
2197     {
2198     object *above = op->above;
2199    
2200     for (tmp = above; tmp != NULL; tmp = tmp->above)
2201     if (tmp->type == PLAYER)
2202     esrv_send_item(tmp, op);
2203     }
2204     }
2205     break;
2206    
2207     case CFAPI_OBJECT_PROP_WEIGHT_LIMIT:
2208     iarg = va_arg(args, int);
2209     op->weight_limit = iarg;
2210     break;
2211    
2212     case CFAPI_OBJECT_PROP_GLOW_RADIUS:
2213     iarg = va_arg(args, int);
2214     op->glow_radius = iarg;
2215     break;
2216    
2217     case CFAPI_OBJECT_PROP_PERM_EXP:
2218     larg = va_arg(args, long);
2219     op->perm_exp = larg;
2220     break;
2221    
2222     case CFAPI_OBJECT_PROP_ENEMY:
2223     oparg = va_arg(args, object*);
2224     op->enemy = oparg;
2225     break;
2226    
2227     case CFAPI_OBJECT_PROP_RUN_AWAY:
2228     iarg = va_arg(args, int);
2229     op->run_away = iarg;
2230     break;
2231    
2232     case CFAPI_OBJECT_PROP_CHOSEN_SKILL:
2233     oparg = va_arg(args, object*);
2234     op->chosen_skill = oparg;
2235     break;
2236    
2237     case CFAPI_OBJECT_PROP_HIDDEN:
2238     iarg = va_arg(args, int);
2239     op->hide = iarg;
2240     break;
2241    
2242     case CFAPI_OBJECT_PROP_MOVE_STATUS:
2243     iarg = va_arg(args, int);
2244     op->move_status = iarg;
2245     break;
2246    
2247     case CFAPI_OBJECT_PROP_MOVE_TYPE:
2248     iarg = va_arg(args, int);
2249     op->attack_movement = iarg;
2250     break;
2251    
2252     case CFAPI_OBJECT_PROP_SPELL_ITEM:
2253     oparg = va_arg(args, object*);
2254     op->spellitem = oparg;
2255     break;
2256    
2257     case CFAPI_OBJECT_PROP_EXP_MULTIPLIER:
2258     darg = va_arg(args, double);
2259     op->expmul = darg;
2260     break;
2261    
2262     case CFAPI_OBJECT_PROP_CUSTOM_NAME:
2263     sarg = va_arg(args, char*);
2264     FREE_AND_COPY(op->custom_name, sarg);
2265     send_changed_object(op);
2266     break;
2267    
2268     case CFAPI_OBJECT_PROP_ANIM_SPEED:
2269     iarg = va_arg(args, int);
2270     op->anim_speed = iarg;
2271     break;
2272    
2273     case CFAPI_OBJECT_PROP_FRIENDLY:
2274     iarg = va_arg(args, int);
2275     if (iarg == 1 && is_friendly(op) == 0)
2276     add_friendly_object(op);
2277     else if (iarg == 0 && is_friendly(op) == 1)
2278     remove_friendly_object(op);
2279     break;
2280    
2281     case CFAPI_OBJECT_PROP_LUCK:
2282     iarg = va_arg(args, int);
2283     op->stats.luck = iarg;
2284     break;
2285    
2286     case CFAPI_OBJECT_PROP_EXP:
2287     {
2288     char* skillname;
2289    
2290     larg = va_arg(args, long);
2291     skillname = va_arg(args, char*);
2292     iarg = va_arg(args, int);
2293     change_exp(op, larg, skillname, iarg);
2294     }
2295     break;
2296    
2297     case CFAPI_OBJECT_PROP_OWNER:
2298     oparg = va_arg(args, object*);
2299     set_owner(op, oparg);
2300     break;
2301    
2302     case CFAPI_OBJECT_PROP_CHEATER:
2303     set_cheat(op);
2304     break;
2305    
2306     case CFAPI_OBJECT_PROP_FLAGS:
2307     {
2308     int iargbis;
2309     iarg = va_arg(args, int);
2310     iargbis = va_arg(args, int);
2311     if (iargbis == 1)
2312     SET_FLAG(op, iarg);
2313     else
2314     CLEAR_FLAG(op, iarg);
2315     }
2316     break;
2317    
2318     case CFAPI_OBJECT_PROP_STR:
2319     iarg = va_arg(args, int);
2320     op->stats.Str=iarg;
2321     break;
2322    
2323     case CFAPI_OBJECT_PROP_DEX:
2324     iarg = va_arg(args, int);
2325     op->stats.Dex=iarg;
2326     break;
2327    
2328     case CFAPI_OBJECT_PROP_CON:
2329     iarg = va_arg(args, int);
2330     op->stats.Con=iarg;
2331     break;
2332    
2333     case CFAPI_OBJECT_PROP_WIS:
2334     iarg = va_arg(args, int);
2335     op->stats.Wis=iarg;
2336     break;
2337    
2338     case CFAPI_OBJECT_PROP_INT:
2339     iarg = va_arg(args, int);
2340     op->stats.Int=iarg;
2341     break;
2342    
2343     case CFAPI_OBJECT_PROP_POW:
2344     iarg = va_arg(args, int);
2345     op->stats.Pow=iarg;
2346     break;
2347    
2348     case CFAPI_OBJECT_PROP_CHA:
2349     iarg = va_arg(args, int);
2350     op->stats.Cha=iarg;
2351     break;
2352    
2353     case CFAPI_OBJECT_PROP_WC:
2354     iarg = va_arg(args, int);
2355     op->stats.wc=iarg;
2356     break;
2357    
2358     case CFAPI_OBJECT_PROP_AC:
2359     iarg = va_arg(args, int);
2360     op->stats.ac=iarg;
2361     break;
2362    
2363     case CFAPI_OBJECT_PROP_HP:
2364     iarg = va_arg(args, int);
2365     op->stats.hp=iarg;
2366     break;
2367    
2368     case CFAPI_OBJECT_PROP_SP:
2369     iarg = va_arg(args, int);
2370     op->stats.sp=iarg;
2371     break;
2372    
2373     case CFAPI_OBJECT_PROP_GP:
2374     iarg = va_arg(args, int);
2375     op->stats.grace=iarg;
2376     break;
2377    
2378     case CFAPI_OBJECT_PROP_FP:
2379     iarg = va_arg(args, int);
2380     op->stats.food=iarg;
2381     break;
2382    
2383     case CFAPI_OBJECT_PROP_MAXHP:
2384     iarg = va_arg(args, int);
2385     op->stats.maxhp=iarg;
2386     break;
2387    
2388     case CFAPI_OBJECT_PROP_MAXSP:
2389     iarg = va_arg(args, int);
2390     op->stats.maxsp=iarg;
2391     break;
2392    
2393     case CFAPI_OBJECT_PROP_MAXGP:
2394     iarg = va_arg(args, int);
2395     op->stats.maxgrace=iarg;
2396     break;
2397    
2398     case CFAPI_OBJECT_PROP_DAM:
2399     iarg = va_arg(args, int);
2400     op->stats.dam=iarg;
2401     break;
2402    
2403     case CFAPI_OBJECT_PROP_FACE:
2404     iarg = va_arg(args, int);
2405     op->animation_id = iarg;
2406     update_object(op, UP_OBJ_FACE);
2407     break;
2408    
2409     case CFAPI_OBJECT_ANIMATION:
2410     iarg = va_arg(args, int);
2411     if (iarg != -1) {
2412     SET_ANIMATION(op, iarg);
2413     }
2414     update_object(op, UP_OBJ_FACE);
2415     break;
2416    
2417     case CFAPI_PLAYER_PROP_MARKED_ITEM:
2418     if (op->contr) {
2419     oparg = va_arg(args, object*);
2420     op->contr->mark = oparg;
2421     if (oparg)
2422     op->contr->mark_count = oparg->count;
2423     }
2424     break;
2425    
2426     case CFAPI_PLAYER_PROP_PARTY:
2427     if (op->contr) {
2428     partyarg = va_arg(args, partylist*);
2429     op->contr->party = partyarg;
2430     }
2431     break;
2432    
2433     default:
2434     *type = CFAPI_NONE;
2435     break;
2436     }
2437     }
2438     va_end(args);
2439    
2440     *type = CFAPI_NONE;
2441     return NULL;
2442     }
2443    
2444     void* cfapi_object_apply_below(int* type, ...)
2445     {
2446     va_list args;
2447     object* applier;
2448    
2449     va_start(args, type);
2450    
2451     applier = va_arg(args, object*);
2452    
2453     va_end(args);
2454    
2455     player_apply_below(applier);
2456     *type = CFAPI_NONE;
2457     return NULL;
2458     }
2459    
2460     void* cfapi_object_apply(int* type, ...)
2461     {
2462     va_list args;
2463     object* applied;
2464     object* applier;
2465     int aflags;
2466     static int rv;
2467    
2468     va_start(args, type);
2469    
2470     applied = va_arg(args, object*);
2471     applier = va_arg(args, object*);
2472     aflags = va_arg(args, int);
2473    
2474     va_end(args);
2475    
2476     *type = CFAPI_INT;
2477     rv = manual_apply(applier, applied, aflags);
2478     return &rv;
2479     }
2480     void* cfapi_object_identify(int* type, ...)
2481     {
2482     va_list args;
2483     object* op;
2484    
2485     va_start(args, type);
2486    
2487     op = va_arg(args, object*);
2488    
2489     va_end(args);
2490    
2491     identify(op);
2492     *type = CFAPI_NONE;
2493     return NULL;
2494     }
2495     void* cfapi_object_describe(int* type, ...)
2496     {
2497     va_list args;
2498     object* op;
2499     object* owner;
2500    
2501     va_start(args, type);
2502    
2503     op = va_arg(args, object*);
2504     owner = va_arg(args, object*);
2505     va_end(args);
2506    
2507     *type = CFAPI_STRING;
2508     return describe_item(op, owner);
2509     }
2510     void* cfapi_object_drain(int* type, ...)
2511     {
2512     va_list args;
2513    
2514     object* op;
2515     int ds;
2516    
2517     va_start(args, type);
2518    
2519     op = va_arg(args, object*);
2520     ds = va_arg(args, int);
2521    
2522     va_end(args);
2523    
2524     drain_specific_stat(op, ds);
2525    
2526     *type = CFAPI_NONE;
2527     return NULL;
2528     }
2529     void* cfapi_object_fix(int* type, ...)
2530     {
2531     va_list args;
2532     object* op;
2533    
2534     va_start(args, type);
2535    
2536     op = va_arg(args, object*);
2537    
2538     va_end(args);
2539    
2540     fix_player(op);
2541    
2542     *type = CFAPI_NONE;
2543     return NULL;
2544     }
2545     void* cfapi_object_give_skill(int* type, ...)
2546     {
2547     va_list args;
2548    
2549     object* op;
2550     char* skillname;
2551    
2552     va_start(args, type);
2553    
2554     op = va_arg(args, object*);
2555     skillname = va_arg(args, char*);
2556    
2557     va_end(args);
2558    
2559     *type = CFAPI_POBJECT;
2560     return give_skill_by_name(op, skillname);
2561     }
2562     void* cfapi_object_transmute(int* type, ...)
2563     {
2564     va_list args;
2565    
2566     object* op;
2567     object* chg;
2568    
2569     va_start(args, type);
2570    
2571     op = va_arg(args, object*);
2572     chg = va_arg(args, object*);
2573    
2574     va_end(args);
2575    
2576     transmute_materialname(op, chg);
2577     *type = CFAPI_NONE;
2578     return NULL;
2579     }
2580     void* cfapi_object_remove(int* type, ...)
2581     {
2582     va_list args;
2583     object* op;
2584    
2585     va_start(args, type);
2586    
2587     op = va_arg(args, object*);
2588    
2589     va_end(args);
2590    
2591     send_removed_object(op);
2592     remove_ob(op);
2593     *type = CFAPI_NONE;
2594     return NULL;
2595     }
2596     void* cfapi_object_delete(int* type, ...)
2597     {
2598     va_list args;
2599     object* op;
2600    
2601     va_start(args, type);
2602    
2603     op = va_arg(args, object*);
2604    
2605     va_end(args);
2606    
2607     free_object(op);
2608    
2609     *type = CFAPI_NONE;
2610     return NULL;
2611     }
2612     void* cfapi_object_clone(int* type, ...)
2613     {
2614     va_list args;
2615     object* op;
2616     int kind;
2617    
2618     va_start(args, type);
2619    
2620     op = va_arg(args, object*);
2621     kind = va_arg(args, int);
2622    
2623     va_end(args);
2624    
2625     if (kind == 0) {
2626     *type = CFAPI_POBJECT;
2627     return object_create_clone(op);
2628     } else {
2629     object* tmp;
2630     tmp = get_object();
2631     copy_object(op, tmp);
2632     *type = CFAPI_POBJECT;
2633     return tmp;
2634     }
2635     }
2636     void* cfapi_object_find(int* type, ...)
2637     {
2638     va_list args;
2639     int ftype;
2640     void* rv;
2641     int ival;
2642     int ival2;
2643     char* sval;
2644     object* op;
2645     va_start(args, type);
2646    
2647     *type = CFAPI_POBJECT;
2648     ftype = va_arg(args, int);
2649     switch (ftype)
2650     {
2651     case 0:
2652     ival = va_arg(args, int);
2653     rv = find_object(ival);
2654     break;
2655    
2656     case 1:
2657     sval = va_arg(args, char*);
2658     rv = find_object_name(sval);
2659     break;
2660    
2661     case 2:
2662     op = va_arg(args, object*);
2663     ival = va_arg(args, int);
2664     ival2 = va_arg(args, int);
2665     rv = find_obj_by_type_subtype(op, ival, ival2);
2666     break;
2667    
2668     case 3:
2669     op = va_arg(args, object*);
2670     rv = is_player_inv(op);
2671     break;
2672    
2673     default:
2674     rv = NULL;
2675     *type = CFAPI_NONE;
2676     break;
2677     }
2678    
2679     va_end(args);
2680    
2681     return rv;
2682     }
2683     void* cfapi_object_create(int* type, ...)
2684     {
2685     va_list args;
2686     int ival;
2687     va_start(args, type);
2688     ival = va_arg(args, int);
2689    
2690     *type = CFAPI_POBJECT;
2691     switch (ival)
2692     {
2693     case 0:
2694     va_end(args);
2695     return get_object();
2696     break;
2697    
2698     case 1: /* Named object. Nearly the old plugin behavior, but we don't add artifact suffixes */
2699     {
2700     char* sval;
2701     object* op;
2702     sval = va_arg(args, char*);
2703    
2704     op = get_archetype_by_object_name(sval);
2705    
2706     if (strncmp(query_name(op), ARCH_SINGULARITY, ARCH_SINGULARITY_LEN) == 0) {
2707     free_object(op);
2708     /* Try with archetype names... */
2709     op = get_archetype(sval);
2710     if (strncmp(query_name(op), ARCH_SINGULARITY, ARCH_SINGULARITY_LEN) == 0) {
2711     free_object(op);
2712     *type = CFAPI_NONE;
2713     va_end(args);
2714     return NULL;
2715     }
2716     }
2717     va_end(args);
2718     return op;
2719     }
2720     break;
2721    
2722     default:
2723     *type = CFAPI_NONE;
2724     va_end(args);
2725     return NULL;
2726     break;
2727     }
2728     }
2729     void* cfapi_object_insert(int* type, ...)
2730     {
2731     va_list args;
2732     object* op;
2733     object* orig;
2734     mapstruct* map;
2735     int flag, x, y;
2736     int itype;
2737     char* arch_string;
2738     void* rv = NULL;
2739    
2740     va_start(args, type);
2741    
2742     op = va_arg(args, object*);
2743     itype = va_arg(args, int);
2744    
2745     switch (itype) {
2746     case 0:
2747     map = va_arg(args, mapstruct*);
2748     orig = va_arg(args, object*);
2749     flag = va_arg(args, int);
2750     x = va_arg(args, int);
2751     y = va_arg(args, int);
2752     rv = insert_ob_in_map_at(op, map, orig, flag, x, y);
2753     *type = CFAPI_POBJECT;
2754     break;
2755    
2756     case 1:
2757     map = va_arg(args, mapstruct*);
2758     orig = va_arg(args, object*);
2759     flag = va_arg(args, int);
2760     rv = insert_ob_in_map(op, map, orig, flag);
2761     *type = CFAPI_POBJECT;
2762     break;
2763    
2764     case 2:
2765     arch_string = va_arg(args, char*);
2766     replace_insert_ob_in_map(arch_string, op);
2767     *type = CFAPI_NONE;
2768     break;
2769    
2770     case 3:
2771     orig = va_arg(args, object*);
2772     rv = insert_ob_in_ob(op, orig);
2773     if (orig->type == PLAYER) {
2774     esrv_send_item(orig, op);
2775     }
2776     *type = CFAPI_POBJECT;
2777     break;
2778     }
2779    
2780     va_end(args);
2781    
2782     return rv;
2783     }
2784     void* cfapi_object_split(int* type, ...)
2785     {
2786     va_list args;
2787    
2788     int nr;
2789     object* op;
2790     va_start(args, type);
2791    
2792     op = va_arg(args, object*);
2793     nr = va_arg(args, int);
2794    
2795     va_end(args);
2796     *type = CFAPI_POBJECT;
2797     return get_split_ob(op, nr);
2798     }
2799     void* cfapi_object_merge(int* type, ...)
2800     {
2801     va_list args;
2802     object* op;
2803     object* op2;
2804    
2805     va_start(args, type);
2806    
2807     op = va_arg(args, object*);
2808     op2 = va_arg(args, object*);
2809    
2810     va_end(args);
2811    
2812    
2813     *type = CFAPI_POBJECT;
2814     return merge_ob(op, op2);
2815     }
2816     void* cfapi_object_distance(int* type, ...)
2817     {
2818     va_list args;
2819     static int rv;
2820     object* op;
2821     object* op2;
2822     va_start(args, type);
2823    
2824     op = va_arg(args, object*);
2825     op2 = va_arg(args, object*);
2826    
2827     va_end(args);
2828    
2829     *type = CFAPI_INT;
2830     rv = distance(op, op2);
2831     return &rv;
2832     }
2833     void* cfapi_object_update(int* type, ...)
2834     {
2835     va_list args;
2836     int action;
2837     object* op;
2838     va_start(args, type);
2839    
2840     op = va_arg(args, object*);
2841     action = va_arg(args, int);
2842    
2843     va_end(args);
2844    
2845     update_object(op, action);
2846     *type = CFAPI_NONE;
2847     return NULL;
2848     }
2849     void* cfapi_object_clear(int* type, ...)
2850     {
2851     va_list args;
2852     object* op;
2853     va_start(args, type);
2854    
2855     op = va_arg(args, object*);
2856    
2857     va_end(args);
2858    
2859     clear_object(op);
2860     *type = CFAPI_NONE;
2861     return NULL;
2862     }
2863     void* cfapi_object_reset(int* type, ...)
2864     {
2865     va_list args;
2866     object* op;
2867    
2868     va_start(args, type);
2869    
2870     op = va_arg(args, object*);
2871    
2872     va_end(args);
2873    
2874     reset_object(op);
2875     *type = CFAPI_NONE;
2876     return NULL;
2877     }
2878    
2879     void* cfapi_object_check_inventory(int* type, ...)
2880     {
2881     va_list args;
2882     object* op;
2883     object* op2;
2884     int checktype;
2885     object* ret = NULL;
2886    
2887     va_start(args, type);
2888    
2889     op = va_arg(args, object*);
2890     op2 = va_arg(args, object*);
2891     checktype = va_arg(args, int);
2892    
2893     if (checktype == 0) {
2894     check_inv(op, op2);
2895     *type = CFAPI_NONE;
2896     } else {
2897     ret = check_inv_recursive(op, op2);
2898     *type = CFAPI_POBJECT;
2899     }
2900    
2901     va_end(args);
2902    
2903     return ret;
2904     }
2905    
2906     void* cfapi_object_clean_object(int* type, ...)
2907     {
2908     va_list args;
2909     object* op;
2910     va_start(args, type);
2911     op = va_arg(args, object*);
2912     clean_object(op);
2913     va_end(args);
2914     *type = CFAPI_NONE;
2915     return NULL;
2916     }
2917     void* cfapi_object_on_same_map(int* type, ...)
2918     {
2919     va_list args;
2920     static int rv;
2921     object* op1;
2922     object* op2;
2923    
2924     va_start(args, type);
2925     op1 = va_arg(args, object*);
2926     op2 = va_arg(args, object*);
2927    
2928     rv = on_same_map(op1, op2);
2929     va_end(args);
2930    
2931     *type = CFAPI_INT;
2932     return &rv;
2933     }
2934    
2935     void* cfapi_object_spring_trap(int* type, ...)
2936     {
2937     object* trap;
2938     object* victim;
2939     va_list args;
2940    
2941     va_start(args, type);
2942     trap = va_arg(args, object*);
2943     victim = va_arg(args, object*);
2944     va_end(args);
2945    
2946     spring_trap(trap, victim);
2947     *type = CFAPI_NONE;
2948     return NULL;
2949     }
2950    
2951     void* cfapi_object_check_trigger(int* type, ...)
2952     {
2953     object* op;
2954     object* cause;
2955     va_list args;
2956     static int rv;
2957    
2958     va_start(args, type);
2959     op = va_arg(args, object*);
2960     cause = va_arg(args, object*);
2961     va_end(args);
2962    
2963     rv = check_trigger(op, cause);
2964     *type = CFAPI_INT;
2965     return &rv;
2966     }
2967    
2968     void* cfapi_object_query_cost(int* type, ...)
2969     {
2970     object* op;
2971     object* who;
2972     int flags;
2973     va_list args;
2974     static int rv;
2975    
2976     va_start(args, type);
2977     op = va_arg(args, object*);
2978     who = va_arg(args, object*);
2979     flags = va_arg(args, int);
2980     va_end(args);
2981    
2982     rv = query_cost(op, who, flags);
2983     *type = CFAPI_INT;
2984     return &rv;
2985     }
2986    
2987     void* cfapi_object_query_money(int* type, ...)
2988     {
2989     object* op;
2990     va_list args;
2991     static int rv;
2992    
2993     va_start(args, type);
2994     op = va_arg(args, object*);
2995     va_end(args);
2996    
2997     rv = query_money(op);
2998     *type = CFAPI_INT;
2999     return &rv;
3000     }
3001     void* cfapi_object_cast(int* type, ...)
3002     {
3003     object* op;
3004     object* sp;
3005     int dir;
3006     char* str;
3007     object* caster;
3008     va_list args;
3009     static int rv;
3010     va_start(args, type);
3011     op = va_arg(args, object*);
3012     caster = va_arg(args, object*);
3013     dir = va_arg(args, int);
3014     sp = va_arg(args, object*);
3015     str = va_arg(args, char*);
3016     va_end(args);
3017     rv = cast_spell(op, caster, dir, sp, str);
3018     *type = CFAPI_INT;
3019     return &rv;
3020     }
3021     void* cfapi_object_learn_spell(int* type, ...)
3022     {
3023     object* op;
3024     object* sp;
3025     int prayer;
3026     va_list args;
3027    
3028     va_start(args, type);
3029     op = va_arg(args, object*);
3030     sp = va_arg(args, object*);
3031     prayer = va_arg(args, int);
3032     va_end(args);
3033     do_learn_spell(op, sp, prayer);
3034     *type = CFAPI_NONE;
3035     return NULL;
3036     }
3037     void* cfapi_object_forget_spell(int* type, ...)
3038     {
3039     object* op;
3040     object* sp;
3041     va_list args;
3042    
3043     va_start(args, type);
3044     op = va_arg(args, object*);
3045     sp = va_arg(args, object*);
3046     va_end(args);
3047     do_forget_spell(op, query_name(sp));
3048     *type = CFAPI_NONE;
3049     return NULL;
3050     }
3051     void* cfapi_object_check_spell(int* type, ...)
3052     {
3053     object* op;
3054     char* spellname;
3055     va_list args;
3056     object* rv;
3057    
3058     va_start(args, type);
3059     op = va_arg(args, object*);
3060     spellname = va_arg(args, char*);
3061     va_end(args);
3062     rv = check_spell_known(op, spellname);
3063     *type = CFAPI_POBJECT;
3064     return rv;
3065     }
3066     void* cfapi_object_pay_amount(int* type, ...)
3067     {
3068     object* op;
3069     uint64 amount;
3070     va_list args;
3071     static int rv;
3072    
3073     va_start(args, type);
3074     op = va_arg(args, object*);
3075     amount = va_arg(args, uint64);
3076     va_end(args);
3077    
3078     rv = pay_for_amount(amount, op);
3079     *type = CFAPI_INT;
3080     return &rv;
3081     }
3082     void* cfapi_object_pay_item(int* type, ...)
3083     {
3084     object* op;
3085     object* tobuy;
3086    
3087     va_list args;
3088     static int rv;
3089    
3090     va_start(args, type);
3091     tobuy = va_arg(args, object*);
3092     op = va_arg(args, object*);
3093     va_end(args);
3094    
3095     rv = pay_for_item(tobuy, op);
3096     *type = CFAPI_INT;
3097     return &rv;
3098     }
3099     void* cfapi_object_transfer(int* type, ...)
3100     {
3101     object* op;
3102     object* originator;
3103     int x, y, randompos, ttype;
3104     va_list args;
3105     static int rv=0;
3106     mapstruct* map;
3107    
3108     va_start(args, type);
3109     op = va_arg(args, object*);
3110     ttype = va_arg(args, int);
3111     switch (ttype)
3112     {
3113     case 0:
3114     x = va_arg(args, int);
3115     y = va_arg(args, int);
3116     randompos = va_arg(args, int);
3117     originator = va_arg(args, object*);
3118     va_end(args);
3119    
3120     rv = transfer_ob(op, x, y, randompos, originator);
3121     *type = CFAPI_INT;
3122     return &rv;
3123     break;
3124    
3125     case 1:
3126     x = va_arg(args, int);
3127     y = va_arg(args, int);
3128     map = va_arg(args, mapstruct*);
3129     va_end(args);
3130     if (x < 0 || y < 0) {
3131     x = map->enter_x;
3132     y = map->enter_y;
3133     }
3134     /*
3135     originator = get_object();
3136     EXIT_PATH(originator) = add_string(map->path);
3137     EXIT_X(originator) = x;
3138     EXIT_Y(originator) = y;
3139     printf("B Transfer: X=%d, Y=%d, OP=%s\n", x, y, op->name);*/
3140     /*enter_exit(op, originator);*/
3141     insert_ob_in_map_at(op, map, NULL, 0, x, y);
3142     /*printf("A Transfer: X=%d, Y=%d, MAP=%s\n", x, y, op->map->name);
3143     free_object(originator);
3144     */
3145     *type = CFAPI_INT;
3146     return &rv;
3147     break;
3148    
3149     default:
3150     *type = CFAPI_NONE;
3151     return NULL;
3152     break;
3153     }
3154     }
3155    
3156     void* cfapi_object_find_archetype_inside(int* type, ...)
3157     {
3158     object* op;
3159     int critera;
3160     char* str;
3161     va_list args;
3162     object* rv;
3163    
3164     *type = CFAPI_POBJECT;
3165     va_start(args, type);
3166     op = va_arg(args, object*);
3167     critera = va_arg(args, int);
3168    
3169     switch(critera)
3170     {
3171     case 0: /* By name, either exact or from query_name */
3172     str = va_arg(args, char*);
3173     rv = present_arch_in_ob(find_archetype(str), op);
3174     if (rv == NULL) {
3175     object* tmp;
3176     /* Search by query_name instead */
3177     for (tmp = op->inv; tmp; tmp = tmp->below) {
3178     if (!strncmp(query_name(tmp), str, strlen(str)))
3179     rv = tmp;
3180     if (!strncmp(tmp->name, str, strlen(str)))
3181     rv = tmp;
3182     if (rv != NULL)
3183     break;
3184     }
3185     }
3186     break;
3187    
3188     default:
3189     rv = NULL;
3190     break;
3191     }
3192     va_end(args);
3193    
3194     if (rv == NULL) {
3195     *type = CFAPI_NONE;
3196     }
3197     return rv;
3198     }
3199    
3200     void* cfapi_object_drop(int* type, ...)
3201     {
3202     object* op;
3203     object* author;
3204     va_list args;
3205    
3206     va_start(args, type);
3207     op = va_arg(args, object*);
3208     author = va_arg(args, object*);
3209     va_end(args);
3210    
3211     if (QUERY_FLAG(op, FLAG_NO_DROP))
3212     return NULL;
3213     drop(author, op);
3214    
3215     if (author->type == PLAYER) {
3216     author->contr->count = 0;
3217     author->contr->socket.update_look = 1;
3218     }
3219    
3220     *type = CFAPI_NONE;
3221     return NULL;
3222     }
3223    
3224     void* cfapi_object_take(int* type, ...)
3225     {
3226     object *op;
3227     object *author;
3228     va_list args;
3229    
3230     va_start(args, type);
3231     op = va_arg(args, object*);
3232     author = va_arg(args, object*);
3233     va_end(args);
3234     pick_up(author, op);
3235    
3236     *type = CFAPI_NONE;
3237     return NULL;
3238     }
3239    
3240     void* cfapi_object_say(int* type, ...)
3241     {
3242     static int rv;
3243     object* op;
3244     char* msg;
3245     va_list args;
3246    
3247     va_start(args, type);
3248     op = va_arg(args, object*);
3249     msg = va_arg(args, char*);
3250     va_end(args);
3251    
3252     rv = command_say(op, msg);
3253     *type = CFAPI_INT;
3254     return &rv;
3255     }
3256     void* cfapi_object_speak(int* type, ...)
3257     {
3258     object* op;
3259     char* msg;
3260     va_list args;
3261     static char buf[MAX_BUF];
3262    
3263     va_start(args, type);
3264     op = va_arg(args, object*);
3265     msg = va_arg(args, char*);
3266     va_end(args);
3267    
3268     if (!op || !msg)
3269     return NULL;
3270     sprintf(buf, "%s says: ", op->name);
3271     strncat(buf, msg, MAX_BUF-strlen(buf)-1);
3272     buf[MAX_BUF-1]=0;
3273     new_info_map(NDI_WHITE, op->map, buf);
3274     communicate(op, msg);
3275     *type = CFAPI_NONE;
3276     return NULL;
3277     }
3278     /* PLAYER SUBCLASS */
3279     void* cfapi_player_find(int* type, ...)
3280     {
3281     va_list args;
3282     void* rv;
3283     char* sval;
3284     va_start(args, type);
3285    
3286     sval = va_arg(args, char*);
3287     va_end(args);
3288    
3289     rv = find_player(sval);
3290    
3291     *type = CFAPI_PPLAYER;
3292     return rv;
3293     }
3294     void* cfapi_player_message(int* type, ...)
3295     {
3296     va_list args;
3297     int flags;
3298     int pri;
3299     object* pl;
3300     char* buf;
3301    
3302     va_start(args, type);
3303    
3304     flags = va_arg(args, int);
3305     pri = va_arg(args, int);
3306     pl = va_arg(args, object*);
3307     buf = va_arg(args, char*);
3308     va_end(args);
3309    
3310     new_draw_info(flags, pri, pl, buf);
3311     *type = CFAPI_NONE;
3312     return NULL;
3313     }
3314     void *cfapi_player_send_inventory(int *type, ...)
3315     {
3316     /* Currently a stub. Do we really need this anymore ? */
3317     *type = CFAPI_NONE;
3318     return NULL;
3319     }
3320    
3321     void* cfapi_object_teleport(int *type, ...)
3322     {
3323     mapstruct* map;
3324     int x, y;
3325     object* who;
3326     static int result;
3327     va_list args;
3328    
3329     va_start(args, type);
3330     who = va_arg(args, object*);
3331     map = va_arg(args, mapstruct*);
3332     x = va_arg(args, int);
3333     y = va_arg(args, int);
3334    
3335     if (!out_of_map(map, x, y)) {
3336     int k;
3337     object *tmp;
3338     k = find_first_free_spot(who, map, x, y);
3339     if (k == -1) {
3340     result = 1;
3341     return &result;
3342     }
3343    
3344     send_removed_object(who);
3345     remove_ob(who);
3346    
3347     for (tmp = who; tmp != NULL; tmp = tmp->more)
3348     tmp->x = x+freearr_x[k]+(tmp->arch == NULL ? 0 : tmp->arch->clone.x),
3349     tmp->y = y+freearr_y[k]+(tmp->arch == NULL ? 0 : tmp->arch->clone.y);
3350    
3351     insert_ob_in_map(who, map, NULL, 0);
3352     result = 0;
3353     }
3354    
3355     return &result;
3356     }
3357     void* cfapi_object_pickup(int *type, ...)
3358     {
3359     object* who;
3360     object* what;
3361     va_list args;
3362    
3363     va_start(args, type);
3364     who = va_arg(args, object*);
3365     what = va_arg(args, object*);
3366     va_end(args);
3367    
3368     pick_up(who, what);
3369     *type = CFAPI_NONE;
3370     return NULL;
3371     }
3372    
3373     /* Archetype-related functions */
3374     void* cfapi_archetype_get_first(int* type, ...)
3375     {
3376     va_list args;
3377     va_start(args, type);
3378     va_end(args);
3379     *type = CFAPI_PARCH;
3380     return first_archetype;
3381     }
3382    
3383     void* cfapi_archetype_get_property(int* type, ...)
3384     {
3385     archetype* arch;
3386     int prop;
3387     va_list args;
3388     void* rv;
3389    
3390     va_start(args, type);
3391     arch = va_arg(args, archetype*);
3392     prop = va_arg(args, int);
3393     switch (prop) {
3394     case CFAPI_ARCH_PROP_NAME:
3395     *type = CFAPI_STRING;
3396     rv = (void*)arch->name;
3397     break;
3398    
3399     case CFAPI_ARCH_PROP_NEXT:
3400     *type = CFAPI_PARCH;
3401     rv = arch->next;
3402     break;
3403    
3404     case CFAPI_ARCH_PROP_HEAD:
3405     *type = CFAPI_PARCH;
3406     rv = arch->head;
3407     break;
3408    
3409     case CFAPI_ARCH_PROP_MORE:
3410     *type = CFAPI_PARCH;
3411     rv = arch->more;
3412     break;
3413    
3414     case CFAPI_ARCH_PROP_CLONE:
3415     *type = CFAPI_POBJECT;
3416     rv = &arch->clone;
3417     break;
3418    
3419     default:
3420     *type = CFAPI_NONE;
3421     rv = NULL;
3422     break;
3423     }
3424     va_end(args);
3425     return rv;
3426     }
3427    
3428     /* Party-related functions */
3429     void* cfapi_party_get_property(int* type, ...)
3430     {
3431     partylist* party;
3432     int prop;
3433     va_list args;
3434     void* rv;
3435     object* obarg;
3436     player* pl;
3437    
3438     va_start(args, type);
3439     party = va_arg(args, partylist*);
3440     prop = va_arg(args, int);
3441     switch (prop)
3442     {
3443     case CFAPI_PARTY_PROP_NAME:
3444     *type = CFAPI_STRING;
3445     rv = (void*)party->partyname;
3446     break;
3447    
3448     case CFAPI_PARTY_PROP_NEXT:
3449     *type = CFAPI_PPARTY;
3450     rv = (party ? party->next : get_firstparty());
3451     break;
3452    
3453     case CFAPI_PARTY_PROP_PASSWORD:
3454     *type = CFAPI_STRING;
3455     rv = (void*)party->passwd;
3456     break;
3457    
3458     case CFAPI_PARTY_PROP_PLAYER:
3459     *type = CFAPI_PPLAYER;
3460     obarg = va_arg(args, object*);
3461     pl = (obarg ? obarg->contr : first_player);
3462     rv = NULL;
3463     for (; pl != NULL; pl = pl->next)
3464     if (pl->ob->contr->party == party) {
3465     rv = (void*)pl;
3466     break;
3467     }
3468     break;
3469    
3470     default:
3471     *type = CFAPI_NONE;
3472     rv = NULL;
3473     break;
3474     }
3475     va_end(args);
3476     return rv;
3477     }
3478    
3479     /* Regions-related functions */
3480     void* cfapi_region_get_property(int* type, ...)
3481     {
3482     region* reg;
3483     int prop;
3484     va_list args;
3485     void* rv;
3486    
3487     va_start(args, type);
3488     reg = va_arg(args, region*);
3489     prop = va_arg(args, int);
3490     switch (prop) {
3491     case CFAPI_REGION_PROP_NAME:
3492     *type = CFAPI_STRING;
3493     rv = (void*)reg->name;
3494     break;
3495    
3496     case CFAPI_REGION_PROP_NEXT:
3497     *type = CFAPI_PREGION;
3498     rv = (reg?reg->next:first_region);
3499     break;
3500    
3501     case CFAPI_REGION_PROP_PARENT:
3502     *type = CFAPI_PREGION;
3503     rv = (void*)reg->parent;
3504     break;
3505    
3506     case CFAPI_REGION_PROP_LONGNAME:
3507     *type = CFAPI_STRING;
3508     rv = (void*)reg->longname;
3509     break;
3510    
3511     case CFAPI_REGION_PROP_MESSAGE:
3512     *type = CFAPI_STRING;
3513     rv = (void*)reg->msg;
3514     break;
3515    
3516     default:
3517     *type = CFAPI_NONE;
3518     rv = NULL;
3519     break;
3520     }
3521     va_end(args);
3522     return rv;
3523     }
3524    
3525     /*****************************************************************************/
3526     /* NEW PLUGIN STUFF ENDS HERE */
3527     /*****************************************************************************/
3528    
3529    
3530     /*****************************************************************************/
3531     /* Tries to find if a given command is handled by a plugin. */
3532     /* Note that find_plugin_command is called *before* the internal commands are*/
3533     /* checked, meaning that you can "overwrite" them. */
3534     /*****************************************************************************/
3535     CommArray_s *find_plugin_command(char *cmd, object *op)
3536     {
3537     int i;
3538     crossfire_plugin* cp;
3539     CommArray_s* rtn_cmd;
3540    
3541     if (plugins_list == NULL)
3542     return NULL;
3543    
3544     for (cp = plugins_list; cp != NULL; cp = cp->next) {
3545     rtn_cmd = cp->propfunc(&i, "command?", cmd);
3546     if (rtn_cmd)
3547     return rtn_cmd;
3548     }
3549     return NULL;
3550     }
3551    
3552     /*****************************************************************************/
3553     /* Plugins initialization. Browses the plugins directory and call */
3554     /* initOnePlugin for each file found. */
3555     /* Returns 0 if at least one plugin was successfully loaded, -1 if not */
3556     /*****************************************************************************/
3557     int initPlugins(void)
3558     {
3559     struct dirent *currentfile;
3560     DIR *plugdir;
3561     size_t l;
3562     char buf[MAX_BUF];
3563     char buf2[MAX_BUF];
3564     int result;
3565    
3566     LOG(llevInfo, "Initializing plugins\n");
3567     strcpy(buf, LIBDIR);
3568     strcat(buf, "/plugins/");
3569     LOG(llevInfo, "Plugins directory is %s\n", buf);
3570    
3571     plugdir = opendir(buf);
3572     if (plugdir == NULL)
3573     return -1;
3574    
3575     result = -1;
3576     while ((currentfile = readdir(plugdir)) != NULL) {
3577     l = strlen(currentfile->d_name);
3578     if (l > strlen(PLUGIN_SUFFIX)) {
3579     if (strcmp(currentfile->d_name+l-strlen(PLUGIN_SUFFIX), PLUGIN_SUFFIX) == 0) {
3580     strcpy(buf2, buf);
3581     strcat(buf2, currentfile->d_name);
3582     LOG(llevInfo, " -> Loading plugin : %s\n", currentfile->d_name);
3583     if (plugins_init_plugin(buf2) == 0)
3584     result = 0;
3585     }
3586     }
3587     }
3588    
3589     closedir(plugdir);
3590     return result;
3591     }