ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.36
Committed: Mon Dec 25 14:54:44 2006 UTC (17 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.35: +2 -15 lines
Log Message:
the big rename

File Contents

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