ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.12
Committed: Sat Jul 15 11:57:02 2006 UTC (17 years, 11 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: difficulty_fix_merge_060810_2300
Branch point for: difficulty_fix
Changes since 1.11: +29 -2 lines
Log Message:
finally checked in the 3 plugin events that were still on my
source tree.

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