ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.11
Committed: Fri Sep 8 16:51:44 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.10: +1 -16 lines
Log Message:
generic accessors, take one

File Contents

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