ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.6
Committed: Mon Mar 6 22:59:26 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.5: +24 -0 lines
Log Message:
*** empty log message ***

File Contents

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