ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.15
Committed: Thu Sep 14 22:34:04 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.14: +1 -38 lines
Log Message:
indent

File Contents

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