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

File Contents

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