ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.1.1.1 (vendor branch)
Committed: Fri Feb 3 07:14:36 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: UPSTREAM
CVS Tags: UPSTREAM_2006_02_03
Changes since 1.1: +0 -0 lines
Log Message:
initial import

File Contents

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