00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00034 #include <global.h>
00035 #include <loader.h>
00036 #include <skills.h>
00037 #ifndef __CEXTRACT__
00038 #include <sproto.h>
00039 #endif
00040 #include <living.h>
00041 #include <math.h>
00042
00043 static void set_pickup_mode(const object *op, int i);
00044
00045
00046
00047
00048
00050 #define OBLINKMALLOC(p) if (!((p) = (objectlink *)malloc(sizeof(objectlink)))) \
00051 fatal(OUT_OF_MEMORY);
00052
00070 static object *find_best_apply_object_match(object *start, object *pl, const char *params, int aflag) {
00071 object *tmp, *best = NULL;
00072 int match_val = 0, tmpmatch;
00073
00074 for (tmp = start; tmp; tmp = tmp->below) {
00075 if (tmp->invisible)
00076 continue;
00077 if ((aflag == AP_APPLY) && (QUERY_FLAG(tmp, FLAG_APPLIED)))
00078 continue;
00079 if ((aflag == AP_UNAPPLY) && (!QUERY_FLAG(tmp, FLAG_APPLIED)))
00080 continue;
00081 if ((tmpmatch = item_matched_string(pl, tmp, params)) > match_val) {
00082 match_val = tmpmatch;
00083 best = tmp;
00084 }
00085 }
00086 return best;
00087 }
00088
00099 static object *find_best_object_match(object *pl, const char *params) {
00100 return find_best_apply_object_match(pl->inv, pl, params, AP_NULL);
00101 }
00102
00113 int command_uskill(object *pl, char *params) {
00114 if (!params) {
00115 draw_ext_info(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00116 "Usage: use_skill <skill name>", NULL);
00117 return 0;
00118 }
00119 return use_skill(pl, params);
00120 }
00121
00132 int command_rskill(object *pl, char *params) {
00133 object *skill;
00134
00135 if (!params) {
00136 draw_ext_info(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00137 "Usage: ready_skill <skill name>", NULL);
00138 return 0;
00139 }
00140 skill = find_skill_by_name(pl, params);
00141
00142 if (!skill) {
00143 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_SKILL, MSG_TYPE_SKILL_MISSING,
00144 "You have no knowledge of the skill %s",
00145 "You have no knowledge of the skill %s",
00146 params);
00147 return 0;
00148 }
00149 return change_skill(pl, skill, 0);
00150 }
00151
00152
00153
00154
00155
00156
00167 int command_search(object *op, char *params) {
00168 return use_skill(op, skill_names[SK_FIND_TRAPS]);
00169 }
00170
00181 int command_disarm(object *op, char *params) {
00182 return use_skill(op, skill_names[SK_DISARM_TRAPS]);
00183 }
00184
00198 int command_throw(object *op, char *params) {
00199 object *skop;
00200
00201 skop = find_skill_by_name(op, skill_names[SK_THROWING]);
00202 if (skop)
00203 return do_skill(op, op, skop, op->facing, params);
00204 else {
00205 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_SKILL, MSG_TYPE_SKILL_MISSING,
00206 "You have no knowledge of the skill throwing.", NULL);
00207 }
00208 return 0;
00209 }
00210
00221 int command_apply(object *op, char *params) {
00222 if (!params) {
00223 player_apply_below(op);
00224 return 0;
00225 } else {
00226 int aflag = 0;
00227 object *inv = op->inv;
00228
00229 while (*params == ' ')
00230 params++;
00231 if (!strncmp(params, "-a ", 3)) {
00232 aflag = AP_APPLY;
00233 params += 3;
00234 }
00235 if (!strncmp(params, "-u ", 3)) {
00236 aflag = AP_UNAPPLY;
00237 params += 3;
00238 }
00239 if (!strncmp(params, "-b ", 3)) {
00240 params += 3;
00241 if (op->container)
00242 inv = op->container->inv;
00243 else {
00244 inv = op;
00245 while (inv->above)
00246 inv = inv->above;
00247 }
00248 }
00249 while (*params == ' ')
00250 params++;
00251
00252 inv = find_best_apply_object_match(inv, op, params, aflag);
00253 if (inv) {
00254 player_apply(op, inv, aflag, 0);
00255 } else
00256 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00257 "Could not find any match to the %s.",
00258 "Could not find any match to the %s.",
00259 params);
00260 }
00261 return 0;
00262 }
00263
00282 int sack_can_hold(const object *pl, const object *sack, const object *op, uint32 nrof) {
00283 char name[MAX_BUF];
00284 query_name(sack, name, MAX_BUF);
00285
00286 if (!QUERY_FLAG(sack, FLAG_APPLIED)) {
00287 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00288 "The %s is not active.",
00289 "The %s is not active.",
00290 name);
00291 return 0;
00292 }
00293 if (sack == op) {
00294 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00295 "You can't put the %s into itself.",
00296 "You can't put the %s into itself.",
00297 name);
00298 return 0;
00299 }
00300 if (sack->race
00301 && (sack->race != op->race || op->type == CONTAINER || (sack->stats.food && sack->stats.food != op->type))) {
00302 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00303 "You can put only %s into the %s.",
00304 "You can put only %s into the %s.",
00305 sack->race, name);
00306 return 0;
00307 }
00308 if (op->type == SPECIAL_KEY && sack->slaying && op->slaying) {
00309 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00310 "You can't want put the key into %s.",
00311 "You can't want put the key into %s.",
00312 name);
00313 return 0;
00314 }
00315 if (sack->weight_limit && sack->carrying+(nrof ? nrof : 1)
00316 *(op->weight+(op->type == CONTAINER ? (op->carrying*op->stats.Str) : 0))
00317 *(100-sack->stats.Str)/100 > sack->weight_limit) {
00318 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00319 "That won't fit in the %s!",
00320 "That won't fit in the %s!",
00321 name);
00322 return 0;
00323 }
00324
00325 return 1;
00326 }
00327
00340 static void pick_up_object(object *pl, object *op, object *tmp, int nrof) {
00341
00342
00343
00344 char buf[HUGE_BUF], name[MAX_BUF];
00345 object *env = tmp->env;
00346 uint32 weight, effective_weight_limit;
00347 int tmp_nrof = tmp->nrof ? tmp->nrof : 1;
00348
00349
00350
00351
00352
00353
00354 if ((pl->move_type&MOVE_FLYING)
00355 && !QUERY_FLAG(pl, FLAG_WIZ)
00356 && get_player_container(tmp) != pl) {
00357 draw_ext_info(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00358 "You are levitating, you can't reach the ground!", NULL);
00359 return;
00360 }
00361 if (QUERY_FLAG(tmp, FLAG_NO_DROP))
00362 return;
00363
00364 if (QUERY_FLAG(tmp, FLAG_WAS_WIZ) && !QUERY_FLAG(pl, FLAG_WAS_WIZ)) {
00365 draw_ext_info(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
00366 "The object disappears in a puff of smoke! It must have been an illusion.",
00367 NULL);
00368 if (!QUERY_FLAG(tmp, FLAG_REMOVED))
00369 remove_ob(tmp);
00370 free_object(tmp);
00371 return;
00372 }
00373
00374 if (nrof > tmp_nrof || nrof == 0)
00375 nrof = tmp_nrof;
00376
00377
00378 weight = tmp->weight*nrof;
00379 if (tmp->inv)
00380 weight += tmp->carrying*(100-tmp->stats.Str)/100;
00381
00382 if (pl->stats.Str <= MAX_STAT)
00383 effective_weight_limit = weight_limit[pl->stats.Str];
00384 else
00385 effective_weight_limit = weight_limit[MAX_STAT];
00386
00387 if ((pl->weight+pl->carrying+weight) > effective_weight_limit) {
00388 draw_ext_info(0, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
00389 "That item is too heavy for you to pick up.", NULL);
00390 return;
00391 }
00392
00393 if (settings.real_wiz == FALSE && QUERY_FLAG(pl, FLAG_WAS_WIZ))
00394 SET_FLAG(tmp, FLAG_WAS_WIZ);
00395
00396 if (nrof != tmp_nrof) {
00397 char failure[MAX_BUF];
00398
00399 tmp = get_split_ob(tmp, nrof, failure, sizeof(failure));
00400 if (!tmp) {
00401 draw_ext_info(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00402 failure, NULL);
00403 return;
00404 }
00405 } else {
00406
00407
00408
00409
00410 if (!QUERY_FLAG(tmp, FLAG_REMOVED)) {
00411 remove_ob(tmp);
00412 }
00413 }
00414 query_name(tmp, name, MAX_BUF);
00415
00416 if (QUERY_FLAG(tmp, FLAG_UNPAID)) {
00417 char *value = stringbuffer_finish(query_cost_string(tmp, pl, F_BUY|F_SHOP, NULL));
00418 snprintf(buf, sizeof(buf), "%s will cost you %s.", name, value);
00419 free(value);
00420 } else
00421 snprintf(buf, sizeof(buf), "You pick up the %s.", name);
00422
00423
00424 if (execute_event(tmp, EVENT_PICKUP, pl, op, NULL, SCRIPT_FIX_ALL) != 0)
00425 return;
00426
00427 draw_ext_info(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00428 buf, NULL);
00429
00430 tmp = insert_ob_in_ob(tmp, op);
00431
00432
00433
00434
00435 if (pl->type != PLAYER)
00436 return;
00437
00438
00439 fix_object(pl);
00440
00441
00442
00443
00444 if (op != pl) {
00445 esrv_update_item(UPD_WEIGHT, pl, op);
00446 esrv_update_item(UPD_WEIGHT, pl, pl);
00447 }
00448
00449
00450 if (env && env != pl && env != op)
00451 esrv_update_item(UPD_WEIGHT, pl, env);
00452 }
00453
00462 void pick_up(object *op, object *alt) {
00463
00464 object *tmp = NULL, *tmp1;
00465 mapstruct *tmp_map = NULL;
00466 int count;
00467 tag_t tag;
00468
00469
00470 if (alt) {
00471 if (!can_pick(op, alt)) {
00472 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00473 "You can't pick up the %s.",
00474 "You can't pick up the %s.",
00475 alt->name);
00476 return;
00477 }
00478 tmp = alt;
00479 } else {
00480 if (op->below == NULL || !can_pick(op, op->below)) {
00481 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00482 "There is nothing to pick up here.", NULL);
00483 return;
00484 }
00485 tmp = op->below;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499 tmp_map = tmp->map;
00500 tmp1 = stop_item(tmp);
00501 if (tmp1 == NULL)
00502 return;
00503
00504
00505
00506
00507
00508 if (tmp1 != tmp) {
00509 tmp = insert_ob_in_map(tmp1, tmp_map, op, INS_NO_MERGE);
00510 }
00511
00512 if (tmp == NULL) return;
00513
00514 if (!can_pick(op, tmp)) return;
00515
00516
00517 if (op->type == PLAYER) {
00518 count = op->contr->count;
00519 if (count == 0)
00520 count = tmp->nrof;
00521 } else
00522 count = tmp->nrof;
00523
00524
00525 if (op->container) {
00526 alt = op->container;
00527 if (alt != tmp->env && !sack_can_hold(op, alt, tmp, count)) return;
00528 } else {
00529
00530
00531
00532 object *container=NULL;
00533
00534
00535
00536
00537
00538
00539
00540 for (alt = op->inv; alt; alt = alt->below) {
00541 if (alt->type == CONTAINER
00542 && QUERY_FLAG(alt, FLAG_APPLIED)
00543 && sack_can_hold(NULL, alt, tmp, count)) {
00544 if (alt->race && alt->race == tmp->race) {
00545 break;
00546 }
00547 else if (!container) {
00548 container = alt;
00549 }
00550 }
00551 }
00552
00553 if (!alt) alt=container;
00554
00555 if (!alt)
00556 alt = op;
00557 }
00558
00559
00560
00561 if (tmp->env == alt) {
00562 alt = op;
00563 }
00564
00565
00566
00567
00568 if (tmp->type == CONTAINER && alt->type==CONTAINER) {
00569 alt = op;
00570 }
00571 #ifdef PICKUP_DEBUG
00572 LOG(llevDebug, "Pick_up(): %s picks %s (%d) and inserts it %s.\n", op->name, tmp->name, op->contr->count, alt->name);
00573 #endif
00574
00575
00576
00577
00578 if (op->type == PLAYER
00579 && alt->type == CONTAINER
00580 && QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
00581 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00582 "This object cannot be put into containers!", NULL);
00583 return;
00584 }
00585
00586 tag = tmp->count;
00587 pick_up_object(op, alt, tmp, count);
00588 if (op->type == PLAYER)
00589 op->contr->count = 0;
00590 }
00591
00602 int command_take(object *op, char *params) {
00603 object *tmp, *next;
00604 int ival;
00605 int missed = 0;
00606
00607 if (op->container)
00608 tmp = op->container->inv;
00609 else {
00610 tmp = op->above;
00611 if (tmp)
00612 while (tmp->above) {
00613 tmp = tmp->above;
00614 }
00615 if (!tmp)
00616 tmp = op->below;
00617 }
00618
00619 if (tmp == NULL) {
00620 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00621 "Nothing to take!", NULL);
00622 return 0;
00623 }
00624
00625
00626 if (params && *params == '\0')
00627 params = NULL;
00628
00629 while (tmp) {
00630 next = tmp->below;
00631
00632 if (tmp->invisible) {
00633 tmp = next;
00634 continue;
00635 }
00636
00637
00638
00639
00640 if (params && (ival = item_matched_string(op, tmp, params)) > 0) {
00641 if ((ival <= 2) && (!can_pick(op, tmp))) {
00642 if (!QUERY_FLAG(tmp, FLAG_IS_FLOOR))
00643 missed++;
00644 } else
00645 pick_up(op, tmp);
00646 } else if (can_pick(op, tmp) && !params) {
00647 pick_up(op, tmp);
00648 break;
00649 }
00650 tmp = next;
00651
00652
00653
00654 if (tmp == op)
00655 tmp = tmp->below;
00656 }
00657 if (!params && !tmp) {
00658 for (tmp = op->below; tmp != NULL; tmp = tmp->next)
00659 if (!tmp->invisible) {
00660 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00661 "You can't pick up a %s.",
00662 "You can't pick up a %s.",
00663 tmp->name ? tmp->name : "null");
00664
00665 break;
00666 }
00667 if (!tmp)
00668 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00669 "There is nothing to pick up.", NULL);
00670 }
00671 if (missed == 1)
00672 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00673 "You were unable to take one of the items.", NULL);
00674 else if (missed > 1)
00675 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
00676 "You were unable to take %d of the items.",
00677 "You were unable to take %d of the items.",
00678 missed);
00679 return 0;
00680 }
00681
00700 void put_object_in_sack(object *op, object *sack, object *tmp, uint32 nrof) {
00701 tag_t tmp_tag, tmp2_tag;
00702 object *tmp2, *sack2, *orig = sack;
00703 char name_sack[MAX_BUF], name_tmp[MAX_BUF];
00704
00705 if (sack == tmp)
00706 return;
00707 query_name(sack, name_sack, MAX_BUF);
00708 if (sack->type != CONTAINER && sack->type != TRANSPORT) {
00709 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00710 "The %s is not a container.",
00711 "The %s is not a container.",
00712 name_sack);
00713 return;
00714 }
00715 if (QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
00716 query_name(tmp, name_tmp, MAX_BUF);
00717 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00718 "You cannot put the %s in the %s.",
00719 "You cannot put the %s in the %s.",
00720 name_tmp, name_sack);
00721 return;
00722 }
00723 if (tmp->type == CONTAINER) {
00724 if (tmp->inv) {
00725 if (tmp->slaying)
00726 return;
00727
00728
00729
00730
00731
00732
00733 sack2 = tmp;
00734 query_name(tmp, name_tmp, MAX_BUF);
00735 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00736 "You move the items from %s into %s.",
00737 "You move the items from %s into %s.",
00738 name_tmp, name_sack);
00739
00740 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp) {
00741 tmp = tmp2->below;
00742 if ((sack->type == CONTAINER && sack_can_hold(op, op->container, tmp2, tmp2->nrof))
00743 || (sack->type == TRANSPORT && transport_can_hold(sack, tmp2, tmp2->nrof))) {
00744 put_object_in_sack(op, sack, tmp2, 0);
00745 } else {
00746 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND,
00747 MSG_TYPE_COMMAND_FAILURE,
00748 "Your %s fills up.",
00749 "Your %s fills up.",
00750 name_sack);
00751 break;
00752 }
00753 }
00754 esrv_update_item(UPD_WEIGHT, op, sack2);
00755 return;
00756 } else {
00757 query_name(tmp, name_tmp, MAX_BUF);
00758 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00759 "You can not put a %s into a %s",
00760 "You can not put a %s into a %s",
00761 name_tmp,
00762 name_sack);
00763 return;
00764 }
00765
00766 }
00767
00768
00769
00770
00771 if ((sack->type == CONTAINER) && !sack_can_hold(op, sack, tmp, (nrof ? nrof : tmp->nrof)))
00772 return;
00773
00774 if (QUERY_FLAG(tmp, FLAG_APPLIED)) {
00775 if (apply_special(op, tmp, AP_UNAPPLY|AP_NO_MERGE))
00776 return;
00777 }
00778
00779
00780 if (nrof && tmp->nrof != nrof) {
00781 char failure[MAX_BUF];
00782 object *tmp2 = tmp;
00783
00784 tmp2_tag = tmp2->count;
00785 tmp = get_split_ob(tmp, nrof, failure, sizeof(failure));
00786
00787 if (!tmp) {
00788 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00789 failure, NULL);
00790 return;
00791 }
00792 } else
00793 remove_ob(tmp);
00794
00795 if (sack->nrof > 1) {
00796 orig = get_split_ob(sack, sack->nrof-1, NULL, 0);
00797 set_object_face_main(orig);
00798 CLEAR_FLAG(orig, FLAG_APPLIED);
00799 if (sack->env) {
00800 insert_ob_in_ob(orig, sack->env);
00801 } else {
00802 insert_ob_in_map_at(orig, sack->map, NULL, 0, sack->x, sack->y);
00803 orig->move_off = 0;
00804 }
00805 }
00806
00807 query_name(tmp, name_tmp, MAX_BUF);
00808 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00809 "You put the %s in %s.",
00810 "You put the %s in %s.",
00811 name_tmp, name_sack);
00812 tmp_tag = tmp->count;
00813 tmp2 = insert_ob_in_ob(tmp, sack);
00814 if (!QUERY_FLAG(op, FLAG_NO_FIX_PLAYER))
00815 fix_object(op);
00816
00817
00818
00819
00820
00821 if (sack->type == TRANSPORT) {
00822 for (tmp = sack->inv; tmp; tmp = tmp->below) {
00823 if (tmp->type == PLAYER)
00824 tmp->contr->socket.update_look = 1;
00825 }
00826 } else {
00827
00828 esrv_update_item(UPD_WEIGHT, op, sack);
00829 }
00830 }
00831
00847 object *drop_object(object *op, object *tmp, uint32 nrof) {
00848 tag_t tmp_tag;
00849
00850 if (QUERY_FLAG(tmp, FLAG_NO_DROP)) {
00851 return NULL;
00852 }
00853
00854 if (QUERY_FLAG(tmp, FLAG_APPLIED)) {
00855 if (apply_special(op, tmp, AP_UNAPPLY|AP_NO_MERGE))
00856 return NULL;
00857 }
00858
00859
00860 if (execute_event(tmp, EVENT_DROP, op, NULL, NULL, SCRIPT_FIX_ALL) != 0)
00861 return NULL;
00862
00863
00864
00865
00866 if (nrof && tmp->nrof != nrof) {
00867 char failure[MAX_BUF];
00868
00869 tmp = get_split_ob(tmp, nrof, failure, sizeof(failure));
00870 if (!tmp) {
00871 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00872 failure, NULL);
00873 return NULL;
00874 }
00875 } else
00876 remove_ob(tmp);
00877
00878 if (QUERY_FLAG(tmp, FLAG_STARTEQUIP)) {
00879 char name[MAX_BUF];
00880
00881 query_name(tmp, name, MAX_BUF);
00882 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
00883 "You drop the %s. The gods who lent it to you retrieves it.",
00884 "You drop the %s. The gods who lent it to you retrieves it.",
00885 name);
00886 free_object(tmp);
00887
00888 if (!QUERY_FLAG(op, FLAG_NO_FIX_PLAYER))
00889 fix_object(op);
00890
00891 return NULL;
00892 }
00893
00894
00895
00896
00897 #ifdef SAVE_INTERVAL
00898
00899
00900
00901
00902 if (op->type == PLAYER
00903 && !QUERY_FLAG(tmp, FLAG_UNPAID)
00904 && (tmp->nrof ? tmp->value*tmp->nrof : tmp->value > 2000)
00905 && (op->contr->last_save_time+SAVE_INTERVAL) <= time(NULL)) {
00906 save_player(op, 1);
00907 op->contr->last_save_time = time(NULL);
00908 }
00909 #endif
00910
00911
00912 tmp->x = op->x;
00913 tmp->y = op->y;
00914
00915 tmp_tag = tmp->count;
00916 insert_ob_in_map(tmp, op->map, op, 0);
00917 if (!was_destroyed(tmp, tmp_tag) && !QUERY_FLAG(tmp, FLAG_UNPAID) && tmp->type != MONEY && is_in_shop(op)) {
00918 sell_item(tmp, op);
00919 }
00920
00921
00922
00923
00924 if (!QUERY_FLAG(op, FLAG_NO_FIX_PLAYER)) {
00925 fix_object(op);
00926
00927
00928
00929 if (op->type == PLAYER)
00930 esrv_update_item(UPD_WEIGHT, op, op);
00931 }
00932 return tmp;
00933 }
00934
00943 void drop(object *op, object *tmp) {
00944
00945
00946
00947
00948
00949 if (tmp->invisible) {
00950
00951 if (tmp->env && tmp->env->type != PLAYER) {
00952
00953
00954
00955 remove_ob(tmp);
00956 free_object(tmp);
00957 return;
00958 } else {
00959 while (tmp != NULL && tmp->invisible)
00960 tmp = tmp->below;
00961 }
00962 }
00963
00964 if (tmp == NULL) {
00965 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00966 "You don't have anything to drop.", NULL);
00967 return;
00968 }
00969 if (QUERY_FLAG(tmp, FLAG_INV_LOCKED)) {
00970 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
00971 "This item is locked", NULL);
00972 return;
00973 }
00974 if (QUERY_FLAG(tmp, FLAG_NO_DROP)) {
00975 return;
00976 }
00977
00978 if (op->type == PLAYER) {
00979 if (op->contr->last_used == tmp && op->contr->last_used_id == tmp->count) {
00980 object *n = NULL;
00981
00982 if (tmp->below != NULL)
00983 n = tmp->below;
00984 else if (tmp->above != NULL)
00985 n = tmp->above;
00986 op->contr->last_used = n;
00987 if (n != NULL)
00988 op->contr->last_used_id = n->count;
00989 else
00990 op->contr->last_used_id = 0;
00991 }
00992 };
00993
00994 if (op->container) {
00995 if (op->type == PLAYER) {
00996 put_object_in_sack(op, op->container, tmp, op->contr->count);
00997 } else {
00998 put_object_in_sack(op, op->container, tmp, 0);
00999 };
01000 } else {
01001 if (op->type == PLAYER) {
01002 drop_object(op, tmp, op->contr->count);
01003 } else {
01004 drop_object(op, tmp, 0);
01005 };
01006 }
01007 if (op->type == PLAYER)
01008 op->contr->count = 0;
01009 }
01010
01021 int command_dropall(object *op, char *params) {
01022 object *curinv, *nextinv;
01023 int count = 0;
01024
01025 if (op->inv == NULL) {
01026 draw_ext_info(NDI_UNIQUE, 0, op,
01027 MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01028 "Nothing to drop!", NULL);
01029 return 0;
01030 }
01031
01032 curinv = op->inv;
01033
01034 if (op->contr)
01035 count = op->contr->count;
01036
01037
01038
01039
01040 SET_FLAG(op, FLAG_NO_FIX_PLAYER);
01041
01042
01043
01044
01045
01046
01047
01048
01049 if (params == NULL) {
01050 while (curinv != NULL) {
01051 nextinv = curinv->below;
01052 while (nextinv && nextinv->type == MONEY)
01053 nextinv = nextinv->below;
01054 if (!QUERY_FLAG(curinv, FLAG_INV_LOCKED)
01055 && curinv->type != MONEY
01056 && curinv->type != FOOD
01057 && curinv->type != KEY
01058 && curinv->type != SPECIAL_KEY
01059 && curinv->type != GEM
01060 && !curinv->invisible
01061 && (curinv->type != CONTAINER || op->container != curinv)) {
01062 drop(op, curinv);
01063 if (op->contr)
01064 op->contr->count = count;
01065 }
01066 curinv = nextinv;
01067 }
01068 } else if (strcmp(params, "weapons") == 0) {
01069 while (curinv != NULL) {
01070 nextinv = curinv->below;
01071 while (nextinv && nextinv->type == MONEY)
01072 nextinv = nextinv->below;
01073 if (!QUERY_FLAG(curinv, FLAG_INV_LOCKED)
01074 && ((curinv->type == WEAPON) || (curinv->type == BOW) || (curinv->type == ARROW))) {
01075 drop(op, curinv);
01076 if (op->contr)
01077 op->contr->count = count;
01078 }
01079 curinv = nextinv;
01080 }
01081 } else if (strcmp(params, "armor") == 0 || strcmp(params, "armour") == 0) {
01082 while (curinv != NULL) {
01083 nextinv = curinv->below;
01084 while (nextinv && nextinv->type == MONEY)
01085 nextinv = nextinv->below;
01086 if (!QUERY_FLAG(curinv, FLAG_INV_LOCKED)
01087 && ((curinv->type == ARMOUR) || curinv->type == SHIELD || curinv->type == HELMET)) {
01088 drop(op, curinv);
01089 if (op->contr)
01090 op->contr->count = count;
01091 }
01092 curinv = nextinv;
01093 }
01094 } else if (strcmp(params, "food") == 0) {
01095 while (curinv != NULL) {
01096 nextinv = curinv->below;
01097 if (!QUERY_FLAG(curinv, FLAG_INV_LOCKED) && (curinv->type == FOOD || curinv->type == DRINK)) {
01098 drop(op, curinv);
01099 if (op->contr)
01100 op->contr->count = count;
01101 }
01102 curinv = nextinv;
01103 }
01104 } else if (strcmp(params, "flesh") == 0) {
01105 while (curinv != NULL) {
01106 nextinv = curinv->below;
01107 if (!QUERY_FLAG(curinv, FLAG_INV_LOCKED) && (curinv->type == FLESH)) {
01108 drop(op, curinv);
01109 if (op->contr)
01110 op->contr->count = count;
01111 }
01112 curinv = nextinv;
01113 }
01114 } else if (strcmp(params, "misc") == 0) {
01115 while (curinv != NULL) {
01116 nextinv = curinv->below;
01117 while (nextinv && nextinv->type == MONEY)
01118 nextinv = nextinv->below;
01119 if (!QUERY_FLAG(curinv, FLAG_INV_LOCKED)
01120 && !QUERY_FLAG(curinv, FLAG_APPLIED)) {
01121 switch (curinv->type) {
01122 case HORN:
01123 case BOOK:
01124 case SPELLBOOK:
01125 case GIRDLE:
01126 case AMULET:
01127 case RING:
01128 case CLOAK:
01129 case BOOTS:
01130 case GLOVES:
01131 case BRACERS:
01132 case SCROLL:
01133 case ARMOUR_IMPROVER:
01134 case WEAPON_IMPROVER:
01135 case WAND:
01136 case ROD:
01137 case POTION:
01138 drop(op, curinv);
01139 curinv = nextinv;
01140 if (op->contr)
01141 op->contr->count = count;
01142 break;
01143
01144 default:
01145 curinv = nextinv;
01146 break;
01147 }
01148 }
01149 curinv = nextinv;
01150 }
01151 }
01152 op->contr->socket.update_look = 1;
01153 CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
01154
01155 fix_object(op);
01156
01157 if (op->type == PLAYER)
01158 esrv_update_item(UPD_WEIGHT, op, op);
01159
01160 return 0;
01161 }
01162
01173 int command_drop(object *op, char *params) {
01174 object *tmp, *next;
01175 int did_one = 0;
01176 int ival = 0;
01177 int missed = 0;
01178
01179 if (!params) {
01180 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01181 "Drop what?", NULL);
01182 return 0;
01183 } else {
01184 for (tmp = op->inv; tmp; tmp = next) {
01185 next = tmp->below;
01186 if (QUERY_FLAG(tmp, FLAG_NO_DROP) || tmp->invisible)
01187 continue;
01188 if ((ival = item_matched_string(op, tmp, params)) > 0) {
01189 if ((QUERY_FLAG(tmp, FLAG_INV_LOCKED)) && ((ival == 1) || (ival == 2)))
01190 missed++;
01191 else
01192 drop(op, tmp);
01193 did_one = 1;
01194 }
01195 }
01196 if (!did_one)
01197 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01198 "Nothing to drop.", NULL);
01199 if (missed == 1)
01200 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01201 "One item couldn't be dropped because it was locked.", NULL);
01202 else if (missed > 1)
01203 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01204 "%d items couldn't be dropped because they were locked.",
01205 "%d items couldn't be dropped because they were locked.",
01206 missed);
01207 }
01208 if (op->type == PLAYER) {
01209 op->contr->count = 0;
01210 op->contr->socket.update_look = 1;
01211 }
01212 return 0;
01213 }
01214
01223 static void empty_container(object *container, object *pl) {
01224 object *inv;
01225 object *next;
01226 int left = 0;
01227 char name[MAX_BUF];
01228
01229 if (!container->inv)
01230 return;
01231
01232 for (inv = container->inv; inv; inv = next) {
01233 next = inv->below;
01234 if (QUERY_FLAG(inv, FLAG_INV_LOCKED)) {
01235
01236 left++;
01237 continue;
01238 }
01239 drop(pl, inv);
01240 if (inv->below == next)
01241
01242 left++;
01243 }
01244 esrv_update_item(UPD_WEIGHT, pl, container);
01245
01246 query_name(container, name, sizeof(name));
01247 if (left)
01248 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS, "You empty the %s except %d items.", NULL, name, left);
01249 else
01250 draw_ext_info_format(NDI_UNIQUE, 0, pl, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS, "You empty the %s.", NULL, name);
01251 }
01252
01263 int command_empty(object *op, char *params) {
01264 object *inv;
01265 object *container;
01266
01267 if (!params) {
01268 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01269 "Empty what?", NULL);
01270 return 0;
01271 }
01272
01273 if (strcmp(params, "all") == 0) {
01274 for (inv = op->inv; inv; inv = inv->below)
01275 if (inv->type == CONTAINER)
01276 empty_container(inv, op);
01277 return 0;
01278 }
01279
01280 container = find_best_object_match(op, params);
01281 if (!container) {
01282 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01283 "No such item.", NULL);
01284 return 0;
01285 }
01286 if (container->type != CONTAINER) {
01287 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01288 "This is not a container!", NULL);
01289 return 0;
01290 }
01291 empty_container(container, op);
01292
01293 return 0;
01294 }
01295
01306 int command_examine(object *op, char *params) {
01307 if (!params) {
01308 object *tmp = op->below;
01309
01310 while (tmp && !LOOK_OBJ(tmp))
01311 tmp = tmp->below;
01312 if (tmp)
01313 examine(op, tmp);
01314 } else {
01315 object *tmp = find_best_object_match(op, params);
01316
01317 if (tmp)
01318 examine(op, tmp);
01319 else
01320 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01321 "Could not find an object that matches %s",
01322 "Could not find an object that matches %s",
01323 params);
01324 }
01325 return 0;
01326 }
01327
01339 object *find_marked_object(object *op) {
01340 object *tmp;
01341
01342 if (!op || !op->contr || !op->contr->mark)
01343 return NULL;
01344
01345
01346
01347
01348
01349 for (tmp = op->inv; tmp; tmp = tmp->below) {
01350 if (tmp->invisible)
01351 continue;
01352 if (tmp == op->contr->mark) {
01353 if (tmp->count == op->contr->mark_count)
01354 return tmp;
01355 else {
01356 op->contr->mark = NULL;
01357 op->contr->mark_count = 0;
01358 return NULL;
01359 }
01360 }
01361 }
01362 return NULL;
01363 }
01364
01376 int command_mark(object *op, char *params) {
01377 char name[MAX_BUF];
01378
01379 if (!op->contr)
01380 return 1;
01381 if (!params) {
01382 object *mark = find_marked_object(op);
01383 if (!mark)
01384 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01385 "You have no marked object.", NULL);
01386 else {
01387 query_name(mark, name, MAX_BUF);
01388 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01389 "%s is marked.",
01390 "%s is marked.",
01391 name);
01392 }
01393 } else {
01394 object *mark1 = find_best_object_match(op, params);
01395
01396 if (!mark1) {
01397 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01398 "Could not find an object that matches %s",
01399 "Could not find an object that matches %s",
01400 params);
01401 return 1;
01402 } else {
01403 op->contr->mark = mark1;
01404 op->contr->mark_count = mark1->count;
01405 query_name(mark1, name, MAX_BUF);
01406 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01407 "Marked item %s",
01408 "Marked item %s",
01409 name);
01410 return 0;
01411 }
01412 }
01413 return 0;
01414 }
01415
01424 void examine_monster(object *op, object *tmp) {
01425 object *mon = tmp->head ? tmp->head : tmp;
01426
01427 if (QUERY_FLAG(mon, FLAG_UNDEAD))
01428 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01429 "It is an undead force.", NULL);
01430 if (mon->level > op->level)
01431 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01432 "It is likely more powerful than you.", NULL);
01433 else if (mon->level < op->level)
01434 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01435 "It is likely less powerful than you.", NULL);
01436 else
01437 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01438 "It is probably as powerful as you.", NULL);
01439
01440 if (mon->attacktype&AT_ACID)
01441 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01442 "You smell an acrid odor.", NULL);
01443
01444
01445
01446
01447 switch ((mon->stats.hp+1)*4/(mon->stats.maxhp+1)) {
01448 case 1:
01449 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01450 "It is in a bad shape.", NULL);
01451 break;
01452
01453 case 2:
01454 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01455 "It is hurt.", NULL);
01456 break;
01457
01458 case 3:
01459 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01460 "It is somewhat hurt.", NULL);
01461 break;
01462
01463 case 4:
01464 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01465 "It is in excellent shape.", NULL);
01466 break;
01467 }
01468 if (present_in_ob(POISONING, mon) != NULL)
01469 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01470 "It looks very ill.", NULL);
01471 }
01472
01481 void examine(object *op, object *tmp) {
01482 char buf[VERY_BIG_BUF];
01483 int in_shop;
01484 int i;
01485
01486 buf[0] = '\0';
01487
01488 if (tmp == NULL || tmp->type == CLOSE_CON)
01489 return;
01490
01491
01492 ob_describe(tmp, op, buf, sizeof(buf));
01493
01494
01495
01496
01497 if (tmp->nrof <= 1)
01498 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01499 "That is %s",
01500 "That is %s",
01501 buf);
01502 else
01503 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01504 "Those are %s",
01505 "Those are %s",
01506 buf);
01507 buf[0] = '\0';
01508
01509 if (tmp->custom_name) {
01510 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01511 "You name it %s",
01512 "You name it %s",
01513 tmp->custom_name);
01514 }
01515
01516 switch (tmp->type) {
01517 case SPELLBOOK:
01518 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED) && tmp->inv) {
01519 char level[100];
01520
01521 get_levelnumber(tmp->inv->level, level, 100);
01522 snprintf(buf, sizeof(buf), "%s is a %s level %s spell", tmp->inv->name, level, tmp->inv->skill);
01523 }
01524 break;
01525
01526 case BOOK:
01527 if (tmp->msg != NULL)
01528 snprintf(buf, sizeof(buf), "Something is written in it.");
01529 break;
01530
01531 case CONTAINER:
01532 if (tmp->race != NULL) {
01533 if (tmp->weight_limit && tmp->stats.Str < 100)
01534 snprintf(buf, sizeof(buf), "It can hold only %s and its weight limit is %.1f kg.", tmp->race, tmp->weight_limit/(10.0*(100-tmp->stats.Str)));
01535 else
01536 snprintf(buf, sizeof(buf), "It can hold only %s.", tmp->race);
01537 } else
01538 if (tmp->weight_limit && tmp->stats.Str < 100)
01539 snprintf(buf, sizeof(buf), "Its weight limit is %.1f kg.", tmp->weight_limit/(10.0*(100-tmp->stats.Str)));
01540 break;
01541
01542 case WAND:
01543 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01544 snprintf(buf, sizeof(buf), "It has %d charges left.", tmp->stats.food);
01545 break;
01546 }
01547
01548 if (buf[0] != '\0')
01549 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01550 buf, NULL);
01551
01552 if (tmp->materialname != NULL && !tmp->msg) {
01553 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01554 "It is made of: %s.",
01555 "It is made of: %s.",
01556 tmp->materialname);
01557 }
01558
01559 for (i = 0; i < NUM_BODY_LOCATIONS; i++) {
01560 if (tmp->body_info[i] < -1) {
01561 if (op->body_info[i])
01562 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01563 "It goes %s (%d)",
01564 "It goes %s (%d)",
01565 body_locations[i].use_name, -tmp->body_info[i]);
01566 else
01567 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01568 "It goes %s",
01569 "It goes %s",
01570 body_locations[i].nonuse_name);
01571 } else if (tmp->body_info[i]) {
01572 if (op->body_info[i])
01573 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01574 "It goes %s",
01575 "It goes %s",
01576 body_locations[i].use_name);
01577 else
01578 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01579 "It goes %s",
01580 "It goes %s",
01581 body_locations[i].nonuse_name);
01582 }
01583 }
01584
01585 if (tmp->weight) {
01586 snprintf(buf, sizeof(buf), tmp->nrof > 1 ? "They weigh %3.3f kg." : "It weighs %3.3f kg.", tmp->weight*((float)(tmp->nrof ? tmp->nrof : 1)/1000.0));
01587 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01588 buf, NULL);
01589 }
01590
01591 in_shop = is_in_shop(op);
01592
01593 if (tmp->value && !QUERY_FLAG(tmp, FLAG_STARTEQUIP) && !QUERY_FLAG(tmp, FLAG_NO_PICK)) {
01594 char *value = stringbuffer_finish(query_cost_string(tmp, op, F_SELL|F_APPROX, NULL));
01595 snprintf(buf, sizeof(buf), "You reckon %s worth %s.", tmp->nrof > 1 ? "they are" : "it is", value);
01596 free(value);
01597 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01598 buf, NULL);
01599 if (in_shop) {
01600 if (QUERY_FLAG(tmp, FLAG_UNPAID)) {
01601 value = stringbuffer_finish(query_cost_string(tmp, op, F_BUY|F_SHOP, NULL));
01602 snprintf(buf, sizeof(buf), "%s would cost you %s.", tmp->nrof > 1 ? "They" : "It", value);
01603 free(value);
01604 } else {
01605 value = stringbuffer_finish(query_cost_string(tmp, op, F_SELL+F_SHOP, NULL));
01606 snprintf(buf, sizeof(buf), "You are offered %s for %s.", value, tmp->nrof > 1 ? "them" : "it");
01607 free(value);
01608 }
01609 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01610 buf, NULL);
01611 }
01612 }
01613
01614 if (QUERY_FLAG(tmp, FLAG_MONSTER))
01615 examine_monster(op, tmp);
01616
01617
01618 if (QUERY_FLAG(tmp, FLAG_IS_BUILDABLE))
01619 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01620 "This is a buildable item.", NULL);
01621
01622
01623
01624
01625 if (tmp->msg
01626 && tmp->type != EXIT
01627 && tmp->type != BOOK
01628 && tmp->type != CORPSE
01629 && !tmp->move_on
01630 && strncasecmp(tmp->msg, "@match", 6)) {
01631
01632
01633
01634 if (need_identify(tmp) && QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01635 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01636 "The object has a story:", NULL);
01637
01638 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01639 tmp->msg, NULL);
01640 }
01641 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_EXAMINE,
01642 " ", " ");
01643 }
01644
01653 void inventory(object *op, object *inv) {
01654 object *tmp;
01655 const char *in;
01656 int items = 0, length;
01657 char weight[MAX_BUF], name[MAX_BUF];
01658
01659 if (inv == NULL && op == NULL) {
01660 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01661 "Inventory of what object?", NULL);
01662 return;
01663 }
01664 tmp = inv ? inv->inv : op->inv;
01665
01666 while (tmp) {
01667 if ((!tmp->invisible && (inv == NULL || inv->type == CONTAINER || QUERY_FLAG(tmp, FLAG_APPLIED)))
01668 || (!op || QUERY_FLAG(op, FLAG_WIZ)))
01669 items++;
01670 tmp = tmp->below;
01671 }
01672 if (inv == NULL) {
01673 if (items == 0) {
01674 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01675 "You carry nothing.", NULL);
01676 return;
01677 } else {
01678 length = 28;
01679 in = "";
01680 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INVENTORY,
01681 "Inventory:", NULL);
01682 }
01683 } else {
01684 if (items == 0)
01685 return;
01686 else {
01687 length = 28;
01688 in = " ";
01689 }
01690 }
01691 for (tmp = inv ? inv->inv : op->inv; tmp; tmp = tmp->below) {
01692 if ((!op || !QUERY_FLAG(op, FLAG_WIZ))
01693 && (tmp->invisible || (inv && inv->type != CONTAINER && !QUERY_FLAG(tmp, FLAG_APPLIED))))
01694 continue;
01695 query_weight(tmp, weight, MAX_BUF);
01696 query_name(tmp, name, MAX_BUF);
01697 if ((!op || QUERY_FLAG(op, FLAG_WIZ)))
01698 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INVENTORY,
01699 "[fixed]%s- %-*.*s (%5d) %-8s",
01700 "%s- %-*.*s (%5d) %-8s",
01701 in, length, length, name, tmp->count, weight);
01702 else
01703 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INVENTORY,
01704 "[fixed]%s- %-*.*s %-8s",
01705 "%s- %-*.*s %-8s",
01706 in, length+8, length+8, name, weight);
01707 }
01708 if (!inv && op) {
01709 query_weight(op, weight, MAX_BUF);
01710 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INVENTORY,
01711 "[fixed]%-*s %-8s",
01712 "%-*s %-8s",
01713 41, "Total weight :", weight);
01714 }
01715 }
01716
01723 static void display_new_pickup(const object *op) {
01724 int i = op->contr->mode;
01725
01726 if (!(i&PU_NEWMODE))
01727 return;
01728
01729 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01730 "%d NEWMODE",
01731 "%d NEWMODE",
01732 i&PU_NEWMODE ? 1 : 0);
01733 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01734 "%d DEBUG",
01735 "%d DEBUG",
01736 i&PU_DEBUG ? 1 : 0);
01737 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01738 "%d INHIBIT",
01739 "%d INHIBIT",
01740 i&PU_INHIBIT ? 1 : 0);
01741 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01742 "%d STOP",
01743 "%d STOP",
01744 i&PU_STOP ? 1 : 0);
01745
01746 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01747 "%d <= x pickup weight/value RATIO (0==off)",
01748 "%d <= x pickup weight/value RATIO (0==off)",
01749 (i&PU_RATIO)*5);
01750
01751 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01752 "%d FOOD",
01753 "%d FOOD",
01754 i&PU_FOOD ? 1 : 0);
01755 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01756 "%d DRINK",
01757 "%d DRINK",
01758 i&PU_DRINK ? 1 : 0);
01759 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01760 "%d VALUABLES",
01761 "%d VALUABLES",
01762 i&PU_VALUABLES ? 1 : 0);
01763
01764 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01765 "%d BOW",
01766 "%d BOW",
01767 i&PU_BOW ? 1 : 0);
01768 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01769 "%d ARROW",
01770 "%d ARROW",
01771 i&PU_ARROW ? 1 : 0);
01772
01773 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01774 "%d HELMET",
01775 "%d HELMET",
01776 i&PU_HELMET ? 1 : 0);
01777 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01778 "%d SHIELD",
01779 "%d SHIELD",
01780 i&PU_SHIELD ? 1 : 0);
01781 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01782 "%d ARMOUR",
01783 "%d ARMOUR",
01784 i&PU_ARMOUR ? 1 : 0);
01785
01786 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01787 "%d BOOTS",
01788 "%d BOOTS",
01789 i&PU_BOOTS ? 1 : 0);
01790 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01791 "%d GLOVES",
01792 "%d GLOVES",
01793 i&PU_GLOVES ? 1 : 0);
01794 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01795 "%d CLOAK",
01796 "%d CLOAK",
01797 i&PU_CLOAK ? 1 : 0);
01798 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01799 "%d KEY",
01800 "%d KEY",
01801 i&PU_KEY ? 1 : 0);
01802
01803 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01804 "%d MISSILEWEAPON",
01805 "%d MISSILEWEAPON",
01806 i&PU_MISSILEWEAPON ? 1 : 0);
01807 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01808 "%d ALLWEAPON",
01809 "%d ALLWEAPON",
01810 i&PU_ALLWEAPON ? 1 : 0);
01811 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01812 "%d MAGICAL",
01813 "%d MAGICAL",
01814 i&PU_MAGICAL ? 1 : 0);
01815 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01816 "%d POTION",
01817 "%d POTION",
01818 i&PU_POTION ? 1 : 0);
01819
01820 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01821 "%d SPELLBOOK",
01822 "%d SPELLBOOK",
01823 i&PU_SPELLBOOK ? 1 : 0);
01824 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01825 "%d SKILLSCROLL",
01826 "%d SKILLSCROLL",
01827 i&PU_SKILLSCROLL ? 1 : 0);
01828 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01829 "%d READABLES",
01830 "%d READABLES",
01831 i&PU_READABLES ? 1 : 0);
01832 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01833 "%d MAGICDEVICE",
01834 "%d MAGICDEVICE",
01835 i&PU_MAGIC_DEVICE ? 1 : 0);
01836
01837 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01838 "%d NOT CURSED",
01839 "%d NOT CURSED",
01840 i&PU_NOT_CURSED ? 1 : 0);
01841
01842 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01843 "%d JEWELS",
01844 "%d JEWELS",
01845 i&PU_JEWELS ? 1 : 0);
01846
01847 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01848 "%d FLESH",
01849 "%d FLESH",
01850 i&PU_FLESH ? 1 : 0);
01851
01852 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
01853 "", "");
01854 }
01855
01867 int command_pickup(object *op, char *params) {
01868 uint32 i;
01869 static const char *names[] = {
01870 "debug", "inhibit", "stop", "food", "drink",
01871 "valuables", "bow", "arrow", "helmet", "shield",
01872 "armour", "boots", "gloves", "cloak", "key",
01873 "missile", "allweapon", "magical", "potion", "spellbook",
01874 "skillscroll", "readables", "magicdevice", "notcursed", "jewels",
01875 "flesh", NULL
01876 };
01877 static const uint32 modes[] = {
01878 PU_DEBUG, PU_INHIBIT, PU_STOP, PU_FOOD, PU_DRINK, PU_VALUABLES, PU_BOW, PU_ARROW, PU_HELMET,
01879 PU_SHIELD, PU_ARMOUR, PU_BOOTS, PU_GLOVES, PU_CLOAK, PU_KEY, PU_MISSILEWEAPON, PU_ALLWEAPON,
01880 PU_MAGICAL, PU_POTION, PU_SPELLBOOK, PU_SKILLSCROLL, PU_READABLES, PU_MAGIC_DEVICE,
01881 PU_NOT_CURSED, PU_JEWELS, PU_FLESH, 0
01882 };
01883
01884 if (!params) {
01885
01886 if (op->contr->mode&PU_NEWMODE) {
01887 display_new_pickup(op);
01888 return 1;
01889 }
01890 if (1)
01891 LOG(llevDebug, "command_pickup: !params\n");
01892 set_pickup_mode(op, (op->contr->mode > 6) ? 0 : op->contr->mode+1);
01893 return 0;
01894 }
01895
01896 while (*params == ' ')
01897 params++;
01898
01899 if (*params == '+' || *params == '-') {
01900 int mode;
01901
01902 for (mode = 0; names[mode]; mode++) {
01903 if (!strcmp(names[mode], params+1)) {
01904 i = op->contr->mode;
01905 if (!(i&PU_NEWMODE))
01906 i = PU_NEWMODE;
01907 if (*params == '+')
01908 i = i|modes[mode];
01909 else
01910 i = i&~modes[mode];
01911 op->contr->mode = i;
01912 display_new_pickup(op);
01913 return 1;
01914 }
01915 }
01916 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01917 "Pickup: invalid item %s\n",
01918 "Pickup: invalid item %s\n",
01919 params);
01920 return 1;
01921 }
01922
01923 if (sscanf(params, "%u", &i) != 1) {
01924 if (1)
01925 LOG(llevDebug, "command_pickup: params==NULL\n");
01926 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
01927 "Usage: pickup <0-7> or <value_density> .", NULL);
01928 return 1;
01929 }
01930 set_pickup_mode(op, i);
01931 display_new_pickup(op);
01932
01933 return 1;
01934 }
01935
01944 static void set_pickup_mode(const object *op, int i) {
01945 switch (op->contr->mode = i) {
01946 case 0:
01947 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01948 "Mode: Don't pick up.", NULL);
01949 break;
01950
01951 case 1:
01952 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01953 "Mode: Pick up one item.", NULL);
01954 break;
01955
01956 case 2:
01957 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01958 "Mode: Pick up one item and stop.", NULL);
01959 break;
01960
01961 case 3:
01962 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01963 "Mode: Stop before picking up.", NULL);
01964 break;
01965
01966 case 4:
01967 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01968 "Mode: Pick up all items.", NULL);
01969 break;
01970
01971 case 5:
01972 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01973 "Mode: Pick up all items and stop.", NULL);
01974 break;
01975
01976 case 6:
01977 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01978 "Mode: Pick up all magic items.", NULL);
01979 break;
01980
01981 case 7:
01982 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
01983 "Mode: Pick up all coins and gems", NULL);
01984 break;
01985 }
01986 }
01987
01998 int command_search_items(object *op, char *params) {
01999 if (settings.search_items == FALSE)
02000 return 1;
02001
02002 if (params == NULL) {
02003 if (op->contr->search_str[0] == '\0') {
02004 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
02005 "Example: search magic+1 "
02006 "Would automatically pick up all "
02007 "items containing the word 'magic+1'.",
02008 NULL);
02009 return 1;
02010 }
02011 op->contr->search_str[0] = '\0';
02012 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
02013 "Search mode turned off.", NULL);
02014 fix_object(op);
02015 return 1;
02016 }
02017 if ((int)strlen(params) >= MAX_BUF) {
02018 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02019 "Search string too long.", NULL);
02020 return 1;
02021 }
02022 strcpy(op->contr->search_str, params);
02023 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
02024 "Searching for '%s'.",
02025 "Searching for '%s'.",
02026 op->contr->search_str);
02027 fix_object(op);
02028 return 1;
02029 }
02030
02047 int command_rename_item(object *op, char *params) {
02048 char buf[VERY_BIG_BUF], name[MAX_BUF];
02049 int itemnumber;
02050 object *item = NULL;
02051 object *tmp;
02052 char *closebrace;
02053 size_t counter;
02054 tag_t tag;
02055
02056 if (params) {
02057
02058 while (' ' == *params)
02059 params++;
02060
02061
02062 if ((itemnumber = atoi(params)) != 0) {
02063 for (item = op->inv; item && ((item->count != itemnumber) || item->invisible); item = item->below)
02064 ;
02065 if (!item) {
02066 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02067 "Tried to rename an invalid item.", NULL);
02068 return 1;
02069 }
02070 while (isdigit(*params) || ' ' == *params)
02071 params++;
02072 } else if ('<' == *params) {
02073
02074 closebrace = strchr(params, '>');
02075 if (!closebrace) {
02076 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02077 "Syntax error!", NULL);
02078 return 1;
02079 }
02080
02081 if ((closebrace-params) > 127) {
02082 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02083 "Old name too long (up to 127 characters allowed)!", NULL);
02084 return 1;
02085 }
02086
02087 snprintf(buf, sizeof(buf), "%.*s", (int)(closebrace-(params+1)), params+1);
02088
02089
02090 item = find_best_object_match(op, buf);
02091 if (!item) {
02092 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02093 "Could not find a matching item to rename.", NULL);
02094 return 1;
02095 }
02096
02097
02098 params = closebrace+1;
02099 while (' ' == *params)
02100 params++;
02101 } else {
02102
02103 item = find_marked_object(op);
02104 if (!item) {
02105 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02106 "No marked item to rename.", NULL);
02107 return 1;
02108 }
02109 }
02110
02111
02112 if (!strncmp(params, "to ", 3)) {
02113 params += 3;
02114 while (' ' == *params)
02115 params++;
02116 if ('<' != *params) {
02117 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02118 "Syntax error, expecting < at start of new name!", NULL);
02119 return 1;
02120 }
02121 closebrace = strchr(params+1, '>');
02122 if (!closebrace) {
02123 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02124 "Syntax error, expecting > at end of new name!", NULL);
02125 return 1;
02126 }
02127
02128
02129 if ((closebrace-params) > 127) {
02130 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02131 "New name too long (up to 127 characters allowed)!", NULL);
02132 return 1;
02133 }
02134
02135
02136 snprintf(buf, sizeof(buf), "%.*s", (int)(closebrace-(params+1)), params+1);
02137
02138
02139 for (counter = 0; counter < strlen(buf); counter++) {
02140 if (isalnum(buf[counter]))
02141 continue;
02142 if (' ' == buf[counter])
02143 continue;
02144 if ('\'' == buf[counter])
02145 continue;
02146 if ('+' == buf[counter])
02147 continue;
02148 if ('_' == buf[counter])
02149 continue;
02150 if ('-' == buf[counter])
02151 continue;
02152
02153
02154
02155
02156 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02157 "Invalid new name!", NULL);
02158 return 1;
02159 }
02160 } else {
02161
02162 if (strlen(params)) {
02163 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02164 "Syntax error, expected 'to <' after old name!", NULL);
02165 return 1;
02166 }
02167
02168 buf[0] = '\0';
02169 }
02170 } else {
02171
02172 item = find_marked_object(op);
02173 if (!item) {
02174 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02175 "No marked item to rename.", NULL);
02176 return 1;
02177 }
02178 buf[0] = '\0';
02179 }
02180
02181
02182 if (!strlen(buf)) {
02183
02184 if (item->custom_name == NULL) {
02185 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
02186 "This item has no custom name.", NULL);
02187 return 1;
02188 }
02189
02190 FREE_AND_CLEAR_STR(item->custom_name);
02191 query_base_name(item, item->nrof > 1 ? 1 : 0, name, MAX_BUF);
02192 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
02193 "You stop calling your %s with weird names.",
02194 "You stop calling your %s with weird names.",
02195 name);
02196 } else {
02197 if (item->custom_name != NULL && strcmp(item->custom_name, buf) == 0) {
02198 query_base_name(item, item->nrof > 1 ? 1 : 0, name, MAX_BUF);
02199 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
02200 "You keep calling your %s %s.",
02201 "You keep calling your %s %s.",
02202 name, buf);
02203 return 1;
02204 }
02205
02206
02207 FREE_AND_COPY(item->custom_name, buf);
02208
02209 query_base_name(item, item->nrof > 1 ? 1 : 0, name, MAX_BUF);
02210 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_SUCCESS,
02211 "Your %s will now be called %s.",
02212 "Your %s will now be called %s.",
02213 name, buf);
02214 }
02215
02216 tag = item->count;
02217 tmp = merge_ob(item, NULL);
02218 if (tmp == NULL) {
02219
02220 esrv_update_item(UPD_NAME, op, item);
02221 }
02222
02223 return 1;
02224 }
02225
02234 int command_lock_item(object *op, char *params) {
02235 object *item;
02236 object *tmp;
02237 tag_t tag;
02238 char name[HUGE_BUF];
02239
02240 if (!params || strlen(params) == 0) {
02241 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
02242 "Lock what item?", "Lock what item?");
02243 return 1;
02244 }
02245
02246 item = find_best_object_match(op, params);
02247 if (!item) {
02248 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
02249 "Can't find any matching item.", "Can't find any matching item.");
02250 return 1;
02251 }
02252
02253 query_short_name(item, name, HUGE_BUF);
02254 if (QUERY_FLAG(item, FLAG_INV_LOCKED)) {
02255 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
02256 "Unlocked %s.", "Unlocked %s.", name);
02257 CLEAR_FLAG(item, FLAG_INV_LOCKED);
02258 } else {
02259 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE,
02260 "Locked %s.", "Locked %s.", name);
02261 SET_FLAG(item, FLAG_INV_LOCKED);
02262 }
02263
02264 tag = item->count;
02265 tmp = merge_ob(item, NULL);
02266 if (tmp == NULL) {
02267
02268 esrv_update_item(UPD_FLAGS, op, item);
02269 }
02270 return 1;
02271 }
02272
02282 int command_use(object *op, char *params) {
02283 char *with, copy[MAX_BUF];
02284 object *first, *second, *add;
02285 archetype *arch;
02286 int count;
02287 sstring data;
02288
02289 if (!op->type == PLAYER)
02290 return 1;
02291
02292 snprintf(copy, sizeof(copy), "%s", params);
02293 with = strstr(copy, " with ");
02294 if (!with) {
02295 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "Syntax is use <item> with <item>.", NULL);
02296 return 1;
02297 }
02298
02299 with[0] = '\0';
02300 with = with+strlen(" with ");
02301
02302 first = find_best_object_match(op, copy);
02303 if (!first) {
02304 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "No match for %s.", NULL, copy);
02305 return 1;
02306 }
02307 second = find_best_object_match(op, with);
02308 if (!second) {
02309 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "No match for %s.", NULL, with);
02310 return 1;
02311 }
02312
02313 snprintf(copy, sizeof(copy), "on_use_with_%s", first->arch->name);
02314 data = get_ob_key_value(second, copy);
02315 if (!data) {
02316 snprintf(copy, sizeof(copy), "on_use_with_%d_%d", first->type, first->subtype);
02317 data = get_ob_key_value(second, copy);
02318 if (!data) {
02319 snprintf(copy, sizeof(copy), "on_use_with_%d", first->type);
02320 data = get_ob_key_value(second, copy);
02321 if (!data) {
02322 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_FAILURE, "Nothing happens.", NULL);
02323 return 1;
02324 }
02325 }
02326 }
02327
02328 while (data != NULL) {
02329 if (strncmp(data, "add ", 4) == 0) {
02330 data += 4;
02331 if (isdigit(*data)) {
02332 count = atol(data);
02333 data = strchr(data, ' ')+1;
02334 } else
02335 count = 1;
02336 with = strchr(data, ' ');
02337 if (!with) {
02338 strncpy(copy, data, sizeof(copy));
02339 data = NULL;
02340 } else {
02341 *with = '\0';
02342 strncpy(copy, data, sizeof(copy));
02343 data += strlen(copy)+1;
02344 }
02345 arch = find_archetype(copy);
02346 if (!arch) {
02347 LOG(llevError, "Use: invalid archetype %s in %s.\n", copy, second->name);
02348 return 1;
02349 }
02350 add = object_create_arch(arch);
02351 add->nrof = count;
02352 insert_ob_in_ob(add, op);
02353 } else if (strncmp(data, "remove $", 8) == 0) {
02354 data += 8;
02355 if (*data == '1') {
02356 if (first)
02357 first = decrease_ob(first);
02358 data += 2;
02359 } else if (*data == '2') {
02360 if (second)
02361 second = decrease_ob(second);
02362 data += 2;
02363 } else {
02364 LOG(llevError, "Use: invalid use string %s in %s\n", data, second->name);
02365 return 1;
02366 }
02367 } else {
02368 LOG(llevError, "Use: invalid use string %s in %s\n", data, second->name);
02369 return 1;
02370 }
02371 }
02372
02373 return 1;
02374 }