ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/c_object.C
(Generate patch)

Comparing deliantra/server/server/c_object.C (file contents):
Revision 1.25 by root, Tue Dec 12 21:39:57 2006 UTC vs.
Revision 1.52 by root, Sat May 12 20:21:54 2007 UTC

1/* 1/*
2 CrossFire, A Multiplayer game for X-windows 2 * CrossFire, A Multiplayer game
3 3 *
4 * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team
4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 5 * Copyright (C) 2002 Mark Wedel & Crossfire Development Team
5 Copyright (C) 1992 Frank Tore Johansen 6 * Copyright (C) 1992 Frank Tore Johansen
6 7 *
7 This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version. 11 * (at your option) any later version.
11 12 *
12 This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 16 * GNU General Public License for more details.
16 17 *
17 You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21 *
21 The author can be reached via e-mail to <crossfire@schmorp.de> 22 * The author can be reached via e-mail to <crossfire@schmorp.de>
23 *
24 */
22 25
26/*
23 Object (handling) commands 27 * Object (handling) commands
24*/ 28 */
25 29
26#include <global.h> 30#include <global.h>
27#include <loader.h> 31#include <loader.h>
28#include <skills.h> 32#include <skills.h>
29#ifndef __CEXTRACT__
30# include <sproto.h> 33#include <sproto.h>
31#endif
32#include <living.h> 34#include <living.h>
33#include <math.h> 35#include <math.h>
34 36
35/* 37/*
36 * Object id parsing functions 38 * Object id parsing functions
56 * only unapply applied, or apply unapplied objects 58 * only unapply applied, or apply unapplied objects
57 **/ 59 **/
58static object * 60static object *
59find_best_apply_object_match (object *pl, const char *params, enum apply_flag aflag) 61find_best_apply_object_match (object *pl, const char *params, enum apply_flag aflag)
60{ 62{
61 object *tmp, *best = NULL; 63 object *best = 0;
62 int match_val = 0, tmpmatch; 64 int match_val = 0;
63 65
64 for (tmp = pl->inv; tmp; tmp = tmp->below) 66 for (object *tmp = pl->inv; tmp; tmp = tmp->below)
65 { 67 {
66 if (tmp->invisible) 68 if (tmp->invisible)
67 continue; 69 continue;
70
68 if ((tmpmatch = item_matched_string (pl, tmp, params)) > match_val) 71 int tmpmatch = item_matched_string (pl, tmp, params);
72
73 if (tmpmatch > match_val)
69 { 74 {
70 if ((aflag == AP_APPLY) && (QUERY_FLAG (tmp, FLAG_APPLIED))) 75 if ((aflag == AP_APPLY) && (QUERY_FLAG (tmp, FLAG_APPLIED)))
71 continue; 76 continue;
77
72 if ((aflag == AP_UNAPPLY) && (!QUERY_FLAG (tmp, FLAG_APPLIED))) 78 if ((aflag == AP_UNAPPLY) && (!QUERY_FLAG (tmp, FLAG_APPLIED)))
73 continue; 79 continue;
80
74 match_val = tmpmatch; 81 match_val = tmpmatch;
75 best = tmp; 82 best = tmp;
76 } 83 }
77 } 84 }
85
78 return best; 86 return best;
79} 87}
80 88
81/** 89/**
82 * Shortcut to find_best_apply_object_match(pl, params, AF_NULL); 90 * Shortcut to find_best_apply_object_match(pl, params, AF_NULL);
93 if (!params) 101 if (!params)
94 { 102 {
95 new_draw_info (NDI_UNIQUE, 0, pl, "Usage: use_skill <skill name>"); 103 new_draw_info (NDI_UNIQUE, 0, pl, "Usage: use_skill <skill name>");
96 return 0; 104 return 0;
97 } 105 }
106
98 return use_skill (pl, params); 107 return use_skill (pl, params);
99} 108}
100 109
101int 110int
102command_rskill (object *pl, char *params) 111command_rskill (object *pl, char *params)
106 if (!params) 115 if (!params)
107 { 116 {
108 new_draw_info (NDI_UNIQUE, 0, pl, "Usage: ready_skill <skill name>"); 117 new_draw_info (NDI_UNIQUE, 0, pl, "Usage: ready_skill <skill name>");
109 return 0; 118 return 0;
110 } 119 }
120
111 skill = find_skill_by_name (pl, params); 121 skill = find_skill_by_name (pl, params);
112 122
113 if (!skill) 123 if (!skill)
114 { 124 {
115 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no knowledge of the skill %s", params); 125 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no knowledge of the skill %s", params);
116 return 0; 126 return 0;
117 } 127 }
128
118 return change_skill (pl, skill, 0); 129 return change_skill (pl, skill, 0);
119} 130}
120
121 131
122/* These functions (command_search, command_disarm) are really just wrappers for 132/* These functions (command_search, command_disarm) are really just wrappers for
123 * things like 'use_skill ...'). In fact, they should really be obsoleted 133 * things like 'use_skill ...'). In fact, they should really be obsoleted
124 * and replaced with those. 134 * and replaced with those.
125 */ 135 */
133command_disarm (object *op, char *params) 143command_disarm (object *op, char *params)
134{ 144{
135 return use_skill (op, skill_names[SK_DISARM_TRAPS]); 145 return use_skill (op, skill_names[SK_DISARM_TRAPS]);
136} 146}
137 147
138
139/* A little special because we do want to pass the full params along 148/* A little special because we do want to pass the full params along
140 * as it includes the object to throw. 149 * as it includes the object to throw.
141 */ 150 */
142int 151int
143command_throw (object *op, char *params) 152command_throw (object *op, char *params)
144{ 153{
145 object *skop;
146
147 skop = find_skill_by_name (op, skill_names[SK_THROWING]); 154 if (object *skop = find_skill_by_name (op, skill_names[SK_THROWING]))
148 if (skop)
149 return do_skill (op, op, skop, op->facing, params); 155 return do_skill (op, op, skop, op->facing, params);
150 else 156 else
151 {
152 new_draw_info (NDI_UNIQUE, 0, op, "You have no knowledge of the skill throwing."); 157 new_draw_info (NDI_UNIQUE, 0, op, "You have no knowledge of the skill throwing.");
153 } 158
154 return 0; 159 return 0;
155} 160}
156
157 161
158int 162int
159command_apply (object *op, char *params) 163command_apply (object *op, char *params)
160{ 164{
161 if (!params) 165 if (!params)
163 player_apply_below (op); 167 player_apply_below (op);
164 return 0; 168 return 0;
165 } 169 }
166 else 170 else
167 { 171 {
168 apply_flag aflag = (apply_flag) 0; 172 apply_flag aflag = (apply_flag)0;
169 object *inv;
170 173
171 while (*params == ' ') 174 while (*params == ' ')
172 params++; 175 params++;
176
173 if (!strncmp (params, "-a ", 3)) 177 if (!strncmp (params, "-a ", 3))
174 { 178 {
175 aflag = AP_APPLY; 179 aflag = AP_APPLY;
176 params += 3; 180 params += 3;
177 } 181 }
182
178 if (!strncmp (params, "-u ", 3)) 183 if (!strncmp (params, "-u ", 3))
179 { 184 {
180 aflag = AP_UNAPPLY; 185 aflag = AP_UNAPPLY;
181 params += 3; 186 params += 3;
182 } 187 }
188
183 while (*params == ' ') 189 while (*params == ' ')
184 params++; 190 params++;
185 191
186 inv = find_best_apply_object_match (op, params, aflag); 192 if (object *inv = find_best_apply_object_match (op, params, aflag))
187 if (inv)
188 {
189 player_apply (op, inv, aflag, 0); 193 player_apply (op, inv, aflag, 0);
190 }
191 else 194 else
192 new_draw_info_format (NDI_UNIQUE, 0, op, "Could not find any match to the %s.", params); 195 new_draw_info_format (NDI_UNIQUE, 0, op, "Could not find any match to the %s.", params);
193 } 196 }
197
194 return 0; 198 return 0;
195} 199}
196 200
197/* 201/*
198 * Check if an item op can be put into a sack. If pl exists then tell 202 * Check if an item op can be put into a sack. If pl exists then tell
259 /* IF the player is flying & trying to take the item out of a container 263 /* IF the player is flying & trying to take the item out of a container
260 * that is in his inventory, let him. tmp->env points to the container 264 * that is in his inventory, let him. tmp->env points to the container
261 * (sack, luggage, etc), tmp->env->env then points to the player (nested 265 * (sack, luggage, etc), tmp->env->env then points to the player (nested
262 * containers not allowed as of now) 266 * containers not allowed as of now)
263 */ 267 */
264 if ((pl->move_type & MOVE_FLYING) && !QUERY_FLAG (pl, FLAG_WIZ) && is_player_inv (tmp) != pl) 268 if ((pl->move_type & MOVE_FLYING) && !QUERY_FLAG (pl, FLAG_WIZ) && tmp->in_player () != pl)
265 { 269 {
266 new_draw_info (NDI_UNIQUE, 0, pl, "You are levitating, you can't reach the ground!"); 270 new_draw_info (NDI_UNIQUE, 0, pl, "You are levitating, you can't reach the ground!");
267 return; 271 return;
268 } 272 }
269 273
273 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ)) 277 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
274 { 278 {
275 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff of smoke!"); 279 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff of smoke!");
276 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion."); 280 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
277 281
278 if (pl->type == PLAYER) 282 if (pl->contr)
279 esrv_del_item (pl->contr, tmp->count); 283 esrv_del_item (pl->contr, tmp->count);
280 284
281 tmp->destroy (); 285 tmp->destroy ();
282 return; 286 return;
283 } 287 }
299 { 303 {
300 new_draw_info (0, 0, pl, "That item is too heavy for you to pick up."); 304 new_draw_info (0, 0, pl, "That item is too heavy for you to pick up.");
301 return; 305 return;
302 } 306 }
303 307
304 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ))
305 SET_FLAG (tmp, FLAG_WAS_WIZ);
306
307 if (nrof != tmp_nrof) 308 if (nrof != tmp_nrof)
308 { 309 {
309 object *tmp2 = tmp; 310 object *tmp2 = tmp;
310 311
311 tmp = get_split_ob (tmp, nrof); 312 tmp = get_split_ob (tmp, nrof);
313 { 314 {
314 new_draw_info (NDI_UNIQUE, 0, pl, errmsg); 315 new_draw_info (NDI_UNIQUE, 0, pl, errmsg);
315 return; 316 return;
316 } 317 }
317 318
318 /* Tell a client what happened rest of objects */ 319 /* Tell the client what happened to the rest of objects */
319 if (pl->type == PLAYER) 320 if (pl->contr)
320 {
321 if (tmp2->destroyed ()) 321 if (tmp2->destroyed ())
322 esrv_del_item (pl->contr, tmp2->count); 322 esrv_del_item (pl->contr, tmp2->count);
323 else 323 else
324 esrv_send_item (pl, tmp2); 324 esrv_update_item (UPD_NROF, pl, tmp2);
325 }
326 } 325 }
327 else 326 else
328 { 327 {
329 /* If the object is in a container, send a delete to the client. 328 /* If the object is in a container, send a delete to the client.
330 * - we are moving all the items from the container to elsewhere, 329 * - we are moving all the items from the container to elsewhere,
332 */ 331 */
333 if (!QUERY_FLAG (tmp, FLAG_REMOVED)) 332 if (!QUERY_FLAG (tmp, FLAG_REMOVED))
334 { 333 {
335 if (tmp->env && pl->type == PLAYER) 334 if (tmp->env && pl->type == PLAYER)
336 esrv_del_item (pl->contr, tmp->count); 335 esrv_del_item (pl->contr, tmp->count);
336
337 tmp->remove (); /* Unlink it */ 337 tmp->remove (); /* Unlink it */
338 } 338 }
339 } 339 }
340
340 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 341 if (QUERY_FLAG (tmp, FLAG_UNPAID))
341 (void) sprintf (buf, "%s will cost you %s.", query_name (tmp), query_cost_string (tmp, pl, F_BUY | F_SHOP)); 342 sprintf (buf, "%s will cost you %s.", query_name (tmp), query_cost_string (tmp, pl, F_BUY | F_SHOP));
342 else 343 else
343 (void) sprintf (buf, "You pick up the %s.", query_name (tmp)); 344 sprintf (buf, "You pick up the %s.", query_name (tmp));
345
344 new_draw_info (NDI_UNIQUE, 0, pl, buf); 346 new_draw_info (NDI_UNIQUE, 0, pl, buf);
345 347
346 tmp = insert_ob_in_ob (tmp, op); 348 tmp = insert_ob_in_ob (tmp, op);
347 349
348 /* All the stuff below deals with client/server code, and is only 350 /* All the stuff below deals with client/server code, and is only
349 * usable by players 351 * usable by players
350 */ 352 */
351 if (pl->type != PLAYER) 353 if (pl->contr)
352 return; 354 {
353
354 esrv_send_item (pl, tmp); 355 esrv_send_item (pl, tmp);
356
355 /* These are needed to update the weight for the container we 357 /* These are needed to update the weight for the container we
356 * are putting the object in. 358 * are putting the object in.
357 */ 359 */
358 if (op != pl) 360 if (op != pl)
359 { 361 {
360 esrv_update_item (UPD_WEIGHT, pl, op); 362 esrv_update_item (UPD_WEIGHT, pl, op);
361 esrv_send_item (pl, pl); 363 esrv_send_item (pl, pl);
362 } 364 }
363 365
364 /* Update the container the object was in */ 366 /* Update the container the object was in */
365 if (env && env != pl && env != op) 367 if (env && env != pl && env != op)
366 esrv_update_item (UPD_WEIGHT, pl, env); 368 esrv_update_item (UPD_WEIGHT, pl, env);
369 }
367} 370}
368 371
369/* modified slightly to allow monsters use this -b.t. 5-31-95 */ 372/* modified slightly to allow monsters use this -b.t. 5-31-95 */
370void 373void
371pick_up (object *op, object *alt) 374pick_up (object *op, object *alt)
430 433
431 if (!alt) 434 if (!alt)
432 for (alt = op->inv; alt; alt = alt->below) 435 for (alt = op->inv; alt; alt = alt->below)
433 if (alt->type == CONTAINER && QUERY_FLAG (alt, FLAG_APPLIED) && sack_can_hold (NULL, alt, tmp, count)) 436 if (alt->type == CONTAINER && QUERY_FLAG (alt, FLAG_APPLIED) && sack_can_hold (NULL, alt, tmp, count))
434 break; /* General container comes next */ 437 break; /* General container comes next */
438
435 if (!alt) 439 if (!alt)
436 alt = op; /* No free containers */ 440 alt = op; /* No free containers */
437 } 441 }
438 442
439 if (tmp->env == alt) 443 if (tmp->env == alt)
466 470
467leave: 471leave:
468 if (need_fix_tmp) 472 if (need_fix_tmp)
469 fix_stopped_item (tmp, tmp_map, op); 473 fix_stopped_item (tmp, tmp_map, op);
470} 474}
471
472 475
473/* This takes (picks up) and item. op is the player 476/* This takes (picks up) and item. op is the player
474 * who issued the command. params is a string to 477 * who issued the command. params is a string to
475 * match against the item name. Basically, always 478 * match against the item name. Basically, always
476 * returns zero, but that should be improved. 479 * returns zero, but that should be improved.
491 494
492 if (!tmp) 495 if (!tmp)
493 tmp = op->below; 496 tmp = op->below;
494 } 497 }
495 498
496 if (tmp == NULL) 499 if (!tmp)
497 { 500 {
498 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to take!"); 501 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to take!");
499 return 0; 502 return 0;
500 } 503 }
501 504
502 /* Makes processing easier */ 505 /* Makes processing easier */
503 if (params && *params == '\0') 506 if (params && *params == '\0')
504 params = NULL; 507 params = 0;
505 508
506 while (tmp) 509 while (tmp)
507 { 510 {
508 next = tmp->below; 511 next = tmp->below;
509 512
510 if (tmp->invisible) 513 if (tmp->invisible)
511 { 514 {
512 tmp = next; 515 tmp = next;
513 continue; 516 continue;
514 } 517 }
518
515 /* This following two if and else if could be merged into line 519 /* This following two if and else if could be merged into line
516 * but that probably will make it more difficult to read, and 520 * but that probably will make it more difficult to read, and
517 * not make it any more efficient 521 * not make it any more efficient
518 */ 522 */
519 if (params && item_matched_string (op, tmp, params)) 523 if (params && item_matched_string (op, tmp, params))
520 {
521 pick_up (op, tmp); 524 pick_up (op, tmp);
522 }
523 else if (can_pick (op, tmp) && !params) 525 else if (can_pick (op, tmp) && !params)
524 { 526 {
525 pick_up (op, tmp); 527 pick_up (op, tmp);
526 break; 528 break;
527 } 529 }
530
528 tmp = next; 531 tmp = next;
529 /* Might as well just skip over the player immediately -
530 * we know it can't be picked up
531 */
532 if (tmp == op)
533 tmp = tmp->below;
534 } 532 }
533
535 if (!params && !tmp) 534 if (!params && !tmp)
536 { 535 {
537 for (tmp = op->below; tmp != NULL; tmp = tmp->next) 536 for (tmp = op->below; tmp; tmp = tmp->below)
538 if (!tmp->invisible) 537 if (!tmp->invisible)
539 { 538 {
540 char buf[MAX_BUF]; 539 char buf[MAX_BUF];
541 540
542 sprintf (buf, "You can't pick up a %s.", &tmp->name); 541 sprintf (buf, "You can't pick up a %s.", &tmp->name);
543 new_draw_info (NDI_UNIQUE, 0, op, buf); 542 new_draw_info (NDI_UNIQUE, 0, op, buf);
544 break; 543 break;
545 } 544 }
545
546 if (!tmp) 546 if (!tmp)
547 new_draw_info (NDI_UNIQUE, 0, op, "There is nothing to pick up."); 547 new_draw_info (NDI_UNIQUE, 0, op, "There is nothing to pick up.");
548 } 548 }
549
549 return 0; 550 return 0;
550} 551}
551 552
552 553
553/* 554/*
633 else 634 else
634 tmp->remove (); 635 tmp->remove ();
635 636
636 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack)); 637 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack));
637 tmp2 = insert_ob_in_ob (tmp, sack); 638 tmp2 = insert_ob_in_ob (tmp, sack);
638 fix_player (op); /* This is overkill, fix_player() is called somewhere */ 639 op->update_stats (); /* This is overkill, fix_player() is called somewhere */
639 /* in object.c */ 640 /* in object.c */
640 641
641 /* If an object merged (and thus, different object), we need to 642 /* If an object merged (and thus, different object), we need to
642 * delete the original. 643 * delete the original.
643 */ 644 */
667 668
668 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 669 if (QUERY_FLAG (tmp, FLAG_APPLIED))
669 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) 670 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
670 return; /* can't unapply it */ 671 return; /* can't unapply it */
671 672
673 //fprintf (stderr, "ui, on space is %ld\n", op->ms ().volume ());//D
674
672 /* We are only dropping some of the items. We split the current object 675 /* We are only dropping some of the items. We split the current object
673 * off 676 * off
674 */ 677 */
675 if (nrof && tmp->nrof != nrof) 678 if (nrof && tmp->nrof != nrof)
676 { 679 {
702 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 705 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP))
703 { 706 {
704 sprintf (buf, "You drop the %s.", query_name (tmp)); 707 sprintf (buf, "You drop the %s.", query_name (tmp));
705 new_draw_info (NDI_UNIQUE, 0, op, buf); 708 new_draw_info (NDI_UNIQUE, 0, op, buf);
706 new_draw_info (NDI_UNIQUE, 0, op, "The gods who lent it to you retrieves it."); 709 new_draw_info (NDI_UNIQUE, 0, op, "The gods who lent it to you retrieves it.");
710
707 if (op->type == PLAYER) 711 if (op->type == PLAYER)
708 esrv_del_item (op->contr, tmp->count); 712 esrv_del_item (op->contr, tmp->count);
713
709 tmp->destroy (); 714 tmp->destroy ();
710 fix_player (op); 715 op->update_stats ();
711 return; 716 return;
712 } 717 }
713
714/* If SAVE_INTERVAL is commented out, we never want to save
715 * the player here.
716 */
717#ifdef SAVE_INTERVAL
718 /* I'm not sure why there is a value check - since the save
719 * is done every SAVE_INTERVAL seconds, why care the value
720 * of what he is dropping?
721 */
722 if (op->type == PLAYER && !QUERY_FLAG (tmp, FLAG_UNPAID) &&
723 (tmp->nrof ? tmp->value * tmp->nrof : tmp->value > 2000) && (op->contr->last_save_time + SAVE_INTERVAL) <= time (NULL))
724 {
725 save_player (op, 1);
726 op->contr->last_save_time = time (NULL);
727 }
728#endif /* SAVE_INTERVAL */
729 718
730 if (op->type == PLAYER) 719 if (op->type == PLAYER)
731 esrv_del_item (op->contr, tmp->count); 720 esrv_del_item (op->contr, tmp->count);
732 721
733 /* Call this before we update the various windows/players. At least 722 /* Call this before we update the various windows/players. At least
734 * that we, we know the weight is correct. 723 * that we, we know the weight is correct.
735 */ 724 */
736 fix_player (op); /* This is overkill, fix_player() is called somewhere */ 725 op->update_stats (); /* This is overkill, fix_player() is called somewhere */
737 /* in object.c */ 726 /* in object.c */
738 727
739 if (op->type == PLAYER) 728 if (op->type == PLAYER)
740 { 729 {
741 op->contr->socket.update_look = 1;
742 /* Need to update the weight for the player */ 730 /* Need to update the weight for the player */
743 esrv_send_item (op, op); 731 esrv_send_item (op, op);
732 op->contr->ns->floorbox_update ();
744 } 733 }
745 734
746 for (floor = get_map_ob (op->map, op->x, op->y); floor; floor = floor->above) 735 for (floor = GET_MAP_OB (op->map, op->x, op->y); floor; floor = floor->above)
747 if (INVOKE_OBJECT (DROP_ON, floor, ARG_OBJECT (tmp), ARG_OBJECT (op))) 736 if (INVOKE_OBJECT (DROP_ON, floor, ARG_OBJECT (tmp), ARG_OBJECT (op)))
748 return; 737 return;
749 738
750 if (is_in_shop (op) && !QUERY_FLAG (tmp, FLAG_UNPAID) && tmp->type != MONEY) 739 if (is_in_shop (op) && !QUERY_FLAG (tmp, FLAG_UNPAID) && tmp->type != MONEY)
751 sell_item (tmp, op); 740 sell_item (tmp, op);
800 new_draw_info (NDI_UNIQUE, 0, op, "This item can't be dropped."); 789 new_draw_info (NDI_UNIQUE, 0, op, "This item can't be dropped.");
801#endif 790#endif
802 return; 791 return;
803 } 792 }
804 793
805 if (op->type == PLAYER) 794 if (op->type == PLAYER && op->contr->last_used == tmp)
806 { 795 op->contr->last_used = tmp->below ? tmp->below
807 if (op->contr->last_used == tmp && op->contr->last_used_id == tmp->count) 796 : tmp->above ? tmp->above
808 { 797 : 0;
809 object *n = NULL;
810
811 if (tmp->below != NULL)
812 n = tmp->below;
813 else if (tmp->above != NULL)
814 n = tmp->above;
815 op->contr->last_used = n;
816 if (n != NULL)
817 op->contr->last_used_id = n->count;
818 else
819 op->contr->last_used_id = 0;
820 }
821 };
822 798
823 if (op->container) 799 if (op->container)
824 { 800 {
825 if (op->type == PLAYER) 801 if (op->type == PLAYER)
826 {
827 put_object_in_sack (op, op->container, tmp, op->contr->count); 802 put_object_in_sack (op, op->container, tmp, op->contr->count);
828 }
829 else 803 else
830 {
831 put_object_in_sack (op, op->container, tmp, 0); 804 put_object_in_sack (op, op->container, tmp, 0);
832 };
833 } 805 }
834 else 806 else
835 { 807 {
836 if (op->type == PLAYER) 808 if (op->type == PLAYER)
837 {
838 drop_object (op, tmp, op->contr->count); 809 drop_object (op, tmp, op->contr->count);
839 }
840 else 810 else
841 {
842 drop_object (op, tmp, 0); 811 drop_object (op, tmp, 0);
843 };
844 } 812 }
813
845 if (op->type == PLAYER) 814 if (op->type == PLAYER)
846 op->contr->count = 0; 815 op->contr->count = 0;
847} 816}
848 817
849 818
957 } 926 }
958 } 927 }
959 curinv = nextinv; 928 curinv = nextinv;
960 } 929 }
961 } 930 }
962 op->contr->socket.update_look = 1; 931
932 op->contr->ns->floorbox_update ();
963 933
964/* draw_look(op);*/ 934/* draw_look(op);*/
965 return 0; 935 return 0;
966} 936}
967 937
997 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to drop."); 967 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to drop.");
998 } 968 }
999 if (op->type == PLAYER) 969 if (op->type == PLAYER)
1000 { 970 {
1001 op->contr->count = 0; 971 op->contr->count = 0;
1002 op->contr->socket.update_look = 1; 972 op->contr->ns->floorbox_update ();
1003 }; 973 };
1004 974
1005/* draw_look(op);*/ 975/* draw_look(op);*/
1006 return 0; 976 return 0;
1007} 977}
1011{ 981{
1012 if (!params) 982 if (!params)
1013 { 983 {
1014 object *tmp = op->below; 984 object *tmp = op->below;
1015 985
1016 while (tmp && !LOOK_OBJ (tmp)) 986 while (tmp && !tmp->client_visible ())
1017 tmp = tmp->below; 987 tmp = tmp->below;
1018 if (tmp) 988 if (tmp)
1019 examine (op, tmp); 989 examine (op, tmp);
1020 } 990 }
1021 else 991 else
1073 } 1043 }
1074 1044
1075 return 0; 1045 return 0;
1076} 1046}
1077 1047
1078 1048std::string
1079/* op should be a player, params is any params. 1049object::describe_monster (object *who)
1080 * If no params given, we print out the currently marked object.
1081 * otherwise, try to find a matching object - try best match first.
1082 */
1083int
1084command_mark (object *op, char *params)
1085{ 1050{
1086 if (!op->contr) 1051 dynbuf_text buf (512, 512);
1087 return 1;
1088 1052
1089 if (!params) 1053 object *mon = head ? head : this;
1090 {
1091 object *mark = find_marked_object (op);
1092 1054
1093 if (!mark) 1055 if (QUERY_FLAG (mon, FLAG_UNDEAD))
1094 new_draw_info (NDI_UNIQUE, 0, op, "You have no marked object."); 1056 buf << "It is an undead force.\n";
1095 else 1057
1096 new_draw_info_format (NDI_UNIQUE, 0, op, "%s is marked.", query_name (mark)); 1058 if (mon->level > who->level)
1097 } 1059 buf << "It is likely more powerful than you.\n";
1060 else if (mon->level < who->level)
1061 buf << "It is likely less powerful than you.\n";
1098 else 1062 else
1099 { 1063 buf << "It is probably as powerful as you.\n";
1100 object *mark1 = find_best_object_match (op, params);
1101 1064
1102 if (!mark1)
1103 {
1104 new_draw_info_format (NDI_UNIQUE, 0, op, "Could not find an object that matches %s", params);
1105 return 1;
1106 }
1107 else
1108 {
1109 op->contr->mark = mark1;
1110 new_draw_info_format (NDI_UNIQUE, 0, op, "Marked item %s", query_name (mark1));
1111 return 0;
1112 }
1113 }
1114
1115 return 0; /*shouldnt get here */
1116}
1117
1118
1119/* op is the player
1120 * tmp is the monster being examined.
1121 */
1122void
1123examine_monster (object *op, object *tmp)
1124{
1125 object *mon = tmp->head ? tmp->head : tmp;
1126
1127 if (QUERY_FLAG (mon, FLAG_UNDEAD))
1128 new_draw_info (NDI_UNIQUE, 0, op, "It is an undead force.");
1129 if (mon->level > op->level)
1130 new_draw_info (NDI_UNIQUE, 0, op, "It is likely more powerful than you.");
1131 else if (mon->level < op->level)
1132 new_draw_info (NDI_UNIQUE, 0, op, "It is likely less powerful than you.");
1133 else
1134 new_draw_info (NDI_UNIQUE, 0, op, "It is probably as powerful as you.");
1135 if (mon->attacktype & AT_ACID) 1065 if (mon->attacktype & AT_ACID)
1136 new_draw_info (NDI_UNIQUE, 0, op, "You seem to smell an acrid odor."); 1066 buf << "You seem to smell an acrid odor.\n";
1137 1067
1138 /* Anyone know why this used to use the clone value instead of the 1068 /* Anyone know why this used to use the clone value instead of the
1139 * maxhp field? This seems that it should give more accurate results. 1069 * maxhp field? This seems that it should give more accurate results.
1140 */ 1070 */
1141 switch ((mon->stats.hp + 1) * 4 / (mon->stats.maxhp + 1)) 1071 switch ((mon->stats.hp + 1) * 4 / (mon->stats.maxhp + 1))
1142 { /* From 1-4 */ 1072 { /* From 1-4 */
1143 case 1: 1073 case 1:
1144 new_draw_info (NDI_UNIQUE, 0, op, "It is in a bad shape."); 1074 buf << "It is in a bad shape.\n";
1145 break; 1075 break;
1146 case 2: 1076 case 2:
1147 new_draw_info (NDI_UNIQUE, 0, op, "It is hurt."); 1077 buf << "It is hurt.\n";
1148 break; 1078 break;
1149 case 3: 1079 case 3:
1150 new_draw_info (NDI_UNIQUE, 0, op, "It is somewhat hurt."); 1080 buf << "It is somewhat hurt.\n";
1151 break; 1081 break;
1152 case 4: 1082 case 4:
1153 new_draw_info (NDI_UNIQUE, 0, op, "It is in excellent shape."); 1083 buf << "It is in excellent shape.\n";
1154 break; 1084 break;
1155 } 1085 }
1086
1156 if (present_in_ob (POISONING, mon) != NULL) 1087 if (present_in_ob (POISONING, mon))
1157 new_draw_info (NDI_UNIQUE, 0, op, "It looks very ill."); 1088 buf << "It looks very ill.\n";
1158}
1159 1089
1090 return buf;
1091}
1160 1092
1161/* tmp is the object being described, pl is who is examing it. */ 1093/* tmp is the object being described, pl is who is examing it. */
1162char * 1094const char *
1163long_desc (object *tmp, object *pl) 1095long_desc (object *tmp, object *pl)
1164{ 1096{
1165 static char buf[VERY_BIG_BUF]; 1097 static std::string s;
1166 char *cp;
1167 1098
1168 if (tmp == NULL) 1099 return (s = tmp->long_desc (pl)).c_str ();
1169 return ""; 1100}
1170 1101
1171 buf[0] = '\0'; 1102std::string
1103object::long_desc (object *who)
1104{
1105 std::string buf (query_name (this));
1106
1172 switch (tmp->type) 1107 switch (type)
1173 { 1108 {
1174 case RING: 1109 case RING:
1175 case SKILL: 1110 case SKILL:
1176 case WEAPON: 1111 case WEAPON:
1177 case ARMOUR: 1112 case ARMOUR:
1188 case FOOD: 1123 case FOOD:
1189 case DRINK: 1124 case DRINK:
1190 case FLESH: 1125 case FLESH:
1191 case SKILL_TOOL: 1126 case SKILL_TOOL:
1192 case POWER_CRYSTAL: 1127 case POWER_CRYSTAL:
1193 if (*(cp = describe_item (tmp, pl)) != '\0') 1128 {
1129 const char *cp = ::describe_item (this, who);
1130
1131 if (*cp)
1132 {
1133 buf.append (" ");
1134 buf.append (cp);
1135 }
1136 }
1137 }
1138
1139 return buf;
1140}
1141
1142/* op is the player
1143 * tmp is the monster being examined.
1144 */
1145void
1146examine_monster (object *op, object *tmp)
1147{
1148 new_draw_info (NDI_UNIQUE, 0, op, tmp->describe_monster (op).c_str ());
1149}
1150
1151std::string
1152object::describe (object *who)
1153{
1154 dynbuf_text buf (1024, 1024);
1155
1156 buf.printf ("That is: %s.\n", long_desc (who).c_str ());
1157
1158 if (custom_name)
1159 buf,printf ("You call it %s\n", &custom_name);
1160
1161 switch (type)
1162 {
1163 case SPELLBOOK:
1164 if (flag [FLAG_IDENTIFIED] && inv)
1165 buf.printf ("%s is a %s %s spell\n", &inv->name, get_levelnumber (inv->level), &inv->skill);
1166 break;
1167
1168 case BOOK:
1169 if (msg)
1170 buf << "Something is written in it.\n";
1171 break;
1172
1173 case CONTAINER:
1174 if (race != NULL)
1194 { 1175 {
1176 if (weight_limit && stats.Str < 100)
1177 buf.printf ("It can hold only %s and its weight limit is %.1f kg.\n",
1178 &race, weight_limit / (10.0 * (100 - stats.Str)));
1195 int len; 1179 else
1196 1180 buf.printf ("It can hold only %s.\n", &race);
1197 assign (buf, query_name (tmp));
1198 len = strlen (buf);
1199 if (len < VERY_BIG_BUF - 5)
1200 {
1201 /* Since we know the length, we save a few cpu cycles by using
1202 * it instead of calling strcat */
1203 strcpy (buf + len, " ");
1204 len++;
1205 assign (buf + len, cp, VERY_BIG_BUF - len - 1);
1206 }
1207 } 1181 }
1208 } 1182 else if (weight_limit && stats.Str < 100)
1209 1183 buf.printf ("Its weight limit is %.1f kg.\n", weight_limit / (10.0 * (100 - stats.Str)));
1210 if (buf[0] == '\0')
1211 assign (buf, query_name (tmp));
1212
1213 return buf;
1214}
1215
1216void
1217examine (object *op, object *tmp)
1218{
1219 char buf[VERY_BIG_BUF];
1220 int i;
1221
1222 if (tmp == NULL || tmp->type == CLOSE_CON)
1223 return;
1224
1225 strcpy (buf, "That is ");
1226 strncat (buf, long_desc (tmp, op), VERY_BIG_BUF - strlen (buf) - 1);
1227 buf[VERY_BIG_BUF - 1] = 0;
1228
1229 new_draw_info (NDI_UNIQUE, 0, op, buf);
1230 buf[0] = '\0';
1231
1232 if (tmp->custom_name)
1233 {
1234 strcpy (buf, "You call it ");
1235 strncat (buf, tmp->custom_name, VERY_BIG_BUF - strlen (buf) - 1);
1236 buf[VERY_BIG_BUF - 1] = 0;
1237 new_draw_info (NDI_UNIQUE, 0, op, buf);
1238 buf[0] = '\0';
1239 }
1240
1241 switch (tmp->type)
1242 {
1243 case SPELLBOOK:
1244 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) && tmp->inv)
1245 {
1246 sprintf (buf, "%s is a %s level %s spell", &tmp->inv->name, get_levelnumber (tmp->inv->level), &tmp->inv->skill);
1247 }
1248 break; 1184 break;
1249 1185
1250 case BOOK: 1186 case WAND:
1251 if (tmp->msg != NULL) 1187 if (flag [FLAG_IDENTIFIED])
1252 strcpy (buf, "Something is written in it."); 1188 buf.printf ("It has %d charges left.\n", stats.food);
1253 break; 1189 break;
1254
1255 case CONTAINER:
1256 if (tmp->race != NULL)
1257 {
1258 if (tmp->weight_limit && tmp->stats.Str < 100)
1259 sprintf (buf, "It can hold only %s and its weight limit is %.1f kg.",
1260 &tmp->race, tmp->weight_limit / (10.0 * (100 - tmp->stats.Str)));
1261 else
1262 sprintf (buf, "It can hold only %s.", &tmp->race);
1263 }
1264 else if (tmp->weight_limit && tmp->stats.Str < 100)
1265 sprintf (buf, "Its weight limit is %.1f kg.", tmp->weight_limit / (10.0 * (100 - tmp->stats.Str)));
1266 break;
1267
1268 case WAND:
1269 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1270 sprintf (buf, "It has %d charges left.", tmp->stats.food);
1271 break;
1272 }
1273
1274 if (buf[0] != '\0')
1275 new_draw_info (NDI_UNIQUE, 0, op, buf);
1276
1277 if (tmp->materialname != NULL && !tmp->msg)
1278 { 1190 }
1191
1192 if (materialname && !msg)
1279 sprintf (buf, "It is made of: %s.", &tmp->materialname); 1193 buf.printf ("It is made of: %s.\n", &materialname);
1280 new_draw_info (NDI_UNIQUE, 0, op, buf); 1194
1281 } 1195 if (who)
1282 /* Where to wear this item */ 1196 /* Where to wear this item */
1283 for (i = 0; i < NUM_BODY_LOCATIONS; i++) 1197 for (int i = 0; i < NUM_BODY_LOCATIONS; i++)
1284 { 1198 if (slot[i].info)
1285 if (tmp->body_info[i] < -1) 1199 {
1200 buf << (who->slot[i].info ? body_locations[i].use_name : body_locations[i].nonuse_name);
1201
1202 if (slot[i].info < -1 && who->slot[i].info)
1203 buf.printf ("(%d)", -slot[i].info);
1204
1205 buf << ".\n";
1286 { 1206 }
1287 if (op->body_info[i]) 1207
1288 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s (%d)", body_locations[i].use_name, -tmp->body_info[i]); 1208 if (weight)
1209 buf.printf (nrof > 1 ? "They weigh %3.3f kg.\n" : "It weighs %3.3f kg.\n", weight * (nrof ? nrof : 1) / 1000.0);
1210
1211 if (value && !flag [FLAG_STARTEQUIP] && !flag [FLAG_NO_PICK] && who)
1212 {
1213 buf.printf ("You reckon %s worth %s.\n", nrof > 1 ? "they are" : "it is", query_cost_string (this, who, F_TRUE | F_APPROX));
1214
1215 if (is_in_shop (who))
1216 {
1217 if (flag [FLAG_UNPAID])
1218 buf.printf ("%s would cost you %s.\n", nrof > 1 ? "They" : "It", query_cost_string (this, who, F_BUY | F_SHOP));
1289 else 1219 else
1290 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s", body_locations[i].nonuse_name);
1291 }
1292 else if (tmp->body_info[i])
1293 {
1294 if (op->body_info[i])
1295 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s", body_locations[i].use_name);
1296 else
1297 new_draw_info_format (NDI_UNIQUE, 0, op, "It goes %s", body_locations[i].nonuse_name);
1298 }
1299 }
1300
1301 if (tmp->weight)
1302 {
1303 sprintf (buf, tmp->nrof > 1 ? "They weigh %3.3f kg." : "It weighs %3.3f kg.", tmp->weight * (tmp->nrof ? tmp->nrof : 1) / 1000.0);
1304 new_draw_info (NDI_UNIQUE, 0, op, buf);
1305 }
1306
1307 if (tmp->value && !QUERY_FLAG (tmp, FLAG_STARTEQUIP) && !QUERY_FLAG (tmp, FLAG_NO_PICK))
1308 {
1309 sprintf (buf, "You reckon %s worth %s.", tmp->nrof > 1 ? "they are" : "it is", query_cost_string (tmp, op, F_TRUE | F_APPROX));
1310 new_draw_info (NDI_UNIQUE, 0, op, buf);
1311 if (is_in_shop (op))
1312 {
1313 if (QUERY_FLAG (tmp, FLAG_UNPAID))
1314 sprintf (buf, "%s would cost you %s.", tmp->nrof > 1 ? "They" : "It", query_cost_string (tmp, op, F_BUY | F_SHOP));
1315 else
1316 sprintf (buf, "You are offered %s for %s.", query_cost_string (tmp, op, F_SELL + F_SHOP), tmp->nrof > 1 ? "them" : "it"); 1220 buf.printf ("You are offered %s for %s.\n", query_cost_string (this, who, F_SELL + F_SHOP), nrof > 1 ? "them" : "it");
1317 new_draw_info (NDI_UNIQUE, 0, op, buf);
1318 } 1221 }
1319 } 1222 }
1320 1223
1321 if (QUERY_FLAG (tmp, FLAG_MONSTER)) 1224 if (flag [FLAG_MONSTER])
1322 examine_monster (op, tmp); 1225 buf << describe_monster (who);
1323 1226
1324 /* Is this item buildable? */ 1227 /* Is this item buildable? */
1325 if (QUERY_FLAG (tmp, FLAG_IS_BUILDABLE)) 1228 if (flag [FLAG_IS_BUILDABLE])
1326 new_draw_info (NDI_UNIQUE, 0, op, "This is a buildable item."); 1229 buf << "This is a buildable item.\n";
1327 1230
1328 /* Does the object have a message? Don't show message for all object 1231 /* Does the object have a message? Don't show message for all object
1329 * types - especially if the first entry is a match 1232 * types - especially if the first entry is a match
1330 */ 1233 */
1331 if (tmp->msg && tmp->type != EXIT && tmp->type != BOOK && tmp->type != CORPSE && !tmp->move_on && strncasecmp (tmp->msg, "@match", 7)) 1234 if (msg && type != EXIT && type != BOOK && type != CORPSE && !move_on && strncasecmp (msg, "@match", 7))
1332 { 1235 {
1333
1334 /* This is just a hack so when identifying the items, we print 1236 /* This is just a hack so when identifying the items, we print
1335 * out the extra message 1237 * out the extra message
1336 */ 1238 */
1337 if (need_identify (tmp) && QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1239 if (need_identify (this) && flag [FLAG_IDENTIFIED])
1338 new_draw_info (NDI_UNIQUE, 0, op, "The object has a story:"); 1240 buf << "The object has a story:\n";
1339 1241
1242 buf << msg << '\n';
1243 }
1244
1245 buf << '\n';
1246
1247 return std::string (buf.linearise (), buf.size ());
1248}
1249
1250void
1251examine (object *op, object *tmp)
1252{
1253 std::string s = tmp->describe (op);
1254
1340 new_draw_info (NDI_UNIQUE, 0, op, tmp->msg); 1255 new_draw_info (NDI_UNIQUE, 0, op, s.c_str ());
1341 }
1342 new_draw_info (NDI_UNIQUE, 0, op, " "); /* Blank line */
1343} 1256}
1344 1257
1345/* 1258/*
1346 * inventory prints object's inventory. If inv==NULL then print player's 1259 * inventory prints object's inventory. If inv==NULL then print player's
1347 * inventory. 1260 * inventory.
1349 */ 1262 */
1350void 1263void
1351inventory (object *op, object *inv) 1264inventory (object *op, object *inv)
1352{ 1265{
1353 object *tmp; 1266 object *tmp;
1354 char *in; 1267 const char *in;
1355 int items = 0, length; 1268 int items = 0, length;
1356 1269
1357 if (inv == NULL && op == NULL) 1270 if (inv == NULL && op == NULL)
1358 { 1271 {
1359 new_draw_info (NDI_UNIQUE, 0, op, "Inventory of what object?"); 1272 new_draw_info (NDI_UNIQUE, 0, op, "Inventory of what object?");
1360 return; 1273 return;
1361 } 1274 }
1275
1362 tmp = inv ? inv->inv : op->inv; 1276 tmp = inv ? inv->inv : op->inv;
1363 1277
1364 while (tmp) 1278 while (tmp)
1365 { 1279 {
1366 if ((!tmp->invisible && 1280 if ((!tmp->invisible &&
1367 (inv == NULL || inv->type == CONTAINER || QUERY_FLAG (tmp, FLAG_APPLIED))) || (!op || QUERY_FLAG (op, FLAG_WIZ))) 1281 (inv == NULL || inv->type == CONTAINER || QUERY_FLAG (tmp, FLAG_APPLIED))) || (!op || QUERY_FLAG (op, FLAG_WIZ)))
1368 items++; 1282 items++;
1369 tmp = tmp->below; 1283 tmp = tmp->below;
1370 } 1284 }
1285
1371 if (inv == NULL) 1286 if (inv == NULL)
1372 { /* player's inventory */ 1287 { /* player's inventory */
1373 if (items == 0) 1288 if (items == 0)
1374 { 1289 {
1375 new_draw_info (NDI_UNIQUE, 0, op, "You carry nothing."); 1290 new_draw_info (NDI_UNIQUE, 0, op, "You carry nothing.");
1392 { 1307 {
1393 length = 28; 1308 length = 28;
1394 in = " "; 1309 in = " ";
1395 } 1310 }
1396 } 1311 }
1312
1397 for (tmp = inv ? inv->inv : op->inv; tmp; tmp = tmp->below) 1313 for (tmp = inv ? inv->inv : op->inv; tmp; tmp = tmp->below)
1398 { 1314 {
1399 if ((!op || !QUERY_FLAG (op, FLAG_WIZ)) && (tmp->invisible || (inv && inv->type != CONTAINER && !QUERY_FLAG (tmp, FLAG_APPLIED)))) 1315 if ((!op || !QUERY_FLAG (op, FLAG_WIZ)) && (tmp->invisible || (inv && inv->type != CONTAINER && !QUERY_FLAG (tmp, FLAG_APPLIED))))
1400 continue; 1316 continue;
1401 if ((!op || QUERY_FLAG (op, FLAG_WIZ))) 1317 if ((!op || QUERY_FLAG (op, FLAG_WIZ)))
1402 new_draw_info_format (NDI_UNIQUE, 0, op, "%s- %-*.*s (%5d) %-8s", in, length, length, 1318 new_draw_info_format (NDI_UNIQUE, 0, op, "%s- %-*.*s (%5d) %-8s", in, length, length,
1403 query_name (tmp), tmp->count, query_weight (tmp)); 1319 query_name (tmp), tmp->count, query_weight (tmp));
1404 else 1320 else
1405 new_draw_info_format (NDI_UNIQUE, 0, op, "%s- %-*.*s %-8s", in, length + 8, length + 8, query_name (tmp), query_weight (tmp)); 1321 new_draw_info_format (NDI_UNIQUE, 0, op, "%s- %-*.*s %-8s", in, length + 8, length + 8, query_name (tmp), query_weight (tmp));
1406 } 1322 }
1323
1407 if (!inv && op) 1324 if (!inv && op)
1408 {
1409 new_draw_info_format (NDI_UNIQUE, 0, op, "%-*s %-8s", 41, "Total weight :", query_weight (op)); 1325 new_draw_info_format (NDI_UNIQUE, 0, op, "%-*s %-8s", 41, "Total weight :", query_weight (op));
1410 }
1411} 1326}
1412 1327
1413static void 1328static void
1414display_new_pickup (object *op) 1329display_new_pickup (object *op)
1415{ 1330{
1576 new_draw_info (NDI_UNIQUE, 0, op, "Example: search magic+1"); 1491 new_draw_info (NDI_UNIQUE, 0, op, "Example: search magic+1");
1577 new_draw_info (NDI_UNIQUE, 0, op, "Would automatically pick up all"); 1492 new_draw_info (NDI_UNIQUE, 0, op, "Would automatically pick up all");
1578 new_draw_info (NDI_UNIQUE, 0, op, "items containing the word 'magic+1'."); 1493 new_draw_info (NDI_UNIQUE, 0, op, "items containing the word 'magic+1'.");
1579 return 1; 1494 return 1;
1580 } 1495 }
1496
1581 op->contr->search_str[0] = '\0'; 1497 op->contr->search_str[0] = '\0';
1582 new_draw_info (NDI_UNIQUE, 0, op, "Search mode turned off."); 1498 new_draw_info (NDI_UNIQUE, 0, op, "Search mode turned off.");
1583 fix_player (op); 1499 op->update_stats ();
1584 return 1; 1500 return 1;
1585 } 1501 }
1502
1586 if ((int) strlen (params) >= MAX_BUF) 1503 if ((int) strlen (params) >= MAX_BUF)
1587 { 1504 {
1588 new_draw_info (NDI_UNIQUE, 0, op, "Search string too long."); 1505 new_draw_info (NDI_UNIQUE, 0, op, "Search string too long.");
1589 return 1; 1506 return 1;
1590 } 1507 }
1508
1591 strcpy (op->contr->search_str, params); 1509 strcpy (op->contr->search_str, params);
1592 sprintf (buf, "Searching for '%s'.", op->contr->search_str); 1510 sprintf (buf, "Searching for '%s'.", op->contr->search_str);
1593 new_draw_info (NDI_UNIQUE, 0, op, buf); 1511 new_draw_info (NDI_UNIQUE, 0, op, buf);
1594 fix_player (op); 1512 op->update_stats ();
1595 return 1; 1513 return 1;
1596} 1514}
1597 1515

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines