ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/plugins.c
Revision: 1.3
Committed: Wed Feb 8 03:46:15 2006 UTC (18 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.2: +2 -2 lines
Log Message:
*** empty log message ***

File Contents

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