Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 * static char *rcsid_plugins_c = 00003 * "$Id: plugins.c 11578 2009-02-23 22:02:27Z lalo $"; 00004 */ 00005 00006 /*****************************************************************************/ 00007 /* CrossFire, A Multiplayer game for X-windows */ 00008 /* */ 00009 /* Copyright (C) 2000-2006 Mark Wedel & Crossfire Development Team */ 00010 /* Copyright (C) 1992 Frank Tore Johansen */ 00011 /* */ 00012 /* This program is free software; you can redistribute it and/or modify */ 00013 /* it under the terms of the GNU General Public License as published by */ 00014 /* the Free Software Foundation; either version 2 of the License, or */ 00015 /* (at your option) any later version. */ 00016 /* */ 00017 /* This program is distributed in the hope that it will be useful, */ 00018 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 00019 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 00020 /* GNU General Public License for more details. */ 00021 /* */ 00022 /* You should have received a copy of the GNU General Public License */ 00023 /* along with this program; if not, write to the Free Software */ 00024 /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 00025 /* */ 00026 /* The authors can be reached via e-mail to crossfire-devel@real-time.com */ 00027 /*****************************************************************************/ 00028 /* This is the server-side plugin management part. */ 00029 /*****************************************************************************/ 00030 /* Original code by Yann Chachkoff (yann.chachkoff@mailandnews.com). */ 00031 /* Special thanks to: */ 00032 /* David Delbecq (david.delbecq@mailandnews.com); */ 00033 /* Joris Bontje (jbontje@suespammers.org); */ 00034 /* Philip Currlin (?); */ 00035 /*****************************************************************************/ 00036 00045 #if 0 00046 00047 #define PLUGIN_DEBUG 00048 #endif 00049 00050 /*****************************************************************************/ 00051 /* First, the headers. We only include plugin.h, because all other includes */ 00052 /* are done into it, and plugproto.h (which is used only by this file). */ 00053 /*****************************************************************************/ 00054 #include <plugin.h> 00055 00056 #ifndef __CEXTRACT__ 00057 #include <sproto.h> 00058 #include <timers.h> 00059 #endif 00060 00061 #define NR_OF_HOOKS 89 00062 00063 static const hook_entry plug_hooks[NR_OF_HOOKS] = { 00064 { cfapi_system_add_string, 0, "cfapi_system_add_string" }, 00065 { cfapi_system_register_global_event, 1, "cfapi_system_register_global_event" }, 00066 { cfapi_system_remove_string, 2, "cfapi_system_remove_string" }, 00067 { cfapi_system_unregister_global_event, 3, "cfapi_system_unregister_global_event" }, 00068 { cfapi_system_check_path, 4, "cfapi_system_check_path" }, 00069 { cfapi_system_re_cmp, 5, "cfapi_system_re_cmp" }, 00070 { cfapi_system_strdup_local, 6, "cfapi_system_strdup_local" }, 00071 { cfapi_system_directory, 7, "cfapi_system_directory" }, 00072 { cfapi_system_find_animation, 8, "cfapi_system_find_animation" }, 00073 { cfapi_object_clean_object, 9, "cfapi_object_clean_object" }, 00074 { cfapi_object_on_same_map, 10, "cfapi_object_on_same_map" }, 00075 { cfapi_object_get_key, 11, "cfapi_object_get_key" }, 00076 { cfapi_object_set_key, 12, "cfapi_object_set_key" }, 00077 { cfapi_object_get_property, 13, "cfapi_object_get_property" }, 00078 { cfapi_object_set_property, 14, "cfapi_object_set_property" }, 00079 { cfapi_object_apply, 15, "cfapi_object_apply" }, 00080 { cfapi_object_identify, 16, "cfapi_object_identify" }, 00081 { cfapi_object_describe, 17, "cfapi_object_describe" }, 00082 { cfapi_object_drain, 18, "cfapi_object_drain" }, 00083 { cfapi_object_fix, 19, "cfapi_object_fix" }, 00084 { cfapi_object_give_skill, 20, "cfapi_object_give_skill" }, 00085 { cfapi_object_transmute, 21, "cfapi_object_transmute" }, 00086 { cfapi_object_remove, 22, "cfapi_object_remove" }, 00087 { cfapi_object_delete, 23, "cfapi_object_delete" }, 00088 { cfapi_object_clone, 24, "cfapi_object_clone" }, 00089 { cfapi_object_find, 25, "cfapi_object_find" }, 00090 { cfapi_object_create, 26, "cfapi_object_create" }, 00091 { cfapi_object_insert, 27, "cfapi_object_insert" }, 00092 { cfapi_object_split, 28, "cfapi_object_split" }, 00093 { cfapi_object_merge, 29, "cfapi_object_merge" }, 00094 { cfapi_object_distance, 30, "cfapi_object_distance" }, 00095 { cfapi_object_update, 31, "cfapi_object_update" }, 00096 { cfapi_object_clear, 32, "cfapi_object_clear" }, 00097 { cfapi_object_reset, 33, "cfapi_object_reset" }, 00098 { cfapi_object_check_inventory, 34, "cfapi_object_check_inventory" }, 00099 { cfapi_object_spring_trap, 35, "cfapi_object_spring_trap" }, 00100 { cfapi_object_check_trigger, 36, "cfapi_object_check_trigger" }, 00101 { cfapi_object_query_cost, 37, "cfapi_object_query_cost" }, 00102 { cfapi_object_query_money, 38, "cfapi_object_query_money" }, 00103 { cfapi_object_cast, 39, "cfapi_object_cast" }, 00104 { cfapi_object_learn_spell, 40, "cfapi_object_learn_spell" }, 00105 { cfapi_object_forget_spell, 41, "cfapi_object_forget_spell" }, 00106 { cfapi_object_check_spell, 42, "cfapi_object_check_spell" }, 00107 { cfapi_object_pay_amount, 43, "cfapi_object_pay_amount" }, 00108 { cfapi_object_pay_item, 44, "cfapi_object_pay_item" }, 00109 { cfapi_object_transfer, 45, "cfapi_object_transfer" }, 00110 { cfapi_object_drop, 46, "cfapi_object_drop" }, 00111 { cfapi_object_change_abil, 47, "cfapi_object_change_abil" }, 00112 { cfapi_object_find_archetype_inside, 48, "cfapi_object_find_archetype_inside" }, 00113 { cfapi_object_say, 49, "cfapi_object_say" }, 00114 { cfapi_map_get_map, 50, "cfapi_map_get_map" }, 00115 { cfapi_map_has_been_loaded, 51, "cfapi_map_has_been_loaded" }, 00116 { cfapi_map_create_path, 52, "cfapi_map_create_path" }, 00117 { cfapi_map_get_map_property, 53, "cfapi_map_get_property" }, 00118 { cfapi_map_set_map_property, 54, "cfapi_map_set_property" }, 00119 { cfapi_map_out_of_map, 55, "cfapi_map_out_of_map" }, 00120 { cfapi_map_update_position, 56, "cfapi_map_update_position" }, 00121 { cfapi_map_delete_map, 57, "cfapi_map_delete_map" }, 00122 { cfapi_map_message, 58, "cfapi_map_message" }, 00123 { cfapi_map_get_object_at, 59, "cfapi_map_get_object_at" }, 00124 { cfapi_map_change_light, 60, "cfapi_map_change_light" }, 00125 { cfapi_map_present_arch_by_name, 61, "cfapi_map_present_arch_by_name" }, 00126 { cfapi_player_find, 62, "cfapi_player_find" }, 00127 { cfapi_player_message, 63, "cfapi_player_message" }, 00128 { cfapi_object_change_exp, 64, "cfapi_object_change_exp" }, 00129 { cfapi_object_teleport, 65, "cfapi_object_teleport" }, 00130 { cfapi_object_pickup, 67, "cfapi_object_pickup" }, 00131 { cfapi_object_move, 68, "cfapi_object_move" }, 00132 { cfapi_object_apply_below, 69, "cfapi_object_apply_below" }, 00133 { cfapi_generate_random_map, 70, "cfapi_generate_random_map" }, 00134 { cfapi_archetype_get_property, 71, "cfapi_archetype_get_property" }, 00135 { cfapi_party_get_property, 72, "cfapi_party_get_property" }, 00136 { cfapi_region_get_property, 73, "cfapi_region_get_property" }, 00137 { cfapi_player_can_pay, 74, "cfapi_player_can_pay" }, 00138 { cfapi_log, 75, "cfapi_log" }, 00139 { cfapi_get_time, 76, "cfapi_system_get_time" }, 00140 { cfapi_timer_create, 77, "cfapi_system_timer_create" }, 00141 { cfapi_timer_destroy, 78, "cfapi_system_timer_destroy" }, 00142 { cfapi_friendlylist_get_next, 79, "cfapi_friendlylist_get_next" }, 00143 { cfapi_set_random_map_variable, 80, "cfapi_set_random_map_variable" }, 00144 { cfapi_system_find_face, 81, "cfapi_system_find_face" }, 00145 { cfapi_get_season_name, 82, "cfapi_system_get_season_name" }, 00146 { cfapi_get_month_name, 83, "cfapi_system_get_month_name" }, 00147 { cfapi_get_weekday_name, 84, "cfapi_system_get_weekday_name" }, 00148 { cfapi_get_periodofday_name, 85, "cfapi_system_get_periodofday_name" }, 00149 { cfapi_map_trigger_connected, 86, "cfapi_map_trigger_connected" }, 00150 { cfapi_object_user_event, 87, "cfapi_object_user_event" }, 00151 { cfapi_system_find_string, 88, "cfapi_system_find_string" } 00152 }; 00153 00154 int plugin_number = 0; 00155 00156 crossfire_plugin *plugins_list = NULL; 00157 00158 /*****************************************************************************/ 00159 /* NEW PLUGIN STUFF STARTS HERE */ 00160 /*****************************************************************************/ 00161 00162 #ifdef WIN32 00163 static const char *plugins_dlerror(void) { 00164 static char buf[256]; 00165 DWORD err; 00166 char *p; 00167 00168 err = GetLastError(); 00169 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, sizeof(buf), NULL) == 0) 00170 snprintf(buf, sizeof(buf), "error %lu", err); 00171 p = strchr(buf, '\0'); 00172 while (p > buf && (p[-1] == '\r' || p[-1] == '\n')) 00173 p--; 00174 *p = '\0'; 00175 return buf; 00176 } 00177 #endif /* WIN32 */ 00178 00184 static void send_changed_object(object *op) { 00185 object *tmp; 00186 player *pl; 00187 00188 if (op->env != NULL) { 00189 tmp = get_player_container(op->env); 00190 if (!tmp) { 00191 for (pl = first_player; pl; pl = pl->next) 00192 if (pl->ob->container == op->env) 00193 break; 00194 if (pl) 00195 tmp = pl->ob; 00196 else 00197 tmp = NULL; 00198 } 00199 if (tmp) 00200 /* We don't know what changed, so we send everything. */ 00201 esrv_update_item(UPD_ALL, tmp, op); 00202 } else { 00203 for (tmp = op->above; tmp != NULL; tmp = tmp->above) 00204 if (tmp->type == PLAYER) 00205 tmp->contr->socket.update_look = 1; 00206 } 00207 } 00208 00209 int user_event(object *op, object *activator, object *third, const char *message, int fix) { 00210 return execute_event(op, EVENT_USER, activator, third, message, fix); 00211 } 00212 00213 int execute_event(object *op, int eventcode, object *activator, object *third, const char *message, int fix) { 00214 object *tmp, *next; 00215 crossfire_plugin *plugin; 00216 int rv = 0; 00217 00218 for (tmp = op->inv; tmp != NULL; tmp = next) { 00219 next = tmp->below; 00220 if (tmp->type == EVENT_CONNECTOR && tmp->subtype == eventcode) { 00221 #ifdef PLUGIN_DEBUG 00222 LOG(llevDebug, "********** EVENT HANDLER **********\n"); 00223 LOG(llevDebug, " - Who am I :%s\n", op->name); 00224 if (activator != NULL) 00225 LOG(llevDebug, " - Activator :%s\n", activator->name); 00226 if (third != NULL) 00227 LOG(llevDebug, " - Other object :%s\n", third->name); 00228 LOG(llevDebug, " - Event code :%d\n", tmp->subtype); 00229 if (tmp->title != NULL) 00230 LOG(llevDebug, " - Event plugin :%s\n", tmp->title); 00231 if (tmp->slaying != NULL) 00232 LOG(llevDebug, " - Event hook :%s\n", tmp->slaying); 00233 if (tmp->name != NULL) 00234 LOG(llevDebug, " - Event options :%s\n", tmp->name); 00235 #endif 00236 00237 if (tmp->title == NULL) { 00238 object *env = object_get_env_recursive(tmp); 00239 LOG(llevError, "Event object without title at %d/%d in map %s\n", env->x, env->y, env->map->name); 00240 remove_ob(tmp); 00241 free_object(tmp); 00242 } else if (tmp->slaying == NULL) { 00243 object *env = object_get_env_recursive(tmp); 00244 LOG(llevError, "Event object without slaying at %d/%d in map %s\n", env->x, env->y, env->map->name); 00245 remove_ob(tmp); 00246 free_object(tmp); 00247 } else { 00248 plugin = plugins_find_plugin(tmp->title); 00249 if (plugin == NULL) { 00250 object *env = object_get_env_recursive(tmp); 00251 LOG(llevError, "The requested plugin doesn't exit: %s at %d/%d in map %s\n", tmp->title, env->x, env->y, env->map->name); 00252 remove_ob(tmp); 00253 free_object(tmp); 00254 } else { 00255 int rvt = 0; 00256 int *rv; 00257 00258 rv = plugin->eventfunc(&rvt, op, /*eventcode, */ activator, third, message, fix, /*tmp->slaying, tmp->name*/ tmp); 00259 if (QUERY_FLAG(tmp, FLAG_UNIQUE)) { 00260 #ifdef PLUGIN_DEBUG 00261 LOG(llevDebug, "Removing unique event %s\n", tmp->slaying); 00262 #endif 00263 remove_ob(tmp); 00264 free_object(tmp); 00265 } 00266 return *rv; 00267 } 00268 } 00269 } 00270 } 00271 return rv; 00272 } 00273 00274 int execute_global_event(int eventcode, ...) { 00275 va_list args; 00276 mapstruct *map; 00277 object *op; 00278 object *op2; 00279 player *pl; 00280 const char *buf; 00281 int i, rt; 00282 crossfire_plugin *cp; 00283 00284 if (plugins_list == NULL) 00285 return -1; 00286 00287 va_start(args, eventcode); 00288 00289 switch (eventcode) { 00290 case EVENT_BORN: 00291 /*BORN: op*/ 00292 op = va_arg(args, object *); 00293 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00294 if (cp->gevent[eventcode] != NULL) 00295 cp->gevent[eventcode](&rt, eventcode, op); 00296 } 00297 break; 00298 00299 case EVENT_CLOCK: 00300 /*CLOCK: -*/ 00301 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00302 if (cp->gevent[eventcode] != NULL) 00303 cp->gevent[eventcode](&rt, eventcode); 00304 } 00305 break; 00306 00307 case EVENT_CRASH: 00308 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00309 if (cp->gevent[eventcode] != NULL) 00310 cp->gevent[eventcode](&rt, eventcode); 00311 } 00312 break; 00313 00314 case EVENT_PLAYER_DEATH: 00315 /*PLAYER_DEATH: op*/ 00316 op = va_arg(args, object *); 00317 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00318 if (cp->gevent[eventcode] != NULL) 00319 cp->gevent[eventcode](&rt, eventcode, op); 00320 } 00321 break; 00322 00323 case EVENT_GKILL: 00324 /*GKILL: op, hitter*/ 00325 op = va_arg(args, object *); 00326 op2 = va_arg(args, object *); 00327 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00328 if (cp->gevent[eventcode] != NULL) 00329 cp->gevent[eventcode](&rt, eventcode, op, op2); 00330 } 00331 break; 00332 00333 case EVENT_LOGIN: 00334 /*LOGIN: pl, pl->socket.host*/ 00335 pl = va_arg(args, player *); 00336 buf = va_arg(args, char *); 00337 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00338 if (cp->gevent[eventcode] != NULL) 00339 cp->gevent[eventcode](&rt, eventcode, pl, buf); 00340 } 00341 break; 00342 00343 case EVENT_LOGOUT: 00344 /*LOGOUT: pl, pl->socket.host*/ 00345 pl = va_arg(args, player *); 00346 buf = va_arg(args, char *); 00347 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00348 if (cp->gevent[eventcode] != NULL) 00349 cp->gevent[eventcode](&rt, eventcode, pl, buf); 00350 } 00351 break; 00352 00353 case EVENT_MAPENTER: 00354 /*MAPENTER: op, map*/ 00355 op = va_arg(args, object *); 00356 map = va_arg(args, mapstruct *); 00357 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00358 if (cp->gevent[eventcode] != NULL) 00359 cp->gevent[eventcode](&rt, eventcode, op, map); 00360 } 00361 break; 00362 00363 case EVENT_MAPLEAVE: 00364 /*MAPLEAVE: op, map*/ 00365 op = va_arg(args, object *); 00366 map = va_arg(args, mapstruct *); 00367 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00368 if (cp->gevent[eventcode] != NULL) 00369 cp->gevent[eventcode](&rt, eventcode, op, map); 00370 } 00371 break; 00372 00373 case EVENT_MAPRESET: 00374 /*MAPRESET: map*/ 00375 map = va_arg(args, mapstruct *); 00376 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00377 if (cp->gevent[eventcode] != NULL) 00378 cp->gevent[eventcode](&rt, eventcode, map); 00379 } 00380 break; 00381 00382 case EVENT_REMOVE: 00383 /*REMOVE: op*/ 00384 op = va_arg(args, object *); 00385 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00386 if (cp->gevent[eventcode] != NULL) 00387 cp->gevent[eventcode](&rt, eventcode, op); 00388 } 00389 break; 00390 00391 case EVENT_SHOUT: 00392 /*SHOUT: op, parms, priority*/ 00393 op = va_arg(args, object *); 00394 buf = va_arg(args, char *); 00395 i = va_arg(args, int); 00396 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00397 if (cp->gevent[eventcode] != NULL) 00398 cp->gevent[eventcode](&rt, eventcode, op, buf, i); 00399 } 00400 break; 00401 00402 case EVENT_TELL: 00403 /* Tell: who, what, to who */ 00404 op = va_arg(args, object *); 00405 buf = va_arg(args, const char *); 00406 op2 = va_arg(args, object *); 00407 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00408 if (cp->gevent[eventcode] != NULL) 00409 cp->gevent[eventcode](&rt, eventcode, op, buf, op2); 00410 } 00411 break; 00412 00413 case EVENT_MUZZLE: 00414 /*MUZZLE: op, parms*/ 00415 op = va_arg(args, object *); 00416 buf = va_arg(args, char *); 00417 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00418 if (cp->gevent[eventcode] != NULL) 00419 cp->gevent[eventcode](&rt, eventcode, op, buf); 00420 } 00421 break; 00422 00423 case EVENT_KICK: 00424 /*KICK: op, parms*/ 00425 op = va_arg(args, object *); 00426 buf = va_arg(args, char *); 00427 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00428 if (cp->gevent[eventcode] != NULL) 00429 cp->gevent[eventcode](&rt, eventcode, op, buf); 00430 } 00431 break; 00432 00433 case EVENT_MAPUNLOAD: 00434 /*MAPUNLOAD: map*/ 00435 map = va_arg(args, mapstruct *); 00436 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00437 if (cp->gevent[eventcode] != NULL) 00438 cp->gevent[eventcode](&rt, eventcode, map); 00439 } 00440 break; 00441 00442 case EVENT_MAPLOAD: 00443 /*MAPLOAD: map*/ 00444 map = va_arg(args, mapstruct *); 00445 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00446 if (cp->gevent[eventcode] != NULL) 00447 cp->gevent[eventcode](&rt, eventcode, map); 00448 } 00449 break; 00450 } 00451 va_end(args); 00452 return 0; 00453 } 00454 00455 int plugins_init_plugin(const char *libfile) { 00456 LIBPTRTYPE ptr; 00457 f_plug_init initfunc; 00458 f_plug_api propfunc; 00459 f_plug_api eventfunc; 00460 f_plug_postinit postfunc; 00461 f_plug_postinit closefunc; 00462 int i; 00463 crossfire_plugin *cp; 00464 crossfire_plugin *ccp; 00465 00466 /* Open the plugin lib and load the required functions */ 00467 ptr = plugins_dlopen(libfile); 00468 if (ptr == NULL) { 00469 LOG(llevError, "Error trying to load %s: %s\n", libfile, plugins_dlerror()); 00470 return -1; 00471 } 00472 initfunc = (f_plug_init)plugins_dlsym(ptr, "initPlugin"); 00473 if (initfunc == NULL) { 00474 LOG(llevError, "Plugin error while requesting %s.initPlugin: %s\n", libfile, plugins_dlerror()); 00475 plugins_dlclose(ptr); 00476 return -1; 00477 } 00478 propfunc = (f_plug_api)plugins_dlsym(ptr, "getPluginProperty"); 00479 if (propfunc == NULL) { 00480 LOG(llevError, "Plugin error while requesting %s.getPluginProperty: %s\n", libfile, plugins_dlerror()); 00481 plugins_dlclose(ptr); 00482 return -1; 00483 } 00484 eventfunc = (f_plug_api)plugins_dlsym(ptr, "eventListener"); 00485 if (eventfunc == NULL) { 00486 LOG(llevError, "Plugin error while requesting %s.eventListener: %s\n", libfile, plugins_dlerror()); 00487 plugins_dlclose(ptr); 00488 return -1; 00489 } 00490 postfunc = (f_plug_postinit)plugins_dlsym(ptr, "postInitPlugin"); 00491 if (postfunc == NULL) { 00492 LOG(llevError, "Plugin error while requesting %s.postInitPlugin: %s\n", libfile, plugins_dlerror()); 00493 plugins_dlclose(ptr); 00494 return -1; 00495 } 00496 closefunc = (f_plug_postinit)plugins_dlsym(ptr, "closePlugin"); 00497 if (closefunc == NULL) { 00498 LOG(llevError, "Plugin error while requesting %s.closePlugin: %s\n", libfile, plugins_dlerror()); 00499 plugins_dlclose(ptr); 00500 return -1; 00501 } 00502 i = initfunc("2.0", cfapi_get_hooks); 00503 cp = malloc(sizeof(crossfire_plugin)); 00504 for (i = 0; i < NR_EVENTS; i++) 00505 cp->gevent[i] = NULL; 00506 cp->eventfunc = eventfunc; 00507 cp->propfunc = propfunc; 00508 cp->closefunc = closefunc; 00509 cp->libptr = ptr; 00510 propfunc(&i, "Identification", cp->id, sizeof(cp->id)); 00511 propfunc(&i, "FullName", cp->fullname, sizeof(cp->fullname)); 00512 cp->next = NULL; 00513 cp->prev = NULL; 00514 if (plugins_list == NULL) { 00515 plugins_list = cp; 00516 } else { 00517 for (ccp = plugins_list; ccp->next != NULL; ccp = ccp->next) 00518 ; 00519 ccp->next = cp; 00520 cp->prev = ccp; 00521 } 00522 postfunc(); 00523 plugin_number++; 00524 return 0; 00525 } 00526 00527 void *cfapi_get_hooks(int *type, ...) { 00528 va_list args; 00529 int request_type; 00530 char *buf; 00531 int fid; 00532 f_plug_api *rapi; 00533 int i; 00534 00535 *type = CFAPI_NONE; 00536 00537 va_start(args, type); 00538 request_type = va_arg(args, int); 00539 if (request_type == 0) { /* By nr */ 00540 fid = va_arg(args, int); 00541 rapi = va_arg(args, f_plug_api *); 00542 if (fid < 0 || fid >= NR_OF_HOOKS) { 00543 *rapi = NULL; 00544 *type = CFAPI_NONE; 00545 } else { 00546 *rapi = plug_hooks[fid].func; 00547 *type = CFAPI_FUNC; 00548 } 00549 } else { /* by name */ 00550 buf = va_arg(args, char *); 00551 rapi = va_arg(args, f_plug_api *); 00552 *rapi = NULL; 00553 *type = CFAPI_NONE; 00554 for (i = 0; i < NR_OF_HOOKS; i++) { 00555 if (!strcmp(buf, plug_hooks[i].fname)) { 00556 *rapi = plug_hooks[i].func; 00557 *type = CFAPI_FUNC; 00558 break; 00559 } 00560 } 00561 } 00562 va_end(args); 00563 return NULL; 00564 } 00565 00566 int plugins_remove_plugin(const char *id) { 00567 crossfire_plugin *cp; 00568 00569 if (plugins_list == NULL) 00570 return -1; 00571 00572 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00573 if (!strcmp(id, cp->id)) { 00574 crossfire_plugin *n; 00575 crossfire_plugin *p; 00576 00577 n = cp->next; 00578 p = cp->prev; 00579 if (cp->closefunc) 00580 cp->closefunc(); 00581 plugins_dlclose(cp->libptr); 00582 if (n != NULL) { 00583 if (p != NULL) { 00584 n->prev = p; 00585 p->next = n; 00586 } else { 00587 n->prev = NULL; 00588 plugins_list = n; 00589 } 00590 } else { 00591 if (p != NULL) 00592 p->next = NULL; 00593 else 00594 plugins_list = NULL; 00595 } 00596 free(cp); 00597 plugin_number--; 00598 return 0; 00599 } 00600 } 00601 return -1; 00602 } 00603 00604 crossfire_plugin *plugins_find_plugin(const char *id) { 00605 crossfire_plugin *cp; 00606 00607 if (plugins_list == NULL) 00608 return NULL; 00609 00610 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00611 if (!strcmp(id, cp->id)) { 00612 return cp; 00613 } 00614 } 00615 return NULL; 00616 } 00617 00618 /*****************************************************************************/ 00619 /* Displays a list of loaded plugins (keystrings and description) in the */ 00620 /* game log window. */ 00621 /*****************************************************************************/ 00622 void plugins_display_list(object *op) { 00623 crossfire_plugin *cp; 00624 00625 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG, 00626 "List of loaded plugins:\n-----------------------", NULL); 00627 00628 if (plugins_list == NULL) 00629 return; 00630 00631 for (cp = plugins_list; cp != NULL; cp = cp->next) { 00632 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG, 00633 "%s, %s", 00634 "%s, %s", 00635 cp->id, cp->fullname); 00636 } 00637 } 00638 00639 /* SYSTEM-RELATED HOOKS */ 00640 00648 void *cfapi_system_find_animation(int *type, ...) { 00649 va_list args; 00650 const char *anim; 00651 int *num; 00652 00653 va_start(args, type); 00654 anim = va_arg(args, const char *); 00655 num = va_arg(args, int *); 00656 va_end(args); 00657 00658 *num = find_animation(anim); 00659 *type = CFAPI_INT; 00660 return NULL; 00661 } 00662 00670 void *cfapi_system_find_face(int *type, ...) { 00671 va_list args; 00672 const char *face; 00673 int error; 00674 int *num; 00675 00676 va_start(args, type); 00677 face = va_arg(args, const char *); 00678 error = va_arg(args, int); 00679 num = va_arg(args, int *); 00680 va_end(args); 00681 00682 *num = find_face(face, error); 00683 *type = CFAPI_INT; 00684 return NULL; 00685 } 00686 00694 void *cfapi_system_strdup_local(int *type, ...) { 00695 va_list args; 00696 const char *txt; 00697 char **ret; 00698 00699 va_start(args, type); 00700 txt = va_arg(args, const char *); 00701 ret = va_arg(args, char **); 00702 va_end(args); 00703 00704 *ret = strdup_local(txt); 00705 *type = CFAPI_STRING; 00706 return NULL; 00707 } 00708 00709 void *cfapi_system_register_global_event(int *type, ...) { 00710 va_list args; 00711 int eventcode; 00712 char *pname; 00713 f_plug_api hook; 00714 crossfire_plugin *cp; 00715 00716 va_start(args, type); 00717 eventcode = va_arg(args, int); 00718 pname = va_arg(args, char *); 00719 hook = va_arg(args, f_plug_api); 00720 va_end(args); 00721 00722 *type = CFAPI_NONE; 00723 00724 cp = plugins_find_plugin(pname); 00725 cp->gevent[eventcode] = hook; 00726 return NULL; 00727 } 00728 00729 void *cfapi_system_unregister_global_event(int *type, ...) { 00730 va_list args; 00731 int eventcode; 00732 char *pname; 00733 crossfire_plugin *cp; 00734 00735 va_start(args, type); 00736 eventcode = va_arg(args, int); 00737 pname = va_arg(args, char *); 00738 va_end(args); 00739 00740 *type = CFAPI_NONE; 00741 00742 cp = plugins_find_plugin(pname); 00743 cp->gevent[eventcode] = NULL; 00744 00745 return NULL; 00746 } 00747 00756 void *cfapi_system_add_string(int *type, ...) { 00757 va_list args; 00758 const char *str; 00759 sstring *rv; 00760 00761 va_start(args, type); 00762 str = va_arg(args, const char *); 00763 rv = va_arg(args, sstring *); 00764 va_end(args); 00765 00766 *rv = add_string(str); 00767 *type = CFAPI_SSTRING; 00768 return NULL; 00769 } 00770 00779 void *cfapi_system_remove_string(int *type, ...) { 00780 va_list args; 00781 sstring str; 00782 00783 va_start(args, type); 00784 str = va_arg(args, sstring); 00785 va_end(args); 00786 00787 free_string(str); 00788 *type = CFAPI_NONE; 00789 return NULL; 00790 } 00791 00800 void *cfapi_system_find_string(int *type, ...) { 00801 va_list args; 00802 const char *str; 00803 sstring *rv; 00804 00805 va_start(args, type); 00806 str = va_arg(args, const char *); 00807 rv = va_arg(args, sstring *); 00808 va_end(args); 00809 00810 *rv = find_string(str); 00811 *type = CFAPI_SSTRING; 00812 return NULL; 00813 } 00814 00822 void *cfapi_system_check_path(int *type, ...) { 00823 va_list args; 00824 const char *name; 00825 int prepend_dir; 00826 int *ret; 00827 00828 va_start(args, type); 00829 00830 name = va_arg(args, char *); 00831 prepend_dir = va_arg(args, int); 00832 ret = va_arg(args, int *); 00833 00834 *ret = check_path(name, prepend_dir); 00835 00836 va_end(args); 00837 *type = CFAPI_INT; 00838 return NULL; 00839 } 00840 00848 void *cfapi_system_re_cmp(int *type, ...) { 00849 va_list args; 00850 const char *str; 00851 const char *regexp; 00852 const char **rv; 00853 00854 va_start(args, type); 00855 00856 str = va_arg(args, char *); 00857 regexp = va_arg(args, char *); 00858 rv = va_arg(args, const char **); 00859 00860 *rv = re_cmp(str, regexp); 00861 00862 va_end(args); 00863 *type = CFAPI_STRING; 00864 return NULL; 00865 } 00866 00867 void *cfapi_system_directory(int *type, ...) { 00868 va_list args; 00869 int dirtype; 00870 const char **str; 00871 00872 va_start(args, type); 00873 00874 dirtype = va_arg(args, int); 00875 str = va_arg(args, const char **); 00876 va_end(args); 00877 00878 *type = CFAPI_STRING; 00879 00880 switch (dirtype) { 00881 case 0: 00882 *str = settings.mapdir; 00883 break; 00884 00885 case 1: 00886 *str = settings.uniquedir; 00887 break; 00888 00889 case 2: 00890 *str = settings.tmpdir; 00891 break; 00892 00893 case 3: 00894 *str = settings.confdir; 00895 break; 00896 00897 case 4: 00898 *str = settings.localdir; 00899 break; 00900 00901 case 5: 00902 *str = settings.playerdir; 00903 break; 00904 00905 case 6: 00906 *str = settings.datadir; 00907 break; 00908 00909 default: 00910 *str = NULL; 00911 } 00912 00913 return NULL; 00914 } 00915 00924 void *cfapi_get_time(int *type, ...) { 00925 va_list args; 00926 timeofday_t *tod; 00927 00928 va_start(args, type); 00929 tod = va_arg(args, timeofday_t *); 00930 va_end(args); 00931 00932 get_tod(tod); 00933 *type = CFAPI_NONE; 00934 return NULL; 00935 } 00936 00937 #define string_get_int(name) \ 00938 va_list args; \ 00939 int index; \ 00940 const char **str; \ 00941 va_start(args, type); \ 00942 index = va_arg(args, int); \ 00943 str = va_arg(args, const char **); \ 00944 va_end(args); \ 00945 *str = name(index); \ 00946 *type = CFAPI_STRING; \ 00947 return NULL; \ 00948 00949 00957 void *cfapi_get_season_name(int *type, ...) { 00958 string_get_int(get_season_name) 00959 } 00960 00969 void *cfapi_get_weekday_name(int *type, ...) { 00970 string_get_int(get_weekday) 00971 } 00972 00981 void *cfapi_get_month_name(int *type, ...) { 00982 string_get_int(get_month_name) 00983 } 00984 00993 void *cfapi_get_periodofday_name(int *type, ...) { 00994 string_get_int(get_periodofday) 00995 } 00996 01010 void *cfapi_timer_create(int *type, ...) { 01011 va_list args; 01012 int res; 01013 object *ob; 01014 long delay; 01015 int mode; 01016 int *timer; 01017 01018 va_start(args, type); 01019 ob = va_arg(args, object *); 01020 delay = va_arg(args, long); 01021 mode = va_arg(args, int); 01022 timer = va_arg(args, int *); 01023 va_end(args); 01024 *type = CFAPI_INT; 01025 01026 *timer = cftimer_find_free_id(); 01027 if (*timer != TIMER_ERR_ID) { 01028 res = cftimer_create(*timer, delay, ob, mode); 01029 if (res != TIMER_ERR_NONE) 01030 *timer = res; 01031 } 01032 return NULL; 01033 } 01034 01046 void *cfapi_timer_destroy(int *type, ...) { 01047 va_list args; 01048 int id; 01049 int *err; 01050 01051 va_start(args, type); 01052 id = va_arg(args, int); 01053 err = va_arg(args, int *); 01054 va_end(args); 01055 *type = CFAPI_INT; 01056 01057 *err = cftimer_destroy(id); 01058 01059 return NULL; 01060 } 01061 01069 void *cfapi_log(int *type, ...) { 01070 va_list args; 01071 LogLevel logLevel; 01072 const char *message; 01073 01074 va_start(args, type); 01075 logLevel = va_arg(args, LogLevel); 01076 message = va_arg(args, const char *); 01077 LOG(logLevel, "%s", message); 01078 va_end(args); 01079 01080 *type = CFAPI_NONE; 01081 01082 return NULL; 01083 } 01084 01085 /* MAP RELATED HOOKS */ 01086 01095 void *cfapi_map_get_map(int *type, ...) { 01096 va_list args; 01097 mapstruct **ret; 01098 int ctype; 01099 int x, y; 01100 sint16 nx, ny; 01101 const char *name; 01102 mapstruct *m; 01103 01104 va_start(args, type); 01105 01106 ctype = va_arg(args, int); 01107 01108 switch (ctype) { 01109 case 0: 01110 x = va_arg(args, int); 01111 y = va_arg(args, int); 01112 ret = va_arg(args, mapstruct **); 01113 *ret = get_empty_map(x, y); 01114 break; 01115 01116 case 1: 01117 name = va_arg(args, const char *); 01118 x = va_arg(args, int); 01119 ret = va_arg(args, mapstruct **); 01120 *ret = ready_map_name(name, x); 01121 break; 01122 01123 case 2: 01124 m = va_arg(args, mapstruct *); 01125 nx = va_arg(args, int); 01126 ny = va_arg(args, int); 01127 ret = va_arg(args, mapstruct **); 01128 *ret = get_map_from_coord(m, &nx, &ny); 01129 break; 01130 01131 default: 01132 *type = CFAPI_NONE; 01133 va_end(args); 01134 return NULL; 01135 break; 01136 } 01137 va_end(args); 01138 *type = CFAPI_PMAP; 01139 return NULL; 01140 } 01141 01149 void *cfapi_map_has_been_loaded(int *type, ...) { 01150 va_list args; 01151 mapstruct **map; 01152 char *string; 01153 01154 va_start(args, type); 01155 string = va_arg(args, char *); 01156 map = va_arg(args, mapstruct **); 01157 *map = has_been_loaded(string); 01158 va_end(args); 01159 *type = CFAPI_PMAP; 01160 return NULL; 01161 } 01162 01170 void *cfapi_map_create_path(int *type, ...) { 01171 va_list args; 01172 int ctype, size; 01173 const char *str; 01174 char *name; 01175 01176 va_start(args, type); 01177 01178 ctype = va_arg(args, int); 01179 str = va_arg(args, const char *); 01180 name = va_arg(args, char *); 01181 size = va_arg(args, int); 01182 *type = CFAPI_STRING; 01183 01184 switch (ctype) { 01185 case 0: 01186 create_pathname(str, name, size); 01187 break; 01188 01189 case 1: 01190 create_overlay_pathname(str, name, MAX_BUF); 01191 break; 01192 01193 /* case 2: 01194 rv = create_items_path(str); 01195 break;*/ 01196 01197 default: 01198 *type = CFAPI_NONE; 01199 break; 01200 } 01201 va_end(args); 01202 return NULL; 01203 } 01204 01205 void *cfapi_map_get_map_property(int *type, ...) { 01206 va_list args; 01207 mapstruct *map; 01208 int property; 01209 01210 int *rint; 01211 mapstruct **rmap; 01212 sstring *rstr; 01213 region **rreg; 01214 sint16 *nx, *ny; 01215 int x, y; 01216 01217 va_start(args, type); 01218 01219 map = va_arg(args, mapstruct *); 01220 property = va_arg(args, int); 01221 01222 switch (property) { 01223 case CFAPI_MAP_PROP_FLAGS: 01224 rmap = va_arg(args, mapstruct **); 01225 x = va_arg(args, int); 01226 y = va_arg(args, int); 01227 nx = va_arg(args, sint16 *); 01228 ny = va_arg(args, sint16 *); 01229 rint = va_arg(args, int *); 01230 *rint = get_map_flags(map, rmap, x, y, nx, ny); 01231 *type = CFAPI_INT; 01232 break; 01233 01234 case CFAPI_MAP_PROP_DIFFICULTY: 01235 rint = va_arg(args, int *); 01236 *rint = calculate_difficulty(map); 01237 *type = CFAPI_INT; 01238 break; 01239 01240 case CFAPI_MAP_PROP_PATH: 01241 rstr = va_arg(args, sstring *); 01242 *rstr = map->path; 01243 *type = CFAPI_SSTRING; 01244 break; 01245 01246 case CFAPI_MAP_PROP_TMPNAME: 01247 rstr = va_arg(args, sstring *); 01248 *rstr = map->tmpname; 01249 *type = CFAPI_SSTRING; 01250 break; 01251 01252 case CFAPI_MAP_PROP_NAME: 01253 rstr = va_arg(args, sstring *); 01254 *rstr = map->name; 01255 *type = CFAPI_SSTRING; 01256 break; 01257 01258 case CFAPI_MAP_PROP_RESET_TIME: 01259 rint = va_arg(args, int *); 01260 *rint = map->reset_time; 01261 *type = CFAPI_INT; 01262 break; 01263 01264 case CFAPI_MAP_PROP_RESET_TIMEOUT: 01265 rint = va_arg(args, int *); 01266 *rint = map->reset_timeout; 01267 *type = CFAPI_INT; 01268 break; 01269 01270 case CFAPI_MAP_PROP_PLAYERS: 01271 rint = va_arg(args, int *); 01272 *rint = map->players; 01273 *type = CFAPI_INT; 01274 break; 01275 01276 case CFAPI_MAP_PROP_DARKNESS: 01277 rint = va_arg(args, int *); 01278 *rint = map->darkness; 01279 *type = CFAPI_INT; 01280 break; 01281 01282 case CFAPI_MAP_PROP_WIDTH: 01283 rint = va_arg(args, int *); 01284 *rint = map->width; 01285 *type = CFAPI_INT; 01286 break; 01287 01288 case CFAPI_MAP_PROP_HEIGHT: 01289 rint = va_arg(args, int *); 01290 *rint = map->height; 01291 *type = CFAPI_INT; 01292 break; 01293 01294 case CFAPI_MAP_PROP_ENTER_X: 01295 rint = va_arg(args, int *); 01296 *rint = map->enter_x; 01297 *type = CFAPI_INT; 01298 break; 01299 01300 case CFAPI_MAP_PROP_ENTER_Y: 01301 rint = va_arg(args, int *); 01302 *rint = map->enter_y; 01303 *type = CFAPI_INT; 01304 break; 01305 01306 case CFAPI_MAP_PROP_MESSAGE: 01307 rstr = va_arg(args, sstring *); 01308 *rstr = map->msg; 01309 *type = CFAPI_SSTRING; 01310 break; 01311 01312 case CFAPI_MAP_PROP_NEXT: 01313 rmap = va_arg(args, mapstruct **); 01314 *rmap = map ? map->next : first_map; 01315 *type = CFAPI_PMAP; 01316 break; 01317 01318 case CFAPI_MAP_PROP_REGION: 01319 rreg = va_arg(args, region **); 01320 *rreg = get_region_by_map(map); 01321 *type = CFAPI_PREGION; 01322 break; 01323 01324 case CFAPI_MAP_PROP_UNIQUE: 01325 rint = va_arg(args, int *); 01326 *rint = map->unique; 01327 *type = CFAPI_INT; 01328 break; 01329 01330 default: 01331 *type = CFAPI_NONE; 01332 break; 01333 } 01334 va_end(args); 01335 return NULL; 01336 } 01337 01338 void *cfapi_map_set_map_property(int *type, ...) { 01339 va_list args; 01340 mapstruct *map; 01341 int property; 01342 const char *buf; 01343 01344 va_start(args, type); 01345 01346 map = va_arg(args, mapstruct *); 01347 property = va_arg(args, int); 01348 01349 switch (property) { 01350 case CFAPI_MAP_PROP_PATH: 01351 buf = va_arg(args, const char *); 01352 snprintf(map->path, sizeof(map->path), "%s", buf); 01353 *type = CFAPI_STRING; 01354 break; 01355 01356 default: 01357 *type = CFAPI_NONE; 01358 break; 01359 } 01360 va_end(args); 01361 return NULL; 01362 } 01363 01371 void *cfapi_map_out_of_map(int *type, ...) { 01372 va_list args; 01373 mapstruct *map; 01374 int x, y; 01375 int *rint; 01376 01377 va_start(args, type); 01378 map = va_arg(args, mapstruct *); 01379 x = va_arg(args, int); 01380 y = va_arg(args, int); 01381 rint = va_arg(args, int *); 01382 01383 *rint = out_of_map(map, x, y); 01384 va_end(args); 01385 *type = CFAPI_INT; 01386 return NULL; 01387 } 01388 01396 void *cfapi_map_update_position(int *type, ...) { 01397 va_list args; 01398 mapstruct *map; 01399 int x, y; 01400 01401 va_start(args, type); 01402 01403 map = va_arg(args, mapstruct *); 01404 x = va_arg(args, int); 01405 y = va_arg(args, int); 01406 01407 update_position(map, x, y); 01408 va_end(args); 01409 *type = CFAPI_NONE; 01410 return NULL; 01411 } 01412 01413 void *cfapi_map_delete_map(int *type, ...) { 01414 va_list args; 01415 mapstruct *map; 01416 va_start(args, type); 01417 01418 map = va_arg(args, mapstruct *); 01419 01420 delete_map(map); 01421 01422 va_end(args); 01423 *type = CFAPI_NONE; 01424 return NULL; 01425 } 01426 void *cfapi_map_message(int *type, ...) { 01427 va_list args; 01428 mapstruct *map; 01429 const char *string; 01430 int color; 01431 01432 va_start(args, type); 01433 map = va_arg(args, mapstruct *); 01434 string = va_arg(args, const char *); 01435 color = va_arg(args, int); 01436 va_end(args); 01437 01438 /* function should be extended to take message types probably */ 01439 ext_info_map(color, map, MSG_TYPE_MISC, MSG_SUBTYPE_NONE, string, string); 01440 *type = CFAPI_NONE; 01441 return NULL; 01442 } 01443 01451 void *cfapi_map_get_object_at(int *type, ...) { 01452 va_list args; 01453 mapstruct *map; 01454 int x, y; 01455 sint16 sx, sy; 01456 object **robj; 01457 01458 va_start(args, type); 01459 map = va_arg(args, mapstruct *); 01460 x = va_arg(args, int); 01461 y = va_arg(args, int); 01462 robj = va_arg(args, object **); 01463 va_end(args); 01464 01465 sx = x; 01466 sy = y; 01467 if (get_map_flags(map, &map, x, y, &sx, &sy)&P_OUT_OF_MAP) 01468 *robj = NULL; 01469 else 01470 *robj = GET_MAP_OB(map, sx, sy); 01471 *type = CFAPI_POBJECT; 01472 return NULL; 01473 } 01474 01483 void *cfapi_map_present_arch_by_name(int *type, ...) { 01484 va_list args; 01485 int x, y; 01486 mapstruct *map; 01487 char *msg; 01488 object **robj; 01489 01490 va_start(args, type); 01491 01492 msg = va_arg(args, char *); 01493 map = va_arg(args, mapstruct *); 01494 x = va_arg(args, int); 01495 y = va_arg(args, int); 01496 robj = va_arg(args, object **); 01497 01498 va_end(args); 01499 01500 *robj = present_arch(try_find_archetype(msg), map, x, y); 01501 *type = CFAPI_POBJECT; 01502 return NULL; 01503 } 01504 01512 void *cfapi_map_change_light(int *type, ...) { 01513 va_list args; 01514 int change; 01515 mapstruct *map; 01516 int *rint; 01517 01518 va_start(args, type); 01519 map = va_arg(args, mapstruct *); 01520 change = va_arg(args, int); 01521 rint = va_arg(args, int *); 01522 va_end(args); 01523 01524 *type = CFAPI_INT; 01525 *rint = change_map_light(map, change); 01526 01527 return NULL; 01528 } 01529 01530 /* OBJECT-RELATED HOOKS */ 01531 01546 void *cfapi_object_move(int *type, ...) { 01547 va_list args; 01548 int kind; 01549 object *op; 01550 object *activator; 01551 player *pl; 01552 int direction; 01553 int *ret; 01554 01555 va_start(args, type); 01556 kind = va_arg(args, int); 01557 switch (kind) { 01558 case 0: 01559 op = va_arg(args, object *); 01560 direction = va_arg(args, int); 01561 activator = va_arg(args, object *); 01562 ret = va_arg(args, int *); 01563 va_end(args); 01564 *ret = move_ob(op, direction, activator); 01565 break; 01566 01567 case 1: 01568 pl = va_arg(args, player *); 01569 direction = va_arg(args, int); 01570 ret = va_arg(args, int *); 01571 va_end(args); 01572 *ret = move_player(pl->ob, direction); 01573 break; 01574 } 01575 *type = CFAPI_INT; 01576 return NULL; 01577 } 01578 01588 void *cfapi_object_get_key(int *type, ...) { 01589 va_list args; 01590 const char *keyname; 01591 const char **value; 01592 object *op; 01593 01594 va_start(args, type); 01595 op = va_arg(args, object *); 01596 keyname = va_arg(args, const char *); 01597 value = va_arg(args, const char **); 01598 va_end(args); 01599 01600 *value = get_ob_key_value(op, keyname); 01601 *type = CFAPI_SSTRING; 01602 return NULL; 01603 } 01604 01613 void *cfapi_object_set_key(int *type, ...) { 01614 va_list args; 01615 const char *keyname; 01616 const char *value; 01617 int *ret; 01618 object *op; 01619 int add_key; 01620 01621 va_start(args, type); 01622 op = va_arg(args, object *); 01623 keyname = va_arg(args, char *); 01624 value = va_arg(args, char *); 01625 add_key = va_arg(args, int); 01626 ret = va_arg(args, int *); 01627 va_end(args); 01628 01629 *ret = set_ob_key_value(op, keyname, value, add_key); 01630 *type = CFAPI_INT; 01631 return NULL; 01632 } 01633 01637 void *cfapi_object_get_property(int *type, ...) { 01638 va_list args; 01639 int property; 01640 object *op; 01641 int *rint; 01642 object **robject; 01643 mapstruct **rmap; 01644 float *rfloat; 01645 archetype **rarch; 01646 sstring *rsstring; 01647 char *rbuffer; 01648 int rbufsize; 01649 MoveType *rmove; 01650 sint64 *rint64; 01651 partylist **rparty; 01652 double *rdouble; 01653 long *rlong; 01654 01655 va_start(args, type); 01656 01657 op = va_arg(args, object *); 01658 property = va_arg(args, int); 01659 switch (property) { 01660 case CFAPI_OBJECT_PROP_OB_ABOVE: 01661 robject = va_arg(args, object **); 01662 *robject = op->above; 01663 *type = CFAPI_POBJECT; 01664 break; 01665 01666 case CFAPI_OBJECT_PROP_OB_BELOW: 01667 robject = va_arg(args, object **); 01668 *robject = op->below; 01669 *type = CFAPI_POBJECT; 01670 break; 01671 01672 case CFAPI_OBJECT_PROP_NEXT_ACTIVE_OB: 01673 robject = va_arg(args, object **); 01674 *robject = op->active_next; 01675 *type = CFAPI_POBJECT; 01676 break; 01677 01678 case CFAPI_OBJECT_PROP_PREV_ACTIVE_OB: 01679 robject = va_arg(args, object **); 01680 *robject = op->active_prev; 01681 *type = CFAPI_POBJECT; 01682 break; 01683 01684 case CFAPI_OBJECT_PROP_INVENTORY: 01685 robject = va_arg(args, object **); 01686 *robject = op->inv; 01687 *type = CFAPI_POBJECT; 01688 break; 01689 01690 case CFAPI_OBJECT_PROP_ENVIRONMENT: 01691 robject = va_arg(args, object **); 01692 *robject = op->env; 01693 *type = CFAPI_POBJECT; 01694 break; 01695 01696 case CFAPI_OBJECT_PROP_HEAD: 01697 robject = va_arg(args, object **); 01698 *robject = op->head; 01699 *type = CFAPI_POBJECT; 01700 break; 01701 01702 case CFAPI_OBJECT_PROP_CONTAINER: 01703 robject = va_arg(args, object **); 01704 *robject = op->container; 01705 *type = CFAPI_POBJECT; 01706 break; 01707 01708 case CFAPI_OBJECT_PROP_MAP: 01709 rmap = va_arg(args, mapstruct **); 01710 *rmap = op->map; 01711 *type = CFAPI_PMAP; 01712 break; 01713 01714 case CFAPI_OBJECT_PROP_COUNT: 01715 rint = va_arg(args, int *); 01716 *rint = op->count; 01717 *type = CFAPI_INT; 01718 break; 01719 01720 case CFAPI_OBJECT_PROP_NAME: 01721 rbuffer = va_arg(args, char *); 01722 rbufsize = va_arg(args, int); 01723 query_name(op, rbuffer, rbufsize); 01724 *type = CFAPI_STRING; 01725 break; 01726 01727 case CFAPI_OBJECT_PROP_NAME_PLURAL: 01728 rsstring = va_arg(args, sstring *); 01729 *rsstring = op->name_pl; 01730 *type = CFAPI_SSTRING; 01731 break; 01732 01733 case CFAPI_OBJECT_PROP_TITLE: 01734 rsstring = va_arg(args, sstring *); 01735 *rsstring = op->title; 01736 *type = CFAPI_SSTRING; 01737 break; 01738 01739 case CFAPI_OBJECT_PROP_RACE: 01740 rsstring = va_arg(args, sstring *); 01741 *rsstring = op->race; 01742 *type = CFAPI_SSTRING; 01743 break; 01744 01745 case CFAPI_OBJECT_PROP_SLAYING: 01746 rsstring = va_arg(args, sstring *); 01747 *rsstring = op->slaying; 01748 *type = CFAPI_SSTRING; 01749 break; 01750 01751 case CFAPI_OBJECT_PROP_SKILL: 01752 rsstring = va_arg(args, sstring *); 01753 *rsstring = op->skill; 01754 *type = CFAPI_SSTRING; 01755 break; 01756 01757 case CFAPI_OBJECT_PROP_MESSAGE: 01758 rsstring = va_arg(args, sstring *); 01759 *rsstring = op->msg; 01760 *type = CFAPI_SSTRING; 01761 break; 01762 01763 case CFAPI_OBJECT_PROP_LORE: 01764 rsstring = va_arg(args, sstring *); 01765 *rsstring = op->lore; 01766 *type = CFAPI_SSTRING; 01767 break; 01768 01769 case CFAPI_OBJECT_PROP_X: 01770 rint = va_arg(args, int *); 01771 *rint = op->x; 01772 *type = CFAPI_INT; 01773 break; 01774 01775 case CFAPI_OBJECT_PROP_Y: 01776 rint = va_arg(args, int *); 01777 *rint = op->y; 01778 *type = CFAPI_INT; 01779 break; 01780 01781 case CFAPI_OBJECT_PROP_SPEED: 01782 rfloat = va_arg(args, float *); 01783 *rfloat = op->speed; 01784 *type = CFAPI_FLOAT; 01785 break; 01786 01787 case CFAPI_OBJECT_PROP_SPEED_LEFT: 01788 rfloat = va_arg(args, float *); 01789 *rfloat = op->speed_left; 01790 *type = CFAPI_FLOAT; 01791 break; 01792 01793 case CFAPI_OBJECT_PROP_NROF: 01794 rint = va_arg(args, int *); 01795 *rint = op->nrof; 01796 *type = CFAPI_INT; 01797 break; 01798 01799 case CFAPI_OBJECT_PROP_DIRECTION: 01800 rint = va_arg(args, int *); 01801 *rint = op->direction; 01802 *type = CFAPI_INT; 01803 break; 01804 01805 case CFAPI_OBJECT_PROP_FACING: 01806 rint = va_arg(args, int *); 01807 *rint = op->facing; 01808 *type = CFAPI_INT; 01809 break; 01810 01811 case CFAPI_OBJECT_PROP_TYPE: 01812 rint = va_arg(args, int *); 01813 *rint = op->type; 01814 *type = CFAPI_INT; 01815 break; 01816 01817 case CFAPI_OBJECT_PROP_SUBTYPE: 01818 rint = va_arg(args, int *); 01819 *rint = op->subtype; 01820 *type = CFAPI_INT; 01821 break; 01822 01823 case CFAPI_OBJECT_PROP_CLIENT_TYPE: 01824 rint = va_arg(args, int *); 01825 *rint = op->client_type; 01826 *type = CFAPI_INT; 01827 break; 01828 01829 case CFAPI_OBJECT_PROP_RESIST: { 01830 int idx; 01831 sint16 *resist; 01832 01833 idx = va_arg(args, int); 01834 resist = va_arg(args, sint16 *); 01835 *resist = op->resist[idx]; 01836 } 01837 *type = CFAPI_INT16; 01838 break; 01839 01840 case CFAPI_OBJECT_PROP_ATTACK_TYPE: 01841 rint = va_arg(args, int *); 01842 *rint = op->attacktype; 01843 *type = CFAPI_INT; 01844 break; 01845 01846 case CFAPI_OBJECT_PROP_PATH_ATTUNED: 01847 rint = va_arg(args, int *); 01848 *rint = op->path_attuned; 01849 *type = CFAPI_INT; 01850 break; 01851 01852 case CFAPI_OBJECT_PROP_PATH_REPELLED: 01853 rint = va_arg(args, int *); 01854 *rint = op->path_repelled; 01855 *type = CFAPI_INT; 01856 break; 01857 01858 case CFAPI_OBJECT_PROP_PATH_DENIED: 01859 rint = va_arg(args, int *); 01860 *rint = op->path_denied; 01861 *type = CFAPI_INT; 01862 break; 01863 01864 case CFAPI_OBJECT_PROP_MATERIAL: 01865 rint = va_arg(args, int *); 01866 *rint = op->material; 01867 *type = CFAPI_INT; 01868 break; 01869 01870 case CFAPI_OBJECT_PROP_MATERIAL_NAME: 01871 rsstring = va_arg(args, sstring *); 01872 *rsstring = op->materialname; 01873 *type = CFAPI_SSTRING; 01874 break; 01875 01876 case CFAPI_OBJECT_PROP_MAGIC: 01877 rint = va_arg(args, int *); 01878 *rint = op->magic; 01879 *type = CFAPI_INT; 01880 break; 01881 01882 case CFAPI_OBJECT_PROP_VALUE: 01883 rlong = va_arg(args, long *); 01884 *rlong = op->value; 01885 *type = CFAPI_LONG; 01886 break; 01887 01888 case CFAPI_OBJECT_PROP_LEVEL: 01889 rint = va_arg(args, int *); 01890 *rint = op->level; 01891 *type = CFAPI_INT; 01892 break; 01893 01894 case CFAPI_OBJECT_PROP_LAST_HEAL: 01895 rint = va_arg(args, int *); 01896 *rint = op->last_heal; 01897 *type = CFAPI_INT; 01898 break; 01899 01900 case CFAPI_OBJECT_PROP_LAST_SP: 01901 rint = va_arg(args, int *); 01902 *rint = op->last_sp; 01903 *type = CFAPI_INT; 01904 break; 01905 01906 case CFAPI_OBJECT_PROP_LAST_GRACE: 01907 rint = va_arg(args, int *); 01908 *rint = op->last_grace; 01909 *type = CFAPI_INT; 01910 break; 01911 01912 case CFAPI_OBJECT_PROP_LAST_EAT: 01913 rint = va_arg(args, int *); 01914 *rint = op->last_eat; 01915 *type = CFAPI_INT; 01916 break; 01917 01918 case CFAPI_OBJECT_PROP_INVISIBLE_TIME: 01919 rint = va_arg(args, int *); 01920 *rint = op->invisible; 01921 *type = CFAPI_INT; 01922 break; 01923 01924 case CFAPI_OBJECT_PROP_PICK_UP: 01925 rint = va_arg(args, int *); 01926 *rint = op->pick_up; 01927 *type = CFAPI_INT; 01928 break; 01929 01930 case CFAPI_OBJECT_PROP_ITEM_POWER: 01931 rint = va_arg(args, int *); 01932 *rint = op->item_power; 01933 *type = CFAPI_INT; 01934 break; 01935 01936 case CFAPI_OBJECT_PROP_GEN_SP_ARMOUR: 01937 rint = va_arg(args, int *); 01938 *rint = op->gen_sp_armour; 01939 *type = CFAPI_INT; 01940 break; 01941 01942 case CFAPI_OBJECT_PROP_WEIGHT: 01943 rint = va_arg(args, int *); 01944 *rint = op->weight; 01945 *type = CFAPI_INT; 01946 break; 01947 01948 case CFAPI_OBJECT_PROP_WEIGHT_LIMIT: 01949 rint = va_arg(args, int *); 01950 *rint = op->weight_limit; 01951 *type = CFAPI_INT; 01952 break; 01953 01954 case CFAPI_OBJECT_PROP_CARRYING: 01955 rint = va_arg(args, int *); 01956 *rint = op->carrying; 01957 *type = CFAPI_INT; 01958 break; 01959 01960 case CFAPI_OBJECT_PROP_GLOW_RADIUS: 01961 rint = va_arg(args, int *); 01962 *rint = op->glow_radius; 01963 *type = CFAPI_INT; 01964 break; 01965 01966 case CFAPI_OBJECT_PROP_PERM_EXP: 01967 rint64 = va_arg(args, sint64 *); 01968 *rint64 = op->perm_exp; 01969 *type = CFAPI_SINT64; 01970 break; 01971 01972 case CFAPI_OBJECT_PROP_CURRENT_WEAPON: 01973 robject = va_arg(args, object **); 01974 *robject = op->current_weapon; 01975 *type = CFAPI_POBJECT; 01976 break; 01977 01978 case CFAPI_OBJECT_PROP_ENEMY: 01979 robject = va_arg(args, object **); 01980 *robject = op->enemy; 01981 *type = CFAPI_POBJECT; 01982 break; 01983 01984 case CFAPI_OBJECT_PROP_ATTACKED_BY: 01985 robject = va_arg(args, object **); 01986 *robject = op->attacked_by; 01987 *type = CFAPI_POBJECT; 01988 break; 01989 01990 case CFAPI_OBJECT_PROP_RUN_AWAY: 01991 rint = va_arg(args, int *); 01992 *rint = op->run_away; 01993 *type = CFAPI_INT; 01994 break; 01995 01996 case CFAPI_OBJECT_PROP_CHOSEN_SKILL: 01997 robject = va_arg(args, object **); 01998 *robject = op->chosen_skill; 01999 *type = CFAPI_POBJECT; 02000 break; 02001 02002 case CFAPI_OBJECT_PROP_HIDDEN: 02003 rint = va_arg(args, int *); 02004 *rint = op->hide; 02005 *type = CFAPI_INT; 02006 break; 02007 02008 case CFAPI_OBJECT_PROP_MOVE_STATUS: 02009 rint = va_arg(args, int *); 02010 *rint = op->move_status; 02011 *type = CFAPI_INT; 02012 break; 02013 02014 case CFAPI_OBJECT_PROP_ATTACK_MOVEMENT: 02015 rint = va_arg(args, int *); 02016 *rint = op->attack_movement; 02017 *type = CFAPI_INT; 02018 break; 02019 02020 case CFAPI_OBJECT_PROP_SPELL_ITEM: 02021 robject = va_arg(args, object **); 02022 *robject = op->spellitem; 02023 *type = CFAPI_POBJECT; 02024 break; 02025 02026 case CFAPI_OBJECT_PROP_EXP_MULTIPLIER: 02027 rdouble = va_arg(args, double *); 02028 *rdouble = op->expmul; 02029 *type = CFAPI_DOUBLE; 02030 break; 02031 02032 case CFAPI_OBJECT_PROP_ARCHETYPE: 02033 rarch = va_arg(args, archetype **); 02034 *rarch = op->arch; 02035 *type = CFAPI_PARCH; 02036 break; 02037 02038 case CFAPI_OBJECT_PROP_OTHER_ARCH: 02039 rarch = va_arg(args, archetype **); 02040 *rarch = op->other_arch; 02041 *type = CFAPI_PARCH; 02042 break; 02043 02044 case CFAPI_OBJECT_PROP_CUSTOM_NAME: 02045 rsstring = va_arg(args, sstring *); 02046 *rsstring = (char *)op->custom_name; 02047 *type = CFAPI_SSTRING; 02048 break; 02049 02050 case CFAPI_OBJECT_PROP_ANIM_SPEED: 02051 rint = va_arg(args, int *); 02052 *rint = op->anim_speed; 02053 *type = CFAPI_INT; 02054 break; 02055 02056 case CFAPI_OBJECT_PROP_FRIENDLY: 02057 rint = va_arg(args, int *); 02058 *rint = is_friendly(op); 02059 *type = CFAPI_INT; 02060 break; 02061 02062 case CFAPI_OBJECT_PROP_SHORT_NAME: 02063 rbuffer = va_arg(args, char *); 02064 rbufsize = va_arg(args, int); 02065 query_short_name(op, rbuffer, rbufsize); 02066 *type = CFAPI_STRING; 02067 break; 02068 02069 case CFAPI_OBJECT_PROP_BASE_NAME: { 02070 int i; 02071 02072 i = va_arg(args, int); 02073 rbuffer = va_arg(args, char *); 02074 rbufsize = va_arg(args, int); 02075 query_base_name(op, i, rbuffer, rbufsize); 02076 *type = CFAPI_STRING; 02077 } 02078 break; 02079 02080 case CFAPI_OBJECT_PROP_MAGICAL: 02081 rint = va_arg(args, int *); 02082 *rint = is_magical(op); 02083 *type = CFAPI_INT; 02084 break; 02085 02086 case CFAPI_OBJECT_PROP_LUCK: 02087 rint = va_arg(args, int *); 02088 *rint = op->stats.luck; 02089 *type = CFAPI_INT; 02090 break; 02091 02092 case CFAPI_OBJECT_PROP_EXP: 02093 rint64 = va_arg(args, sint64 *); 02094 *rint64 = op->stats.exp; 02095 *type = CFAPI_SINT64; 02096 break; 02097 02098 case CFAPI_OBJECT_PROP_OWNER: 02099 robject = va_arg(args, object **); 02100 *robject = get_owner(op); 02101 *type = CFAPI_POBJECT; 02102 break; 02103 02104 case CFAPI_OBJECT_PROP_PRESENT: { 02105 int stype; 02106 02107 stype = va_arg(args, int); 02108 switch (stype) { 02109 unsigned char ptype; 02110 char *buf; 02111 archetype *at; 02112 02113 case 0: /* present_in_ob */ 02114 ptype = (unsigned char)(va_arg(args, int)); 02115 robject = va_arg(args, object **); 02116 *robject = present_in_ob(ptype, op); 02117 break; 02118 02119 case 1: /* present_in_ob_by_name */ 02120 ptype = (unsigned char)(va_arg(args, int)); 02121 buf = va_arg(args, char *); 02122 robject = va_arg(args, object **); 02123 *robject = present_in_ob_by_name(ptype, buf, op); 02124 break; 02125 02126 case 2: /* present_arch_in_ob */ 02127 at = va_arg(args, archetype *); 02128 robject = va_arg(args, object **); 02129 *robject = present_arch_in_ob(at, op); 02130 break; 02131 } 02132 } 02133 *type = CFAPI_POBJECT; 02134 break; 02135 02136 case CFAPI_OBJECT_PROP_CHEATER: 02137 rint = va_arg(args, int *); 02138 *rint = (QUERY_FLAG(op, FLAG_WAS_WIZ)); 02139 *type = CFAPI_INT; 02140 break; 02141 02142 case CFAPI_OBJECT_PROP_MERGEABLE: { 02143 object *op2; 02144 02145 op2 = va_arg(args, object *); 02146 rint = va_arg(args, int *); 02147 *rint = can_merge(op, op2); 02148 } 02149 *type = CFAPI_INT; 02150 break; 02151 02152 case CFAPI_OBJECT_PROP_PICKABLE: { 02153 object *op2; 02154 02155 op2 = va_arg(args, object *); 02156 rint = va_arg(args, int *); 02157 *rint = can_pick(op2, op); 02158 } 02159 *type = CFAPI_INT; 02160 break; 02161 02162 case CFAPI_OBJECT_PROP_FLAGS: { 02163 int fl; 02164 02165 fl = va_arg(args, int); 02166 rint = va_arg(args, int *); 02167 *rint = QUERY_FLAG(op, fl); 02168 } 02169 *type = CFAPI_INT; 02170 break; 02171 02172 case CFAPI_OBJECT_PROP_STR: 02173 rint = va_arg(args, int *); 02174 *rint = op->stats.Str; 02175 *type = CFAPI_INT; 02176 break; 02177 02178 case CFAPI_OBJECT_PROP_DEX: 02179 rint = va_arg(args, int *); 02180 *rint = op->stats.Dex; 02181 *type = CFAPI_INT; 02182 break; 02183 02184 case CFAPI_OBJECT_PROP_CON: 02185 rint = va_arg(args, int *); 02186 *rint = op->stats.Con; 02187 *type = CFAPI_INT; 02188 break; 02189 02190 case CFAPI_OBJECT_PROP_WIS: 02191 rint = va_arg(args, int *); 02192 *rint = op->stats.Wis; 02193 *type = CFAPI_INT; 02194 break; 02195 02196 case CFAPI_OBJECT_PROP_INT: 02197 rint = va_arg(args, int *); 02198 *rint = op->stats.Int; 02199 *type = CFAPI_INT; 02200 break; 02201 02202 case CFAPI_OBJECT_PROP_POW: 02203 rint = va_arg(args, int *); 02204 *rint = op->stats.Pow; 02205 *type = CFAPI_INT; 02206 break; 02207 02208 case CFAPI_OBJECT_PROP_CHA: 02209 rint = va_arg(args, int *); 02210 *rint = op->stats.Cha; 02211 *type = CFAPI_INT; 02212 break; 02213 02214 case CFAPI_OBJECT_PROP_WC: 02215 rint = va_arg(args, int *); 02216 *rint = op->stats.wc; 02217 *type = CFAPI_INT; 02218 break; 02219 02220 case CFAPI_OBJECT_PROP_AC: 02221 rint = va_arg(args, int *); 02222 *rint = op->stats.ac; 02223 *type = CFAPI_INT; 02224 break; 02225 02226 case CFAPI_OBJECT_PROP_HP: 02227 rint = va_arg(args, int *); 02228 *rint = op->stats.hp; 02229 *type = CFAPI_INT; 02230 break; 02231 02232 case CFAPI_OBJECT_PROP_SP: 02233 rint = va_arg(args, int *); 02234 *rint = op->stats.sp; 02235 *type = CFAPI_INT; 02236 break; 02237 02238 case CFAPI_OBJECT_PROP_GP: 02239 rint = va_arg(args, int *); 02240 *rint = op->stats.grace; 02241 *type = CFAPI_INT; 02242 break; 02243 02244 case CFAPI_OBJECT_PROP_FP: 02245 rint = va_arg(args, int *); 02246 *rint = op->stats.food; 02247 *type = CFAPI_INT; 02248 break; 02249 02250 case CFAPI_OBJECT_PROP_MAXHP: 02251 rint = va_arg(args, int *); 02252 *rint = op->stats.maxhp; 02253 *type = CFAPI_INT; 02254 break; 02255 02256 case CFAPI_OBJECT_PROP_MAXSP: 02257 rint = va_arg(args, int *); 02258 *rint = op->stats.maxsp; 02259 *type = CFAPI_INT; 02260 break; 02261 02262 case CFAPI_OBJECT_PROP_MAXGP: 02263 rint = va_arg(args, int *); 02264 *rint = op->stats.maxgrace; 02265 *type = CFAPI_INT; 02266 break; 02267 02268 case CFAPI_OBJECT_PROP_DAM: 02269 rint = va_arg(args, int *); 02270 *rint = op->stats.dam; 02271 *type = CFAPI_INT; 02272 break; 02273 02274 case CFAPI_OBJECT_PROP_GOD: 02275 rsstring = va_arg(args, sstring *); 02276 *rsstring = determine_god(op); 02277 *type = CFAPI_SSTRING; 02278 break; 02279 02280 case CFAPI_OBJECT_PROP_ARCH_NAME: 02281 rsstring = va_arg(args, sstring *); 02282 *rsstring = op->arch->name; 02283 *type = CFAPI_SSTRING; 02284 break; 02285 02286 case CFAPI_OBJECT_PROP_INVISIBLE: 02287 rint = va_arg(args, int *); 02288 *rint = op->invisible; 02289 *type = CFAPI_INT; 02290 break; 02291 02292 case CFAPI_OBJECT_PROP_FACE: 02293 rint = va_arg(args, int *); 02294 *rint = op->face->number; 02295 *type = CFAPI_INT; 02296 break; 02297 02298 case CFAPI_OBJECT_PROP_ANIMATION: 02299 rint = va_arg(args, int *); 02300 *rint = op->animation_id; 02301 *type = CFAPI_INT; 02302 break; 02303 02304 case CFAPI_PLAYER_PROP_IP: 02305 rsstring = va_arg(args, sstring *); 02306 *rsstring = op->contr->socket.host; 02307 *type = CFAPI_SSTRING; 02308 break; 02309 02310 case CFAPI_PLAYER_PROP_MARKED_ITEM: 02311 robject = va_arg(args, object **); 02312 *robject = find_marked_object(op); 02313 *type = CFAPI_POBJECT; 02314 break; 02315 02316 case CFAPI_PLAYER_PROP_PARTY: 02317 rparty = va_arg(args, partylist **); 02318 *rparty = (op->contr ? op->contr->party : NULL); 02319 *type = CFAPI_PPARTY; 02320 break; 02321 02322 case CFAPI_PLAYER_PROP_NEXT: 02323 robject = va_arg(args, object **); 02324 if (op) 02325 *robject = op->contr->next ? op->contr->next->ob : NULL; 02326 else 02327 /* This can be called when there is no player. */ 02328 *robject = first_player ? first_player->ob : NULL; 02329 *type = CFAPI_POBJECT; 02330 break; 02331 02332 case CFAPI_PLAYER_PROP_TITLE: 02333 rsstring = va_arg(args, sstring *); 02334 *rsstring = op->contr->title; 02335 *type = CFAPI_SSTRING; 02336 break; 02337 02338 case CFAPI_OBJECT_PROP_NO_SAVE: 02339 rint = va_arg(args, int *); 02340 *rint = op->no_save; 02341 *type = CFAPI_INT; 02342 break; 02343 02344 case CFAPI_OBJECT_PROP_MOVE_TYPE: 02345 rmove = va_arg(args, MoveType *); 02346 *rmove = op->move_type; 02347 *type = CFAPI_MOVETYPE; 02348 break; 02349 02350 case CFAPI_OBJECT_PROP_MOVE_BLOCK: 02351 rmove = va_arg(args, MoveType *); 02352 *rmove = op->move_block; 02353 *type = CFAPI_MOVETYPE; 02354 break; 02355 02356 case CFAPI_OBJECT_PROP_MOVE_ALLOW: 02357 rmove = va_arg(args, MoveType *); 02358 *rmove = op->move_allow; 02359 *type = CFAPI_MOVETYPE; 02360 break; 02361 02362 case CFAPI_OBJECT_PROP_MOVE_ON: 02363 rmove = va_arg(args, MoveType *); 02364 *rmove = op->move_on; 02365 *type = CFAPI_MOVETYPE; 02366 break; 02367 02368 case CFAPI_OBJECT_PROP_MOVE_OFF: 02369 rmove = va_arg(args, MoveType *); 02370 *rmove = op->move_off; 02371 *type = CFAPI_MOVETYPE; 02372 break; 02373 02374 case CFAPI_OBJECT_PROP_MOVE_SLOW: 02375 rmove = va_arg(args, MoveType *); 02376 *rmove = op->move_type; 02377 *type = CFAPI_MOVETYPE; 02378 break; 02379 02380 case CFAPI_OBJECT_PROP_MOVE_SLOW_PENALTY: 02381 rfloat = va_arg(args, float *); 02382 *rfloat = op->move_slow_penalty; 02383 *type = CFAPI_FLOAT; 02384 break; 02385 02386 case CFAPI_PLAYER_PROP_BED_MAP: 02387 rbuffer = va_arg(args, char *); 02388 rbufsize = va_arg(args, int); 02389 snprintf(rbuffer, rbufsize, "%s", op->contr->savebed_map); 02390 *type = CFAPI_STRING; 02391 break; 02392 02393 case CFAPI_PLAYER_PROP_BED_X: 02394 rint = va_arg(args, int *); 02395 *rint = op->contr->bed_x; 02396 *type = CFAPI_INT; 02397 break; 02398 02399 case CFAPI_PLAYER_PROP_BED_Y: 02400 rint = va_arg(args, int *); 02401 *rint = op->contr->bed_y; 02402 *type = CFAPI_INT; 02403 break; 02404 02405 case CFAPI_OBJECT_PROP_DURATION: 02406 rint = va_arg(args, int *); 02407 *rint = op->duration; 02408 *type = CFAPI_INT; 02409 break; 02410 02411 default: 02412 *type = CFAPI_NONE; 02413 break; 02414 } 02415 va_end(args); 02416 return NULL; 02417 } 02418 02427 static void copy_message(object *op, const char *msg) { 02428 char *temp; 02429 int size; 02430 02431 if (!msg) 02432 return; 02433 02434 size = strlen(msg); 02435 02436 if (msg[0] != 0 && msg[size-1] == '\n') { 02437 FREE_AND_COPY(op->msg, msg); 02438 return; 02439 } 02440 02441 temp = malloc(size+2); 02442 if (!temp) 02443 fatal(OUT_OF_MEMORY); 02444 snprintf(temp, size+2, "%s\n", msg); 02445 FREE_AND_COPY(op->msg, temp); 02446 free(temp); 02447 } 02448 02459 void *cfapi_object_set_property(int *type, ...) { 02460 va_list args; 02461 int iarg; 02462 long larg; 02463 char *sarg; 02464 double darg; 02465 object *oparg; 02466 object *op; 02467 int property; 02468 sint64 s64arg; 02469 partylist *partyarg; 02470 float farg; 02471 02472 va_start(args, type); 02473 op = va_arg(args, object *); 02474 property = va_arg(args, int); 02475 *type = CFAPI_NONE; 02476 02477 if (op != NULL && (!op->arch || (op != &op->arch->clone))) { 02478 switch (property) { 02479 case CFAPI_OBJECT_PROP_NAME: 02480 sarg = va_arg(args, char *); 02481 *type = CFAPI_STRING; 02482 FREE_AND_COPY(op->name, sarg); 02483 send_changed_object(op); 02484 break; 02485 02486 case CFAPI_OBJECT_PROP_NAME_PLURAL: 02487 sarg = va_arg(args, char *); 02488 *type = CFAPI_STRING; 02489 FREE_AND_COPY(op->name_pl, sarg); 02490 send_changed_object(op); 02491 break; 02492 02493 case CFAPI_OBJECT_PROP_TITLE: 02494 sarg = va_arg(args, char *); 02495 *type = CFAPI_STRING; 02496 FREE_AND_COPY(op->title, sarg); 02497 break; 02498 02499 case CFAPI_OBJECT_PROP_RACE: 02500 sarg = va_arg(args, char *); 02501 *type = CFAPI_STRING; 02502 FREE_AND_COPY(op->race, sarg); 02503 break; 02504 02505 case CFAPI_OBJECT_PROP_SLAYING: 02506 sarg = va_arg(args, char *); 02507 *type = CFAPI_STRING; 02508 FREE_AND_COPY(op->slaying, sarg); 02509 break; 02510 02511 case CFAPI_OBJECT_PROP_SKILL: 02512 sarg = va_arg(args, char *); 02513 *type = CFAPI_STRING; 02514 FREE_AND_COPY(op->skill, sarg); 02515 break; 02516 02517 case CFAPI_OBJECT_PROP_MESSAGE: 02518 sarg = va_arg(args, char *); 02519 *type = CFAPI_STRING; 02520 copy_message(op, sarg); 02521 break; 02522 02523 case CFAPI_OBJECT_PROP_LORE: 02524 sarg = va_arg(args, char *); 02525 *type = CFAPI_STRING; 02526 FREE_AND_COPY(op->lore, sarg); 02527 break; 02528 02529 case CFAPI_OBJECT_PROP_SPEED: 02530 farg = va_arg(args, double); 02531 *type = CFAPI_FLOAT; 02532 if (farg != op->speed) { 02533 op->speed = farg; 02534 update_ob_speed(op); 02535 } 02536 break; 02537 02538 case CFAPI_OBJECT_PROP_SPEED_LEFT: 02539 farg = va_arg(args, double); 02540 *type = CFAPI_FLOAT; 02541 op->speed_left = farg; 02542 break; 02543 02544 case CFAPI_OBJECT_PROP_NROF: 02545 iarg = va_arg(args, int); 02546 *type = CFAPI_INT; 02547 if (iarg < 0) 02548 iarg = 0; 02549 if (op->nrof > (uint32)iarg) 02550 decrease_ob_nr(op, op->nrof-iarg); 02551 else if (op->nrof < (uint32)iarg) { 02552 object *tmp; 02553 player *pl; 02554 02555 op->nrof = iarg; 02556 if (op->env != NULL) { 02557 tmp = get_player_container(op->env); 02558 if (!tmp) { 02559 for (pl = first_player; pl; pl = pl->next) 02560 if (pl->ob->container == op->env) 02561 break; 02562 if (pl) 02563 tmp = pl->ob; 02564 else 02565 tmp = NULL; 02566 } else { 02567 sum_weight(tmp); 02568 fix_object(tmp); 02569 } 02570 if (tmp) 02571 esrv_update_item(UPD_NROF, tmp, op); 02572 } else { 02573 object *above = op->above; 02574 02575 for (tmp = above; tmp != NULL; tmp = tmp->above) 02576 if (tmp->type == PLAYER) 02577 tmp->contr->socket.update_look = 1; 02578 } 02579 } 02580 break; 02581 02582 case CFAPI_OBJECT_PROP_DIRECTION: 02583 iarg = va_arg(args, int); 02584 *type = CFAPI_INT; 02585 op->direction = iarg; 02586 break; 02587 02588 case CFAPI_OBJECT_PROP_FACING: 02589 iarg = va_arg(args, int); 02590 *type = CFAPI_INT; 02591 op->facing = iarg; 02592 break; 02593 02594 case CFAPI_OBJECT_PROP_RESIST: { 02595 int iargbis = va_arg(args, int); 02596 02597 *type = CFAPI_INT16; 02598 iarg = va_arg(args, int); 02599 op->resist[iargbis] = iarg; 02600 } 02601 break; 02602 02603 case CFAPI_OBJECT_PROP_ATTACK_TYPE: 02604 iarg = va_arg(args, int); 02605 *type = CFAPI_INT; 02606 op->attacktype = iarg; 02607 break; 02608 02609 case CFAPI_OBJECT_PROP_PATH_ATTUNED: 02610 iarg = va_arg(args, int); 02611 *type = CFAPI_INT; 02612 op->path_attuned = iarg; 02613 break; 02614 02615 case CFAPI_OBJECT_PROP_PATH_REPELLED: 02616 iarg = va_arg(args, int); 02617 *type = CFAPI_INT; 02618 op->path_repelled = iarg; 02619 break; 02620 02621 case CFAPI_OBJECT_PROP_PATH_DENIED: 02622 iarg = va_arg(args, int); 02623 *type = CFAPI_INT; 02624 op->path_denied = iarg; 02625 break; 02626 02627 case CFAPI_OBJECT_PROP_MATERIAL: 02628 iarg = va_arg(args, int); 02629 *type = CFAPI_INT; 02630 op->material = iarg; 02631 break; 02632 02633 case CFAPI_OBJECT_PROP_MATERIAL_NAME: 02634 break; 02635 02636 case CFAPI_OBJECT_PROP_MAGIC: 02637 iarg = va_arg(args, int); 02638 *type = CFAPI_INT; 02639 op->magic = iarg; 02640 break; 02641 02642 case CFAPI_OBJECT_PROP_VALUE: 02643 larg = va_arg(args, long); 02644 *type = CFAPI_LONG; 02645 op->value = larg; 02646 break; 02647 02648 case CFAPI_OBJECT_PROP_LEVEL: 02649 iarg = va_arg(args, int); 02650 *type = CFAPI_INT; 02651 op->level = iarg; 02652 break; 02653 02654 case CFAPI_OBJECT_PROP_LAST_HEAL: 02655 iarg = va_arg(args, int); 02656 *type = CFAPI_INT; 02657 op->last_heal = iarg; 02658 break; 02659 02660 case CFAPI_OBJECT_PROP_LAST_SP: 02661 iarg = va_arg(args, int); 02662 *type = CFAPI_INT; 02663 op->last_sp = iarg; 02664 break; 02665 02666 case CFAPI_OBJECT_PROP_LAST_GRACE: 02667 iarg = va_arg(args, int); 02668 *type = CFAPI_INT; 02669 op->last_grace = iarg; 02670 break; 02671 02672 case CFAPI_OBJECT_PROP_LAST_EAT: 02673 iarg = va_arg(args, int); 02674 *type = CFAPI_INT; 02675 op->last_eat = iarg; 02676 break; 02677 02678 case CFAPI_OBJECT_PROP_INVISIBLE_TIME: 02679 iarg = va_arg(args, int); 02680 *type = CFAPI_INT; 02681 op->invisible = iarg; 02682 break; 02683 02684 case CFAPI_OBJECT_PROP_PICK_UP: 02685 iarg = va_arg(args, int); 02686 *type = CFAPI_INT; 02687 op->pick_up = iarg; 02688 break; 02689 02690 case CFAPI_OBJECT_PROP_ITEM_POWER: 02691 iarg = va_arg(args, int); 02692 *type = CFAPI_INT; 02693 op->item_power = iarg; 02694 break; 02695 02696 case CFAPI_OBJECT_PROP_GEN_SP_ARMOUR: 02697 iarg = va_arg(args, int); 02698 *type = CFAPI_INT; 02699 op->gen_sp_armour = iarg; 02700 break; 02701 02702 case CFAPI_OBJECT_PROP_WEIGHT: 02703 iarg = va_arg(args, int); 02704 *type = CFAPI_INT; 02705 if (op->weight != iarg) { 02706 object *tmp; 02707 player *pl; 02708 02709 op->weight = iarg; 02710 if (op->env != NULL) { 02711 tmp = get_player_container(op->env); 02712 if (!tmp) { 02713 for (pl = first_player; pl; pl = pl->next) 02714 if (pl->ob->container == op->env) 02715 break; 02716 if (pl) 02717 tmp = pl->ob; 02718 else 02719 tmp = NULL; 02720 } else { 02721 sum_weight(tmp); 02722 fix_object(tmp); 02723 } 02724 if (tmp) 02725 esrv_update_item(UPD_WEIGHT, tmp, op); 02726 } else { 02727 object *above = op->above; 02728 02729 for (tmp = above; tmp != NULL; tmp = tmp->above) 02730 if (tmp->type == PLAYER) 02731 esrv_update_item(UPD_WEIGHT, tmp, op); 02732 } 02733 } 02734 break; 02735 02736 case CFAPI_OBJECT_PROP_WEIGHT_LIMIT: 02737 iarg = va_arg(args, int); 02738 *type = CFAPI_INT; 02739 op->weight_limit = iarg; 02740 break; 02741 02742 case CFAPI_OBJECT_PROP_GLOW_RADIUS: 02743 iarg = va_arg(args, int); 02744 *type = CFAPI_INT; 02745 if (op->glow_radius != iarg) { 02746 object *tmp; 02747 02748 op->glow_radius = iarg; 02749 tmp = object_get_env_recursive(op); 02750 if (tmp->map != NULL) { 02751 SET_MAP_FLAGS(tmp->map, tmp->x, tmp->y, P_NEED_UPDATE); 02752 update_position(tmp->map, tmp->x, tmp->y); 02753 update_all_los(tmp->map, tmp->x, tmp->y); 02754 } 02755 } 02756 break; 02757 02758 case CFAPI_OBJECT_PROP_PERM_EXP: 02759 s64arg = va_arg(args, sint64); 02760 *type = CFAPI_SINT64; 02761 op->perm_exp = s64arg; 02762 break; 02763 02764 case CFAPI_OBJECT_PROP_ENEMY: 02765 oparg = va_arg(args, object *); 02766 *type = CFAPI_POBJECT; 02767 op->enemy = oparg; 02768 break; 02769 02770 case CFAPI_OBJECT_PROP_RUN_AWAY: 02771 iarg = va_arg(args, int); 02772 *type = CFAPI_INT; 02773 op->run_away = iarg; 02774 break; 02775 02776 case CFAPI_OBJECT_PROP_CHOSEN_SKILL: 02777 oparg = va_arg(args, object *); 02778 *type = CFAPI_POBJECT; 02779 op->chosen_skill = oparg; 02780 break; 02781 02782 case CFAPI_OBJECT_PROP_HIDDEN: 02783 iarg = va_arg(args, int); 02784 *type = CFAPI_INT; 02785 op->hide = iarg; 02786 break; 02787 02788 case CFAPI_OBJECT_PROP_MOVE_STATUS: 02789 iarg = va_arg(args, int); 02790 *type = CFAPI_INT; 02791 op->move_status = iarg; 02792 break; 02793 02794 case CFAPI_OBJECT_PROP_ATTACK_MOVEMENT: 02795 iarg = va_arg(args, int); 02796 *type = CFAPI_INT; 02797 op->attack_movement = iarg; 02798 break; 02799 02800 case CFAPI_OBJECT_PROP_SPELL_ITEM: 02801 oparg = va_arg(args, object *); 02802 *type = CFAPI_POBJECT; 02803 op->spellitem = oparg; 02804 break; 02805 02806 case CFAPI_OBJECT_PROP_EXP_MULTIPLIER: 02807 darg = va_arg(args, double); 02808 *type = CFAPI_DOUBLE; 02809 op->expmul = darg; 02810 break; 02811 02812 case CFAPI_OBJECT_PROP_CUSTOM_NAME: 02813 sarg = va_arg(args, char *); 02814 *type = CFAPI_STRING; 02815 FREE_AND_COPY(op->custom_name, sarg); 02816 send_changed_object(op); 02817 break; 02818 02819 case CFAPI_OBJECT_PROP_ANIM_SPEED: 02820 iarg = va_arg(args, int); 02821 *type = CFAPI_INT; 02822 op->anim_speed = iarg; 02823 break; 02824 02825 case CFAPI_OBJECT_PROP_FRIENDLY: 02826 iarg = va_arg(args, int); 02827 *type = CFAPI_INT; 02828 if (iarg == 1 && is_friendly(op) == 0) 02829 add_friendly_object(op); 02830 else if (iarg == 0 && is_friendly(op) == 1) 02831 remove_friendly_object(op); 02832 break; 02833 02834 case CFAPI_OBJECT_PROP_LUCK: 02835 iarg = va_arg(args, int); 02836 *type = CFAPI_INT; 02837 op->stats.luck = iarg; 02838 break; 02839 02840 case CFAPI_OBJECT_PROP_EXP: 02841 s64arg = va_arg(args, sint64); 02842 *type = CFAPI_SINT64; 02843 op->stats.exp = s64arg; 02844 break; 02845 02846 case CFAPI_OBJECT_PROP_OWNER: 02847 oparg = va_arg(args, object *); 02848 *type = CFAPI_POBJECT; 02849 set_owner(op, oparg); 02850 break; 02851 02852 case CFAPI_OBJECT_PROP_CHEATER: 02853 set_cheat(op); 02854 *type = CFAPI_NONE; 02855 break; 02856 02857 case CFAPI_OBJECT_PROP_FLAGS: { 02858 int iargbis; 02859 02860 iarg = va_arg(args, int); 02861 iargbis = va_arg(args, int); 02862 *type = CFAPI_INT; 02863 02864 if (iargbis == 1) 02865 SET_FLAG(op, iarg); 02866 else 02867 CLEAR_FLAG(op, iarg); 02868 } 02869 break; 02870 02871 case CFAPI_OBJECT_PROP_STR: 02872 iarg = va_arg(args, int); 02873 *type = CFAPI_INT; 02874 op->stats.Str = iarg; 02875 break; 02876 02877 case CFAPI_OBJECT_PROP_DEX: 02878 iarg = va_arg(args, int); 02879 *type = CFAPI_INT; 02880 op->stats.Dex = iarg; 02881 break; 02882 02883 case CFAPI_OBJECT_PROP_CON: 02884 iarg = va_arg(args, int); 02885 *type = CFAPI_INT; 02886 op->stats.Con = iarg; 02887 break; 02888 02889 case CFAPI_OBJECT_PROP_WIS: 02890 iarg = va_arg(args, int); 02891 *type = CFAPI_INT; 02892 op->stats.Wis = iarg; 02893 break; 02894 02895 case CFAPI_OBJECT_PROP_INT: 02896 iarg = va_arg(args, int); 02897 *type = CFAPI_INT; 02898 op->stats.Int = iarg; 02899 break; 02900 02901 case CFAPI_OBJECT_PROP_POW: 02902 iarg = va_arg(args, int); 02903 *type = CFAPI_INT; 02904 op->stats.Pow = iarg; 02905 break; 02906 02907 case CFAPI_OBJECT_PROP_CHA: 02908 iarg = va_arg(args, int); 02909 *type = CFAPI_INT; 02910 op->stats.Cha = iarg; 02911 break; 02912 02913 case CFAPI_OBJECT_PROP_WC: 02914 iarg = va_arg(args, int); 02915 *type = CFAPI_INT; 02916 op->stats.wc = iarg; 02917 break; 02918 02919 case CFAPI_OBJECT_PROP_AC: 02920 iarg = va_arg(args, int); 02921 *type = CFAPI_INT; 02922 op->stats.ac = iarg; 02923 break; 02924 02925 case CFAPI_OBJECT_PROP_HP: 02926 iarg = va_arg(args, int); 02927 *type = CFAPI_INT; 02928 op->stats.hp = iarg; 02929 break; 02930 02931 case CFAPI_OBJECT_PROP_SP: 02932 iarg = va_arg(args, int); 02933 *type = CFAPI_INT; 02934 op->stats.sp = iarg; 02935 break; 02936 02937 case CFAPI_OBJECT_PROP_GP: 02938 iarg = va_arg(args, int); 02939 *type = CFAPI_INT; 02940 op->stats.grace = iarg; 02941 break; 02942 02943 case CFAPI_OBJECT_PROP_FP: 02944 iarg = va_arg(args, int); 02945 *type = CFAPI_INT; 02946 op->stats.food = iarg; 02947 break; 02948 02949 case CFAPI_OBJECT_PROP_MAXHP: 02950 iarg = va_arg(args, int); 02951 *type = CFAPI_INT; 02952 op->stats.maxhp = iarg; 02953 break; 02954 02955 case CFAPI_OBJECT_PROP_MAXSP: 02956 iarg = va_arg(args, int); 02957 *type = CFAPI_INT; 02958 op->stats.maxsp = iarg; 02959 break; 02960 02961 case CFAPI_OBJECT_PROP_MAXGP: 02962 iarg = va_arg(args, int); 02963 *type = CFAPI_INT; 02964 op->stats.maxgrace = iarg; 02965 break; 02966 02967 case CFAPI_OBJECT_PROP_DAM: 02968 iarg = va_arg(args, int); 02969 *type = CFAPI_INT; 02970 op->stats.dam = iarg; 02971 break; 02972 02973 case CFAPI_OBJECT_PROP_FACE: 02974 iarg = va_arg(args, int); 02975 *type = CFAPI_INT; 02976 op->face = &new_faces[iarg]; 02977 op->state = 0; 02978 update_object(op, UP_OBJ_FACE); 02979 break; 02980 02981 case CFAPI_OBJECT_PROP_ANIMATION: 02982 iarg = va_arg(args, int); 02983 *type = CFAPI_INT; 02984 op->animation_id = iarg; 02985 SET_ANIMATION(op, 0); 02986 update_object(op, UP_OBJ_FACE); 02987 break; 02988 02989 case CFAPI_OBJECT_PROP_DURATION: 02990 iarg = va_arg(args, int); 02991 *type = CFAPI_INT; 02992 op->duration = iarg; 02993 break; 02994 02995 case CFAPI_PLAYER_PROP_MARKED_ITEM: 02996 if (op->contr) { 02997 oparg = va_arg(args, object *); 02998 *type = CFAPI_POBJECT; 02999 op->contr->mark = oparg; 03000 if (oparg) 03001 op->contr->mark_count = oparg->count; 03002 } 03003 break; 03004 03005 case CFAPI_PLAYER_PROP_PARTY: 03006 if (op->contr) { 03007 partyarg = va_arg(args, partylist *); 03008 *type = CFAPI_PPARTY; 03009 op->contr->party = partyarg; 03010 } 03011 break; 03012 03013 case CFAPI_OBJECT_PROP_NO_SAVE: 03014 iarg = va_arg(args, int); 03015 *type = CFAPI_INT; 03016 op->no_save = iarg; 03017 break; 03018 03019 case CFAPI_PLAYER_PROP_BED_MAP: 03020 sarg = va_arg(args, char *); 03021 *type = CFAPI_STRING; 03022 strncpy(op->contr->savebed_map, sarg, MAX_BUF); 03023 break; 03024 03025 case CFAPI_PLAYER_PROP_BED_X: 03026 iarg = va_arg(args, int); 03027 *type = CFAPI_INT; 03028 op->contr->bed_x = iarg; 03029 break; 03030 03031 case CFAPI_PLAYER_PROP_BED_Y: 03032 iarg = va_arg(args, int); 03033 *type = CFAPI_INT; 03034 op->contr->bed_y = iarg; 03035 break; 03036 03037 case CFAPI_PLAYER_PROP_TITLE: 03038 sarg = va_arg(args, char *); 03039 *type = CFAPI_STRING; 03040 strncpy(op->contr->title, sarg, sizeof(op->contr->title)); 03041 op->contr->title[sizeof(op->contr->title) - 1]= '\0'; 03042 break; 03043 03044 default: 03045 break; 03046 } 03047 } 03048 va_end(args); 03049 03050 return NULL; 03051 } 03052 03061 void *cfapi_object_apply_below(int *type, ...) { 03062 va_list args; 03063 object *applier; 03064 03065 va_start(args, type); 03066 03067 applier = va_arg(args, object *); 03068 03069 va_end(args); 03070 03071 player_apply_below(applier); 03072 *type = CFAPI_NONE; 03073 return NULL; 03074 } 03075 03084 void *cfapi_object_apply(int *type, ...) { 03085 va_list args; 03086 object *applied; 03087 object *applier; 03088 int aflags; 03089 int *ret; 03090 03091 va_start(args, type); 03092 03093 applier = va_arg(args, object *); 03094 applied = va_arg(args, object *); 03095 aflags = va_arg(args, int); 03096 ret = va_arg(args, int *); 03097 03098 va_end(args); 03099 03100 *type = CFAPI_INT; 03101 *ret = manual_apply(applier, applied, aflags); 03102 return NULL; 03103 } 03104 03112 void *cfapi_object_identify(int *type, ...) { 03113 va_list args; 03114 object *op; 03115 03116 va_start(args, type); 03117 03118 op = va_arg(args, object *); 03119 03120 va_end(args); 03121 03122 identify(op); 03123 *type = CFAPI_NONE; 03124 return NULL; 03125 } 03126 03134 void *cfapi_object_describe(int *type, ...) { 03135 va_list args; 03136 object *op; 03137 object *owner; 03138 char *desc; 03139 int size; 03140 03141 va_start(args, type); 03142 03143 op = va_arg(args, object *); 03144 owner = va_arg(args, object *); 03145 desc = va_arg(args, char *); 03146 size = va_arg(args, int); 03147 va_end(args); 03148 03149 *type = CFAPI_STRING; 03150 describe_item(op, owner, desc, size); 03151 return NULL; 03152 } 03153 03154 void *cfapi_object_drain(int *type, ...) { 03155 va_list args; 03156 03157 object *op; 03158 int ds; 03159 03160 va_start(args, type); 03161 03162 op = va_arg(args, object *); 03163 ds = va_arg(args, int); 03164 03165 va_end(args); 03166 03167 drain_specific_stat(op, ds); 03168 03169 *type = CFAPI_NONE; 03170 return NULL; 03171 } 03172 03173 void *cfapi_object_fix(int *type, ...) { 03174 va_list args; 03175 object *op; 03176 03177 va_start(args, type); 03178 03179 op = va_arg(args, object *); 03180 03181 va_end(args); 03182 03183 fix_object(op); 03184 03185 *type = CFAPI_NONE; 03186 return NULL; 03187 } 03188 03189 void *cfapi_object_give_skill(int *type, ...) { 03190 va_list args; 03191 03192 object *op; 03193 char *skillname; 03194 03195 va_start(args, type); 03196 03197 op = va_arg(args, object *); 03198 skillname = va_arg(args, char *); 03199 03200 va_end(args); 03201 03202 *type = CFAPI_POBJECT; 03203 return give_skill_by_name(op, skillname); 03204 } 03205 03206 void *cfapi_object_transmute(int *type, ...) { 03207 va_list args; 03208 03209 object *op; 03210 object *chg; 03211 03212 va_start(args, type); 03213 03214 op = va_arg(args, object *); 03215 chg = va_arg(args, object *); 03216 03217 va_end(args); 03218 03219 transmute_materialname(op, chg); 03220 *type = CFAPI_NONE; 03221 return NULL; 03222 } 03223 03224 void *cfapi_object_remove(int *type, ...) { 03225 va_list args; 03226 object *op; 03227 03228 va_start(args, type); 03229 03230 op = va_arg(args, object *); 03231 03232 if (QUERY_FLAG(op, FLAG_REMOVED)) { 03233 LOG(llevError, "Plugin trying to remove removed object %s\n", op->name); 03234 *type = CFAPI_NONE; 03235 return NULL; 03236 } 03237 03238 va_end(args); 03239 03240 remove_ob(op); 03241 *type = CFAPI_NONE; 03242 return NULL; 03243 } 03244 03245 void *cfapi_object_delete(int *type, ...) { 03246 va_list args; 03247 object *op; 03248 03249 va_start(args, type); 03250 03251 op = va_arg(args, object *); 03252 03253 if (QUERY_FLAG(op, FLAG_FREED) || !QUERY_FLAG(op, FLAG_REMOVED)) { 03254 LOG(llevError, "Plugin trying to free freed/non removed object %s\n", op->name); 03255 *type = CFAPI_NONE; 03256 return NULL; 03257 } 03258 03259 va_end(args); 03260 03261 free_object(op); 03262 03263 *type = CFAPI_NONE; 03264 return NULL; 03265 } 03266 03274 void *cfapi_object_clone(int *type, ...) { 03275 va_list args; 03276 object *op; 03277 int kind; 03278 object **robj; 03279 03280 va_start(args, type); 03281 03282 op = va_arg(args, object *); 03283 kind = va_arg(args, int); 03284 robj = va_arg(args, object **); 03285 03286 va_end(args); 03287 03288 if (kind == 0) { 03289 *type = CFAPI_POBJECT; 03290 *robj = object_create_clone(op); 03291 } else { 03292 object *tmp; 03293 tmp = get_object(); 03294 copy_object(op, tmp); 03295 *type = CFAPI_POBJECT; 03296 *robj = tmp; 03297 } 03298 return NULL; 03299 } 03300 03301 void *cfapi_object_find(int *type, ...) { 03302 va_list args; 03303 int ftype; 03304 void *rv; 03305 int ival; 03306 int ival2; 03307 char *sval; 03308 object *op; 03309 03310 va_start(args, type); 03311 03312 *type = CFAPI_POBJECT; 03313 ftype = va_arg(args, int); 03314 switch (ftype) { 03315 case 0: 03316 ival = va_arg(args, int); 03317 rv = find_object(ival); 03318 break; 03319 03320 case 1: 03321 sval = va_arg(args, char *); 03322 rv = find_object_name(sval); 03323 break; 03324 03325 case 2: 03326 op = va_arg(args, object *); 03327 ival = va_arg(args, int); 03328 ival2 = va_arg(args, int); 03329 rv = find_obj_by_type_subtype(op, ival, ival2); 03330 break; 03331 03332 case 3: 03333 op = va_arg(args, object *); 03334 rv = get_player_container(op); 03335 break; 03336 03337 default: 03338 rv = NULL; 03339 *type = CFAPI_NONE; 03340 break; 03341 } 03342 03343 va_end(args); 03344 03345 return rv; 03346 } 03347 03355 void *cfapi_object_create(int *type, ...) { 03356 va_list args; 03357 int ival; 03358 object **robj; 03359 va_start(args, type); 03360 ival = va_arg(args, int); 03361 03362 *type = CFAPI_POBJECT; 03363 switch (ival) { 03364 case 0: 03365 robj = va_arg(args, object **); 03366 *robj = get_object(); 03367 break; 03368 03369 case 1: { /* Named object. Nearly the old plugin behavior, but we don't add artifact suffixes */ 03370 const char *sval; 03371 archetype *at; 03372 03373 sval = va_arg(args, const char *); 03374 robj = va_arg(args, object **); 03375 va_end(args); 03376 03377 at = try_find_archetype(sval); 03378 if (!at) 03379 at = find_archetype_by_object_name(sval); 03380 if (at) { 03381 *robj = object_create_arch(at); 03382 } else 03383 *robj = NULL; 03384 } 03385 break; 03386 03387 default: 03388 *type = CFAPI_NONE; 03389 break; 03390 } 03391 va_end(args); 03392 return NULL; 03393 } 03394 void *cfapi_object_insert(int *type, ...) { 03395 va_list args; 03396 object *op; 03397 object *orig; 03398 mapstruct *map; 03399 int flag, x, y; 03400 int itype; 03401 object **robj; 03402 03403 va_start(args, type); 03404 03405 op = va_arg(args, object *); 03406 if (!op) { 03407 LOG(llevError, "cfapi_object_insert: called with NULL object!\n"); 03408 va_end(args); 03409 return NULL; 03410 } 03411 if (QUERY_FLAG(op, FLAG_FREED)) { 03412 LOG(llevError, "cfapi_object_insert: called with FREED object!\n"); 03413 va_end(args); 03414 return NULL; 03415 } 03416 if (!QUERY_FLAG(op, FLAG_REMOVED)) { 03417 LOG(llevError, "cfapi_object_insert: called with not removed object %s!\n", op->name); 03418 remove_ob(op); 03419 } 03420 itype = va_arg(args, int); 03421 03422 switch (itype) { 03423 case 0: 03424 map = va_arg(args, mapstruct *); 03425 orig = va_arg(args, object *); 03426 flag = va_arg(args, int); 03427 x = va_arg(args, int); 03428 y = va_arg(args, int); 03429 robj = va_arg(args, object **); 03430 if (!map) { 03431 LOG(llevError, "cfapi_object_insert (0): called with NULL map, object %s!\n", op->name); 03432 free_object(op); 03433 *robj = NULL; 03434 } else 03435 *robj = insert_ob_in_map_at(op, map, orig, flag, x, y); 03436 *type = CFAPI_POBJECT; 03437 break; 03438 03439 case 1: 03440 map = va_arg(args, mapstruct *); 03441 orig = va_arg(args, object *); 03442 flag = va_arg(args, int); 03443 robj = va_arg(args, object **); 03444 if (!map) { 03445 LOG(llevError, "cfapi_object_insert (1): called with NULL map, object %s!\n", op->name); 03446 free_object(op); 03447 *robj = NULL; 03448 } else 03449 *robj = insert_ob_in_map(op, map, orig, flag); 03450 *type = CFAPI_POBJECT; 03451 break; 03452 03453 case 3: 03454 orig = va_arg(args, object *); 03455 robj = va_arg(args, object **); 03456 if (!orig) { 03457 LOG(llevError, "cfapi_object_insert (3): called with NULL orig, object %s!\n", op->name); 03458 free_object(op); 03459 *robj = NULL; 03460 } else 03461 *robj = insert_ob_in_ob(op, orig); 03462 *type = CFAPI_POBJECT; 03463 break; 03464 03465 default: 03466 LOG(llevError, "cfapi_object_insert (1): called with itype %d which is not valid, object %s!\n", itype, op->name); 03467 free_object(op); 03468 *type = CFAPI_NONE; 03469 break; 03470 } 03471 03472 va_end(args); 03473 03474 return NULL; 03475 } 03483 void *cfapi_object_split(int *type, ...) { 03484 va_list args; 03485 03486 int nr, size; 03487 object *op; 03488 char *buf; 03489 object **split; 03490 03491 va_start(args, type); 03492 03493 op = va_arg(args, object *); 03494 nr = va_arg(args, int); 03495 buf = va_arg(args, char *); 03496 size = va_arg(args, int); 03497 split = va_arg(args, object **); 03498 va_end(args); 03499 03500 *type = CFAPI_POBJECT; 03501 *split = get_split_ob(op, nr, buf, size); 03502 return NULL; 03503 } 03504 03512 void *cfapi_object_merge(int *type, ...) { 03513 va_list args; 03514 object *op; 03515 object *op2; 03516 object **merge; 03517 03518 va_start(args, type); 03519 03520 op = va_arg(args, object *); 03521 op2 = va_arg(args, object *); 03522 merge = va_arg(args, object **); 03523 03524 va_end(args); 03525 03526 *type = CFAPI_POBJECT; 03527 *merge = merge_ob(op, op2); 03528 return NULL; 03529 } 03530 03538 void *cfapi_object_distance(int *type, ...) { 03539 va_list args; 03540 object *op; 03541 object *op2; 03542 int *rint; 03543 va_start(args, type); 03544 03545 op = va_arg(args, object *); 03546 op2 = va_arg(args, object *); 03547 rint = va_arg(args, int *); 03548 03549 va_end(args); 03550 03551 *type = CFAPI_INT; 03552 *rint = distance(op, op2); 03553 return NULL; 03554 } 03562 void *cfapi_object_update(int *type, ...) { 03563 va_list args; 03564 int action; 03565 object *op; 03566 va_start(args, type); 03567 03568 op = va_arg(args, object *); 03569 action = va_arg(args, int); 03570 03571 va_end(args); 03572 03573 update_object(op, action); 03574 *type = CFAPI_NONE; 03575 return NULL; 03576 } 03577 03585 void *cfapi_object_clear(int *type, ...) { 03586 va_list args; 03587 object *op; 03588 va_start(args, type); 03589 03590 op = va_arg(args, object *); 03591 03592 va_end(args); 03593 03594 clear_object(op); 03595 *type = CFAPI_NONE; 03596 return NULL; 03597 } 03598 03606 void *cfapi_object_reset(int *type, ...) { 03607 va_list args; 03608 object *op; 03609 03610 va_start(args, type); 03611 03612 op = va_arg(args, object *); 03613 03614 va_end(args); 03615 03616 reset_object(op); 03617 *type = CFAPI_NONE; 03618 return NULL; 03619 } 03620 03621 void *cfapi_object_check_inventory(int *type, ...) { 03622 va_list args; 03623 object *op; 03624 object *op2; 03625 int checktype; 03626 object *ret = NULL; 03627 03628 va_start(args, type); 03629 03630 op = va_arg(args, object *); 03631 op2 = va_arg(args, object *); 03632 checktype = va_arg(args, int); 03633 03634 if (checktype == 0) { 03635 check_inv(op, op2); 03636 *type = CFAPI_NONE; 03637 } else { 03638 ret = check_inv_recursive(op, op2); 03639 *type = CFAPI_POBJECT; 03640 } 03641 03642 va_end(args); 03643 03644 return ret; 03645 } 03646 03647 void *cfapi_object_clean_object(int *type, ...) { 03648 va_list args; 03649 object *op; 03650 03651 va_start(args, type); 03652 op = va_arg(args, object *); 03653 clean_object(op); 03654 va_end(args); 03655 *type = CFAPI_NONE; 03656 return NULL; 03657 } 03658 03659 void *cfapi_object_on_same_map(int *type, ...) { 03660 va_list args; 03661 object *op1; 03662 object *op2; 03663 int *rint; 03664 03665 va_start(args, type); 03666 op1 = va_arg(args, object *); 03667 op2 = va_arg(args, object *); 03668 rint = va_arg(args, int *); 03669 va_end(args); 03670 03671 *type = CFAPI_INT; 03672 *rint = on_same_map(op1, op2); 03673 03674 return NULL; 03675 } 03676 03677 void *cfapi_object_spring_trap(int *type, ...) { 03678 object *trap; 03679 object *victim; 03680 va_list args; 03681 03682 va_start(args, type); 03683 trap = va_arg(args, object *); 03684 victim = va_arg(args, object *); 03685 va_end(args); 03686 03687 spring_trap(trap, victim); 03688 *type = CFAPI_NONE; 03689 return NULL; 03690 } 03691 03699 void *cfapi_object_check_trigger(int *type, ...) { 03700 object *op; 03701 object *cause; 03702 va_list args; 03703 int *rint; 03704 03705 va_start(args, type); 03706 op = va_arg(args, object *); 03707 cause = va_arg(args, object *); 03708 rint = va_arg(args, int *); 03709 va_end(args); 03710 03711 *rint = check_trigger(op, cause); 03712 *type = CFAPI_INT; 03713 return NULL; 03714 } 03715 03729 void *cfapi_map_trigger_connected(int *type, ...) { 03730 objectlink *ol; 03731 object *cause; 03732 int state; 03733 va_list args; 03734 03735 va_start(args, type); 03736 ol = va_arg(args, objectlink *); 03737 cause = va_arg(args, object *); 03738 state = va_arg(args, int); 03739 va_end(args); 03740 trigger_connected(ol, cause, state); 03741 *type = CFAPI_NONE; 03742 return NULL; 03743 } 03744 03752 void *cfapi_object_query_cost(int *type, ...) { 03753 object *op; 03754 object *who; 03755 int flags; 03756 va_list args; 03757 int *rint; 03758 03759 va_start(args, type); 03760 op = va_arg(args, object *); 03761 who = va_arg(args, object *); 03762 flags = va_arg(args, int); 03763 rint = va_arg(args, int *); 03764 va_end(args); 03765 03766 *rint = query_cost(op, who, flags); 03767 *type = CFAPI_INT; 03768 return NULL; 03769 } 03770 03778 void *cfapi_object_query_money(int *type, ...) { 03779 object *op; 03780 va_list args; 03781 int *rint; 03782 03783 va_start(args, type); 03784 op = va_arg(args, object *); 03785 rint = va_arg(args, int *); 03786 va_end(args); 03787 03788 *rint = query_money(op); 03789 *type = CFAPI_INT; 03790 return NULL; 03791 } 03792 03800 void *cfapi_object_cast(int *type, ...) { 03801 object *op; 03802 object *sp; 03803 int dir; 03804 char *str; 03805 object *caster; 03806 va_list args; 03807 int *rint; 03808 03809 va_start(args, type); 03810 op = va_arg(args, object *); 03811 caster = va_arg(args, object *); 03812 dir = va_arg(args, int); 03813 sp = va_arg(args, object *); 03814 str = va_arg(args, char *); 03815 rint = va_arg(args, int *); 03816 va_end(args); 03817 03818 *type = CFAPI_INT; 03819 03820 if (!op->map) { 03821 *rint = -1; 03822 return NULL; 03823 } 03824 03825 *rint = cast_spell(op, caster, dir, sp, str); 03826 return NULL; 03827 } 03828 03829 void *cfapi_object_learn_spell(int *type, ...) { 03830 object *op; 03831 object *sp; 03832 int prayer; 03833 va_list args; 03834 03835 va_start(args, type); 03836 op = va_arg(args, object *); 03837 sp = va_arg(args, object *); 03838 prayer = va_arg(args, int); 03839 va_end(args); 03840 do_learn_spell(op, sp, prayer); 03841 *type = CFAPI_NONE; 03842 return NULL; 03843 } 03844 03845 void *cfapi_object_forget_spell(int *type, ...) { 03846 object *op; 03847 object *sp; 03848 va_list args; 03849 char name[MAX_BUF]; 03850 03851 va_start(args, type); 03852 op = va_arg(args, object *); 03853 sp = va_arg(args, object *); 03854 va_end(args); 03855 query_name(sp, name, MAX_BUF); 03856 do_forget_spell(op, name); 03857 *type = CFAPI_NONE; 03858 return NULL; 03859 } 03860 03868 void *cfapi_object_check_spell(int *type, ...) { 03869 object *op; 03870 char *spellname; 03871 va_list args; 03872 object **robj; 03873 03874 va_start(args, type); 03875 op = va_arg(args, object *); 03876 spellname = va_arg(args, char *); 03877 robj = va_arg(args, object **); 03878 va_end(args); 03879 *robj = check_spell_known(op, spellname); 03880 *type = CFAPI_POBJECT; 03881 return NULL; 03882 } 03883 03891 void *cfapi_object_pay_amount(int *type, ...) { 03892 object *op; 03893 uint64 amount; 03894 va_list args; 03895 int *rint; 03896 03897 va_start(args, type); 03898 op = va_arg(args, object *); 03899 amount = va_arg(args, uint64); 03900 rint = va_arg(args, int *); 03901 va_end(args); 03902 03903 *rint = pay_for_amount(amount, op); 03904 *type = CFAPI_INT; 03905 return NULL; 03906 } 03914 void *cfapi_object_pay_item(int *type, ...) { 03915 object *op; 03916 object *tobuy; 03917 int *rint; 03918 03919 va_list args; 03920 03921 va_start(args, type); 03922 tobuy = va_arg(args, object *); 03923 op = va_arg(args, object *); 03924 rint = va_arg(args, int *); 03925 va_end(args); 03926 03927 *rint = pay_for_item(tobuy, op); 03928 *type = CFAPI_INT; 03929 return NULL; 03930 } 03931 03941 void *cfapi_object_transfer(int *type, ...) { 03942 object *op; 03943 object *originator; 03944 int x, y, randompos, ttype, flag; 03945 va_list args; 03946 mapstruct *map; 03947 int *rint; 03948 object **robj; 03949 03950 va_start(args, type); 03951 op = va_arg(args, object *); 03952 ttype = va_arg(args, int); 03953 switch (ttype) { 03954 case 0: 03955 x = va_arg(args, int); 03956 y = va_arg(args, int); 03957 randompos = va_arg(args, int); 03958 originator = va_arg(args, object *); 03959 rint = va_arg(args, int *); 03960 va_end(args); 03961 03962 *rint = transfer_ob(op, x, y, randompos, originator); 03963 *type = CFAPI_INT; 03964 return NULL; 03965 break; 03966 03967 case 1: 03968 map = va_arg(args, mapstruct *); 03969 originator = va_arg(args, object *); 03970 flag = va_arg(args, int); 03971 x = va_arg(args, int); 03972 y = va_arg(args, int); 03973 robj = va_arg(args, object **); 03974 va_end(args); 03975 if (x < 0 || y < 0) { 03976 x = map->enter_x; 03977 y = map->enter_y; 03978 } 03979 *robj = insert_ob_in_map_at(op, map, originator, flag, x, y); 03980 *type = CFAPI_POBJECT; 03981 return NULL; 03982 break; 03983 03984 case 2: 03985 x = va_arg(args, int); 03986 y = va_arg(args, int); 03987 rint = va_arg(args, int *); 03988 va_end(args); 03989 03990 *rint = move_to(op, x, y); 03991 *type = CFAPI_INT; 03992 return NULL; 03993 03994 default: 03995 *type = CFAPI_NONE; 03996 return NULL; 03997 break; 03998 } 03999 } 04000 04004 void *cfapi_object_find_archetype_inside(int *type, ...) { 04005 object *op; 04006 char *str; 04007 va_list args; 04008 object **robj; 04009 04010 *type = CFAPI_POBJECT; 04011 va_start(args, type); 04012 op = va_arg(args, object *); 04013 04014 str = va_arg(args, char *); 04015 robj = va_arg(args, object **); 04016 *robj = present_arch_in_ob(try_find_archetype(str), op); 04017 if (*robj == NULL) { 04018 object *tmp; 04019 char name[MAX_BUF]; 04020 04021 /* Search by query_name instead */ 04022 for (tmp = op->inv; tmp; tmp = tmp->below) { 04023 query_name(tmp, name, MAX_BUF); 04024 if (!strncmp(name, str, strlen(str))) 04025 *robj = tmp; 04026 if (!strncmp(tmp->name, str, strlen(str))) 04027 *robj = tmp; 04028 if (*robj != NULL) 04029 break; 04030 } 04031 } 04032 va_end(args); 04033 04034 return NULL; 04035 } 04036 04044 void *cfapi_object_drop(int *type, ...) { 04045 object *op; 04046 object *author; 04047 va_list args; 04048 04049 va_start(args, type); 04050 op = va_arg(args, object *); 04051 author = va_arg(args, object *); 04052 va_end(args); 04053 *type = CFAPI_NONE; 04054 04055 if (QUERY_FLAG(op, FLAG_NO_DROP)) 04056 return NULL; 04057 drop(author, op); 04058 04059 if (author->type == PLAYER) { 04060 author->contr->count = 0; 04061 author->contr->socket.update_look = 1; 04062 } 04063 04064 return NULL; 04065 } 04066 04070 void *cfapi_object_change_abil(int *type, ...) { 04071 object *op, *tmp; 04072 int *rint; 04073 va_list args; 04074 04075 va_start(args, type); 04076 op = va_arg(args, object *); 04077 tmp = va_arg(args, object *); 04078 rint = va_arg(args, int *); 04079 va_end(args); 04080 04081 *type = CFAPI_INT; 04082 *rint = change_abil(op, tmp); 04083 04084 return NULL; 04085 } 04086 04087 void *cfapi_object_say(int *type, ...) { 04088 object *op; 04089 char *msg; 04090 va_list args; 04091 int *rint; 04092 04093 va_start(args, type); 04094 op = va_arg(args, object *); 04095 msg = va_arg(args, char *); 04096 rint = va_arg(args, int *); 04097 va_end(args); 04098 04099 if (op->type == PLAYER) { 04100 *rint = command_say(op, msg); 04101 } else { 04102 npc_say(op, msg); 04103 *rint = 0; 04104 } 04105 *type = CFAPI_INT; 04106 return NULL; 04107 } 04108 04109 /* PLAYER SUBCLASS */ 04110 04118 void *cfapi_player_find(int *type, ...) { 04119 va_list args; 04120 char *sval; 04121 player **rpl; 04122 va_start(args, type); 04123 04124 sval = va_arg(args, char *); 04125 rpl = va_arg(args, player **); 04126 va_end(args); 04127 04128 *rpl = find_player_partial_name(sval); 04129 04130 *type = CFAPI_PPLAYER; 04131 return NULL; 04132 } 04133 04134 void *cfapi_player_message(int *type, ...) { 04135 va_list args; 04136 int flags; 04137 int pri; 04138 object *pl; 04139 char *buf; 04140 04141 va_start(args, type); 04142 04143 flags = va_arg(args, int); 04144 pri = va_arg(args, int); 04145 pl = va_arg(args, object *); 04146 buf = va_arg(args, char *); 04147 va_end(args); 04148 04149 draw_ext_info(flags, pri, pl, MSG_TYPE_MISC, MSG_SUBTYPE_NONE, 04150 buf, buf); 04151 *type = CFAPI_NONE; 04152 return NULL; 04153 } 04154 04162 void *cfapi_object_change_exp(int *type, ...) { 04163 va_list(args); 04164 int flag; 04165 object *ob; 04166 const char *skill; 04167 sint64 exp; 04168 04169 va_start(args, type); 04170 ob = va_arg(args, object *); 04171 exp = va_arg(args, sint64); 04172 skill = va_arg(args, const char *); 04173 flag = va_arg(args, int); 04174 va_end(args); 04175 04176 *type = CFAPI_NONE; 04177 change_exp(ob, exp, skill, flag); 04178 return NULL; 04179 } 04180 04188 void *cfapi_player_can_pay(int *type, ...) { 04189 va_list args; 04190 object *pl; 04191 int *rint; 04192 04193 va_start(args, type); 04194 pl = va_arg(args, object *); 04195 rint = va_arg(args, int *); 04196 va_end(args); 04197 04198 *rint = can_pay(pl); 04199 *type = CFAPI_INT; 04200 return NULL; 04201 } 04202 04210 void *cfapi_object_teleport(int *type, ...) { 04211 mapstruct *map; 04212 int x, y; 04213 object *who; 04214 int *res; 04215 va_list args; 04216 04217 va_start(args, type); 04218 who = va_arg(args, object *); 04219 map = va_arg(args, mapstruct *); 04220 x = va_arg(args, int); 04221 y = va_arg(args, int); 04222 res = va_arg(args, int *); 04223 *type = CFAPI_INT; 04224 04225 if (!out_of_map(map, x, y)) { 04226 int k; 04227 k = find_first_free_spot(who, map, x, y); 04228 if (k == -1) { 04229 *res = 1; 04230 return NULL; 04231 } 04232 04233 if (!QUERY_FLAG(who, FLAG_REMOVED)) { 04234 remove_ob(who); 04235 } 04236 04237 insert_ob_in_map_at(who, map, NULL, 0, x, y); 04238 if (who->type == PLAYER) 04239 map_newmap_cmd(&who->contr->socket); 04240 *res = 0; 04241 } 04242 04243 return NULL; 04244 } 04245 04246 void *cfapi_object_pickup(int *type, ...) { 04247 object *who; 04248 object *what; 04249 va_list args; 04250 04251 va_start(args, type); 04252 who = va_arg(args, object *); 04253 what = va_arg(args, object *); 04254 va_end(args); 04255 04256 pick_up(who, what); 04257 *type = CFAPI_NONE; 04258 return NULL; 04259 } 04260 04261 /* Archetype-related functions */ 04262 void *cfapi_archetype_get_property(int *type, ...) { 04263 int prop; 04264 archetype *arch; 04265 va_list args; 04266 sstring *rsstring; 04267 archetype **rarch; 04268 object **robject; 04269 04270 va_start(args, type); 04271 arch = va_arg(args, archetype *); 04272 prop = va_arg(args, int); 04273 switch (prop) { 04274 case CFAPI_ARCH_PROP_NAME: 04275 *type = CFAPI_SSTRING; 04276 rsstring = va_arg(args, sstring *); 04277 *rsstring = arch->name; 04278 break; 04279 04280 case CFAPI_ARCH_PROP_NEXT: 04281 *type = CFAPI_PARCH; 04282 rarch = va_arg(args, archetype **); 04283 *rarch = arch ? arch->next : first_archetype; 04284 break; 04285 04286 case CFAPI_ARCH_PROP_HEAD: 04287 *type = CFAPI_PARCH; 04288 rarch = va_arg(args, archetype **); 04289 *rarch = arch->head; 04290 break; 04291 04292 case CFAPI_ARCH_PROP_MORE: 04293 *type = CFAPI_PARCH; 04294 rarch = va_arg(args, archetype **); 04295 *rarch = arch->more; 04296 break; 04297 04298 case CFAPI_ARCH_PROP_CLONE: 04299 *type = CFAPI_POBJECT; 04300 robject = va_arg(args, object **); 04301 *robject = &arch->clone; 04302 break; 04303 04304 default: 04305 *type = CFAPI_NONE; 04306 break; 04307 } 04308 va_end(args); 04309 return NULL; 04310 } 04311 04320 void *cfapi_party_get_property(int *type, ...) { 04321 partylist *party; 04322 int prop; 04323 va_list args; 04324 object *obarg; 04325 sstring *rsstring; 04326 player **rplayer; 04327 partylist **rparty; 04328 04329 va_start(args, type); 04330 party = va_arg(args, partylist *); 04331 prop = va_arg(args, int); 04332 switch (prop) { 04333 case CFAPI_PARTY_PROP_NAME: 04334 rsstring = va_arg(args, sstring *); 04335 *rsstring = party->partyname; 04336 *type = CFAPI_SSTRING; 04337 break; 04338 04339 case CFAPI_PARTY_PROP_NEXT: 04340 rparty = va_arg(args, partylist **); 04341 *rparty = (party ? party->next : get_firstparty()); 04342 *type = CFAPI_PPARTY; 04343 break; 04344 04345 case CFAPI_PARTY_PROP_PASSWORD: 04346 rsstring = va_arg(args, sstring *); 04347 *rsstring = party->passwd; 04348 *type = CFAPI_SSTRING; 04349 break; 04350 04351 case CFAPI_PARTY_PROP_PLAYER: 04352 *type = CFAPI_PPLAYER; 04353 obarg = va_arg(args, object *); 04354 rplayer = va_arg(args, player **); 04355 *rplayer = (obarg ? obarg->contr : first_player); 04356 for (; *rplayer != NULL; (*rplayer) = (*rplayer)->next) 04357 if ((*rplayer)->ob->contr->party == party) { 04358 break; 04359 } 04360 break; 04361 04362 default: 04363 *type = CFAPI_NONE; 04364 break; 04365 } 04366 va_end(args); 04367 return NULL; 04368 } 04369 04378 void *cfapi_region_get_property(int *type, ...) { 04379 region *reg; 04380 int prop; 04381 va_list args; 04383 sstring *rsstring; 04384 region **rregion; 04385 04386 va_start(args, type); 04387 reg = va_arg(args, region *); 04388 prop = va_arg(args, int); 04389 switch (prop) { 04390 case CFAPI_REGION_PROP_NAME: 04391 rsstring = va_arg(args, sstring *); 04392 *rsstring = reg->name; 04393 *type = CFAPI_SSTRING; 04394 break; 04395 04396 case CFAPI_REGION_PROP_NEXT: 04397 rregion = va_arg(args, region **); 04398 *rregion = (reg ? reg->next : first_region); 04399 *type = CFAPI_PREGION; 04400 break; 04401 04402 case CFAPI_REGION_PROP_PARENT: 04403 rregion = va_arg(args, region **); 04404 *rregion = reg->parent; 04405 *type = CFAPI_PREGION; 04406 break; 04407 04408 case CFAPI_REGION_PROP_LONGNAME: 04409 rsstring = va_arg(args, sstring *); 04410 *rsstring = reg->longname; 04411 *type = CFAPI_SSTRING; 04412 break; 04413 04414 case CFAPI_REGION_PROP_MESSAGE: 04415 rsstring = va_arg(args, sstring *); 04416 *rsstring = reg->msg; 04417 *type = CFAPI_SSTRING; 04418 break; 04419 04420 default: 04421 *type = CFAPI_NONE; 04422 break; 04423 } 04424 va_end(args); 04425 return NULL; 04426 } 04427 04439 void *cfapi_friendlylist_get_next(int *type, ...) { 04440 object *ob; 04441 va_list args; 04442 objectlink *link; 04443 object **robject; 04444 04445 va_start(args, type); 04446 ob = va_arg(args, object *); 04447 robject = va_arg(args, object **); 04448 va_end(args); 04449 04450 *type = CFAPI_POBJECT; 04451 *robject = NULL; 04452 04453 if (ob) { 04454 for (link = first_friendly_object; link; link = link->next) { 04455 if (ob == link->ob) { 04456 if (link->next) { 04457 *robject = link->next->ob; 04458 return NULL; 04459 } else { 04460 return NULL; 04461 } 04462 } 04463 } 04464 return NULL; 04465 } 04466 04467 if (first_friendly_object) 04468 *robject = first_friendly_object->ob; 04469 04470 return NULL; 04471 } 04472 04473 /* 04474 * Random-map related stuff. 04475 */ 04476 04485 void *cfapi_set_random_map_variable(int *type, ...) { 04486 va_list args; 04487 RMParms *rp; 04488 const char *buf; 04489 int *ret; 04490 04491 va_start(args, type); 04492 rp = va_arg(args, RMParms *); 04493 buf = va_arg(args, const char *); 04494 ret = va_arg(args, int *); 04495 va_end(args); 04496 04497 *ret = set_random_map_variable(rp, buf); 04498 *type = CFAPI_INT; 04499 04500 return NULL; 04501 } 04502 04511 void *cfapi_generate_random_map(int *type, ...) { 04512 va_list args; 04513 const char *name; 04514 RMParms *rp; 04515 char **use_layout; 04516 mapstruct **ret; 04517 04518 va_start(args, type); 04519 name = va_arg(args, const char *); 04520 rp = va_arg(args, RMParms *); 04521 use_layout = va_arg(args, char **); 04522 ret = va_arg(args, mapstruct **); 04523 va_end(args); 04524 04525 *ret = generate_random_map(name, rp, use_layout); 04526 04527 return NULL; 04528 } 04529 04530 void *cfapi_object_user_event(int *type, ...) { 04531 object *op; 04532 object *activator; 04533 object *third; 04534 const char *message; 04535 int fix; 04536 int *ret; 04537 va_list args; 04538 04539 va_start(args, type); 04540 op = va_arg(args, object *); 04541 activator = va_arg(args, object *); 04542 third = va_arg(args, object *); 04543 message = va_arg(args, const char *); 04544 fix = va_arg(args, int); 04545 ret = va_arg(args, int *); 04546 va_end(args); 04547 04548 *ret = user_event(op, activator, third, message, fix); 04549 *type = CFAPI_INT; 04550 04551 return NULL; 04552 } 04553 04554 /*****************************************************************************/ 04555 /* NEW PLUGIN STUFF ENDS HERE */ 04556 /*****************************************************************************/ 04557 04558 04559 /*****************************************************************************/ 04560 /* Tries to find if a given command is handled by a plugin. */ 04561 /* Note that find_plugin_command is called *before *the internal commands are*/ 04562 /* checked, meaning that you can "overwrite" them. */ 04563 /*****************************************************************************/ 04568 command_array_struct *find_plugin_command(char *cmd, object *op) { 04569 int i; 04570 crossfire_plugin *cp; 04571 static command_array_struct rtn_cmd; 04572 04573 if (plugins_list == NULL) 04574 return NULL; 04575 04576 for (cp = plugins_list; cp != NULL; cp = cp->next) { 04577 if (cp->propfunc(&i, "command?", cmd, &rtn_cmd) != NULL) 04578 return &rtn_cmd; 04579 } 04580 return NULL; 04581 } 04582 04583 /*****************************************************************************/ 04584 /* Plugins initialization. Browses the plugins directory and call */ 04585 /* initOnePlugin for each file found. */ 04586 /* Returns 0 if at least one plugin was successfully loaded, -1 if not */ 04587 /*****************************************************************************/ 04588 int initPlugins(void) { 04589 struct dirent *currentfile; 04590 DIR *plugdir; 04591 size_t l; 04592 char buf[MAX_BUF]; 04593 int result; 04594 04595 LOG(llevInfo, "Initializing plugins\n"); 04596 snprintf(buf, sizeof(buf), "%s/plugins/", LIBDIR); 04597 LOG(llevInfo, "Plugins directory is %s\n", buf); 04598 04599 plugdir = opendir(buf); 04600 if (plugdir == NULL) 04601 return -1; 04602 04603 result = -1; 04604 while ((currentfile = readdir(plugdir)) != NULL) { 04605 l = strlen(currentfile->d_name); 04606 if (l > strlen(PLUGIN_SUFFIX)) { 04607 if (strcmp(currentfile->d_name+l-strlen(PLUGIN_SUFFIX), PLUGIN_SUFFIX) == 0) { 04608 snprintf(buf, sizeof(buf), "%s/plugins/%s", LIBDIR, currentfile->d_name); 04609 LOG(llevInfo, " -> Loading plugin : %s\n", currentfile->d_name); 04610 if (plugins_init_plugin(buf) == 0) 04611 result = 0; 04612 } 04613 } 04614 } 04615 04616 closedir(plugdir); 04617 return result; 04618 } 04619 04623 void cleanupPlugins(void) { 04624 crossfire_plugin *cp; 04625 04626 if (!plugins_list) 04627 return; 04628 04629 for (cp = plugins_list; cp != NULL; ) { 04630 crossfire_plugin *next = cp->next; 04631 if (cp->closefunc) 04632 cp->closefunc(); 04633 /* Don't actually unload plugins, it makes backtraces for memory 04634 * debugging (printed at exit) messed up. And it doesn't matter if we 04635 * don't free it here. The OS will do it for us. 04636 */ 04637 /* plugins_dlclose(cp->libptr); */ 04638 free(cp); 04639 plugin_number--; 04640 cp = next; 04641 } 04642 plugins_list = NULL; 04643 }