ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.1.1.2 (vendor branch)
Committed: Wed Feb 22 18:03:23 2006 UTC (18 years, 3 months ago) by elmex
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_03_15, UPSTREAM_2006_02_22
Changes since 1.1.1.1: +2 -2 lines
Log Message:
cvs -z7 -d:ext:elmex@cvs.schmorp.de:/schmorpforge import cf.schmorp.de UPSTREAM UPSTREAM_2006_02_22

File Contents

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