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

File Contents

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