ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.8
Committed: Thu Mar 16 21:08:20 2006 UTC (18 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.7: +11 -0 lines
Log Message:
allow perl to save/restore pelr data associated with players

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