ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.21
Committed: Tue Dec 12 21:39:57 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.20: +8 -8 lines
Log Message:
- more ooficiation
- removed now superfluous remove calls

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