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
00030 #include <global.h>
00031
00039 object *find_best_object_match(object *pl, char *params)
00040 {
00041 object *tmp, *best = NULL;
00042 int match_val = 0, tmpmatch;
00043
00044 for (tmp = pl->inv; tmp; tmp = tmp->below)
00045 {
00046 if (IS_SYS_INVISIBLE(tmp))
00047 {
00048 continue;
00049 }
00050
00051 if ((tmpmatch = item_matched_string(pl, tmp, params)) > match_val)
00052 {
00053 match_val = tmpmatch;
00054 best = tmp;
00055 }
00056 }
00057
00058 return best;
00059 }
00060
00061
00067 int command_uskill(object *pl, char *params)
00068 {
00069 if (!params)
00070 {
00071 new_draw_info(NDI_UNIQUE, pl, "Usage: /use_skill <skill name>");
00072 return 0;
00073 }
00074
00075 if (pl->type == PLAYER)
00076 {
00077 CONTR(pl)->praying = 0;
00078 }
00079
00080 return use_skill(pl, params);
00081 }
00082
00088 int command_rskill(object *pl, char *params)
00089 {
00090 int skillno;
00091
00092 if (!params)
00093 {
00094 new_draw_info(NDI_UNIQUE, pl, "Usage: /ready_skill <skill name>");
00095 return 0;
00096 }
00097
00098 if (pl->type == PLAYER)
00099 {
00100 CONTR(pl)->praying = 0;
00101 }
00102
00103 skillno = lookup_skill_by_name(params);
00104
00105 if (skillno == -1)
00106 {
00107 new_draw_info_format(NDI_UNIQUE, pl, "Couldn't find the skill %s", params);
00108 return 0;
00109 }
00110
00111 return change_skill(pl, skillno);
00112 }
00113
00120 int command_apply(object *op, char *params)
00121 {
00122 if (op->type == PLAYER)
00123 CONTR(op)->praying = 0;
00124
00125 if (!params)
00126 {
00127 player_apply_below(op);
00128 return 0;
00129 }
00130 else
00131 {
00132 enum apply_flag aflag = 0;
00133 object *inv;
00134
00135 while (*params == ' ')
00136 {
00137 params++;
00138 }
00139
00140 if (!strncmp(params, "-a ", 3))
00141 {
00142 aflag = AP_APPLY;
00143 params += 3;
00144 }
00145
00146 if (!strncmp(params, "-u ", 3))
00147 {
00148 aflag = AP_UNAPPLY;
00149 params += 3;
00150 }
00151
00152 while (*params == ' ')
00153 {
00154 params++;
00155 }
00156
00157 inv = find_best_object_match(op, params);
00158
00159 if (inv)
00160 {
00161 player_apply(op, inv, aflag, 0);
00162 }
00163 else
00164 {
00165 new_draw_info_format(NDI_UNIQUE, op, "Could not find any match to the %s.", params);
00166 }
00167 }
00168
00169 return 0;
00170 }
00171
00180 int sack_can_hold(object *pl, object *sack, object *op, int nrof)
00181 {
00182 char buf[MAX_BUF];
00183
00184 buf[0] = '\0';
00185
00186 if (!QUERY_FLAG(sack, FLAG_APPLIED))
00187 {
00188 snprintf(buf, sizeof(buf), "The %s is not active.", query_name(sack, NULL));
00189 }
00190
00191 if (sack == op)
00192 {
00193 snprintf(buf, sizeof(buf), "You can't put the %s into itself.", query_name(sack, NULL));
00194 }
00195
00196 if ((sack->race && (sack->sub_type & 1) != ST1_CONTAINER_CORPSE) && (sack->race != op->race || op->type == CONTAINER || (sack->stats.food && sack->stats.food != op->type)))
00197 {
00198 snprintf(buf, sizeof(buf), "You can put only %s into the %s.", sack->race, query_name(sack, NULL));
00199 }
00200
00201 if (op->type == KEY && sack->slaying && op->slaying)
00202 {
00203 snprintf(buf, sizeof(buf), "You don't want put the key into %s.", query_name(sack, NULL));
00204 }
00205
00206 if (sack->weight_limit && sack->carrying + (sint32) ((float) (((nrof ? nrof : 1) * op->weight) + op->carrying) * sack->weapon_speed) > (sint32) sack->weight_limit)
00207 {
00208 snprintf(buf, sizeof(buf), "That won't fit in the %s!", query_name(sack, NULL));
00209 }
00210
00211 if (buf[0])
00212 {
00213 if (pl)
00214 {
00215 new_draw_info(NDI_UNIQUE, pl, buf);
00216 }
00217
00218 return 0;
00219 }
00220
00221 return 1;
00222 }
00223
00231 static void pick_up_object(object *pl, object *op, object *tmp, int nrof, int no_mevent)
00232 {
00233 char buf[HUGE_BUF];
00234 object *env = tmp->env;
00235 int tmp_nrof = tmp->nrof ? tmp->nrof : 1;
00236
00237 if (pl->type == PLAYER)
00238 {
00239 CONTR(pl)->praying = 0;
00240 }
00241
00242
00243
00244
00245
00246 if (QUERY_FLAG(pl, FLAG_FLYING) && !QUERY_FLAG(pl, FLAG_WIZ) && is_player_inv(tmp) != pl)
00247 {
00248 new_draw_info(NDI_UNIQUE, pl, "You are levitating, you can't reach the ground!");
00249 return;
00250 }
00251
00252 if (QUERY_FLAG(tmp, FLAG_WAS_WIZ) && !QUERY_FLAG(pl, FLAG_WAS_WIZ))
00253 {
00254 new_draw_info(NDI_UNIQUE, pl, "The object disappears in a puff of smoke!\nIt must have been an illusion.");
00255
00256 if (pl->type == PLAYER)
00257 {
00258 esrv_del_item(CONTR(pl), tmp->count, tmp->env);
00259 }
00260
00261 if (!QUERY_FLAG(tmp, FLAG_REMOVED))
00262 {
00263 remove_ob(tmp);
00264 check_walk_off(tmp, NULL, MOVE_APPLY_VANISHED);
00265 }
00266
00267 return;
00268 }
00269
00270 if (nrof > tmp_nrof || nrof == 0)
00271 {
00272 nrof = tmp_nrof;
00273 }
00274
00275 if (!player_can_carry(pl, WEIGHT_NROF(tmp, nrof)))
00276 {
00277 new_draw_info(NDI_UNIQUE, pl, "That item is too heavy for you to pick up.");
00278 return;
00279 }
00280
00281 if (tmp->type == CONTAINER)
00282 {
00283 container_unlink(NULL, tmp);
00284 }
00285
00286
00287 if (trigger_event(EVENT_PICKUP, pl, tmp, op, NULL, tmp_nrof, 0, 0, SCRIPT_FIX_ACTIVATOR))
00288 {
00289 return;
00290 }
00291
00292
00293 if (!no_mevent && pl->map && pl->map->events && trigger_map_event(MEVENT_PICK, pl->map, pl, tmp, op, NULL, nrof))
00294 {
00295 return;
00296 }
00297
00298 #ifndef REAL_WIZ
00299 if (QUERY_FLAG(pl, FLAG_WAS_WIZ))
00300 {
00301 SET_FLAG(tmp, FLAG_WAS_WIZ);
00302 }
00303 #endif
00304
00305 if (QUERY_FLAG(tmp, FLAG_UNPAID))
00306 {
00307
00308 if (QUERY_FLAG(tmp, FLAG_NO_PICK))
00309 {
00310 tmp = object_create_clone(tmp);
00311 CLEAR_FLAG(tmp, FLAG_NO_PICK);
00312 SET_FLAG(tmp, FLAG_STARTEQUIP);
00313 tmp->nrof = nrof;
00314 tmp_nrof = nrof;
00315 snprintf(buf, sizeof(buf), "You pick up %s for %s from the storage.", query_name(tmp, NULL), query_cost_string(tmp, pl, F_BUY));
00316 }
00317
00318 else
00319 {
00320 tmp->nrof = nrof;
00321 snprintf(buf, sizeof(buf), "%s will cost you %s.", query_name(tmp, NULL), query_cost_string(tmp, pl, F_BUY));
00322 tmp->nrof = tmp_nrof;
00323 }
00324 }
00325 else
00326 {
00327 tmp->nrof = nrof;
00328 snprintf(buf, sizeof(buf), "You pick up the %s.", query_name(tmp, NULL));
00329 tmp->nrof = tmp_nrof;
00330 }
00331
00332 if (nrof != tmp_nrof)
00333 {
00334 object *tmp2 = tmp, *tmp2_cont = tmp->env;
00335 tag_t tmp2_tag = tmp2->count;
00336 char err[MAX_BUF];
00337 tmp = get_split_ob(tmp, nrof, err, sizeof(err));
00338
00339 if (!tmp)
00340 {
00341 new_draw_info(NDI_UNIQUE, pl, err);
00342 return;
00343 }
00344
00345
00346 if (pl->type == PLAYER)
00347 {
00348 if (was_destroyed(tmp2, tmp2_tag))
00349 {
00350 esrv_del_item(CONTR(pl), tmp2_tag, tmp2_cont);
00351 }
00352 else
00353 {
00354 esrv_send_item(pl, tmp2);
00355 }
00356 }
00357 }
00358 else
00359 {
00360
00361
00362
00363 if (!QUERY_FLAG(tmp, FLAG_REMOVED))
00364 {
00365 if (tmp->env && pl->type == PLAYER)
00366 {
00367 esrv_del_item (CONTR(pl), tmp->count, tmp->env);
00368 }
00369
00370
00371 remove_ob(tmp);
00372 }
00373 }
00374
00375 new_draw_info(NDI_UNIQUE, pl, buf);
00376 tmp = insert_ob_in_ob(tmp, op);
00377
00378
00379
00380 if (pl->type != PLAYER)
00381 {
00382 return;
00383 }
00384
00385 esrv_send_item(pl, tmp);
00386
00387
00388 esrv_update_item(UPD_WEIGHT, pl, op);
00389
00390 if (op != pl)
00391 {
00392 esrv_send_item(pl, pl);
00393 }
00394
00395
00396 if (env && env != pl && env != op)
00397 {
00398 esrv_update_item(UPD_WEIGHT, pl, env);
00399 }
00400 }
00401
00408 void pick_up(object *op, object *alt, int no_mevent)
00409 {
00410 int need_fix_tmp = 0, count;
00411 object *tmp = NULL;
00412 mapstruct *tmp_map = NULL;
00413 tag_t tag;
00414
00415
00416 if (alt)
00417 {
00418 if (!can_pick(op, alt))
00419 {
00420 new_draw_info_format(NDI_UNIQUE, op, "You can't pick up %s.", alt->name);
00421 goto leave;
00422 }
00423
00424 tmp = alt;
00425 }
00426 else
00427 {
00428 if (op->below == NULL || !can_pick(op, op->below))
00429 {
00430 new_draw_info(NDI_UNIQUE, op, "There is nothing to pick up here.");
00431 goto leave;
00432 }
00433
00434 tmp = op->below;
00435 }
00436
00437 if (tmp->type == CONTAINER)
00438 {
00439 container_unlink(NULL, tmp);
00440 }
00441
00442
00443 tmp_map = tmp->map;
00444 tmp = stop_item(tmp);
00445
00446 if (tmp == NULL)
00447 {
00448 goto leave;
00449 }
00450
00451 need_fix_tmp = 1;
00452
00453 if (!can_pick(op, tmp))
00454 {
00455 goto leave;
00456 }
00457
00458 if (op->type == PLAYER)
00459 {
00460 count = CONTR(op)->count;
00461
00462 if (count == 0)
00463 {
00464 count = tmp->nrof;
00465 }
00466 }
00467 else
00468 {
00469 count = tmp->nrof;
00470 }
00471
00472
00473 if (op->type == PLAYER && CONTR(op)->container)
00474 {
00475 alt = CONTR(op)->container;
00476
00477 if (alt != tmp->env && !sack_can_hold(op, alt, tmp, count))
00478 {
00479 goto leave;
00480 }
00481 }
00482
00483 else
00484 {
00485 for (alt = op->inv; alt; alt = alt->below)
00486 {
00487 if (alt->type == CONTAINER && QUERY_FLAG(alt, FLAG_APPLIED) && alt->race && alt->race == tmp->race && sack_can_hold(NULL, alt, tmp, count))
00488 {
00489
00490 break;
00491 }
00492 }
00493
00494 if (!alt)
00495 {
00496 for (alt = op->inv; alt; alt = alt->below)
00497 {
00498 if (alt->type == CONTAINER && QUERY_FLAG(alt, FLAG_APPLIED) && sack_can_hold(NULL, alt, tmp, count))
00499 {
00500
00501 break;
00502 }
00503 }
00504 }
00505
00506
00507 if (!alt)
00508 {
00509 alt = op;
00510 }
00511 }
00512
00513 if (tmp->env == alt)
00514 {
00515 alt = op;
00516 }
00517
00518
00519 if (op->type == PLAYER && alt->type == CONTAINER && QUERY_FLAG(tmp, FLAG_STARTEQUIP))
00520 {
00521 new_draw_info(NDI_UNIQUE, op, "This object cannot be put into containers!");
00522 goto leave;
00523 }
00524
00525 tag = tmp->count;
00526 pick_up_object(op, alt, tmp, count, no_mevent);
00527
00528 if (was_destroyed(tmp, tag) || tmp->env)
00529 {
00530 need_fix_tmp = 0;
00531 }
00532
00533 if (op->type == PLAYER)
00534 {
00535 CONTR(op)->count = 0;
00536 }
00537
00538 goto leave;
00539
00540 leave:
00541 if (need_fix_tmp)
00542 {
00543 fix_stopped_item(tmp, tmp_map, op);
00544 }
00545 }
00546
00554 void put_object_in_sack(object *op, object *sack, object *tmp, long nrof)
00555 {
00556 tag_t tmp_tag, tmp2_tag;
00557 object *tmp2, *tmp_cont;
00558 char buf[MAX_BUF];
00559 int tmp_nrof = tmp->nrof ? tmp->nrof : 1;
00560
00561 if (op->type != PLAYER)
00562 {
00563 LOG(llevDebug, "DEBUG: put_object_in_sack: op not a player.\n");
00564 return;
00565 }
00566
00567
00568 if (sack == tmp)
00569 {
00570 return;
00571 }
00572
00573 if (sack->type != CONTAINER)
00574 {
00575 new_draw_info_format(NDI_UNIQUE, op, "The %s is not a container.", query_name(sack, NULL));
00576 return;
00577 }
00578
00579 if (check_magical_container(tmp, sack))
00580 {
00581 new_draw_info(NDI_UNIQUE, op, "You can't put a magical container into another magical container.");
00582 return;
00583 }
00584
00585
00586 if (op->map && op->map->events && trigger_map_event(MEVENT_PUT, op->map, op, tmp, sack, NULL, nrof))
00587 {
00588 return;
00589 }
00590
00591 if (tmp->type == CONTAINER)
00592 {
00593 container_unlink(NULL, tmp);
00594 }
00595
00596 if (nrof > tmp_nrof || nrof == 0)
00597 {
00598 nrof = tmp_nrof;
00599 }
00600
00601 if (!sack_can_hold(op, sack, tmp, nrof))
00602 {
00603 return;
00604 }
00605
00606 if (QUERY_FLAG(tmp, FLAG_APPLIED))
00607 {
00608 if (apply_special(op, tmp, AP_UNAPPLY | AP_NO_MERGE))
00609 {
00610 return;
00611 }
00612 }
00613
00614 if (QUERY_FLAG(tmp, FLAG_UNPAID))
00615 {
00616
00617 if (QUERY_FLAG(tmp, FLAG_NO_PICK))
00618 {
00619 tmp = object_create_clone(tmp);
00620 CLEAR_FLAG(tmp, FLAG_NO_PICK);
00621 SET_FLAG(tmp, FLAG_STARTEQUIP);
00622 tmp->nrof = nrof;
00623 tmp_nrof = nrof;
00624 new_draw_info_format(NDI_UNIQUE, op, "You pick up %s for %s from the storage.", query_name(tmp, NULL), query_cost_string(tmp, op, F_BUY));
00625 }
00626
00627 else
00628 {
00629 tmp->nrof = nrof;
00630 new_draw_info_format(NDI_UNIQUE, op, "%s will cost you %s.", query_name(tmp, NULL), query_cost_string(tmp, op, F_BUY));
00631 tmp->nrof = tmp_nrof;
00632 }
00633 }
00634
00635
00636 if (nrof != tmp_nrof)
00637 {
00638 object *tmp2 = tmp, *tmp2_cont = tmp->env;
00639 char err[MAX_BUF];
00640
00641 tmp2_tag = tmp2->count;
00642 tmp = get_split_ob(tmp, nrof, err, sizeof(err));
00643
00644 if (!tmp)
00645 {
00646 new_draw_info(NDI_UNIQUE, op, err);
00647 return;
00648 }
00649
00650
00651 if (was_destroyed(tmp2, tmp2_tag))
00652 {
00653 esrv_del_item(CONTR(op), tmp2_tag, tmp2_cont);
00654 }
00655
00656 else
00657 {
00658 esrv_send_item(op, tmp2);
00659 }
00660 }
00661 else
00662 {
00663
00664
00665
00666 if (!QUERY_FLAG(tmp, FLAG_REMOVED))
00667 {
00668 esrv_del_item(CONTR(op), tmp->count, tmp->env);
00669
00670 remove_ob(tmp);
00671 }
00672 }
00673
00674 snprintf(buf, sizeof(buf), "You put the %s in %s.", query_name(tmp, NULL), query_name(sack, NULL));
00675 tmp_tag = tmp->count;
00676 tmp_cont = tmp->env;
00677 tmp2 = insert_ob_in_ob(tmp, sack);
00678 new_draw_info(NDI_UNIQUE, op, buf);
00679
00680 fix_player(op);
00681
00682
00683
00684 if (tmp2 != tmp)
00685 {
00686 esrv_del_item(CONTR(op), tmp_tag, tmp_cont);
00687 }
00688
00689 esrv_send_item(op, tmp2);
00690
00691 esrv_update_item(UPD_WEIGHT, op, sack);
00692 esrv_update_item(UPD_WEIGHT, op, op);
00693 }
00694
00701 void drop_object(object *op, object *tmp, long nrof, int no_mevent)
00702 {
00703 object *floor;
00704
00705 if (QUERY_FLAG(tmp, FLAG_NO_DROP) && !QUERY_FLAG(op, FLAG_WIZ))
00706 {
00707 return;
00708 }
00709
00710
00711 if (!no_mevent && op->map && op->map->events && trigger_map_event(MEVENT_DROP, op->map, op, tmp, NULL, NULL, nrof))
00712 {
00713 return;
00714 }
00715
00716
00717 if (op->type == PLAYER)
00718 {
00719 CONTR(op)->praying = 0;
00720 }
00721
00722 if (QUERY_FLAG(tmp, FLAG_APPLIED))
00723 {
00724
00725 if (apply_special(op, tmp, AP_UNAPPLY | AP_NO_MERGE))
00726 {
00727 return;
00728 }
00729 }
00730
00731 if (tmp->type == CONTAINER)
00732 {
00733 container_unlink(NULL, tmp);
00734 }
00735
00736
00737 if (trigger_event(EVENT_DROP, op, tmp, NULL, NULL, nrof, 0, 0, SCRIPT_FIX_ACTIVATOR))
00738 {
00739 return;
00740 }
00741
00742
00743
00744 if (nrof && tmp->nrof != (uint32) nrof)
00745 {
00746 object *tmp2 = tmp, *tmp2_cont = tmp->env;
00747 tag_t tmp2_tag = tmp2->count;
00748 char err[MAX_BUF];
00749 tmp = get_split_ob(tmp, nrof, err, sizeof(err));
00750
00751 if (!tmp)
00752 {
00753 new_draw_info(NDI_UNIQUE, op, err);
00754 return;
00755 }
00756
00757
00758
00759 if (op->type == PLAYER)
00760 {
00761 if (was_destroyed(tmp2, tmp2_tag))
00762 {
00763 esrv_del_item(CONTR(op), tmp2_tag, tmp2_cont);
00764 }
00765 else
00766 {
00767 esrv_send_item(op, tmp2);
00768 }
00769 }
00770 }
00771 else
00772 {
00773 remove_ob(tmp);
00774
00775 if (check_walk_off(tmp, NULL, MOVE_APPLY_DEFAULT) != CHECK_WALK_OK)
00776 {
00777 return;
00778 }
00779 }
00780
00781 if (QUERY_FLAG(tmp, FLAG_STARTEQUIP) || QUERY_FLAG(tmp, FLAG_UNPAID))
00782 {
00783 if (op->type == PLAYER)
00784 {
00785 new_draw_info_format(NDI_UNIQUE, op, "You drop the %s.", query_name(tmp, NULL));
00786 esrv_del_item(CONTR(op), tmp->count, tmp->env);
00787
00788 if (QUERY_FLAG(tmp, FLAG_UNPAID))
00789 {
00790 new_draw_info(NDI_UNIQUE, op, "The shop magic put it back to the storage.");
00791
00792 floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0);
00793
00794
00795 if (floor && floor->type == SHOP_FLOOR && (QUERY_FLAG(floor, FLAG_IS_MAGICAL) || (floor->randomitems && QUERY_FLAG(floor, FLAG_CURSED))))
00796 {
00797 tmp->x = op->x;
00798 tmp->y = op->y;
00799 insert_ob_in_map(tmp, op->map, op, 0);
00800 }
00801 }
00802 else
00803 {
00804 new_draw_info(NDI_UNIQUE, op, "The god-given item vanishes to nowhere as you drop it!");
00805 }
00806 }
00807
00808 fix_player(op);
00809 return;
00810 }
00811
00812
00813
00814 #ifdef SAVE_INTERVAL
00815 if (op->type == PLAYER && !QUERY_FLAG(tmp, FLAG_UNPAID) && (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000) && (CONTR(op)->last_save_time + SAVE_INTERVAL) <= time(NULL))
00816 {
00817 save_player(op, 1);
00818 CONTR(op)->last_save_time = time(NULL);
00819 }
00820 #endif
00821
00822 floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0);
00823
00824 if (floor && floor->type == SHOP_FLOOR && !QUERY_FLAG(tmp, FLAG_UNPAID) && tmp->type != MONEY)
00825 {
00826 sell_item(tmp, op, -1);
00827
00828
00829
00830 if (QUERY_FLAG(tmp, FLAG_UNPAID) && !QUERY_FLAG(floor, FLAG_IS_MAGICAL))
00831 {
00832 if (op->type == PLAYER)
00833 {
00834 new_draw_info(NDI_UNIQUE, op, "The shop magic put it to the storage.");
00835 esrv_del_item(CONTR(op), tmp->count, tmp->env);
00836 }
00837
00838 fix_player(op);
00839
00840 if (op->type == PLAYER)
00841 {
00842 esrv_send_item(op, op);
00843 }
00844
00845 return;
00846 }
00847 }
00848
00849 tmp->x = op->x;
00850 tmp->y = op->y;
00851
00852 if (op->type == PLAYER)
00853 {
00854 esrv_del_item(CONTR(op), tmp->count, tmp->env);
00855 }
00856
00857 insert_ob_in_map(tmp, op->map, op, 0);
00858
00859 SET_FLAG(op, FLAG_NO_APPLY);
00860 remove_ob(op);
00861 insert_ob_in_map(op, op->map, op, INS_NO_MERGE | INS_NO_WALK_ON);
00862 CLEAR_FLAG(op, FLAG_NO_APPLY);
00863
00864
00865 if (op->type == PLAYER)
00866 {
00867 fix_player(op);
00868 esrv_send_item(op, op);
00869 }
00870 }
00871
00877 void drop(object *op, object *tmp, int no_mevent)
00878 {
00879 if (tmp == NULL)
00880 {
00881 new_draw_info(NDI_UNIQUE, op, "You don't have anything to drop.");
00882 return;
00883 }
00884
00885 if (QUERY_FLAG(tmp, FLAG_INV_LOCKED))
00886 {
00887 new_draw_info(NDI_UNIQUE, op, "This item is locked.");
00888 return;
00889 }
00890
00891 if (QUERY_FLAG(tmp, FLAG_NO_DROP))
00892 {
00893 return;
00894 }
00895
00896 if (op->type == PLAYER)
00897 {
00898 if (CONTR(op)->container)
00899 {
00900 put_object_in_sack(op, CONTR(op)->container, tmp, CONTR(op)->count);
00901 }
00902 else
00903 {
00904 drop_object(op, tmp, CONTR(op)->count, no_mevent);
00905 }
00906
00907 CONTR(op)->count = 0;
00908 }
00909 else
00910 {
00911 drop_object(op, tmp, 0, no_mevent);
00912 }
00913 }
00914
00920 int command_take(object *op, char *params)
00921 {
00922 object *tmp, *next;
00923 int did_one = 0, missed = 0, ival;
00924
00925 if (!params)
00926 {
00927 new_draw_info(NDI_UNIQUE, op, "Take what?");
00928 return 0;
00929 }
00930
00931 if (CONTR(op)->container)
00932 {
00933 tmp = CONTR(op)->container->inv;
00934 }
00935 else
00936 {
00937 tmp = GET_MAP_OB_LAST(op->map, op->x, op->y);
00938 }
00939
00940 if (!tmp)
00941 {
00942 new_draw_info(NDI_UNIQUE, op, "Nothing to take.");
00943 return 0;
00944 }
00945
00946 if (op->map && op->map->events && trigger_map_event(MEVENT_CMD_TAKE, op->map, op, tmp, NULL, params, 0))
00947 {
00948 return 0;
00949 }
00950
00951 SET_FLAG(op, FLAG_NO_FIX_PLAYER);
00952
00953 for ( ; tmp; tmp = next)
00954 {
00955 next = tmp->below;
00956
00957 if ((tmp->layer != LAYER_ITEM && tmp->layer != LAYER_ITEM2) || QUERY_FLAG(tmp, FLAG_NO_PICK) || IS_SYS_INVISIBLE(tmp))
00958 {
00959 continue;
00960 }
00961
00962 ival = item_matched_string(op, tmp, params);
00963
00964 if (ival > 0)
00965 {
00966 if (ival <= 2 && !can_pick(op, tmp))
00967 {
00968 missed++;
00969 }
00970 else
00971 {
00972 pick_up(op, tmp, 1);
00973 did_one = 1;
00974 }
00975 }
00976 }
00977
00978 CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
00979
00980 if (did_one)
00981 {
00982 fix_player(op);
00983 }
00984 else if (!missed)
00985 {
00986 new_draw_info(NDI_UNIQUE, op, "Nothing to take.");
00987 }
00988
00989 if (missed == 1)
00990 {
00991 new_draw_info(NDI_UNIQUE, op, "You were unable to take one of the items.");
00992 }
00993 else if (missed > 1)
00994 {
00995 new_draw_info_format(NDI_UNIQUE, op, "You were unable to take %d of the items.", missed);
00996 }
00997
00998 if (op->type == PLAYER)
00999 {
01000 CONTR(op)->count = 0;
01001 }
01002
01003 return 0;
01004 }
01005
01011 int command_drop(object *op, char *params)
01012 {
01013 object *tmp, *next;
01014 int did_one = 0, missed = 0, ival;
01015
01016 if (!params)
01017 {
01018 new_draw_info(NDI_UNIQUE, op, "Drop what?");
01019 return 0;
01020 }
01021
01022 if (op->map && op->map->events && trigger_map_event(MEVENT_CMD_DROP, op->map, op, NULL, NULL, params, 0))
01023 {
01024 return 0;
01025 }
01026
01027 SET_FLAG(op, FLAG_NO_FIX_PLAYER);
01028
01029 for (tmp = op->inv; tmp; tmp = next)
01030 {
01031 next = tmp->below;
01032
01033 if (QUERY_FLAG(tmp, FLAG_NO_DROP) || QUERY_FLAG(tmp, FLAG_STARTEQUIP) || IS_SYS_INVISIBLE(tmp))
01034 {
01035 continue;
01036 }
01037
01038 ival = item_matched_string(op, tmp, params);
01039
01040 if (ival > 0)
01041 {
01042 if (ival <= 2 && QUERY_FLAG(tmp, FLAG_INV_LOCKED))
01043 {
01044 missed++;
01045 }
01046 else
01047 {
01048 drop(op, tmp, 1);
01049 did_one = 1;
01050 }
01051 }
01052 }
01053
01054 CLEAR_FLAG(op, FLAG_NO_FIX_PLAYER);
01055
01056 if (did_one)
01057 {
01058 fix_player(op);
01059 }
01060 else if (!missed)
01061 {
01062 new_draw_info(NDI_UNIQUE, op, "Nothing to drop.");
01063 }
01064
01065 if (missed == 1)
01066 {
01067 new_draw_info(NDI_UNIQUE, op, "One item couldn't be dropped because it was locked.");
01068 }
01069 else if (missed > 1)
01070 {
01071 new_draw_info_format(NDI_UNIQUE, op, "%d items couldn't be dropped because they were locked.", missed);
01072 }
01073
01074 if (op->type == PLAYER)
01075 {
01076 CONTR(op)->count = 0;
01077 }
01078
01079 return 0;
01080 }
01081
01089 static object *find_marked_object_rec(object *op, object **marked, uint32 *marked_count)
01090 {
01091 object *tmp, *tmp2;
01092 int wiz = QUERY_FLAG(op, FLAG_WIZ);
01093
01094
01095
01096
01097 for (tmp = op->inv; tmp; tmp = tmp->below)
01098 {
01099 if (IS_SYS_INVISIBLE(tmp) && !wiz)
01100 {
01101 continue;
01102 }
01103
01104 if (tmp == *marked)
01105 {
01106 if (tmp->count == *marked_count)
01107 {
01108 return tmp;
01109 }
01110 else
01111 {
01112 *marked = NULL;
01113 *marked_count = 0;
01114 return NULL;
01115 }
01116 }
01117 else if (tmp->inv)
01118 {
01119 tmp2 = find_marked_object_rec(tmp, marked, marked_count);
01120
01121 if (tmp2)
01122 {
01123 return tmp2;
01124 }
01125
01126 if (*marked == NULL)
01127 {
01128 return NULL;
01129 }
01130 }
01131 }
01132
01133 return NULL;
01134 }
01135
01140 object *find_marked_object(object *op)
01141 {
01142 if (op->type != PLAYER || !op || !CONTR(op) || !CONTR(op)->mark)
01143 {
01144 return NULL;
01145 }
01146
01147 return find_marked_object_rec(op, &CONTR(op)->mark, &CONTR(op)->mark_count);
01148 }
01149
01154 void examine_living(object *op, object *tmp)
01155 {
01156 object *mon = tmp->head ? tmp->head : tmp;
01157 int val, val2, i, gender;
01158
01159 CONTR(op)->praying = 0;
01160 gender = object_get_gender(mon);
01161
01162 if (QUERY_FLAG(mon, FLAG_IS_GOOD))
01163 {
01164 new_draw_info_format(NDI_UNIQUE, op, "%s is a good aligned %s %s.", gender_subjective_upper[gender], gender_noun[gender], mon->race);
01165 }
01166 else if (QUERY_FLAG(mon, FLAG_IS_EVIL))
01167 {
01168 new_draw_info_format(NDI_UNIQUE, op, "%s is an evil aligned %s %s.", gender_subjective_upper[gender], gender_noun[gender], mon->race);
01169 }
01170 else if (QUERY_FLAG(mon, FLAG_IS_NEUTRAL))
01171 {
01172 new_draw_info_format(NDI_UNIQUE, op, "%s is a neutral aligned %s %s.", gender_subjective_upper[gender], gender_noun[gender], mon->race);
01173 }
01174 else
01175 {
01176 new_draw_info_format(NDI_UNIQUE, op, "%s is a %s %s.", gender_subjective_upper[gender], gender_noun[gender], mon->race);
01177 }
01178
01179 new_draw_info_format(NDI_UNIQUE, op, "%s is level %d.", gender_subjective_upper[gender], mon->level);
01180 new_draw_info_format(NDI_UNIQUE, op, "%s has a base damage of %d and hp of %d.", gender_subjective_upper[gender], mon->stats.dam, mon->stats.maxhp);
01181 new_draw_info_format(NDI_UNIQUE, op, "%s has a wc of %d and ac of %d.", gender_subjective_upper[gender], mon->stats.wc, mon->stats.ac);
01182
01183 for (val = val2 = -1, i = 0; i < NROFATTACKS; i++)
01184 {
01185 if (mon->protection[i] > 0)
01186 {
01187 val = i;
01188 }
01189 else if (mon->protection[i] < 0)
01190 {
01191 val = i;
01192 }
01193 }
01194
01195 if (val != -1)
01196 {
01197 new_draw_info_format(NDI_UNIQUE, op, "%s can naturally resist some attacks.", gender_subjective_upper[gender]);
01198 }
01199
01200 if (val2 != -1)
01201 {
01202 new_draw_info_format(NDI_UNIQUE, op, "%s is naturally vulnerable to some attacks.", gender_subjective_upper[gender]);
01203 }
01204
01205 for (val =- 1, val2 = i = 0; i < NROFATTACKS; i++)
01206 {
01207 if (mon->protection[i] > val2)
01208 {
01209 val = i;
01210 val2 = mon->protection[i];
01211 }
01212 }
01213
01214 if (val != -1)
01215 {
01216 new_draw_info_format(NDI_UNIQUE, op, "Best armour protection seems to be for %s.", attack_name[val]);
01217 }
01218
01219 if (QUERY_FLAG(mon, FLAG_UNDEAD))
01220 {
01221 new_draw_info_format(NDI_UNIQUE, op, "%s is an undead force.", gender_subjective_upper[gender]);
01222 }
01223
01224 switch ((mon->stats.hp + 1) * 4 / (mon->stats.maxhp + 1))
01225 {
01226 case 1:
01227 new_draw_info_format(NDI_UNIQUE, op, "%s is in a bad shape.", gender_subjective_upper[gender]);
01228 break;
01229
01230 case 2:
01231 new_draw_info_format(NDI_UNIQUE, op, "%s is hurt.", gender_subjective_upper[gender]);
01232 break;
01233
01234 case 3:
01235 new_draw_info_format(NDI_UNIQUE, op, "%s is somewhat hurt.", gender_subjective_upper[gender]);
01236 break;
01237
01238 default:
01239 new_draw_info_format(NDI_UNIQUE, op, "%s is in excellent shape.", gender_subjective_upper[gender]);
01240 break;
01241 }
01242
01243 if (present_in_ob(POISONING, mon) != NULL)
01244 {
01245 new_draw_info_format(NDI_UNIQUE, op, "%s looks very ill.", gender_subjective_upper[gender]);
01246 }
01247 }
01248
01254 char *long_desc(object *tmp, object *caller)
01255 {
01256 static char buf[VERY_BIG_BUF];
01257 char *cp;
01258
01259 if (tmp == NULL)
01260 {
01261 return "";
01262 }
01263
01264 buf[0] = '\0';
01265
01266 switch (tmp->type)
01267 {
01268 case RING:
01269 case SKILL:
01270 case WEAPON:
01271 case ARMOUR:
01272 case BRACERS:
01273 case HELMET:
01274 case SHIELD:
01275 case BOOTS:
01276 case GLOVES:
01277 case AMULET:
01278 case GIRDLE:
01279 case POTION:
01280 case BOW:
01281 case ARROW:
01282 case CLOAK:
01283 case FOOD:
01284 case DRINK:
01285 case HORN:
01286 case WAND:
01287 case ROD:
01288 case FLESH:
01289 case BOOK:
01290 case CONTAINER:
01291 if (*(cp = describe_item(tmp)) != '\0')
01292 {
01293 size_t len;
01294
01295 strncat(buf, query_name(tmp, caller), VERY_BIG_BUF - 1);
01296
01297 buf[VERY_BIG_BUF - 1] = '\0';
01298 len = strlen(buf);
01299
01300 if (len < VERY_BIG_BUF - 5 && ((tmp->type != AMULET && tmp->type != RING) || tmp->title))
01301 {
01302
01303
01304 strcpy(buf + len, " ");
01305 len++;
01306 strncpy(buf + len, cp, VERY_BIG_BUF - len - 1);
01307 buf[VERY_BIG_BUF - 1] = '\0';
01308 }
01309 }
01310
01311 break;
01312 }
01313
01314 if (buf[0] == '\0')
01315 {
01316 strncat(buf, query_name(tmp, caller), VERY_BIG_BUF - 1);
01317 buf[VERY_BIG_BUF - 1] = '\0';
01318 }
01319
01320 return buf;
01321 }
01322
01327 void examine(object *op, object *tmp)
01328 {
01329 char buf[VERY_BIG_BUF], tmp_buf[64];
01330 int i;
01331
01332 if (tmp == NULL || tmp->type == CLOSE_CON)
01333 {
01334 return;
01335 }
01336
01337 strcpy(buf, "That is ");
01338 strncat(buf, long_desc(tmp, op), VERY_BIG_BUF - strlen(buf) - 1);
01339 buf[VERY_BIG_BUF - 1] = '\0';
01340
01341
01342
01343 if (!QUERY_FLAG(tmp, FLAG_IDENTIFIED) && need_identify(tmp))
01344 {
01345 strncat(buf, " (unidentified)", VERY_BIG_BUF - strlen(buf) - 1);
01346 }
01347
01348 buf[VERY_BIG_BUF - 1] = '\0';
01349 new_draw_info(NDI_UNIQUE, op, buf);
01350 buf[0] = '\0';
01351
01352 if (tmp->custom_name)
01353 {
01354 new_draw_info_format(NDI_UNIQUE, op, "You name it %s.", tmp->custom_name);
01355 }
01356
01357 if (QUERY_FLAG(tmp, FLAG_MONSTER) || tmp->type == PLAYER)
01358 {
01359 new_draw_info_format(NDI_UNIQUE, op, "%s.", describe_item(tmp->head ? tmp->head : tmp));
01360 examine_living(op, tmp);
01361 }
01362
01363 else if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01364 {
01365 if (QUERY_FLAG(tmp, FLAG_IS_GOOD))
01366 {
01367 new_draw_info_format(NDI_UNIQUE, op, "It is good aligned.");
01368 }
01369 else if (QUERY_FLAG(tmp, FLAG_IS_EVIL))
01370 {
01371 new_draw_info_format(NDI_UNIQUE, op, "It is evil aligned.");
01372 }
01373 else if (QUERY_FLAG(tmp, FLAG_IS_NEUTRAL))
01374 {
01375 new_draw_info_format(NDI_UNIQUE, op, "It is neutral aligned.");
01376 }
01377
01378 if (tmp->item_level)
01379 {
01380 if (tmp->item_skill)
01381 {
01382 new_draw_info_format(NDI_UNIQUE, op, "It needs a level of %d in %s to use.", tmp->item_level, find_skill_exp_skillname(tmp->item_skill));
01383 }
01384 else
01385 {
01386 new_draw_info_format(NDI_UNIQUE, op, "It needs a level of %d to use.", tmp->item_level);
01387 }
01388 }
01389
01390 if (tmp->item_quality)
01391 {
01392 if (QUERY_FLAG(tmp, FLAG_INDESTRUCTIBLE))
01393 {
01394 new_draw_info_format(NDI_UNIQUE, op, "Qua: %d Con: Indestructible.", tmp->item_quality);
01395 }
01396 else
01397 {
01398 new_draw_info_format(NDI_UNIQUE, op, "Qua: %d Con: %d.", tmp->item_quality, tmp->item_condition);
01399 }
01400 }
01401
01402 buf[0] = '\0';
01403 }
01404
01405 switch (tmp->type)
01406 {
01407 case SPELLBOOK:
01408 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED) && tmp->stats.sp >= 0 && tmp->stats.sp <= NROFREALSPELLS)
01409 {
01410 if (tmp->sub_type == ST1_SPELLBOOK_CLERIC)
01411 {
01412 snprintf(buf, sizeof(buf), "%s is a %d level prayer.", spells[tmp->stats.sp].name, spells[tmp->stats.sp].level);
01413 }
01414 else
01415 {
01416 snprintf(buf, sizeof(buf), "%s is a %d level spell.", spells[tmp->stats.sp].name, spells[tmp->stats.sp].level);
01417 }
01418 }
01419
01420 break;
01421
01422 case BOOK:
01423 if (tmp->msg != NULL)
01424 {
01425 strcpy(buf, "Something is written in it.");
01426 }
01427
01428 break;
01429
01430 case CONTAINER:
01431 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01432 {
01433 if (tmp->race != NULL)
01434 {
01435 if (tmp->weight_limit)
01436 {
01437 snprintf(buf, sizeof(buf), "It can hold only %s and its weight limit is %.1f kg.", tmp->race, (float) tmp->weight_limit / 1000.0f);
01438 }
01439 else
01440 {
01441 snprintf(buf, sizeof(buf), "It can hold only %s.", tmp->race);
01442 }
01443
01444
01445 if (tmp->weapon_speed != 1.0f)
01446 {
01447 new_draw_info(NDI_UNIQUE, op, buf);
01448
01449
01450 if (tmp->weapon_speed > 1.0f)
01451 {
01452 snprintf(buf, sizeof(buf), "It increases the weight of items inside by %.1f%%.", tmp->weapon_speed * 100.0f);
01453 }
01454
01455 else
01456 {
01457 snprintf(buf, sizeof(buf), "It decreases the weight of items inside by %.1f%%.", 100.0f - (tmp->weapon_speed * 100.0f));
01458 }
01459 }
01460 }
01461 else
01462 {
01463 if (tmp->weight_limit)
01464 {
01465 snprintf(buf, sizeof(buf), "Its weight limit is %.1f kg.", (float)tmp->weight_limit / 1000.0f);
01466 }
01467
01468
01469 if (tmp->weapon_speed != 1.0f)
01470 {
01471 new_draw_info(NDI_UNIQUE, op, buf);
01472
01473
01474 if (tmp->weapon_speed > 1.0f)
01475 {
01476 snprintf(buf, sizeof(buf), "It increases the weight of items inside by %.1f%%.", tmp->weapon_speed * 100.0f);
01477 }
01478
01479 else
01480 {
01481 snprintf(buf, sizeof(buf), "It decreases the weight of items inside by %.1f%%.", 100.0f - (tmp->weapon_speed * 100.0f));
01482 }
01483 }
01484 }
01485
01486 new_draw_info(NDI_UNIQUE, op, buf);
01487
01488 if (tmp->weapon_speed == 1.0f)
01489 {
01490 snprintf(buf, sizeof(buf), "It contains %3.3f kg.", (float) tmp->carrying / 1000.0f);
01491 }
01492 else if (tmp->weapon_speed > 1.0f)
01493 {
01494 snprintf(buf, sizeof(buf), "It contains %3.3f kg, increased to %3.3f kg.", (float) tmp->damage_round_tag / 1000.0f, (float) tmp->carrying / 1000.0f);
01495 }
01496 else
01497 {
01498 snprintf(buf, sizeof(buf), "It contains %3.3f kg, decreased to %3.3f kg.", (float) tmp->damage_round_tag / 1000.0f, (float) tmp->carrying / 1000.0f);
01499 }
01500 }
01501
01502 break;
01503
01504 case WAND:
01505 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01506 {
01507 snprintf(buf, sizeof(buf), "It has %d charges left.", tmp->stats.food);
01508 }
01509
01510 break;
01511
01512 case POWER_CRYSTAL:
01513
01514 if (tmp->stats.maxsp == 0)
01515 {
01516 snprintf(buf, sizeof(buf), "It has capacity of %d.", tmp->stats.maxsp);
01517 }
01518 else
01519 {
01520 int i;
01521
01522
01523 if (tmp->stats.maxsp > 1000)
01524 {
01525 i = (tmp->stats.maxsp % 1000) / 100;
01526
01527 if (i)
01528 {
01529 snprintf(tmp_buf, sizeof(tmp_buf), "It has capacity of %d.%dk and is ", tmp->stats.maxsp / 1000, i);
01530 }
01531 else
01532 {
01533 snprintf(tmp_buf, sizeof(tmp_buf), "It has capacity of %dk and is ", tmp->stats.maxsp / 1000);
01534 }
01535 }
01536 else
01537 {
01538 snprintf(tmp_buf, sizeof(tmp_buf), "It has capacity of %d and is ", tmp->stats.maxsp);
01539 }
01540
01541 strcat(buf, tmp_buf);
01542 i = (tmp->stats.sp * 10) / tmp->stats.maxsp;
01543
01544 if (tmp->stats.sp == 0)
01545 {
01546 strcat(buf, "empty.");
01547 }
01548 else if (i == 0)
01549 {
01550 strcat(buf, "almost empty.");
01551 }
01552 else if (i < 3)
01553 {
01554 strcat(buf, "partially filled.");
01555 }
01556 else if (i < 6)
01557 {
01558 strcat(buf, "half full.");
01559 }
01560 else if (i < 9)
01561 {
01562 strcat(buf, "well charged.");
01563 }
01564 else if (tmp->stats.sp == tmp->stats.maxsp)
01565 {
01566 strcat(buf, "fully charged.");
01567 }
01568 else
01569 {
01570 strcat(buf, "almost full.");
01571 }
01572 }
01573
01574 break;
01575 }
01576
01577 if (buf[0] != '\0')
01578 {
01579 new_draw_info(NDI_UNIQUE, op, buf);
01580 }
01581
01582 if (tmp->material && (need_identify(tmp) && QUERY_FLAG(tmp, FLAG_IDENTIFIED)))
01583 {
01584 strcpy(buf, "It is made of: ");
01585
01586 for (i = 0; i < NROFMATERIALS; i++)
01587 {
01588 if (tmp->material & (1 << i))
01589 {
01590 strcat(buf, material[i].name);
01591 strcat(buf, " ");
01592 }
01593 }
01594
01595 new_draw_info(NDI_UNIQUE, op, buf);
01596 }
01597
01598 if (tmp->weight)
01599 {
01600 float weight = (float) (tmp->nrof ? tmp->weight * (int) tmp->nrof : tmp->weight) / 1000.0f;
01601
01602 if (tmp->type == MONSTER)
01603 {
01604 new_draw_info_format(NDI_UNIQUE, op, "%s weighs %3.3f kg.", gender_subjective_upper[object_get_gender(tmp)], weight);
01605 }
01606 else if (tmp->type == PLAYER)
01607 {
01608 new_draw_info_format(NDI_UNIQUE, op, "%s weighs %3.3f kg and is carrying %3.3f kg.", gender_subjective_upper[object_get_gender(tmp)], weight, (float) tmp->carrying / 1000.0f);
01609 }
01610 else
01611 {
01612 new_draw_info_format(NDI_UNIQUE, op, tmp->nrof > 1 ? "They weigh %3.3f kg." : "It weighs %3.3f kg.", weight);
01613 }
01614 }
01615
01616 if (QUERY_FLAG(tmp, FLAG_STARTEQUIP))
01617 {
01618
01619 if (QUERY_FLAG(tmp, FLAG_UNPAID))
01620 {
01621 new_draw_info_format(NDI_UNIQUE, op, "%s would cost you %s.", tmp->nrof > 1 ? "They" : "It", query_cost_string(tmp, op, F_BUY));
01622 }
01623
01624 else
01625 {
01626 new_draw_info_format(NDI_UNIQUE, op, "%s god-given item%s.", tmp->nrof > 1 ? "They are" : "It is a", tmp->nrof > 1 ? "s" : "");
01627
01628 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01629 {
01630 if (tmp->value)
01631 {
01632 new_draw_info_format(NDI_UNIQUE, op, "But %s worth %s.", tmp->nrof > 1 ? "they are" : "it is", query_cost_string(tmp, op, F_TRUE));
01633 }
01634 else
01635 {
01636 new_draw_info_format(NDI_UNIQUE, op, "%s worthless.", tmp->nrof > 1 ? "They are" : "It is");
01637 }
01638 }
01639 }
01640 }
01641 else if (tmp->value && !IS_LIVE(tmp))
01642 {
01643 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01644 {
01645 if (QUERY_FLAG(tmp, FLAG_UNPAID))
01646 {
01647 new_draw_info_format(NDI_UNIQUE, op, "%s would cost you %s.", tmp->nrof > 1 ? "They" : "It", query_cost_string(tmp, op, F_BUY));
01648 }
01649 else
01650 {
01651 new_draw_info_format(NDI_UNIQUE, op, "%s worth %s.", tmp->nrof > 1 ? "They are" : "It is", query_cost_string(tmp, op, F_TRUE));
01652 goto dirty_little_jump1;
01653 }
01654 }
01655 else
01656 {
01657 object *floor;
01658 dirty_little_jump1:
01659
01660 floor = GET_MAP_OB_LAYER(op->map, op->x, op->y, 0);
01661
01662 if (floor && floor->type == SHOP_FLOOR && tmp->type != MONEY)
01663 {
01664
01665 int charisma = op->stats.Cha;
01666
01667
01668 if (find_skill(op, SK_BARGAINING))
01669 {
01670 charisma += 4;
01671
01672 if (charisma > MAX_STAT)
01673 {
01674 charisma = MAX_STAT;
01675 }
01676 }
01677
01678 new_draw_info_format(NDI_UNIQUE, op, "This shop will pay you %s (%0.1f%%).", query_cost_string(tmp, op, F_SELL), 20.0f + 100.0f * cha_bonus[charisma]);
01679 }
01680 }
01681 }
01682 else if (!IS_LIVE(tmp))
01683 {
01684 if (QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01685 {
01686 if (QUERY_FLAG(tmp, FLAG_UNPAID))
01687 {
01688 new_draw_info_format(NDI_UNIQUE, op, "%s would cost nothing.", tmp->nrof > 1 ? "They" : "It");
01689 }
01690 else
01691 {
01692 new_draw_info_format(NDI_UNIQUE, op, "%s worthless.", tmp->nrof > 1 ? "They are" : "It is");
01693 }
01694 }
01695 }
01696
01697
01698
01699 if (tmp->msg && tmp->type != EXIT && tmp->type != BOOK && tmp->type != CORPSE && !QUERY_FLAG(tmp, FLAG_WALK_ON) && strncasecmp(tmp->msg, "@match", 7))
01700 {
01701
01702
01703 if (need_identify(tmp) && QUERY_FLAG(tmp, FLAG_IDENTIFIED))
01704 {
01705 new_draw_info(NDI_UNIQUE, op, "The object has a story:");
01706 new_draw_info(NDI_UNIQUE, op, tmp->msg);
01707 }
01708 }
01709
01710
01711 new_draw_info(NDI_UNIQUE, op, " ");
01712
01713 if (QUERY_FLAG(op, FLAG_WIZ))
01714 {
01715 StringBuffer *sb = stringbuffer_new();
01716 char *diff;
01717
01718 stringbuffer_append_printf(sb, "count %d\n", tmp->count);
01719 dump_object(tmp, sb);
01720 diff = stringbuffer_finish(sb);
01721 new_draw_info(NDI_UNIQUE, op, diff);
01722 free(diff);
01723 }
01724 }
01725
01731 int command_rename_item(object *op, char *params)
01732 {
01733 object *tmp = find_marked_object(op), *merged, *cont;
01734 tag_t del_tag;
01735
01736 if (!tmp)
01737 {
01738 new_draw_info(NDI_UNIQUE, op, "No marked item to rename.");
01739 return 1;
01740 }
01741
01742
01743 params = cleanup_chat_string(params);
01744
01745
01746 if (!params)
01747 {
01748 if (!tmp->custom_name)
01749 {
01750 new_draw_info(NDI_UNIQUE, op, "This item has no custom name.");
01751 return 1;
01752 }
01753
01754 FREE_AND_CLEAR_HASH(tmp->custom_name);
01755 new_draw_info_format(NDI_UNIQUE, op, "You stop calling your %s with weird names.", query_base_name(tmp, NULL));
01756 }
01757 else
01758 {
01759 if (tmp->type == MONEY)
01760 {
01761 new_draw_info(NDI_UNIQUE, op, "You cannot rename that item.");
01762 return 1;
01763 }
01764
01765 if (strlen(params) > 127)
01766 {
01767 new_draw_info(NDI_UNIQUE, op, "New name is too long, maximum is 127 characters.");
01768 return 1;
01769 }
01770
01771 if (tmp->custom_name && !strcmp(tmp->custom_name, params))
01772 {
01773 new_draw_info_format(NDI_UNIQUE, op, "You keep calling your %s %s.", query_base_name(tmp, NULL), tmp->custom_name);
01774 return 1;
01775 }
01776
01777
01778 FREE_AND_COPY_HASH(tmp->custom_name, params);
01779 new_draw_info_format(NDI_UNIQUE, op, "Your %s will now be called %s.", query_base_name(tmp, NULL), tmp->custom_name);
01780 }
01781
01782 del_tag = tmp->count;
01783 cont = tmp->env;
01784 merged = merge_ob(tmp, NULL);
01785
01786
01787 if (merged)
01788 {
01789 esrv_del_item(CONTR(op), del_tag, cont);
01790 tmp = merged;
01791 }
01792
01793 esrv_send_item(op, tmp);
01794 return 1;
01795 }