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.89 by elmex, Mon Jan 12 00:17:23 2009 UTC vs.
Revision 1.109 by root, Sat Jan 16 13:41:37 2010 UTC

1/* 1/*
2 * This file is part of Deliantra, the Roguelike Realtime MMORPG. 2 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 * 3 *
4 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4 * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team 5 * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
6 * Copyright (©) 1992,2007 Frank Tore Johansen 6 * Copyright (©) 1992,2007 Frank Tore Johansen
7 * 7 *
8 * Deliantra is free software: you can redistribute it and/or modify 8 * Deliantra is free software: you can redistribute it and/or modify it under
9 * it under the terms of the GNU General Public License as published by 9 * the terms of the Affero GNU General Public License as published by the
10 * the Free Software Foundation, either version 3 of the License, or 10 * Free Software Foundation, either version 3 of the License, or (at your
11 * (at your option) any later version. 11 * option) any later version.
12 * 12 *
13 * 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,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the Affero GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 * and the GNU General Public License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
20 * 21 *
21 * The authors can be reached via e-mail to <support@deliantra.net> 22 * The authors can be reached via e-mail to <support@deliantra.net>
22 */ 23 */
23 24
24/* 25/*
25 * Object (handling) commands 26 * Object (handling) commands
26 */ 27 */
27 28
28#include <global.h> 29#include <global.h>
29#include <loader.h>
30#include <skills.h> 30#include <skills.h>
31#include <sproto.h> 31#include <sproto.h>
32#include <living.h> 32#include <living.h>
33#include <math.h>
34 33
35/* 34/*
36 * Object id parsing functions 35 * Object id parsing functions
37 */ 36 */
38 37
225 return 0; 224 return 0;
226 } 225 }
227 226
228 if (sack->race && (sack->race != op->race || op->type == CONTAINER || (sack->stats.food && sack->stats.food != op->type))) 227 if (sack->race && (sack->race != op->race || op->type == CONTAINER || (sack->stats.food && sack->stats.food != op->type)))
229 { 228 {
230 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can put only %s into the %s.", &sack->race, query_name (sack)); 229 new_draw_info_format (NDI_UNIQUE, 0, pl, "You can only put objects of type '%s' into the %s.", &sack->race, query_name (sack));
231 return 0; 230 return 0;
232 } 231 }
233 232
234 if (op->type == SPECIAL_KEY && sack->slaying && op->slaying) 233 if (op->type == SPECIAL_KEY && sack->slaying && op->slaying)
235 { 234 {
361 count = tmp->nrof; 360 count = tmp->nrof;
362 361
363 /* container is open, so use it */ 362 /* container is open, so use it */
364 if (tmp->flag [FLAG_STARTEQUIP]) 363 if (tmp->flag [FLAG_STARTEQUIP])
365 alt = op; 364 alt = op;
366 else if (op->container) 365 else if ((alt = op->container_ ()))
367 { 366 {
368 alt = op->container;
369 if (alt != tmp->env && !sack_can_hold (op, alt, tmp, count)) 367 if (alt != tmp->env && !sack_can_hold (op, alt, tmp, count))
370 goto leave; 368 goto leave;
371 } 369 }
372 else 370 else
373 { /* non container pickup */ 371 { /* non container pickup */
427int 425int
428command_take (object *op, char *params) 426command_take (object *op, char *params)
429{ 427{
430 object *tmp, *next; 428 object *tmp, *next;
431 429
432 if (op->container) 430 if (op->container_ ())
433 tmp = op->container->inv; 431 tmp = op->container_ ()->inv;
434 else 432 else
435 { 433 {
436 tmp = op->above; 434 tmp = op->above;
437 if (tmp) 435 if (tmp)
438 while (tmp->above) 436 while (tmp->above)
450 448
451 /* Makes processing easier */ 449 /* Makes processing easier */
452 if (params && *params == '\0') 450 if (params && *params == '\0')
453 params = 0; 451 params = 0;
454 452
455 int cnt = MAX_ITEM_PER_DROP; 453 int cnt = MAX_ITEM_PER_ACTION;
456 454
457 while (tmp) 455 while (tmp)
458 { 456 {
459 next = tmp->below; 457 next = tmp->below;
460 458
520 char buf[MAX_BUF]; 518 char buf[MAX_BUF];
521 519
522 if (sack == tmp) 520 if (sack == tmp)
523 return; /* Can't put an object in itself */ 521 return; /* Can't put an object in itself */
524 522
525 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP)) 523 if (QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_DROP))
526 { 524 {
527 new_draw_info_format (NDI_UNIQUE, 0, op, "You cannot put the %s in the %s.", query_name (tmp), query_name (sack)); 525 new_draw_info_format (NDI_UNIQUE, 0, op, "You cannot put the %s in the %s.", query_name (tmp), query_name (sack));
528 return; 526 return;
529 } 527 }
530 528
539 537
540 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp) 538 for (tmp2 = tmp->inv; tmp2; tmp2 = tmp)
541 { 539 {
542 tmp = tmp2->below; 540 tmp = tmp2->below;
543 541
544 if ((sack->type == CONTAINER && sack_can_hold (op, op->container, tmp2, tmp2->nrof))) 542 if ((sack->type == CONTAINER && sack_can_hold (op, op->container_ (), tmp2, tmp2->nrof)))
545 put_object_in_sack (op, sack, tmp2, 0); 543 put_object_in_sack (op, sack, tmp2, 0);
546 else 544 else
547 { 545 {
548 sprintf (buf, "Your %s fills up.", query_name (sack)); 546 sprintf (buf, "Your %s fills up.", query_name (sack));
549 new_draw_info (NDI_UNIQUE, 0, op, buf); 547 new_draw_info (NDI_UNIQUE, 0, op, buf);
568 if (!can_split (op, tmp, nrof)) 566 if (!can_split (op, tmp, nrof))
569 return; 567 return;
570 568
571 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack)); 569 new_draw_info_format (NDI_UNIQUE, 0, op, "You put the %s in %s.", query_name (tmp), query_name (sack));
572 sack->insert (tmp); 570 sack->insert (tmp);
573}
574
575/*
576 * This function was part of drop, now is own function.
577 * Player 'op' tries to drop object 'tmp', if tmp is non zero, then
578 * nrof objects is tried to dropped.
579 * This is used when dropping objects onto the floor.
580 */
581void
582drop_object (object *op, object *tmp, uint32 nrof)
583{
584 if (QUERY_FLAG (tmp, FLAG_NO_DROP))
585 return;
586
587 if (QUERY_FLAG (tmp, FLAG_APPLIED))
588 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
589 return; /* can't unapply it */
590
591 //fprintf (stderr, "ui, on space is %ld\n", op->ms ().volume ());//D
592
593 /* We are only dropping some of the items. We split the current object
594 * off
595 */
596 if (!can_split (op, tmp, nrof))
597 return;
598
599 drop_object (op, tmp);
600
601 if (!tmp->destroyed () && !tmp->is_inserted ())
602 {
603 // if nothing happened with the object we give it back
604 op->insert (tmp);
605 }
606} 571}
607 572
608/* In contrast to drop_object (op, tmp, nrof) above this function takes the 573/* In contrast to drop_object (op, tmp, nrof) above this function takes the
609 * already split off object, and feeds it to the event handlers and does 574 * already split off object, and feeds it to the event handlers and does
610 * other magic with it. 575 * other magic with it.
613 * object that was dropped. 578 * object that was dropped.
614 * 579 *
615 * Make sure to check what happened with <obj> after this function returns! 580 * Make sure to check what happened with <obj> after this function returns!
616 * Otherwise you may leak this object. 581 * Otherwise you may leak this object.
617 */ 582 */
618
619void 583void
620drop_object (object *dropper, object *obj) 584drop_object (object *dropper, object *obj)
621{ 585{
622 if (INVOKE_OBJECT (DROP, obj, ARG_OBJECT (dropper))) 586 if (INVOKE_OBJECT (DROP, obj, ARG_OBJECT (dropper)))
623 return; 587 return;
646 610
647 if (is_in_shop (dropper) && !QUERY_FLAG (obj, FLAG_UNPAID) && obj->type != MONEY) 611 if (is_in_shop (dropper) && !QUERY_FLAG (obj, FLAG_UNPAID) && obj->type != MONEY)
648 if (!sell_item (obj, dropper)) 612 if (!sell_item (obj, dropper))
649 return; 613 return;
650 614
615 if (!obj->can_drop_at (dropper->map, dropper->x, dropper->y, dropper))
616 return;
617
651 /* If nothing special happened with this object, the default action is to 618 /* If nothing special happened with this object, the default action is to
652 * insert it below the dropper: 619 * insert it below the dropper:
653 */ 620 */
654 621
655 obj->x = dropper->x; 622 obj->x = dropper->x;
656 obj->y = dropper->y; 623 obj->y = dropper->y;
657 624
658 insert_ob_in_map (obj, dropper->map, dropper, INS_BELOW_ORIGINATOR); 625 insert_ob_in_map (obj, dropper->map, dropper, INS_BELOW_ORIGINATOR);
626}
627
628/*
629 * This function was part of drop, now is own function.
630 * Player 'op' tries to drop object 'tmp', if tmp is non zero, then
631 * nrof objects are tried to drop.
632 * This is used when dropping objects onto the floor.
633 */
634void
635drop_object (object *op, object *tmp, uint32 nrof)
636{
637 if (QUERY_FLAG (tmp, FLAG_NO_DROP))
638 return;
639
640 if (QUERY_FLAG (tmp, FLAG_APPLIED))
641 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
642 return; /* can't unapply it */
643
644 /* We are only dropping some of the items. We split the current object
645 * off
646 */
647 if (!can_split (op, tmp, nrof))
648 return;
649
650 drop_object (op, tmp);
651
652 if (!tmp->destroyed () && !tmp->is_inserted ())
653 {
654 // if nothing happened with the object we give it back
655 op->insert (tmp);
656 }
659} 657}
660 658
661void 659void
662drop (object *op, object *tmp) 660drop (object *op, object *tmp)
663{ 661{
676 */ 674 */
677 tmp->destroy (); 675 tmp->destroy ();
678 return; 676 return;
679 } 677 }
680 else 678 else
681 {
682 while (tmp && tmp->invisible) 679 while (tmp && tmp->invisible)
683 tmp = tmp->below; 680 tmp = tmp->below;
684 }
685 } 681 }
686 682
687 if (tmp == NULL) 683 if (!tmp)
688 { 684 {
689 new_draw_info (NDI_UNIQUE, 0, op, "You don't have anything to drop."); 685 new_draw_info (NDI_UNIQUE, 0, op, "You don't have anything to drop.");
690 return; 686 return;
691 } 687 }
692 688
706 } 702 }
707 703
708 if (op->type == PLAYER && op->contr->last_used == tmp) 704 if (op->type == PLAYER && op->contr->last_used == tmp)
709 op->contr->last_used = tmp->below ? tmp->below 705 op->contr->last_used = tmp->below ? tmp->below
710 : tmp->above ? tmp->above 706 : tmp->above ? tmp->above
711 : 0; 707 : (object *)0;
712 708
713 if (op->container) 709 if (op->container_ ())
714 { 710 {
715 if (op->type == PLAYER) 711 if (op->type == PLAYER)
716 put_object_in_sack (op, op->container, tmp, op->contr->count); 712 put_object_in_sack (op, op->container_ (), tmp, op->contr->count);
717 else 713 else
718 put_object_in_sack (op, op->container, tmp, 0); 714 put_object_in_sack (op, op->container_ (), tmp, 0);
719 } 715 }
720 else 716 else
721 { 717 {
722 if (op->type == PLAYER) 718 if (op->type == PLAYER)
723 drop_object (op, tmp, op->contr->count); 719 drop_object (op, tmp, op->contr->count);
750 /* 746 /*
751 Care must be taken that the next item pointer is not to money as 747 Care must be taken that the next item pointer is not to money as
752 the drop() routine will do unknown things to it when dropping 748 the drop() routine will do unknown things to it when dropping
753 in a shop. --Tero.Pelander@utu.fi 749 in a shop. --Tero.Pelander@utu.fi
754 */ 750 */
755
756 int cnt = MAX_ITEM_PER_DROP; 751 int cnt = MAX_ITEM_PER_ACTION;
757 752
758 if (!params) 753 if (!params)
759 { 754 {
760 while (curinv) 755 while (curinv)
761 { 756 {
762 nextinv = curinv->below; 757 nextinv = curinv->below;
763 758
764 while (nextinv && nextinv->type == MONEY) 759 while (nextinv && nextinv->type == MONEY)
765 nextinv = nextinv->below; 760 nextinv = nextinv->below;
766 761
767 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED) && curinv->type != MONEY && 762 if (!QUERY_FLAG (curinv, FLAG_INV_LOCKED)
768 curinv->type != FOOD && curinv->type != KEY && 763 && curinv->type != MONEY
769 curinv->type != SPECIAL_KEY && curinv->type != GEM && 764 && curinv->type != FOOD
765 && curinv->type != KEY
766 && curinv->type != SPECIAL_KEY
767 && curinv->type != GEM
768 && !curinv->invisible
770 !curinv->invisible && (curinv->type != CONTAINER || op->container != curinv)) 769 && (curinv->type != CONTAINER || op->container_ () != curinv))
771 { 770 {
772 drop (op, curinv); 771 drop (op, curinv);
773 if (--cnt <= 0) break; 772 if (--cnt <= 0) break;
774 } 773 }
775 774
869 * <cnt> can be a 0 pointer or a pointer to the maximum number of 868 * <cnt> can be a 0 pointer or a pointer to the maximum number of
870 * drop operations to perform. 869 * drop operations to perform.
871 * 870 *
872 * Returns true if at least one item was dropped. 871 * Returns true if at least one item was dropped.
873 */ 872 */
874bool 873static bool
875drop_vector (object *dropper, vector<object *> &objs, int *cnt) 874drop_vector (object *dropper, vector<object *> &objs, int *cnt)
876{ 875{
877 vector<object *>::iterator i; 876 vector<object *>::iterator i;
878 877
879 bool did_one = false; 878 bool did_one = false;
914 913
915 if (item_matched_string (op, tmp, params)) 914 if (item_matched_string (op, tmp, params))
916 matched_objs.push_back (tmp); 915 matched_objs.push_back (tmp);
917 } 916 }
918 917
919 int cnt = MAX_ITEM_PER_DROP; 918 int cnt = MAX_ITEM_PER_ACTION;
920 919
921 if (!drop_vector (op, matched_objs, &cnt)) 920 if (!drop_vector (op, matched_objs, &cnt))
922 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to drop."); 921 new_draw_info (NDI_UNIQUE, 0, op, "Nothing to drop.");
923 922
924 if (cnt <= 0) 923 if (cnt <= 0)
1103examine_monster (object *op, object *tmp) 1102examine_monster (object *op, object *tmp)
1104{ 1103{
1105 new_draw_info (NDI_UNIQUE, 0, op, tmp->describe_monster (op).c_str ()); 1104 new_draw_info (NDI_UNIQUE, 0, op, tmp->describe_monster (op).c_str ());
1106} 1105}
1107 1106
1107static void
1108describe_dump_object (dynbuf &buf, object *ob)
1109{
1110 char *txt = dump_object (ob);
1111 for (char *p = txt; *p; ++p) if (*p == '\n') *p = '\r';
1112 buf << "\n" << txt << "\n";
1113
1114 if (!ob->is_arch ())
1115 describe_dump_object (buf, ob->arch);
1116}
1117
1108std::string 1118std::string
1109object::describe (object *who) 1119object::describe (object *who)
1110{ 1120{
1111 dynbuf_text buf (1024, 1024); 1121 dynbuf_text buf (1024, 1024);
1112 1122
1144 if (flag [FLAG_IDENTIFIED]) 1154 if (flag [FLAG_IDENTIFIED])
1145 buf.printf ("It has %d charges left.\r", stats.food); 1155 buf.printf ("It has %d charges left.\r", stats.food);
1146 break; 1156 break;
1147 } 1157 }
1148 1158
1149 if (materialname && !msg) 1159 if (material != MATERIAL_NULL && !msg)
1150 buf.printf ("It is made of: %s.\r", &materialname); 1160 buf << (nrof > 1 ? "They are made of " : "It is made of ")
1161 << material->description
1162 << ".\r";
1151 1163
1152 if (who) 1164 if (who)
1153 /* Where to wear this item */ 1165 /* Where to wear this item */
1154 for (int i = 0; i < NUM_BODY_LOCATIONS; i++) 1166 for (int i = 0; i < NUM_BODY_LOCATIONS; i++)
1155 if (slot[i].info) 1167 if (slot[i].info)
1163 } 1175 }
1164 1176
1165 if (weight) 1177 if (weight)
1166 buf.printf ("%s %3.3f kg.\r", nrof > 1 ? "They weigh" : "It weighs", weight * (nrof ? nrof : 1) / 1000.0); 1178 buf.printf ("%s %3.3f kg.\r", nrof > 1 ? "They weigh" : "It weighs", weight * (nrof ? nrof : 1) / 1000.0);
1167 1179
1180 if (flag [FLAG_STARTEQUIP])
1181 buf << (nrof > 1 ? "They were" : "It was")
1182 << " given by a god and will vanish when dropped.\r";
1183
1168 if (value && !flag [FLAG_STARTEQUIP] && !flag [FLAG_NO_PICK] && who) 1184 if (value && !flag [FLAG_STARTEQUIP] && !flag [FLAG_NO_PICK] && who)
1169 { 1185 {
1170 buf.printf ("You reckon %s worth %s.\r", nrof > 1 ? "they are" : "it is", query_cost_string (this, who, F_TRUE | F_APPROX)); 1186 buf.printf ("You reckon %s worth %s.\r", nrof > 1 ? "they are" : "it is", query_cost_string (this, who, F_TRUE | F_APPROX));
1171 1187
1172 if (is_in_shop (who)) 1188 if (is_in_shop (who))
1186 buf << "This is a buildable item.\r"; 1202 buf << "This is a buildable item.\r";
1187 1203
1188 /* Does the object have a message? Don't show message for all object 1204 /* Does the object have a message? Don't show message for all object
1189 * types - especially if the first entry is a match 1205 * types - especially if the first entry is a match
1190 */ 1206 */
1207 if (msg)
1208 {
1191 if (msg && type != EXIT && type != BOOK && type != CORPSE && !move_on && !has_dialogue ()) 1209 if (type != EXIT && type != BOOK && type != CORPSE && !move_on && !has_dialogue ())
1192 { 1210 {
1211 buf << '\r';
1212
1193 /* This is just a hack so when identifying the items, we print 1213 /* This is just a hack so when identifying the items, we print
1194 * out the extra message 1214 * out the extra message
1195 */ 1215 */
1196 if (need_identify (this) && flag [FLAG_IDENTIFIED]) 1216 if (need_identify (this) && flag [FLAG_IDENTIFIED])
1197 buf << "The object has a story:\r"; 1217 buf << "The object has a story:\r";
1198 1218
1199 buf << msg << '\n'; 1219 buf << msg << '\n';
1220 }
1221 }
1222 else if (inv && inv->type == SPELL && flag [FLAG_IDENTIFIED]
1223 && (type == SPELLBOOK || type == ROD || type == WAND
1224 || type == ROD || type == POTION || type == SCROLL))
1225 // for spellbooks and other stuff that contains spells, print the spell message,
1226 // unless the object has a custom message handled above.
1227 buf << '\r' << inv->msg << '\n';
1228
1229 // try to display the duration for some potions and scrolls
1230 // this includes change ability potions and group spells,
1231 // but does not handle protection potions
1232 if (inv && inv->type == SPELL && flag [FLAG_IDENTIFIED]
1233 && (type == POTION || type == SCROLL))
1234 {
1235 object *spell = inv;
1236
1237 if (spell->subtype == SP_PARTY_SPELL)
1238 spell = spell->other_arch;
1239
1240 if (spell->subtype == SP_CHANGE_ABILITY)
1241 buf.printf ("\nH<The effect will last about %.10g seconds.>",
1242 TICK2TIME (change_ability_duration (spell, this)));
1243 }
1244
1245 // Display a hint about inscribable items [empty books]
1246 // This includes the amount of text they can hold.
1247 if (type == INSCRIBABLE)
1248 {
1249 if (other_arch && other_arch->type == SCROLL)
1250 buf.printf ("\nH<You can use the inscription skill to inscribe a spell into it.>");
1251 else
1252 buf.printf ("\nH<You can use the inscription skill to inscribe text into it. It has room for up to %d characters.>",
1253 weight_limit);
1200 } 1254 }
1201 1255
1202 buf << '\n'; 1256 buf << '\n';
1257
1258 // the dungeon master additionally gets a complete dump
1259 if (who && who->flag [FLAG_WIZLOOK])
1260 {
1261 buf << "\nT<Object>\n";
1262 describe_dump_object (buf, this);
1263
1264 if (inv)
1265 {
1266 buf << "\nT<Top Inventory>\n";
1267 describe_dump_object (buf, inv);
1268 }
1269 }
1203 1270
1204 return std::string (buf.linearise (), buf.size ()); 1271 return std::string (buf.linearise (), buf.size ());
1205} 1272}
1206 1273
1207static void 1274static void
1315} 1382}
1316 1383
1317int 1384int
1318command_search_items (object *op, char *params) 1385command_search_items (object *op, char *params)
1319{ 1386{
1320 char buf[MAX_BUF];
1321
1322 if (params == NULL) 1387 if (params == NULL)
1323 { 1388 {
1324 if (op->contr->search_str[0] == '\0') 1389 if (op->contr->search_str[0] == '\0')
1325 { 1390 {
1326 new_draw_info (NDI_UNIQUE, 0, op, "Example: search-items magic+1"); 1391 new_draw_info (NDI_UNIQUE, 0, op, "Example: search-items magic+1");
1329 return 1; 1394 return 1;
1330 } 1395 }
1331 1396
1332 op->contr->search_str[0] = '\0'; 1397 op->contr->search_str[0] = '\0';
1333 new_draw_info (NDI_UNIQUE, 0, op, "Search mode turned off."); 1398 new_draw_info (NDI_UNIQUE, 0, op, "Search mode turned off.");
1334 op->update_stats (); 1399 op->contr->queue_stats_update ();
1335 return 1; 1400 return 1;
1336 } 1401 }
1337 1402
1338 if (strlen (params) >= MAX_BUF) 1403 if (strlen (params) >= sizeof (op->contr->search_str))
1339 { 1404 {
1340 new_draw_info (NDI_UNIQUE, 0, op, "Search string too long."); 1405 new_draw_info (NDI_UNIQUE, 0, op, "Search string too long.");
1341 return 1; 1406 return 1;
1342 } 1407 }
1343 1408
1344 strcpy (op->contr->search_str, params); 1409 strcpy (op->contr->search_str, params);
1345 sprintf (buf, "Now searching for '%s'.", op->contr->search_str); 1410 new_draw_info (NDI_UNIQUE, 0, op, format ("Now searching for '%s'.", op->contr->search_str));
1346 new_draw_info (NDI_UNIQUE, 0, op, buf); 1411 op->contr->queue_stats_update ();
1347 op->update_stats ();
1348 1412
1349 return 1; 1413 return 1;
1350} 1414}
1351 1415
1416int
1417command_unlock (object *op, char *params)
1418{
1419 /* if the unlock command typed with nothing, unlock everything,
1420 * this might be bad
1421 */
1422 if (params == NULL)
1423 {
1424 for (object *item = op->inv; item; item = item->below)
1425 {
1426 CLEAR_FLAG(item, FLAG_INV_LOCKED);
1427 //d// new_draw_info (NDI_UNIQUE, 0, op, "unlocked items with null param.");
1428 esrv_update_item (UPD_FLAGS, op, item);
1429 }
1430 return 0;
1431 }
1432
1433 /* if the unlock command is used with a param,
1434 * unlock what matches. i.e. unlock material, should unlock all the materials
1435 */
1436 for (object *item = op->inv; item; item = item->below)
1437 if (item->name.contains (params))
1438 {
1439 CLEAR_FLAG (item, FLAG_INV_LOCKED);
1440 //d// new_draw_info (NDI_UNIQUE, 0, op, "unlocked items with a param.");
1441 esrv_update_item (UPD_FLAGS, op, item);
1442 }
1443
1444 return 0;
1445}
1446
1447int
1448command_lock (object *op, char *params)
1449{
1450 /* if the lock command is typed by itself, lock everything
1451 */
1452 if (params == NULL)
1453 {
1454 for (object *item = op->inv; item; item = item->below)
1455 {
1456 SET_FLAG (item, FLAG_INV_LOCKED);
1457 //d// new_draw_info (NDI_UNIQUE, 0, op, "locked items with null param.");
1458 esrv_update_item (UPD_FLAGS, op, item);
1459 }
1460 return 0;
1461 }
1462
1463 /* if the lock command is used with a param, lock what matches.
1464 * i.e. lock material, should lock all the materials
1465 */
1466 for (object *item = op->inv; item; item = item->below)
1467 if (item->name.contains (params))
1468 {
1469 SET_FLAG (item, FLAG_INV_LOCKED);
1470 //d// new_draw_info (NDI_UNIQUE, 0, op, "locked items with param.");
1471 esrv_update_item (UPD_FLAGS, op, item);
1472 }
1473
1474 return 0;
1475}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines