ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.4
Committed: Wed Feb 8 04:32:19 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +3 -1 lines
Log Message:
*** empty log message ***

File Contents

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