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

File Contents

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