ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.4
Committed: Fri Aug 25 17:11:53 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.3: +1 -52 lines
Log Message:
converted more events, broken per-object events (needs map support), lots of fixes

File Contents

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