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.14 by root, Sun Sep 10 15:59:57 2006 UTC vs.
Revision 1.25 by root, Tue Dec 12 21:39:57 2006 UTC

1
2/*
3 * static char *rcsid_c_object_c =
4 * "$Id: c_object.C,v 1.14 2006/09/10 15:59:57 root Exp $";
5 */
6
7/* 1/*
8 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
9 3
10 Copyright (C) 2002 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2002 Mark Wedel & Crossfire Development Team
11 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
22 16
23 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 20
27 The author can be reached via e-mail to crossfire-devel@real-time.com 21 The author can be reached via e-mail to <crossfire@schmorp.de>
28 22
29 Object (handling) commands 23 Object (handling) commands
30*/ 24*/
31 25
32#include <global.h> 26#include <global.h>
40 34
41/* 35/*
42 * Object id parsing functions 36 * Object id parsing functions
43 */ 37 */
44 38
45#define OBLINKMALLOC(p) if(!((p)=(objectlink *)malloc(sizeof(objectlink))))\
46 fatal(OUT_OF_MEMORY);
47
48#define ADD_ITEM(NEW,COUNT)\ 39#define ADD_ITEM(NEW,COUNT)\
49 if(!first) {\ 40 if(!first) {\
50 OBLINKMALLOC(first);\ 41 first = new objectlink;\
51 last=first;\ 42 last=first;\
52 } else {\ 43 } else {\
53 OBLINKMALLOC(last->next);\ 44 last->next = new objectlink;\
54 last=last->next;\ 45 last=last->next;\
55 }\ 46 }\
56 last->next=NULL;\ 47 last->next=0;\
57 last->ob=(NEW);\ 48 last->ob=(NEW);\
58 last->id=(COUNT); 49 last->id=(COUNT);
59 50
60/** 51/**
61 * Search the inventory of 'pl' for what matches best with params. 52 * Search the inventory of 'pl' for what matches best with params.
273 if ((pl->move_type & MOVE_FLYING) && !QUERY_FLAG (pl, FLAG_WIZ) && is_player_inv (tmp) != pl) 264 if ((pl->move_type & MOVE_FLYING) && !QUERY_FLAG (pl, FLAG_WIZ) && is_player_inv (tmp) != pl)
274 { 265 {
275 new_draw_info (NDI_UNIQUE, 0, pl, "You are levitating, you can't reach the ground!"); 266 new_draw_info (NDI_UNIQUE, 0, pl, "You are levitating, you can't reach the ground!");
276 return; 267 return;
277 } 268 }
269
278 if (QUERY_FLAG (tmp, FLAG_NO_DROP)) 270 if (QUERY_FLAG (tmp, FLAG_NO_DROP))
279 return; 271 return;
272
280 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ)) 273 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) && !QUERY_FLAG (pl, FLAG_WAS_WIZ))
281 { 274 {
282 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff of smoke!"); 275 new_draw_info (NDI_UNIQUE, 0, pl, "The object disappears in a puff of smoke!");
283 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion."); 276 new_draw_info (NDI_UNIQUE, 0, pl, "It must have been an illusion.");
277
284 if (pl->type == PLAYER) 278 if (pl->type == PLAYER)
285 esrv_del_item (pl->contr, tmp->count); 279 esrv_del_item (pl->contr, tmp->count);
286 if (!QUERY_FLAG (tmp, FLAG_REMOVED)) 280
287 remove_ob (tmp); 281 tmp->destroy ();
288 free_object (tmp);
289 return; 282 return;
290 } 283 }
291 284
292 if (nrof > tmp_nrof || nrof == 0) 285 if (nrof > tmp_nrof || nrof == 0)
293 nrof = tmp_nrof; 286 nrof = tmp_nrof;
287
294 /* Figure out how much weight this object will add to the player */ 288 /* Figure out how much weight this object will add to the player */
295 weight = tmp->weight * nrof; 289 weight = tmp->weight * nrof;
296 if (tmp->inv) 290 if (tmp->inv)
297 weight += tmp->carrying * (100 - tmp->stats.Str) / 100; 291 weight += tmp->carrying * (100 - tmp->stats.Str) / 100;
292
298 if (pl->stats.Str <= MAX_STAT) 293 if (pl->stats.Str <= MAX_STAT)
299 effective_weight_limit = weight_limit[pl->stats.Str]; 294 effective_weight_limit = weight_limit[pl->stats.Str];
300 else 295 else
301 effective_weight_limit = weight_limit[MAX_STAT]; 296 effective_weight_limit = weight_limit[MAX_STAT];
297
302 if ((pl->weight + pl->carrying + weight) > effective_weight_limit) 298 if ((pl->weight + pl->carrying + weight) > effective_weight_limit)
303 { 299 {
304 new_draw_info (0, 0, pl, "That item is too heavy for you to pick up."); 300 new_draw_info (0, 0, pl, "That item is too heavy for you to pick up.");
305 return; 301 return;
306 } 302 }
303
307 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ)) 304 if (settings.real_wiz == FALSE && QUERY_FLAG (pl, FLAG_WAS_WIZ))
308 SET_FLAG (tmp, FLAG_WAS_WIZ); 305 SET_FLAG (tmp, FLAG_WAS_WIZ);
306
309 if (nrof != tmp_nrof) 307 if (nrof != tmp_nrof)
310 { 308 {
311 object *tmp2 = tmp; 309 object *tmp2 = tmp;
312 tag_t tmp2_tag = tmp2->count;
313 310
314 tmp = get_split_ob (tmp, nrof); 311 tmp = get_split_ob (tmp, nrof);
315 if (!tmp) 312 if (!tmp)
316 { 313 {
317 new_draw_info (NDI_UNIQUE, 0, pl, errmsg); 314 new_draw_info (NDI_UNIQUE, 0, pl, errmsg);
318 return; 315 return;
319 } 316 }
317
320 /* Tell a client what happened rest of objects */ 318 /* Tell a client what happened rest of objects */
321 if (pl->type == PLAYER) 319 if (pl->type == PLAYER)
322 { 320 {
323 if (was_destroyed (tmp2, tmp2_tag)) 321 if (tmp2->destroyed ())
324 esrv_del_item (pl->contr, tmp2_tag); 322 esrv_del_item (pl->contr, tmp2->count);
325 else 323 else
326 esrv_send_item (pl, tmp2); 324 esrv_send_item (pl, tmp2);
327 } 325 }
328 } 326 }
329 else 327 else
334 */ 332 */
335 if (!QUERY_FLAG (tmp, FLAG_REMOVED)) 333 if (!QUERY_FLAG (tmp, FLAG_REMOVED))
336 { 334 {
337 if (tmp->env && pl->type == PLAYER) 335 if (tmp->env && pl->type == PLAYER)
338 esrv_del_item (pl->contr, tmp->count); 336 esrv_del_item (pl->contr, tmp->count);
339 remove_ob (tmp); /* Unlink it */ 337 tmp->remove (); /* Unlink it */
340 } 338 }
341 } 339 }
342 if (QUERY_FLAG (tmp, FLAG_UNPAID)) 340 if (QUERY_FLAG (tmp, FLAG_UNPAID))
343 (void) sprintf (buf, "%s will cost you %s.", query_name (tmp), query_cost_string (tmp, pl, F_BUY | F_SHOP)); 341 (void) sprintf (buf, "%s will cost you %s.", query_name (tmp), query_cost_string (tmp, pl, F_BUY | F_SHOP));
344 else 342 else
366 /* Update the container the object was in */ 364 /* Update the container the object was in */
367 if (env && env != pl && env != op) 365 if (env && env != pl && env != op)
368 esrv_update_item (UPD_WEIGHT, pl, env); 366 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 */
372void 370void
373pick_up (object *op, object *alt) 371pick_up (object *op, object *alt)
374
375/* modified slightly to allow monsters use this -b.t. 5-31-95 */
376{ 372{
377 int need_fix_tmp = 0; 373 int need_fix_tmp = 0;
378 object *tmp = NULL; 374 object *tmp = NULL;
379 mapstruct *tmp_map = NULL; 375 maptile *tmp_map = NULL;
380 int count; 376 int count;
381 tag_t tag;
382 377
383 /* Decide which object to pick. */ 378 /* Decide which object to pick. */
384 if (alt) 379 if (alt)
385 { 380 {
386 if (!can_pick (op, alt)) 381 if (!can_pick (op, alt))
395 if (op->below == NULL || !can_pick (op, op->below)) 390 if (op->below == NULL || !can_pick (op, op->below))
396 { 391 {
397 new_draw_info (NDI_UNIQUE, 0, op, "There is nothing to pick up here."); 392 new_draw_info (NDI_UNIQUE, 0, op, "There is nothing to pick up here.");
398 goto leave; 393 goto leave;
399 } 394 }
395
400 tmp = op->below; 396 tmp = op->below;
401 } 397 }
402 398
403 /* Try to catch it. */ 399 /* Try to catch it. */
404 tmp_map = tmp->map; 400 tmp_map = tmp->map;
437 if (alt->type == CONTAINER && QUERY_FLAG (alt, FLAG_APPLIED) && sack_can_hold (NULL, alt, tmp, count)) 433 if (alt->type == CONTAINER && QUERY_FLAG (alt, FLAG_APPLIED) && sack_can_hold (NULL, alt, tmp, count))
438 break; /* General container comes next */ 434 break; /* General container comes next */
439 if (!alt) 435 if (!alt)
440 alt = op; /* No free containers */ 436 alt = op; /* No free containers */
441 } 437 }
438
442 if (tmp->env == alt) 439 if (tmp->env == alt)
443 { 440 {
444 /* here it could be possible to check rent, 441 /* here it could be possible to check rent,
445 * if someone wants to implement it 442 * if someone wants to implement it
446 */ 443 */
455 { 452 {
456 new_draw_info (NDI_UNIQUE, 0, op, "This object cannot be put into containers!"); 453 new_draw_info (NDI_UNIQUE, 0, op, "This object cannot be put into containers!");
457 goto leave; 454 goto leave;
458 } 455 }
459 456
460 tag = tmp->count;
461 pick_up_object (op, alt, tmp, count); 457 pick_up_object (op, alt, tmp, count);
458
462 if (was_destroyed (tmp, tag) || tmp->env) 459 if (tmp->destroyed () || tmp->env)
463 need_fix_tmp = 0; 460 need_fix_tmp = 0;
461
464 if (op->type == PLAYER) 462 if (op->type == PLAYER)
465 op->contr->count = 0; 463 op->contr->count = 0;
464
466 goto leave; 465 goto leave;
467 466
468leave: 467leave:
469 if (need_fix_tmp) 468 if (need_fix_tmp)
470 fix_stopped_item (tmp, tmp_map, op); 469 fix_stopped_item (tmp, tmp_map, op);
486 else 485 else
487 { 486 {
488 tmp = op->above; 487 tmp = op->above;
489 if (tmp) 488 if (tmp)
490 while (tmp->above) 489 while (tmp->above)
491 {
492 tmp = tmp->above; 490 tmp = tmp->above;
493 } 491
494 if (!tmp) 492 if (!tmp)
495 tmp = op->below; 493 tmp = op->below;
496 } 494 }
497 495
498 if (tmp == NULL) 496 if (tmp == NULL)
560 * so this function isn't named very good anymore. 558 * so this function isn't named very good anymore.
561 */ 559 */
562void 560void
563put_object_in_sack (object *op, object *sack, object *tmp, uint32 nrof) 561put_object_in_sack (object *op, object *sack, object *tmp, uint32 nrof)
564{ 562{
565 tag_t tmp_tag, tmp2_tag;
566 object *tmp2, *sack2; 563 object *tmp2, *sack2;
567 char buf[MAX_BUF]; 564 char buf[MAX_BUF];
568 565
569 if (sack == tmp) 566 if (sack == tmp)
570 return; /* Can't put an object in itself */ 567 return; /* Can't put an object in itself */
568
571 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 569 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP))
572 { 570 {
573 new_draw_info_format (NDI_UNIQUE, 0, op, "You cannot put the %s in the %s.", query_name (tmp), query_name (sack)); 571 new_draw_info_format (NDI_UNIQUE, 0, op, "You cannot put the %s in the %s.", query_name (tmp), query_name (sack));
574 return; 572 return;
575 } 573 }
574
576 if (tmp->type == CONTAINER && tmp->inv) 575 if (tmp->type == CONTAINER && tmp->inv)
577 { 576 {
578 577
579 /* Eneq(@csd.uu.se): If the object to be dropped is a container 578 /* Eneq(@csd.uu.se): If the object to be dropped is a container
580 * we instead move the contents of that container into the active 579 * we instead move the contents of that container into the active
581 * container, this is only done if the object has something in it. 580 * container, this is only done if the object has something in it.
582 */ 581 */
583 sack2 = tmp; 582 sack2 = tmp;
584 new_draw_info_format (NDI_UNIQUE, 0, op, "You move the items from %s into %s.", query_name (tmp), query_name (sack)); 583 new_draw_info_format (NDI_UNIQUE, 0, op, "You move the items from %s into %s.", query_name (tmp), query_name (sack));
584
585 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp) 585 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp)
586 { 586 {
587 tmp = tmp2->below; 587 tmp = tmp2->below;
588
588 if ((sack->type == CONTAINER && sack_can_hold (op, op->container, tmp2, tmp2->nrof))) 589 if ((sack->type == CONTAINER && sack_can_hold (op, op->container, tmp2, tmp2->nrof)))
589 { 590 {
590 put_object_in_sack (op, sack, tmp2, 0); 591 put_object_in_sack (op, sack, tmp2, 0);
591 } 592 }
592 else 593 else
594 sprintf (buf, "Your %s fills up.", query_name (sack)); 595 sprintf (buf, "Your %s fills up.", query_name (sack));
595 new_draw_info (NDI_UNIQUE, 0, op, buf); 596 new_draw_info (NDI_UNIQUE, 0, op, buf);
596 break; 597 break;
597 } 598 }
598 } 599 }
600
599 esrv_update_item (UPD_WEIGHT, op, sack2); 601 esrv_update_item (UPD_WEIGHT, op, sack2);
600 return; 602 return;
601 } 603 }
602 604
603 /* Don't worry about this for containers - our caller should have 605 /* Don't worry about this for containers - our caller should have
605 */ 607 */
606 if ((sack->type == CONTAINER) && !sack_can_hold (op, sack, tmp, (nrof ? nrof : tmp->nrof))) 608 if ((sack->type == CONTAINER) && !sack_can_hold (op, sack, tmp, (nrof ? nrof : tmp->nrof)))
607 return; 609 return;
608 610
609 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 611 if (QUERY_FLAG (tmp, FLAG_APPLIED))
610 {
611 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) 612 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
612 return; 613 return;
613 }
614 614
615 /* we want to put some portion of the item into the container */ 615 /* we want to put some portion of the item into the container */
616 if (nrof && tmp->nrof != nrof) 616 if (nrof && tmp->nrof != nrof)
617 { 617 {
618 object *tmp2 = tmp; 618 object *tmp2 = tmp;
619 619
620 tmp2_tag = tmp2->count;
621 tmp = get_split_ob (tmp, nrof); 620 tmp = get_split_ob (tmp, nrof);
622 621
623 if (!tmp) 622 if (!tmp)
624 { 623 {
625 new_draw_info (NDI_UNIQUE, 0, op, errmsg); 624 new_draw_info (NDI_UNIQUE, 0, op, errmsg);
626 return; 625 return;
627 } 626 }
628 /* Tell a client what happened other objects */ 627 /* Tell a client what happened other objects */
629 if (was_destroyed (tmp2, tmp2_tag)) 628 if (tmp2->destroyed ())
630 esrv_del_item (op->contr, tmp2_tag); 629 esrv_del_item (op->contr, tmp2->count);
631 else /* this can proably be replaced with an update */ 630 else /* this can proably be replaced with an update */
632 esrv_send_item (op, tmp2); 631 esrv_send_item (op, tmp2);
633 } 632 }
634 else 633 else
635 remove_ob (tmp); 634 tmp->remove ();
636 635
637 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack)); 636 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack));
638 tmp_tag = tmp->count;
639 tmp2 = insert_ob_in_ob (tmp, sack); 637 tmp2 = insert_ob_in_ob (tmp, sack);
640 fix_player (op); /* This is overkill, fix_player() is called somewhere */ 638 fix_player (op); /* This is overkill, fix_player() is called somewhere */
641 /* in object.c */ 639 /* in object.c */
642 640
643 /* If an object merged (and thus, different object), we need to 641 /* If an object merged (and thus, different object), we need to
644 * delete the original. 642 * delete the original.
645 */ 643 */
646 if (tmp2 != tmp) 644 if (tmp2 != tmp)
647 esrv_del_item (op->contr, tmp_tag); 645 esrv_del_item (op->contr, tmp->count);
648 646
649 esrv_send_item (op, tmp2); 647 esrv_send_item (op, tmp2);
650 648
651 /* update the sacks weight */ 649 /* update the sacks weight */
652 esrv_update_item (UPD_WEIGHT, op, sack); 650 esrv_update_item (UPD_WEIGHT, op, sack);
669 667
670 if (QUERY_FLAG (tmp, FLAG_APPLIED)) 668 if (QUERY_FLAG (tmp, FLAG_APPLIED))
671 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) 669 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
672 return; /* can't unapply it */ 670 return; /* can't unapply it */
673 671
674 /* We are only dropping some of the items. We split the current objec 672 /* We are only dropping some of the items. We split the current object
675 * off 673 * off
676 */ 674 */
677 if (nrof && tmp->nrof != nrof) 675 if (nrof && tmp->nrof != nrof)
678 { 676 {
679 object *tmp2 = tmp; 677 object *tmp2 = tmp;
680 tag_t tmp2_tag = tmp2->count;
681 678
682 tmp = get_split_ob (tmp, nrof); 679 tmp = get_split_ob (tmp, nrof);
683 if (!tmp) 680 if (!tmp)
684 { 681 {
685 new_draw_info (NDI_UNIQUE, 0, op, errmsg); 682 new_draw_info (NDI_UNIQUE, 0, op, errmsg);
688 /* Tell a client what happened rest of objects. tmp2 is now the 685 /* Tell a client what happened rest of objects. tmp2 is now the
689 * original object 686 * original object
690 */ 687 */
691 if (op->type == PLAYER) 688 if (op->type == PLAYER)
692 { 689 {
693 if (was_destroyed (tmp2, tmp2_tag)) 690 if (tmp2->destroyed ())
694 esrv_del_item (op->contr, tmp2_tag); 691 esrv_del_item (op->contr, tmp2->count);
695 else 692 else
696 esrv_send_item (op, tmp2); 693 esrv_send_item (op, tmp2);
697 } 694 }
698 } 695 }
699 else 696 else
700 remove_ob (tmp); 697 tmp->remove ();
701 698
702 if (INVOKE_OBJECT (DROP, tmp, ARG_OBJECT (op))) 699 if (INVOKE_OBJECT (DROP, tmp, ARG_OBJECT (op)))
703 return; 700 return;
704 701
705 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 702 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP))
707 sprintf (buf, "You drop the %s.", query_name (tmp)); 704 sprintf (buf, "You drop the %s.", query_name (tmp));
708 new_draw_info (NDI_UNIQUE, 0, op, buf); 705 new_draw_info (NDI_UNIQUE, 0, op, buf);
709 new_draw_info (NDI_UNIQUE, 0, op, "The gods who lent it to you retrieves it."); 706 new_draw_info (NDI_UNIQUE, 0, op, "The gods who lent it to you retrieves it.");
710 if (op->type == PLAYER) 707 if (op->type == PLAYER)
711 esrv_del_item (op->contr, tmp->count); 708 esrv_del_item (op->contr, tmp->count);
712 free_object (tmp); 709 tmp->destroy ();
713 fix_player (op); 710 fix_player (op);
714 return; 711 return;
715 } 712 }
716 713
717/* If SAVE_INTERVAL is commented out, we never want to save 714/* If SAVE_INTERVAL is commented out, we never want to save
773 if (tmp->env && tmp->env->type != PLAYER) 770 if (tmp->env && tmp->env->type != PLAYER)
774 { 771 {
775 /* Just toss the object - probably shouldn't be hanging 772 /* Just toss the object - probably shouldn't be hanging
776 * around anyways 773 * around anyways
777 */ 774 */
778 remove_ob (tmp); 775 tmp->remove ();
779 free_object (tmp); 776 tmp->destroy ();
780 return; 777 return;
781 } 778 }
782 else 779 else
783 { 780 {
784 while (tmp != NULL && tmp->invisible) 781 while (tmp != NULL && tmp->invisible)
933 nextinv = nextinv->below; 930 nextinv = nextinv->below;
934 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && !QUERY_FLAG (curinv, FLAG_APPLIED)) 931 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && !QUERY_FLAG (curinv, FLAG_APPLIED))
935 { 932 {
936 switch (curinv->type) 933 switch (curinv->type)
937 { 934 {
938 case HORN: 935 case HORN:
939 case BOOK: 936 case BOOK:
940 case SPELLBOOK: 937 case SPELLBOOK:
941 case GIRDLE: 938 case GIRDLE:
942 case AMULET: 939 case AMULET:
943 case RING: 940 case RING:
944 case CLOAK: 941 case CLOAK:
945 case BOOTS: 942 case BOOTS:
946 case GLOVES: 943 case GLOVES:
947 case BRACERS: 944 case BRACERS:
948 case SCROLL: 945 case SCROLL:
949 case ARMOUR_IMPROVER: 946 case ARMOUR_IMPROVER:
950 case WEAPON_IMPROVER: 947 case WEAPON_IMPROVER:
951 case WAND: 948 case WAND:
952 case ROD: 949 case ROD:
953 case POTION: 950 case POTION:
954 drop (op, curinv); 951 drop (op, curinv);
955 curinv = nextinv; 952 curinv = nextinv;
956 break; 953 break;
957 default: 954 default:
958 curinv = nextinv; 955 curinv = nextinv;
959 break; 956 break;
960 } 957 }
961 } 958 }
962 curinv = nextinv; 959 curinv = nextinv;
963 } 960 }
964 } 961 }
1044{ 1041{
1045 object *tmp; 1042 object *tmp;
1046 1043
1047 if (!op || !op->contr) 1044 if (!op || !op->contr)
1048 return NULL; 1045 return NULL;
1046
1049 if (!op->contr->mark) 1047 if (!op->contr->mark)
1050 { 1048 {
1051
1052/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/ 1049/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/
1053 return NULL; 1050 return 0;
1054 } 1051 }
1052
1055 /* This may seem like overkill, but we need to make sure that they 1053 /* This may seem like overkill, but we need to make sure that they
1056 * player hasn't dropped the item. We use count on the off chance that 1054 * player hasn't dropped the item. We use count on the off chance that
1057 * an item got reincarnated at some point. 1055 * an item got reincarnated at some point.
1058 */ 1056 */
1059 for (tmp = op->inv; tmp; tmp = tmp->below) 1057 for (tmp = op->inv; tmp; tmp = tmp->below)
1060 { 1058 {
1061 if (tmp->invisible) 1059 if (tmp->invisible)
1062 continue; 1060 continue;
1061
1063 if (tmp == op->contr->mark) 1062 if (tmp == op->contr->mark)
1064 { 1063 {
1065 if (tmp->count == op->contr->mark_count) 1064 if (!tmp->destroyed ())
1066 return tmp; 1065 return tmp;
1067 else 1066 else
1068 { 1067 {
1069 op->contr->mark = NULL; 1068 op->contr->mark = 0;
1070 op->contr->mark_count = 0;
1071
1072/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/ 1069/* new_draw_info(NDI_UNIQUE,0,op,"You have no marked object");*/
1073 return NULL; 1070 return 0;
1074 } 1071 }
1075 } 1072 }
1076 } 1073 }
1074
1077 return NULL; 1075 return 0;
1078} 1076}
1079 1077
1080 1078
1081/* op should be a player, params is any params. 1079/* op should be a player, params is any params.
1082 * If no params given, we print out the currently marked object. 1080 * If no params given, we print out the currently marked object.
1085int 1083int
1086command_mark (object *op, char *params) 1084command_mark (object *op, char *params)
1087{ 1085{
1088 if (!op->contr) 1086 if (!op->contr)
1089 return 1; 1087 return 1;
1088
1090 if (!params) 1089 if (!params)
1091 { 1090 {
1092 object *mark = find_marked_object (op); 1091 object *mark = find_marked_object (op);
1093 1092
1094 if (!mark) 1093 if (!mark)
1106 return 1; 1105 return 1;
1107 } 1106 }
1108 else 1107 else
1109 { 1108 {
1110 op->contr->mark = mark1; 1109 op->contr->mark = mark1;
1111 op->contr->mark_count = mark1->count;
1112 new_draw_info_format (NDI_UNIQUE, 0, op, "Marked item %s", query_name (mark1)); 1110 new_draw_info_format (NDI_UNIQUE, 0, op, "Marked item %s", query_name (mark1));
1113 return 0; 1111 return 0;
1114 } 1112 }
1115 } 1113 }
1114
1116 return 0; /*shouldnt get here */ 1115 return 0; /*shouldnt get here */
1117} 1116}
1118 1117
1119 1118
1120/* op is the player 1119/* op is the player
1139 /* Anyone know why this used to use the clone value instead of the 1138 /* Anyone know why this used to use the clone value instead of the
1140 * maxhp field? This seems that it should give more accurate results. 1139 * maxhp field? This seems that it should give more accurate results.
1141 */ 1140 */
1142 switch ((mon->stats.hp + 1) * 4 / (mon->stats.maxhp + 1)) 1141 switch ((mon->stats.hp + 1) * 4 / (mon->stats.maxhp + 1))
1143 { /* From 1-4 */ 1142 { /* From 1-4 */
1144 case 1: 1143 case 1:
1145 new_draw_info (NDI_UNIQUE, 0, op, "It is in a bad shape."); 1144 new_draw_info (NDI_UNIQUE, 0, op, "It is in a bad shape.");
1146 break; 1145 break;
1147 case 2: 1146 case 2:
1148 new_draw_info (NDI_UNIQUE, 0, op, "It is hurt."); 1147 new_draw_info (NDI_UNIQUE, 0, op, "It is hurt.");
1149 break; 1148 break;
1150 case 3: 1149 case 3:
1151 new_draw_info (NDI_UNIQUE, 0, op, "It is somewhat hurt."); 1150 new_draw_info (NDI_UNIQUE, 0, op, "It is somewhat hurt.");
1152 break; 1151 break;
1153 case 4: 1152 case 4:
1154 new_draw_info (NDI_UNIQUE, 0, op, "It is in excellent shape."); 1153 new_draw_info (NDI_UNIQUE, 0, op, "It is in excellent shape.");
1155 break; 1154 break;
1156 } 1155 }
1157 if (present_in_ob (POISONING, mon) != NULL) 1156 if (present_in_ob (POISONING, mon) != NULL)
1158 new_draw_info (NDI_UNIQUE, 0, op, "It looks very ill."); 1157 new_draw_info (NDI_UNIQUE, 0, op, "It looks very ill.");
1159} 1158}
1160 1159
1170 return ""; 1169 return "";
1171 1170
1172 buf[0] = '\0'; 1171 buf[0] = '\0';
1173 switch (tmp->type) 1172 switch (tmp->type)
1174 { 1173 {
1175 case RING: 1174 case RING:
1176 case SKILL: 1175 case SKILL:
1177 case WEAPON: 1176 case WEAPON:
1178 case ARMOUR: 1177 case ARMOUR:
1179 case BRACERS: 1178 case BRACERS:
1180 case HELMET: 1179 case HELMET:
1181 case SHIELD: 1180 case SHIELD:
1182 case BOOTS: 1181 case BOOTS:
1183 case GLOVES: 1182 case GLOVES:
1184 case AMULET: 1183 case AMULET:
1185 case GIRDLE: 1184 case GIRDLE:
1186 case BOW: 1185 case BOW:
1187 case ARROW: 1186 case ARROW:
1188 case CLOAK: 1187 case CLOAK:
1189 case FOOD: 1188 case FOOD:
1190 case DRINK: 1189 case DRINK:
1191 case FLESH: 1190 case FLESH:
1192 case SKILL_TOOL: 1191 case SKILL_TOOL:
1193 case POWER_CRYSTAL: 1192 case POWER_CRYSTAL:
1194 if (*(cp = describe_item (tmp, pl)) != '\0') 1193 if (*(cp = describe_item (tmp, pl)) != '\0')
1195 { 1194 {
1196 int len; 1195 int len;
1197 1196
1198 strncpy (buf, query_name (tmp), VERY_BIG_BUF - 1); 1197 assign (buf, query_name (tmp));
1199 buf[VERY_BIG_BUF - 1] = 0;
1200 len = strlen (buf); 1198 len = strlen (buf);
1201 if (len < VERY_BIG_BUF - 5) 1199 if (len < VERY_BIG_BUF - 5)
1202 { 1200 {
1203 /* Since we know the length, we save a few cpu cycles by using 1201 /* Since we know the length, we save a few cpu cycles by using
1204 * it instead of calling strcat */ 1202 * it instead of calling strcat */
1205 strcpy (buf + len, " "); 1203 strcpy (buf + len, " ");
1206 len++; 1204 len++;
1207 strncpy (buf + len, cp, VERY_BIG_BUF - len - 1); 1205 assign (buf + len, cp, VERY_BIG_BUF - len - 1);
1208 buf[VERY_BIG_BUF - 1] = 0;
1209 } 1206 }
1210 } 1207 }
1211 } 1208 }
1209
1212 if (buf[0] == '\0') 1210 if (buf[0] == '\0')
1213 { 1211 assign (buf, query_name (tmp));
1214 strncpy (buf, query_name (tmp), VERY_BIG_BUF - 1);
1215 buf[VERY_BIG_BUF - 1] = 0;
1216 }
1217 1212
1218 return buf; 1213 return buf;
1219} 1214}
1220 1215
1221void 1216void
1243 buf[0] = '\0'; 1238 buf[0] = '\0';
1244 } 1239 }
1245 1240
1246 switch (tmp->type) 1241 switch (tmp->type)
1247 { 1242 {
1248 case SPELLBOOK: 1243 case SPELLBOOK:
1249 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) && tmp->inv) 1244 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) && tmp->inv)
1250 { 1245 {
1251 sprintf (buf, "%s is a %s level %s spell", &tmp->inv->name, get_levelnumber (tmp->inv->level), &tmp->inv->skill); 1246 sprintf (buf, "%s is a %s level %s spell", &tmp->inv->name, get_levelnumber (tmp->inv->level), &tmp->inv->skill);
1252 } 1247 }
1253 break; 1248 break;
1254 1249
1255 case BOOK: 1250 case BOOK:
1256 if (tmp->msg != NULL) 1251 if (tmp->msg != NULL)
1257 strcpy (buf, "Something is written in it."); 1252 strcpy (buf, "Something is written in it.");
1258 break; 1253 break;
1259 1254
1260 case CONTAINER: 1255 case CONTAINER:
1261 if (tmp->race != NULL) 1256 if (tmp->race != NULL)
1262 { 1257 {
1263 if (tmp->weight_limit && tmp->stats.Str < 100) 1258 if (tmp->weight_limit && tmp->stats.Str < 100)
1264 sprintf (buf, "It can hold only %s and its weight limit is %.1f kg.", 1259 sprintf (buf, "It can hold only %s and its weight limit is %.1f kg.",
1265 &tmp->race, tmp->weight_limit / (10.0 * (100 - tmp->stats.Str))); 1260 &tmp->race, tmp->weight_limit / (10.0 * (100 - tmp->stats.Str)));
1266 else 1261 else
1267 sprintf (buf, "It can hold only %s.", &tmp->race); 1262 sprintf (buf, "It can hold only %s.", &tmp->race);
1268 } 1263 }
1269 else if (tmp->weight_limit && tmp->stats.Str < 100) 1264 else if (tmp->weight_limit && tmp->stats.Str < 100)
1270 sprintf (buf, "Its weight limit is %.1f kg.", tmp->weight_limit / (10.0 * (100 - tmp->stats.Str))); 1265 sprintf (buf, "Its weight limit is %.1f kg.", tmp->weight_limit / (10.0 * (100 - tmp->stats.Str)));
1271 break; 1266 break;
1272 1267
1273 case WAND: 1268 case WAND:
1274 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED)) 1269 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED))
1275 sprintf (buf, "It has %d charges left.", tmp->stats.food); 1270 sprintf (buf, "It has %d charges left.", tmp->stats.food);
1276 break; 1271 break;
1277 } 1272 }
1278 1273
1279 if (buf[0] != '\0') 1274 if (buf[0] != '\0')
1280 new_draw_info (NDI_UNIQUE, 0, op, buf); 1275 new_draw_info (NDI_UNIQUE, 0, op, buf);
1281 1276
1457 new_draw_info_format (NDI_UNIQUE, 0, op, "%d MAGICDEVICE", i & PU_MAGIC_DEVICE ? 1 : 0); 1452 new_draw_info_format (NDI_UNIQUE, 0, op, "%d MAGICDEVICE", i & PU_MAGIC_DEVICE ? 1 : 0);
1458 1453
1459 new_draw_info_format (NDI_UNIQUE, 0, op, "%d NOT CURSED", i & PU_NOT_CURSED ? 1 : 0); 1454 new_draw_info_format (NDI_UNIQUE, 0, op, "%d NOT CURSED", i & PU_NOT_CURSED ? 1 : 0);
1460 1455
1461 new_draw_info_format (NDI_UNIQUE, 0, op, "%d JEWELS", i & PU_JEWELS ? 1 : 0); 1456 new_draw_info_format (NDI_UNIQUE, 0, op, "%d JEWELS", i & PU_JEWELS ? 1 : 0);
1457 new_draw_info_format (NDI_UNIQUE, 0, op, "%d FLESH", i & PU_FLESH ? 1 : 0);
1462 1458
1463 new_draw_info_format (NDI_UNIQUE, 0, op, ""); 1459 new_draw_info_format (NDI_UNIQUE, 0, op, "");
1464} 1460}
1465 1461
1466int 1462int
1468{ 1464{
1469 uint32 i; 1465 uint32 i;
1470 static const char *names[] = { 1466 static const char *names[] = {
1471 "debug", "inhibit", "stop", "food", "drink", "valuables", "bow", "arrow", "helmet", 1467 "debug", "inhibit", "stop", "food", "drink", "valuables", "bow", "arrow", "helmet",
1472 "shield", "armour", "boots", "gloves", "cloak", "key", "missile", "allweapon", 1468 "shield", "armour", "boots", "gloves", "cloak", "key", "missile", "allweapon",
1473 "magical", "potion", "spellbook", "skillscroll", "readables", "magicdevice", "notcursed", "jewels", NULL 1469 "magical", "potion", "spellbook", "skillscroll", "readables", "magicdevice", "notcursed",
1470 "jewels", "flesh", NULL
1474 }; 1471 };
1475 static uint32 modes[] = { 1472 static uint32 modes[] = {
1476 PU_DEBUG, PU_INHIBIT, PU_STOP, PU_FOOD, PU_DRINK, PU_VALUABLES, PU_BOW, PU_ARROW, PU_HELMET, 1473 PU_DEBUG, PU_INHIBIT, PU_STOP, PU_FOOD, PU_DRINK, PU_VALUABLES, PU_BOW, PU_ARROW, PU_HELMET,
1477 PU_SHIELD, PU_ARMOUR, PU_BOOTS, PU_GLOVES, PU_CLOAK, PU_KEY, PU_MISSILEWEAPON, PU_ALLWEAPON, 1474 PU_SHIELD, PU_ARMOUR, PU_BOOTS, PU_GLOVES, PU_CLOAK, PU_KEY, PU_MISSILEWEAPON, PU_ALLWEAPON,
1478 PU_MAGICAL, PU_POTION, PU_SPELLBOOK, PU_SKILLSCROLL, PU_READABLES, PU_MAGIC_DEVICE, PU_NOT_CURSED, PU_JEWELS, 0 1475 PU_MAGICAL, PU_POTION, PU_SPELLBOOK, PU_SKILLSCROLL, PU_READABLES, PU_MAGIC_DEVICE, PU_NOT_CURSED,
1476 PU_JEWELS, PU_FLESH, 0
1479 }; 1477 };
1480 1478
1481 if (!params) 1479 if (!params)
1482 { 1480 {
1483 /* if the new mode is used, just print the settings */ 1481 /* if the new mode is used, just print the settings */
1534void 1532void
1535set_pickup_mode (object *op, int i) 1533set_pickup_mode (object *op, int i)
1536{ 1534{
1537 switch (op->contr->mode = i) 1535 switch (op->contr->mode = i)
1538 { 1536 {
1539 case 0: 1537 case 0:
1540 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Don't pick up."); 1538 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Don't pick up.");
1541 break; 1539 break;
1542 case 1: 1540 case 1:
1543 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up one item."); 1541 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up one item.");
1544 break; 1542 break;
1545 case 2: 1543 case 2:
1546 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up one item and stop."); 1544 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up one item and stop.");
1547 break; 1545 break;
1548 case 3: 1546 case 3:
1549 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Stop before picking up."); 1547 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Stop before picking up.");
1550 break; 1548 break;
1551 case 4: 1549 case 4:
1552 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all items."); 1550 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all items.");
1553 break; 1551 break;
1554 case 5: 1552 case 5:
1555 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all items and stop."); 1553 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all items and stop.");
1556 break; 1554 break;
1557 case 6: 1555 case 6:
1558 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all magic items."); 1556 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all magic items.");
1559 break; 1557 break;
1560 case 7: 1558 case 7:
1561 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all coins and gems"); 1559 new_draw_info (NDI_UNIQUE, 0, op, "Mode: Pick up all coins and gems");
1562 break; 1560 break;
1563 } 1561 }
1564} 1562}
1565 1563
1566int 1564int
1567command_search_items (object *op, char *params) 1565command_search_items (object *op, char *params)
1595 new_draw_info (NDI_UNIQUE, 0, op, buf); 1593 new_draw_info (NDI_UNIQUE, 0, op, buf);
1596 fix_player (op); 1594 fix_player (op);
1597 return 1; 1595 return 1;
1598} 1596}
1599 1597
1600/*
1601 * Changing the custom name of an item
1602 *
1603 * Syntax is: rename <what object> to <new name>
1604 * if '<what object>' is omitted, marked object is used
1605 * if 'to <new name>' is omitted, custom name is cleared
1606 *
1607 * Names are considered for all purpose having a length <=127 (max length sent to client
1608 * by server) */
1609
1610int
1611command_rename_item (object *op, char *params)
1612{
1613 char buf[VERY_BIG_BUF];
1614 int itemnumber;
1615 object *item = NULL;
1616 char *closebrace;
1617 size_t counter;
1618
1619 if (params)
1620 {
1621 /* Let's skip white spaces */
1622 while (' ' == *params)
1623 params++;
1624
1625 /* Checking the first part */
1626 if ((itemnumber = atoi (params)) != 0)
1627 {
1628 for (item = op->inv; item && ((item->count != (tag_t) itemnumber) || item->invisible); item = item->below);
1629 if (!item)
1630 {
1631 new_draw_info (NDI_UNIQUE, 0, op, "Tried to rename an invalid item.");
1632 return 1;
1633 }
1634 while (isdigit (*params) || ' ' == *params)
1635 params++;
1636 }
1637 else if ('<' == *params)
1638 {
1639 /* Got old name, let's get it & find appropriate matching item */
1640 closebrace = strchr (params, '>');
1641 if (!closebrace)
1642 {
1643 new_draw_info (NDI_UNIQUE, 0, op, "Syntax error!");
1644 return 1;
1645 }
1646 /* Sanity check for buffer overruns */
1647 if ((closebrace - params) > 127)
1648 {
1649 new_draw_info (NDI_UNIQUE, 0, op, "Old name too long (up to 127 characters allowed)!");
1650 return 1;
1651 }
1652 /* Copy the old name */
1653 strncpy (buf, params + 1, closebrace - params - 1);
1654 buf[closebrace - params - 1] = '\0';
1655
1656 /* Find best matching item */
1657 item = find_best_object_match (op, buf);
1658 if (!item)
1659 {
1660 new_draw_info (NDI_UNIQUE, 0, op, "Could not find a matching item to rename.");
1661 return 1;
1662 }
1663
1664 /* Now need to move pointer to just after > */
1665 params = closebrace + 1;
1666 while (' ' == *params)
1667 params++;
1668
1669 }
1670 else
1671 {
1672 /* Use marked item */
1673 item = find_marked_object (op);
1674 if (!item)
1675 {
1676 new_draw_info (NDI_UNIQUE, 0, op, "No marked item to rename.");
1677 return 1;
1678 }
1679 }
1680
1681 /* Now let's find the new name */
1682 if (!strncmp (params, "to ", 3))
1683 {
1684 params += 3;
1685 while (' ' == *params)
1686 params++;
1687 if ('<' != *params)
1688 {
1689 new_draw_info (NDI_UNIQUE, 0, op, "Syntax error, expecting < at start of new name!");
1690 return 1;
1691 }
1692 closebrace = strchr (params + 1, '>');
1693 if (!closebrace)
1694 {
1695 new_draw_info (NDI_UNIQUE, 0, op, "Syntax error, expecting > at end of new name!");
1696 return 1;
1697 }
1698
1699 /* Sanity check for buffer overruns */
1700 if ((closebrace - params) > 127)
1701 {
1702 new_draw_info (NDI_UNIQUE, 0, op, "New name too long (up to 127 characters allowed)!");
1703 return 1;
1704 }
1705
1706 /* Copy the new name */
1707 strncpy (buf, params + 1, closebrace - params - 1);
1708 buf[closebrace - params - 1] = '\0';
1709
1710 /* Let's check it for weird characters */
1711 for (counter = 0; counter < strlen (buf); counter++)
1712 {
1713 if (isalnum (buf[counter]))
1714 continue;
1715 if (' ' == buf[counter])
1716 continue;
1717 if ('\'' == buf[counter])
1718 continue;
1719 if ('+' == buf[counter])
1720 continue;
1721 if ('_' == buf[counter])
1722 continue;
1723 if ('-' == buf[counter])
1724 continue;
1725
1726 /* If we come here, then the name contains an invalid character...
1727 tell the player & exit */
1728 new_draw_info (NDI_UNIQUE, 0, op, "Invalid new name!");
1729 return 1;
1730 }
1731
1732 }
1733 else
1734 {
1735 /* If param contains something, then syntax error... */
1736 if (strlen (params))
1737 {
1738 new_draw_info (NDI_UNIQUE, 0, op, "Syntax error, expected 'to <' after old name!");
1739 return 1;
1740 }
1741 /* New name is empty */
1742 buf[0] = '\0';
1743 }
1744 }
1745 else
1746 {
1747 /* Last case: params==NULL */
1748 item = find_marked_object (op);
1749 if (!item)
1750 {
1751 new_draw_info (NDI_UNIQUE, 0, op, "No marked item to rename.");
1752 return 1;
1753 }
1754 buf[0] = '\0';
1755 }
1756
1757 if (QUERY_FLAG (item, FLAG_UNPAID))
1758 {
1759 new_draw_info (NDI_UNIQUE, 0, op, "You can't rename an unpaid item! You should pay for it first.");
1760 return 1;
1761 }
1762
1763 /* Coming here, everything is fine... */
1764 if (!strlen (buf))
1765 {
1766 /* Clear custom name */
1767 if (item->custom_name)
1768 {
1769 item->custom_name = 0;
1770
1771 new_draw_info_format (NDI_UNIQUE, 0, op, "You stop calling your %s with weird names.",
1772 query_base_name (item, item->nrof > 1 ? 1 : 0));
1773 esrv_update_item (UPD_NAME, op, item);
1774 }
1775 else
1776 {
1777 new_draw_info (NDI_UNIQUE, 0, op, "This item has no custom name.");
1778 }
1779 }
1780 else
1781 {
1782 /* Set custom name */
1783 item->custom_name = buf;
1784
1785 new_draw_info_format (NDI_UNIQUE, 0, op, "Your %s will now be called %s.", query_base_name (item, item->nrof > 1 ? 1 : 0), buf);
1786 esrv_update_item (UPD_NAME, op, item);
1787 }
1788
1789 return 1;
1790}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines