ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.12
Committed: Sun Sep 10 15:59:57 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.11: +3311 -2843 lines
Log Message:
indent

File Contents

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