ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.C
Revision: 1.43
Committed: Thu Mar 1 12:28:16 2007 UTC (17 years, 4 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_0
Changes since 1.42: +0 -35 lines
Log Message:
nano-cleanups

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 removed object.
128 *
129 * @param op the object about to be removed from its environment; it must still
130 * be present in its environment
131 */
132 static void
133 send_removed_object (object *op)
134 {
135 object *tmp;
136
137 if (op->env == NULL)
138 {
139 /* no action necessary: remove_ob() notifies the client */
140 return;
141 }
142
143 tmp = op->in_player ();
144 if (!tmp)
145 {
146 for_all_players (pl)
147 if (pl->ob->container == op->env)
148 {
149 tmp = pl->ob;
150 break;
151 }
152 }
153
154 if (tmp)
155 esrv_del_item (tmp->contr, op->count);
156 }
157
158 extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr);
159 extern "C" void *cfperl_getPluginProperty (int *type, ...);
160 extern "C" int cfperl_postInitPlugin ();
161 extern "C" int cfperl_closePlugin ();
162
163 // this is a temporary hack till the old plugin stuff is removed
164 int
165 plugins_init_perl ()
166 {
167 f_plug_init initfunc;
168 f_plug_api propfunc;
169 f_plug_postinit postfunc;
170 f_plug_postinit closefunc;
171 int i;
172 crossfire_plugin *cp;
173 crossfire_plugin *ccp;
174
175 initfunc = (f_plug_init) cfperl_initPlugin;
176 propfunc = (f_plug_api) cfperl_getPluginProperty;
177 postfunc = (f_plug_postinit) cfperl_postInitPlugin;
178 closefunc = (f_plug_postinit) cfperl_closePlugin;
179 i = initfunc ("2.0", cfapi_get_hooks);
180 cp = (crossfire_plugin *) malloc (sizeof (crossfire_plugin));
181 for (i = 0; i < NR_EVENTS; i++)
182 cp->gevent[i] = NULL;
183 cp->eventfunc = 0;
184 cp->propfunc = propfunc;
185 cp->closefunc = closefunc;
186 cp->libptr = 0;
187 strcpy (cp->id, (const char *) propfunc (&i, "Identification"));
188 strcpy (cp->fullname, (const char *) propfunc (&i, "FullName"));
189 cp->next = NULL;
190 cp->prev = NULL;
191 if (plugins_list == NULL)
192 {
193 plugins_list = cp;
194 }
195 else
196 {
197 for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next)
198 ;
199 ccp->next = cp;
200 cp->prev = ccp;
201 }
202 postfunc ();
203 plugin_number++;
204 return 0;
205 }
206
207 int
208 plugins_init_plugin (const char *libfile)
209 {
210 return 0;
211
212 LIBPTRTYPE ptr;
213 f_plug_init initfunc;
214 f_plug_api propfunc;
215 f_plug_api eventfunc;
216 f_plug_postinit postfunc;
217 f_plug_postinit closefunc;
218 int i;
219 crossfire_plugin *cp;
220 crossfire_plugin *ccp;
221
222 /* Open the plugin lib and load the required functions */
223 ptr = plugins_dlopen (libfile);
224 if (ptr == NULL)
225 {
226 LOG (llevError, "Error trying to load %s: %s\n", libfile, plugins_dlerror ());
227 return -1;
228 }
229 initfunc = (f_plug_init) plugins_dlsym (ptr, "initPlugin");
230 if (initfunc == NULL)
231 {
232 LOG (llevError, "Plugin error while requesting %s.initPlugin: %s\n", libfile, plugins_dlerror ());
233 plugins_dlclose (ptr);
234 return -1;
235 }
236 propfunc = (f_plug_api) plugins_dlsym (ptr, "getPluginProperty");
237 if (propfunc == NULL)
238 {
239 LOG (llevError, "Plugin error while requesting %s.getPluginProperty: %s\n", libfile, plugins_dlerror ());
240 plugins_dlclose (ptr);
241 return -1;
242 }
243 eventfunc = (f_plug_api) plugins_dlsym (ptr, "eventListener");
244 if (eventfunc == NULL)
245 {
246 LOG (llevError, "Plugin error while requesting %s.eventListener: %s\n", libfile, plugins_dlerror ());
247 plugins_dlclose (ptr);
248 return -1;
249 }
250 postfunc = (f_plug_postinit) plugins_dlsym (ptr, "postInitPlugin");
251 if (postfunc == NULL)
252 {
253 LOG (llevError, "Plugin error while requesting %s.postInitPlugin: %s\n", libfile, plugins_dlerror ());
254 plugins_dlclose (ptr);
255 return -1;
256 }
257 closefunc = (f_plug_postinit) plugins_dlsym (ptr, "closePlugin");
258 if (postfunc == NULL)
259 {
260 LOG (llevError, "Plugin error while requesting %s.closePlugin: %s\n", libfile, plugins_dlerror ());
261 plugins_dlclose (ptr);
262 return -1;
263 }
264 i = initfunc ("2.0", cfapi_get_hooks);
265 cp = (crossfire_plugin *) malloc (sizeof (crossfire_plugin));
266 for (i = 0; i < NR_EVENTS; i++)
267 cp->gevent[i] = NULL;
268 cp->eventfunc = eventfunc;
269 cp->propfunc = propfunc;
270 cp->closefunc = closefunc;
271 cp->libptr = ptr;
272 strcpy (cp->id, (const char *) propfunc (&i, "Identification"));
273 strcpy (cp->fullname, (const char *) propfunc (&i, "FullName"));
274 cp->next = NULL;
275 cp->prev = NULL;
276 if (plugins_list == NULL)
277 {
278 plugins_list = cp;
279 }
280 else
281 {
282 for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next)
283 ;
284 ccp->next = cp;
285 cp->prev = ccp;
286 }
287 postfunc ();
288 plugin_number++;
289 return 0;
290 }
291
292 void *
293 cfapi_get_hooks (int *type, ...)
294 {
295 va_list args;
296 int request_type;
297 char *buf;
298 int fid;
299 f_plug_api rv;
300 int i;
301
302 va_start (args, type);
303 request_type = va_arg (args, int);
304
305 if (request_type == 0)
306 { /* By nr */
307 fid = va_arg (args, int);
308
309 if (fid < 0 || fid >= NR_OF_HOOKS)
310 {
311 rv = NULL;
312 *type = CFAPI_NONE;
313 }
314 else
315 {
316 rv = plug_hooks[fid].func;
317 *type = CFAPI_FUNC;
318 }
319 }
320 else
321 { /* by name */
322 buf = va_arg (args, char *);
323
324 rv = NULL;
325 for (i = 0; i < NR_OF_HOOKS; i++)
326 {
327 if (!strcmp (buf, plug_hooks[i].fname))
328 {
329 rv = plug_hooks[i].func;
330 *type = CFAPI_FUNC;
331 break;
332 }
333 }
334 if (rv == NULL)
335 {
336 *type = CFAPI_NONE;
337 }
338 }
339 va_end (args);
340 return (void *) rv;
341 }
342
343 int
344 plugins_remove_plugin (const char *id)
345 {
346 crossfire_plugin *cp;
347
348 if (plugins_list == NULL)
349 return -1;
350
351 for (cp = plugins_list; cp != NULL; cp = cp->next)
352 {
353 if (!strcmp (id, cp->id) && cp->libptr)
354 {
355 crossfire_plugin *n;
356 crossfire_plugin *p;
357
358 n = cp->next;
359 p = cp->prev;
360 plugins_dlclose (cp->libptr);
361 if (n != NULL)
362 {
363 if (p != NULL)
364 {
365 n->prev = p;
366 p->next = n;
367 }
368 else
369 {
370 n->prev = NULL;
371 plugins_list = n;
372 }
373 }
374 else
375 {
376 if (p != NULL)
377 p->next = NULL;
378 else
379 plugins_list = NULL;
380 }
381 free (cp);
382 plugin_number--;
383 return 0;
384 }
385 }
386 return -1;
387 }
388
389 crossfire_plugin *
390 plugins_find_plugin (const char *id)
391 {
392 crossfire_plugin *cp;
393
394 if (plugins_list == NULL)
395 return NULL;
396
397 for (cp = plugins_list; cp != NULL; cp = cp->next)
398 {
399 if (!strcmp (id, cp->id))
400 {
401 return cp;
402 }
403 }
404 return NULL;
405 }
406
407 /*****************************************************************************/
408
409 /* Displays a list of loaded plugins (keystrings and description) in the */
410
411 /* game log window. */
412
413 /*****************************************************************************/
414 void
415 plugins_display_list (object *op)
416 {
417 crossfire_plugin *cp;
418
419 new_draw_info (NDI_UNIQUE, 0, op, "List of loaded plugins:");
420 new_draw_info (NDI_UNIQUE, 0, op, "-----------------------");
421
422 if (plugins_list == NULL)
423 return;
424
425 for (cp = plugins_list; cp != NULL; cp = cp->next)
426 {
427 new_draw_info_format (NDI_UNIQUE, 0, op, "%s, %s", cp->id, cp->fullname);
428 }
429 }
430
431 /* SYSTEM-RELATED HOOKS */
432
433 void *
434 cfapi_system_find_animation (int *type, ...)
435 {
436 va_list args;
437 static int rv;
438 char *anim;
439
440 va_start (args, type);
441 anim = va_arg (args, char *);
442
443 va_end (args);
444
445 rv = find_animation (anim);
446 *type = CFAPI_INT;
447 return &rv;
448 }
449
450 void *
451 cfapi_system_strdup (int *type, ...)
452 {
453 va_list args;
454 char *txt;
455
456 va_start (args, type);
457 txt = va_arg (args, char *);
458
459 va_end (args);
460 *type = CFAPI_STRING;
461 return strdup (txt);
462 }
463
464 void *
465 cfapi_system_register_global_event (int *type, ...)
466 {
467 va_list args;
468 int eventcode;
469 char *pname;
470 f_plug_api hook;
471 crossfire_plugin *cp;
472
473 va_start (args, type);
474 eventcode = va_arg (args, int);
475 pname = va_arg (args, char *);
476
477 hook = va_arg (args, f_plug_api);
478
479 va_end (args);
480 cp = plugins_find_plugin (pname);
481 cp->gevent[eventcode] = hook;
482 return NULL;
483 }
484
485 void *
486 cfapi_system_unregister_global_event (int *type, ...)
487 {
488 va_list args;
489 int eventcode;
490 char *pname;
491 crossfire_plugin *cp;
492
493 va_start (args, type);
494 eventcode = va_arg (args, int);
495 pname = va_arg (args, char *);
496
497 cp = plugins_find_plugin (pname);
498 cp->gevent[eventcode] = NULL;
499
500 va_end (args);
501 return NULL;
502 }
503
504 void *
505 cfapi_system_check_path (int *type, ...)
506 {
507 va_list args;
508 static int rv;
509 char *name;
510 int prepend_dir;
511
512 va_start (args, type);
513
514 name = va_arg (args, char *);
515 prepend_dir = va_arg (args, int);
516
517 rv = check_path (name, prepend_dir);
518
519 va_end (args);
520 *type = CFAPI_INT;
521 return &rv;
522 }
523
524 void *
525 cfapi_system_directory (int *type, ...)
526 {
527 va_list args;
528 int dirtype;
529
530 va_start (args, type);
531
532 dirtype = va_arg (args, int);
533
534 va_end (args);
535
536 *type = CFAPI_STRING;
537
538 switch (dirtype)
539 {
540 case 0:
541 return settings.mapdir;
542 break;
543
544 case 1:
545 return settings.uniquedir;
546 break;
547
548 case 2:
549 return settings.tmpdir;
550 break;
551
552 case 3:
553 return settings.confdir;
554 break;
555
556 case 4:
557 return settings.localdir;
558 break;
559
560 case 5:
561 return settings.playerdir;
562 break;
563
564 case 6:
565 return settings.datadir;
566 break;
567 }
568
569 *type = CFAPI_NONE;
570 return NULL;
571 }
572
573
574 /* MAP RELATED HOOKS */
575
576 void *
577 cfapi_map_get_map (int *type, ...)
578 {
579 abort ();
580 }
581
582 void *
583 cfapi_map_has_been_loaded (int *type, ...)
584 {
585 abort ();
586 }
587
588 void *
589 cfapi_map_create_path (int *type, ...)
590 {
591 abort ();
592 }
593
594 void *
595 cfapi_map_get_map_property (int *type, ...)
596 {
597 abort ();
598 }
599
600 void *
601 cfapi_map_set_map_property (int *type, ...)
602 {
603 abort ();
604 }
605
606 void *
607 cfapi_map_out_of_map (int *type, ...)
608 {
609 abort ();
610 }
611
612 void *
613 cfapi_map_update_position (int *type, ...)
614 {
615 va_list args;
616 maptile *map;
617 int x, y;
618
619 va_start (args, type);
620
621 map = va_arg (args, maptile *);
622 x = va_arg (args, int);
623 y = va_arg (args, int);
624
625 map->at (x, y).flags_ &= ~P_UPTODATE;
626
627 va_end (args);
628 *type = CFAPI_NONE;
629 return NULL;
630 }
631
632 void *
633 cfapi_map_delete_map (int *type, ...)
634 {
635 abort ();
636 }
637
638 void *
639 cfapi_map_message (int *type, ...)
640 {
641 va_list args;
642 maptile *map;
643 char *string;
644 int color;
645
646 va_start (args, type);
647 map = va_arg (args, maptile *);
648 string = va_arg (args, char *);
649 color = va_arg (args, int);
650
651 va_end (args);
652
653 new_info_map (color, map, string);
654 *type = CFAPI_NONE;
655 return NULL;
656 }
657
658 void *
659 cfapi_map_get_object_at (int *type, ...)
660 {
661 va_list args;
662 maptile *map;
663 int x, y;
664 object *rv;
665
666 va_start (args, type);
667 map = va_arg (args, maptile *);
668 x = va_arg (args, int);
669 y = va_arg (args, int);
670
671 va_end (args);
672
673 rv = GET_MAP_OB (map, x, y);
674 *type = CFAPI_POBJECT;
675 return rv;
676 }
677
678 void *
679 cfapi_map_get_flags (int *type, ...)
680 {
681 va_list args;
682 sint16 x, y;
683 sint16 *nx, *ny;
684 static maptile *map;
685 maptile **newmap;
686 static int rv;
687
688 va_start (args, type);
689
690 map = va_arg (args, maptile *);
691 newmap = va_arg (args, maptile **);
692 x = va_arg (args, int);
693 y = va_arg (args, int);
694
695 nx = va_arg (args, sint16 *);
696 ny = va_arg (args, sint16 *);
697 va_end (args);
698
699 rv = get_map_flags (map, newmap, x, y, nx, ny);
700
701 *type = CFAPI_INT;
702 return &rv;
703 }
704
705 void *
706 cfapi_map_present_arch_by_name (int *type, ...)
707 {
708 va_list args;
709 object *rv;
710 int x, y;
711 maptile *map;
712 char *msg;
713
714 va_start (args, type);
715
716 msg = va_arg (args, char *);
717 map = va_arg (args, maptile *);
718 x = va_arg (args, int);
719 y = va_arg (args, int);
720
721 va_end (args);
722
723 rv = present_arch (archetype::find (msg), map, x, y);
724 *type = CFAPI_POBJECT;
725 return rv;
726 }
727
728 /* OBJECT-RELATED HOOKS */
729
730 void *
731 cfapi_object_move (int *type, ...)
732 {
733 va_list args;
734 int kind;
735 object *op;
736 object *activator;
737 player *pl;
738 int direction;
739 static int rv = 0;
740
741 va_start (args, type);
742 kind = va_arg (args, int);
743
744 switch (kind)
745 {
746 case 0:
747 op = va_arg (args, object *);
748 direction = va_arg (args, int);
749 activator = va_arg (args, object *);
750
751 va_end (args);
752 rv = move_ob (op, direction, activator);
753 break;
754
755 case 1:
756 pl = va_arg (args, player *);
757 direction = va_arg (args, int);
758
759 va_end (args);
760 rv = move_player (pl->ob, direction);
761 break;
762 }
763 *type = CFAPI_INT;
764 return &rv;
765 }
766
767 void *
768 cfapi_object_get_key (int *type, ...)
769 {
770 va_list args;
771 char *rv;
772 char *keyname;
773 object *op;
774
775 va_start (args, type);
776 op = va_arg (args, object *);
777 keyname = va_arg (args, char *);
778
779 va_end (args);
780
781 rv = (char *) get_ob_key_value (op, keyname);
782 *type = CFAPI_STRING;
783 return rv;
784 }
785
786 void *
787 cfapi_object_set_key (int *type, ...)
788 {
789 va_list args;
790 char *keyname;
791 char *value;
792 object *op;
793
794 va_start (args, type);
795 op = va_arg (args, object *);
796 keyname = va_arg (args, char *);
797 value = va_arg (args, char *);
798
799 va_end (args);
800
801 set_ob_key_value (op, keyname, value, 0);
802 *type = CFAPI_NONE;
803 return NULL;
804 }
805
806 void *
807 cfapi_object_get_property (int *type, ...)
808 {
809 abort ();
810 }
811
812 void *
813 cfapi_object_set_property (int *type, ...)
814 {
815 abort ();
816 }
817
818 void *
819 cfapi_object_apply_below (int *type, ...)
820 {
821 va_list args;
822 object *applier;
823
824 va_start (args, type);
825
826 applier = va_arg (args, object *);
827
828 va_end (args);
829
830 player_apply_below (applier);
831 *type = CFAPI_NONE;
832 return NULL;
833 }
834
835 void *
836 cfapi_object_apply (int *type, ...)
837 {
838 va_list args;
839 object *applied;
840 object *applier;
841 int aflags;
842 static int rv;
843
844 va_start (args, type);
845
846 applied = va_arg (args, object *);
847 applier = va_arg (args, object *);
848 aflags = va_arg (args, int);
849
850 va_end (args);
851
852 *type = CFAPI_INT;
853 rv = manual_apply (applier, applied, aflags);
854 return &rv;
855 }
856
857 void *
858 cfapi_object_identify (int *type, ...)
859 {
860 va_list args;
861 object *op;
862
863 va_start (args, type);
864
865 op = va_arg (args, object *);
866
867 va_end (args);
868
869 identify (op);
870 *type = CFAPI_NONE;
871 return NULL;
872 }
873
874 void *
875 cfapi_object_describe (int *type, ...)
876 {
877 va_list args;
878 object *op;
879 object *owner;
880
881 va_start (args, type);
882
883 op = va_arg (args, object *);
884 owner = va_arg (args, object *);
885
886 va_end (args);
887
888 *type = CFAPI_STRING;
889 return describe_item (op, owner);
890 }
891
892 void *
893 cfapi_object_drain (int *type, ...)
894 {
895 abort ();
896 }
897
898 void *
899 cfapi_object_fix (int *type, ...)
900 {
901 va_list args;
902 object *op;
903
904 va_start (args, type);
905
906 op = va_arg (args, object *);
907
908 va_end (args);
909
910 op->update_stats ();
911
912 *type = CFAPI_NONE;
913 return NULL;
914 }
915
916 void *
917 cfapi_object_give_skill (int *type, ...)
918 {
919 va_list args;
920
921 object *op;
922 char *skillname;
923
924 va_start (args, type);
925
926 op = va_arg (args, object *);
927 skillname = va_arg (args, char *);
928
929 va_end (args);
930
931 *type = CFAPI_POBJECT;
932 return give_skill_by_name (op, skillname);
933 }
934
935 void *
936 cfapi_object_transmute (int *type, ...)
937 {
938 va_list args;
939
940 object *op;
941 object *chg;
942
943 va_start (args, type);
944
945 op = va_arg (args, object *);
946 chg = va_arg (args, object *);
947
948 va_end (args);
949
950 transmute_materialname (op, chg);
951 *type = CFAPI_NONE;
952 return NULL;
953 }
954
955 void *
956 cfapi_object_remove (int *type, ...)
957 {
958 va_list args;
959 object *op;
960
961 va_start (args, type);
962
963 op = va_arg (args, object *);
964
965 va_end (args);
966
967 send_removed_object (op);
968 op->remove ();
969 *type = CFAPI_NONE;
970 return NULL;
971 }
972
973 void *
974 cfapi_object_delete (int *type, ...)
975 {
976 va_list args;
977 object *op;
978
979 va_start (args, type);
980
981 op = va_arg (args, object *);
982
983 va_end (args);
984
985 op->destroy ();
986
987 *type = CFAPI_NONE;
988 return NULL;
989 }
990
991 void *
992 cfapi_object_clone (int *type, ...)
993 {
994 va_list args;
995 object *op;
996 int kind;
997
998 va_start (args, type);
999
1000 op = va_arg (args, object *);
1001 kind = va_arg (args, int);
1002
1003 va_end (args);
1004
1005 if (kind == 0)
1006 {
1007 *type = CFAPI_POBJECT;
1008 return object_create_clone (op);
1009 }
1010 else
1011 {
1012 object *tmp = op->clone ();
1013 *type = CFAPI_POBJECT;
1014 return tmp;
1015 }
1016 }
1017 void *
1018 cfapi_object_find (int *type, ...)
1019 {
1020 va_list args;
1021 int ftype;
1022 void *rv;
1023 int ival;
1024 int ival2;
1025 char *sval;
1026 object *op;
1027
1028 va_start (args, type);
1029
1030 *type = CFAPI_POBJECT;
1031 ftype = va_arg (args, int);
1032
1033 switch (ftype)
1034 {
1035 case 0:
1036 ival = va_arg (args, int);
1037
1038 rv = find_object (ival);
1039 break;
1040
1041 case 1:
1042 sval = va_arg (args, char *);
1043
1044 rv = find_object_name (sval);
1045 break;
1046
1047 case 2:
1048 op = va_arg (args, object *);
1049 ival = va_arg (args, int);
1050 ival2 = va_arg (args, int);
1051
1052 rv = find_obj_by_type_subtype (op, ival, ival2);
1053 break;
1054
1055 case 3:
1056 op = va_arg (args, object *);
1057
1058 rv = op->in_player ();
1059 break;
1060
1061 default:
1062 rv = NULL;
1063 *type = CFAPI_NONE;
1064 break;
1065 }
1066
1067 va_end (args);
1068
1069 return rv;
1070 }
1071
1072 void *
1073 cfapi_object_create (int *type, ...)
1074 {
1075 va_list args;
1076 int ival;
1077
1078 va_start (args, type);
1079 ival = va_arg (args, int);
1080
1081 *type = CFAPI_POBJECT;
1082 switch (ival)
1083 {
1084 case 0:
1085 va_end (args);
1086 return object::create ();
1087 break;
1088
1089 case 1: /* Named object. Nearly the old plugin behavior, but we don't add artifact suffixes */
1090 {
1091 char *sval;
1092 object *op;
1093 sval = va_arg (args, char *);
1094
1095 op = get_archetype_by_object_name (sval);
1096
1097 if (strncmp (query_name (op), ARCH_SINGULARITY, ARCH_SINGULARITY_LEN) == 0)
1098 {
1099 op->destroy ();
1100 /* Try with archetype names... */
1101 op = get_archetype (sval);
1102 if (strncmp (query_name (op), ARCH_SINGULARITY, ARCH_SINGULARITY_LEN) == 0)
1103 {
1104 op->destroy ();
1105 *type = CFAPI_NONE;
1106 va_end (args);
1107 return NULL;
1108 }
1109 }
1110 va_end (args);
1111 return op;
1112 }
1113 break;
1114
1115 default:
1116 *type = CFAPI_NONE;
1117 va_end (args);
1118 return NULL;
1119 break;
1120 }
1121 }
1122 void *
1123 cfapi_object_insert (int *type, ...)
1124 {
1125 va_list args;
1126 object *op;
1127 object *orig;
1128 maptile *map;
1129 int flag, x, y;
1130 int itype;
1131 char *arch_string;
1132 void *rv = NULL;
1133
1134 va_start (args, type);
1135
1136 op = va_arg (args, object *);
1137 itype = va_arg (args, int);
1138
1139 switch (itype)
1140 {
1141 case 0:
1142 map = va_arg (args, maptile *);
1143 orig = va_arg (args, object *);
1144 flag = va_arg (args, int);
1145 x = va_arg (args, int);
1146 y = va_arg (args, int);
1147
1148 rv = insert_ob_in_map_at (op, map, orig, flag, x, y);
1149 *type = CFAPI_POBJECT;
1150 break;
1151
1152 case 1:
1153 map = va_arg (args, maptile *);
1154 orig = va_arg (args, object *);
1155 flag = va_arg (args, int);
1156
1157 rv = insert_ob_in_map (op, map, orig, flag);
1158 *type = CFAPI_POBJECT;
1159 break;
1160
1161 case 2:
1162 arch_string = va_arg (args, char *);
1163
1164 replace_insert_ob_in_map (arch_string, op);
1165 *type = CFAPI_NONE;
1166 break;
1167
1168 case 3:
1169 orig = va_arg (args, object *);
1170
1171 rv = insert_ob_in_ob (op, orig);
1172 if (orig->type == PLAYER)
1173 {
1174 esrv_send_item (orig, op);
1175 }
1176 *type = CFAPI_POBJECT;
1177 break;
1178 }
1179
1180 va_end (args);
1181
1182 return rv;
1183 }
1184
1185 void *
1186 cfapi_object_split (int *type, ...)
1187 {
1188 va_list args;
1189
1190 int nr;
1191 object *op;
1192
1193 va_start (args, type);
1194
1195 op = va_arg (args, object *);
1196 nr = va_arg (args, int);
1197
1198 va_end (args);
1199 *type = CFAPI_POBJECT;
1200 return get_split_ob (op, nr);
1201 }
1202
1203 void *
1204 cfapi_object_merge (int *type, ...)
1205 {
1206 va_list args;
1207 object *op;
1208 object *op2;
1209
1210 va_start (args, type);
1211
1212 op = va_arg (args, object *);
1213 op2 = va_arg (args, object *);
1214
1215 va_end (args);
1216
1217
1218 *type = CFAPI_POBJECT;
1219 return merge_ob (op, op2);
1220 }
1221
1222 void *
1223 cfapi_object_distance (int *type, ...)
1224 {
1225 va_list args;
1226 static int rv;
1227 object *op;
1228 object *op2;
1229
1230 va_start (args, type);
1231
1232 op = va_arg (args, object *);
1233 op2 = va_arg (args, object *);
1234
1235 va_end (args);
1236
1237 *type = CFAPI_INT;
1238 rv = distance (op, op2);
1239 return &rv;
1240 }
1241
1242 void *
1243 cfapi_object_update (int *type, ...)
1244 {
1245 va_list args;
1246 int action;
1247 object *op;
1248
1249 va_start (args, type);
1250
1251 op = va_arg (args, object *);
1252 action = va_arg (args, int);
1253
1254 va_end (args);
1255
1256 update_object (op, action);
1257 *type = CFAPI_NONE;
1258 return NULL;
1259 }
1260
1261 void *
1262 cfapi_object_clear (int *type, ...)
1263 {
1264 abort ();
1265 }
1266
1267 void *
1268 cfapi_object_reset (int *type, ...)
1269 {
1270 abort ();
1271 }
1272
1273 void *
1274 cfapi_object_check_inventory (int *type, ...)
1275 {
1276 va_list args;
1277 object *op;
1278 object *op2;
1279 int checktype;
1280 object *ret = NULL;
1281
1282 va_start (args, type);
1283
1284 op = va_arg (args, object *);
1285 op2 = va_arg (args, object *);
1286 checktype = va_arg (args, int);
1287
1288 if (checktype == 0)
1289 {
1290 check_inv (op, op2);
1291 *type = CFAPI_NONE;
1292 }
1293 else
1294 {
1295 ret = check_inv_recursive (op, op2);
1296 *type = CFAPI_POBJECT;
1297 }
1298
1299 va_end (args);
1300
1301 return ret;
1302 }
1303
1304 void *
1305 cfapi_object_clean_object (int *type, ...)
1306 {
1307 abort ();
1308 }
1309
1310 void *
1311 cfapi_object_on_same_map (int *type, ...)
1312 {
1313 va_list args;
1314 static int rv;
1315 object *op1;
1316 object *op2;
1317
1318 va_start (args, type);
1319 op1 = va_arg (args, object *);
1320 op2 = va_arg (args, object *);
1321
1322 rv = on_same_map (op1, op2);
1323 va_end (args);
1324
1325 *type = CFAPI_INT;
1326 return &rv;
1327 }
1328
1329 void *
1330 cfapi_object_spring_trap (int *type, ...)
1331 {
1332 object *trap;
1333 object *victim;
1334 va_list args;
1335
1336 va_start (args, type);
1337 trap = va_arg (args, object *);
1338 victim = va_arg (args, object *);
1339
1340 va_end (args);
1341
1342 spring_trap (trap, victim);
1343 *type = CFAPI_NONE;
1344 return NULL;
1345 }
1346
1347 void *
1348 cfapi_object_check_trigger (int *type, ...)
1349 {
1350 object *op;
1351 object *cause;
1352 va_list args;
1353 static int rv;
1354
1355 va_start (args, type);
1356 op = va_arg (args, object *);
1357 cause = va_arg (args, object *);
1358
1359 va_end (args);
1360
1361 rv = check_trigger (op, cause);
1362 *type = CFAPI_INT;
1363 return &rv;
1364 }
1365
1366 void *
1367 cfapi_object_query_cost (int *type, ...)
1368 {
1369 object *op;
1370 object *who;
1371 int flags;
1372 va_list args;
1373 static int rv;
1374
1375 va_start (args, type);
1376 op = va_arg (args, object *);
1377 who = va_arg (args, object *);
1378 flags = va_arg (args, int);
1379
1380 va_end (args);
1381
1382 rv = query_cost (op, who, flags);
1383 *type = CFAPI_INT;
1384 return &rv;
1385 }
1386
1387 void *
1388 cfapi_object_query_money (int *type, ...)
1389 {
1390 object *op;
1391 va_list args;
1392 static int rv;
1393
1394 va_start (args, type);
1395 op = va_arg (args, object *);
1396
1397 va_end (args);
1398
1399 rv = query_money (op);
1400 *type = CFAPI_INT;
1401 return &rv;
1402 }
1403
1404 void *
1405 cfapi_object_cast (int *type, ...)
1406 {
1407 object *op;
1408 object *sp;
1409 int dir;
1410 char *str;
1411 object *caster;
1412 va_list args;
1413 static int rv;
1414
1415 va_start (args, type);
1416 op = va_arg (args, object *);
1417 caster = va_arg (args, object *);
1418 dir = va_arg (args, int);
1419 sp = va_arg (args, object *);
1420 str = va_arg (args, char *);
1421
1422 va_end (args);
1423 rv = cast_spell (op, caster, dir, sp, str);
1424 *type = CFAPI_INT;
1425 return &rv;
1426 }
1427
1428 void *
1429 cfapi_object_learn_spell (int *type, ...)
1430 {
1431 object *op;
1432 object *sp;
1433 int prayer;
1434 va_list args;
1435
1436 va_start (args, type);
1437 op = va_arg (args, object *);
1438 sp = va_arg (args, object *);
1439 prayer = va_arg (args, int);
1440
1441 va_end (args);
1442 do_learn_spell (op, sp, prayer);
1443 *type = CFAPI_NONE;
1444 return NULL;
1445 }
1446
1447 void *
1448 cfapi_object_forget_spell (int *type, ...)
1449 {
1450 object *op;
1451 object *sp;
1452 va_list args;
1453
1454 va_start (args, type);
1455 op = va_arg (args, object *);
1456 sp = va_arg (args, object *);
1457
1458 va_end (args);
1459 do_forget_spell (op, query_name (sp));
1460 *type = CFAPI_NONE;
1461 return NULL;
1462 }
1463
1464 void *
1465 cfapi_object_check_spell (int *type, ...)
1466 {
1467 object *op;
1468 char *spellname;
1469 va_list args;
1470 object *rv;
1471
1472 va_start (args, type);
1473 op = va_arg (args, object *);
1474 spellname = va_arg (args, char *);
1475
1476 va_end (args);
1477 rv = check_spell_known (op, spellname);
1478 *type = CFAPI_POBJECT;
1479 return rv;
1480 }
1481
1482 void *
1483 cfapi_object_pay_amount (int *type, ...)
1484 {
1485 object *op;
1486 uint64 amount;
1487 va_list args;
1488 static int rv;
1489
1490 va_start (args, type);
1491 op = va_arg (args, object *);
1492
1493 amount = va_arg (args, uint64);
1494 va_end (args);
1495
1496 rv = pay_for_amount (amount, op);
1497 *type = CFAPI_INT;
1498 return &rv;
1499 }
1500
1501 void *
1502 cfapi_object_pay_item (int *type, ...)
1503 {
1504 object *op;
1505 object *tobuy;
1506
1507 va_list args;
1508 static int rv;
1509
1510 va_start (args, type);
1511 tobuy = va_arg (args, object *);
1512 op = va_arg (args, object *);
1513
1514 va_end (args);
1515
1516 rv = pay_for_item (tobuy, op);
1517 *type = CFAPI_INT;
1518 return &rv;
1519 }
1520
1521 void *
1522 cfapi_object_transfer (int *type, ...)
1523 {
1524 object *op;
1525 object *originator;
1526 int x, y, randompos, ttype;
1527 va_list args;
1528 static int rv = 0;
1529 maptile *map;
1530
1531 va_start (args, type);
1532 op = va_arg (args, object *);
1533 ttype = va_arg (args, int);
1534
1535 switch (ttype)
1536 {
1537 case 0:
1538 x = va_arg (args, int);
1539 y = va_arg (args, int);
1540 randompos = va_arg (args, int);
1541 originator = va_arg (args, object *);
1542
1543 va_end (args);
1544
1545 rv = transfer_ob (op, x, y, randompos, originator);
1546 *type = CFAPI_INT;
1547 return &rv;
1548 break;
1549
1550 case 1:
1551 x = va_arg (args, int);
1552 y = va_arg (args, int);
1553 map = va_arg (args, maptile *);
1554
1555 va_end (args);
1556 if (x < 0 || y < 0)
1557 {
1558 x = map->enter_x;
1559 y = map->enter_y;
1560 }
1561
1562 /*
1563 originator = object::create();
1564 EXIT_PATH(originator) = map->path;
1565 EXIT_X(originator) = x;
1566 EXIT_Y(originator) = y;
1567 printf("B Transfer: X=%d, Y=%d, OP=%s\n", x, y, op->name);*/
1568 /*enter_exit(op, originator); */
1569 insert_ob_in_map_at (op, map, NULL, 0, x, y);
1570 /*printf("A Transfer: X=%d, Y=%d, MAP=%s\n", x, y, op->map->name);
1571 originator->destroy ();
1572 */
1573 *type = CFAPI_INT;
1574 return &rv;
1575 break;
1576
1577 default:
1578 *type = CFAPI_NONE;
1579 return NULL;
1580 break;
1581 }
1582 }
1583
1584 void *
1585 cfapi_object_find_archetype_inside (int *type, ...)
1586 {
1587 object *op;
1588 int critera;
1589 char *str;
1590 va_list args;
1591 object *rv;
1592
1593 *type = CFAPI_POBJECT;
1594 va_start (args, type);
1595 op = va_arg (args, object *);
1596 critera = va_arg (args, int);
1597
1598 switch (critera)
1599 {
1600 case 0: /* By name, either exact or from query_name */
1601 str = va_arg (args, char *);
1602
1603 rv = present_arch_in_ob (archetype::find (str), op);
1604 if (rv == NULL)
1605 {
1606 object *tmp;
1607
1608 /* Search by query_name instead */
1609 for (tmp = op->inv; tmp; tmp = tmp->below)
1610 {
1611 if (!strncmp (query_name (tmp), str, strlen (str)))
1612 rv = tmp;
1613 if (!strncmp (tmp->name, str, strlen (str)))
1614 rv = tmp;
1615 if (rv != NULL)
1616 break;
1617 }
1618 }
1619 break;
1620
1621 default:
1622 rv = NULL;
1623 break;
1624 }
1625 va_end (args);
1626
1627 if (rv == NULL)
1628 {
1629 *type = CFAPI_NONE;
1630 }
1631 return rv;
1632 }
1633
1634 void *
1635 cfapi_object_drop (int *type, ...)
1636 {
1637 object *op;
1638 object *author;
1639 va_list args;
1640
1641 va_start (args, type);
1642 op = va_arg (args, object *);
1643 author = va_arg (args, object *);
1644
1645 va_end (args);
1646
1647 if (QUERY_FLAG (op, FLAG_NO_DROP))
1648 return NULL;
1649 drop (author, op);
1650
1651 if (author->type == PLAYER)
1652 {
1653 author->contr->count = 0;
1654 author->contr->ns->floorbox_update ();
1655 }
1656
1657 *type = CFAPI_NONE;
1658 return NULL;
1659 }
1660
1661 void *
1662 cfapi_object_take (int *type, ...)
1663 {
1664 object *op;
1665 object *author;
1666 va_list args;
1667
1668 va_start (args, type);
1669 op = va_arg (args, object *);
1670 author = va_arg (args, object *);
1671
1672 va_end (args);
1673 pick_up (author, op);
1674
1675 *type = CFAPI_NONE;
1676 return NULL;
1677 }
1678
1679 void *
1680 cfapi_object_say (int *type, ...)
1681 {
1682 abort ();
1683 }
1684
1685 void *
1686 cfapi_object_speak (int *type, ...)
1687 {
1688 abort ();
1689 }
1690
1691 /* PLAYER SUBCLASS */
1692 void *
1693 cfapi_player_find (int *type, ...)
1694 {
1695 abort ();
1696 }
1697
1698 void *
1699 cfapi_player_message (int *type, ...)
1700 {
1701 va_list args;
1702 int flags;
1703 int pri;
1704 object *pl;
1705 char *buf;
1706
1707 va_start (args, type);
1708
1709 flags = va_arg (args, int);
1710 pri = va_arg (args, int);
1711 pl = va_arg (args, object *);
1712 buf = va_arg (args, char *);
1713
1714 va_end (args);
1715
1716 new_draw_info (flags, pri, pl, buf);
1717 *type = CFAPI_NONE;
1718 return NULL;
1719 }
1720
1721 void *
1722 cfapi_player_send_inventory (int *type, ...)
1723 {
1724 /* Currently a stub. Do we really need this anymore ? */
1725 *type = CFAPI_NONE;
1726 return NULL;
1727 }
1728
1729 void *
1730 cfapi_object_teleport (int *type, ...)
1731 {
1732 maptile *map;
1733 int x, y;
1734 object *who;
1735 static int result;
1736 va_list args;
1737
1738 va_start (args, type);
1739 who = va_arg (args, object *);
1740 map = va_arg (args, maptile *);
1741 x = va_arg (args, int);
1742 y = va_arg (args, int);
1743
1744 if (!out_of_map (map, x, y))
1745 {
1746 int k;
1747 object *tmp;
1748
1749 k = find_first_free_spot (who, map, x, y);
1750 if (k == -1)
1751 {
1752 result = 1;
1753 return &result;
1754 }
1755
1756 send_removed_object (who);
1757 who->remove ();
1758
1759 for (tmp = who; tmp != NULL; tmp = tmp->more)
1760 tmp->x = x + freearr_x[k] + (tmp->arch == NULL ? 0 : tmp->arch->clone.x),
1761 tmp->y = y + freearr_y[k] + (tmp->arch == NULL ? 0 : tmp->arch->clone.y);
1762
1763 insert_ob_in_map (who, map, NULL, 0);
1764 result = 0;
1765 }
1766
1767 return &result;
1768 }
1769
1770 void *
1771 cfapi_object_pickup (int *type, ...)
1772 {
1773 object *who;
1774 object *what;
1775 va_list args;
1776
1777 va_start (args, type);
1778 who = va_arg (args, object *);
1779 what = va_arg (args, object *);
1780
1781 va_end (args);
1782
1783 pick_up (who, what);
1784 *type = CFAPI_NONE;
1785 return NULL;
1786 }
1787
1788 /* Archetype-related functions */
1789 void *
1790 cfapi_archetype_get_first (int *type, ...)
1791 {
1792 va_list args;
1793
1794 va_start (args, type);
1795 va_end (args);
1796 *type = CFAPI_PARCH;
1797 return first_archetype;
1798 }
1799
1800 void *
1801 cfapi_archetype_get_property (int *type, ...)
1802 {
1803 archetype *arch;
1804 int prop;
1805 va_list args;
1806 void *rv;
1807
1808 va_start (args, type);
1809 arch = va_arg (args, archetype *);
1810 prop = va_arg (args, int);
1811
1812 switch (prop)
1813 {
1814 case CFAPI_ARCH_PROP_NAME:
1815 *type = CFAPI_STRING;
1816 rv = (void *) &arch->name;
1817 break;
1818
1819 case CFAPI_ARCH_PROP_NEXT:
1820 *type = CFAPI_PARCH;
1821 rv = arch->next;
1822 break;
1823
1824 case CFAPI_ARCH_PROP_HEAD:
1825 *type = CFAPI_PARCH;
1826 rv = arch->head;
1827 break;
1828
1829 case CFAPI_ARCH_PROP_MORE:
1830 *type = CFAPI_PARCH;
1831 rv = arch->more;
1832 break;
1833
1834 case CFAPI_ARCH_PROP_CLONE:
1835 *type = CFAPI_POBJECT;
1836 rv = &arch->clone;
1837 break;
1838
1839 default:
1840 *type = CFAPI_NONE;
1841 rv = NULL;
1842 break;
1843 }
1844 va_end (args);
1845 return rv;
1846 }
1847
1848 /* Party-related functions */
1849 void *
1850 cfapi_party_get_property (int *type, ...)
1851 {
1852 abort ();
1853 }
1854
1855 /* Regions-related functions */
1856 void *
1857 cfapi_region_get_property (int *type, ...)
1858 {
1859 abort ();
1860 }
1861
1862 /*****************************************************************************/
1863
1864 /* NEW PLUGIN STUFF ENDS HERE */
1865
1866 /*****************************************************************************/
1867
1868
1869 /*****************************************************************************/
1870
1871 /* Tries to find if a given command is handled by a plugin. */
1872
1873 /* Note that find_plugin_command is called *before* the internal commands are*/
1874
1875 /* checked, meaning that you can "overwrite" them. */
1876
1877 /*****************************************************************************/
1878 CommArray_s *
1879 find_plugin_command (char *cmd, object *op)
1880 {
1881 int i;
1882 crossfire_plugin *cp;
1883 CommArray_s *rtn_cmd;
1884
1885 if (plugins_list == NULL)
1886 return NULL;
1887
1888 for (cp = plugins_list; cp != NULL; cp = cp->next)
1889 {
1890 rtn_cmd = (CommArray_s *) cp->propfunc (&i, "command?", cmd);
1891 if (rtn_cmd)
1892 return rtn_cmd;
1893 }
1894 return NULL;
1895 }
1896
1897 /*****************************************************************************/
1898
1899 /* Plugins initialisation. Browses the plugins directory and call */
1900
1901 /* initOnePlugin for each file found. */
1902
1903 /* Returns 0 if at least one plugin was successfully loaded, -1 if not */
1904
1905 /*****************************************************************************/
1906 int
1907 initPlugins (void)
1908 {
1909 struct dirent *currentfile;
1910 DIR *plugdir;
1911 size_t l;
1912 char buf[MAX_BUF];
1913 char buf2[MAX_BUF];
1914 int result;
1915
1916 LOG (llevInfo, "Initialising plugins\n");
1917 strcpy (buf, LIBDIR);
1918 strcat (buf, "/plugins/");
1919 LOG (llevInfo, "Plugins directory is %s\n", buf);
1920
1921 plugins_init_perl ();
1922
1923 plugdir = opendir (buf);
1924 if (plugdir == NULL)
1925 return -1;
1926
1927 result = -1;
1928 while ((currentfile = readdir (plugdir)) != NULL)
1929 {
1930 l = strlen (currentfile->d_name);
1931 if (l > strlen (PLUGIN_SUFFIX))
1932 {
1933 if (strcmp (currentfile->d_name + l - strlen (PLUGIN_SUFFIX), PLUGIN_SUFFIX) == 0)
1934 {
1935 strcpy (buf2, buf);
1936 strcat (buf2, currentfile->d_name);
1937 LOG (llevInfo, " -> Loading plugin : %s\n", currentfile->d_name);
1938 if (plugins_init_plugin (buf2) == 0)
1939 result = 0;
1940 }
1941 }
1942 }
1943
1944 closedir (plugdir);
1945 return result;
1946 }