1 /* File: cmd3.c */
2 
3 /* Purpose: Inventory commands */
4 
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12 
13 #include "mangband.h"
14 
15 
16 
17 
18 /*
19  * Move an item from equipment list to pack
20  * Note that only one item at a time can be wielded per slot.
21  * Note that taking off an item when "full" will cause that item
22  * to fall to the ground.
23  */
inven_takeoff(player_type * p_ptr,int item,int amt)24 static void inven_takeoff(player_type *p_ptr, int item, int amt)
25 {
26 	int			posn;
27 
28 	object_type		*o_ptr;
29 	object_type		tmp_obj;
30 
31 	cptr		act;
32 
33 	char		o_name[80];
34 
35 
36 	/* Get the item to take off */
37 	o_ptr = &(p_ptr->inventory[item]);
38 
39 	/* Paranoia */
40 	if (amt <= 0) return;
41 
42 	/* Check guard inscription '!t' */
43 	__trap(p_ptr, CGI(o_ptr, 't'));
44 
45 	/* Verify */
46 	if (amt > o_ptr->number) amt = o_ptr->number;
47 
48 	/* Make a copy to carry */
49 	tmp_obj = *o_ptr;
50 	tmp_obj.number = amt;
51 
52 	/* What are we "doing" with the object */
53 	if (amt < o_ptr->number)
54 	{
55 		act = "Took off";
56 	}
57 	else if (item == INVEN_WIELD)
58 	{
59 		act = "Was wielding";
60 	}
61 	else if (item == INVEN_BOW)
62 	{
63 		act = "Was shooting with";
64 	}
65 	else if (item == INVEN_LITE)
66 	{
67 		act = "Light source was";
68 	}
69 	else
70 	{
71 		act = "Was wearing";
72 	}
73 
74 	/* Carry the object, saving the slot it went in */
75 	posn = inven_carry(p_ptr, &tmp_obj);
76 
77 	/* Describe the result */
78 	object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, TRUE, 3);
79 
80 	/* Message */
81 	msg_format(p_ptr, "%^s %s (%c).", act, o_name, index_to_label(posn));
82 	sound(p_ptr, MSG_WIELD);
83 
84 	/* Delete (part of) it */
85 	inven_item_increase(p_ptr, item, -amt);
86 	inven_item_optimize(p_ptr, item);
87 
88 	/* Redraw */
89 	p_ptr->redraw |= (PR_PLUSSES | PR_OFLAGS);
90 }
91 
92 
93 
94 
95 /*
96  * Drops (some of) an item from inventory to "near" the current location
97  */
inven_drop(player_type * p_ptr,int item,int amt)98 static void inven_drop(player_type *p_ptr, int item, int amt)
99 {
100 	object_type		*o_ptr;
101 	object_type		 tmp_obj;
102 
103 	cptr		act;
104 
105 	char		o_name[80];
106 
107 
108 
109 	/* Access the slot to be dropped */
110 	o_ptr = &(p_ptr->inventory[item]);
111 
112 	/* Error check */
113 	if (amt <= 0) return;
114 
115 	/* Not too many */
116 	if (amt > o_ptr->number) amt = o_ptr->number;
117 
118 	/* Nothing done? */
119 	if (amt <= 0) return;
120 
121 	/* check for !d  or !* in inscriptions */
122 	__trap(p_ptr, CGI(o_ptr, 'd'));
123 
124 	/* Never drop artifacts above their base depth */
125 	if (!inven_drop_okay(p_ptr, o_ptr))
126 	{
127 		msg_print(p_ptr, "You can not drop this here.");
128 		return;
129 	}
130 
131 	/* Make a "fake" object */
132 	tmp_obj = *o_ptr;
133 	tmp_obj.number = amt;
134 
135 	/* Distribute charges of wands, staves, or rods */
136 	distribute_charges(o_ptr, &tmp_obj, amt);
137 
138 	/* What are we "doing" with the object */
139 	if (amt < o_ptr->number)
140 	{
141 		act = "Dropped";
142 	}
143 	else if (item == INVEN_WIELD)
144 	{
145 		act = "Was wielding";
146 	}
147 	else if (item == INVEN_BOW)
148 	{
149 		act = "Was shooting with";
150 	}
151 	else if (item == INVEN_LITE)
152 	{
153 		act = "Light source was";
154 	}
155 	else if (item >= INVEN_WIELD)
156 	{
157 		act = "Was wearing";
158 	}
159 	else
160 	{
161 		act = "Dropped";
162 	}
163 
164 	/* Dropping from equipment? Update object flags! */
165 	if (item >= INVEN_WIELD)
166 		p_ptr->redraw |= (PR_OFLAGS);
167 
168 	/* Message */
169 	object_desc(p_ptr, o_name, sizeof(o_name), &tmp_obj, TRUE, 3);
170 
171 	/* Message */
172 	msg_format(p_ptr, "%^s %s (%c).", act, o_name, index_to_label(item));
173 
174 	/* Drop it (carefully) near the player */
175 	drop_near(&tmp_obj, 0, p_ptr->dun_depth, p_ptr->py, p_ptr->px);
176 
177 	/* Decrease the item, optimize. */
178 	inven_item_increase(p_ptr, item, -amt);
179 	inven_item_describe(p_ptr, item);
180 	inven_item_optimize(p_ptr, item);
181 }
182 
183 
184 
185 
186 
187 /*
188  * Display inventory
189  *
190  * This is handled by the client now --KLJ--
191  */
do_cmd_inven(void)192 void do_cmd_inven(void)
193 {
194 	/*char out_val[160];*/
195 
196 
197 	/* Note that we are in "inventory" mode */
198 	/*command_wrk = FALSE;*/
199 
200 
201 	/* Save the screen */
202 	/*Term_save();*/
203 
204 	/* Hack -- show empty slots */
205 	/*item_tester_full = TRUE;*/
206 
207 	/* Display the inventory */
208 	/*show_inven();*/
209 
210 	/* Hack -- hide empty slots */
211 	/*item_tester_full = FALSE;*/
212 
213 	/* Build a prompt */
214 	/*sprintf(out_val, "Inventory (carrying %d.%d pounds). Command: ",
215 	        total_weight / 10, total_weight % 10);*/
216 
217 	/* Get a command */
218 	/*prt(out_val, 0, 0);*/
219 
220 	/* Get a new command */
221 	/*command_new = inkey();*/
222 
223 	/* Restore the screen */
224 	/*Term_load();*/
225 
226 
227 	/* Process "Escape" */
228 	/*if (command_new == ESCAPE)
229 	{*/
230 		/* Reset stuff */
231 		/*command_new = 0;
232 		command_gap = 50;
233 	}*/
234 
235 	/* Process normal keys */
236 	/*else
237 	{*/
238 		/* Hack -- Use "display" mode */
239 		/*command_see = TRUE;
240 	}*/
241 }
242 
243 
244 /*
245  * Display equipment
246  *
247  * This is handled be the client --KLJ--
248  */
do_cmd_equip(void)249 void do_cmd_equip(void)
250 {
251 	/*char out_val[160];*/
252 
253 
254 	/* Note that we are in "equipment" mode */
255 	/*command_wrk = TRUE;*/
256 
257 
258 	/* Save the screen */
259 	/*Term_save();*/
260 
261 	/* Hack -- show empty slots */
262 	/*item_tester_full = TRUE;*/
263 
264 	/* Display the equipment */
265 	/*show_equip();*/
266 
267 	/* Hack -- undo the hack above */
268 	/*item_tester_full = FALSE;*/
269 
270 	/* Build a prompt */
271 	/*sprintf(out_val, "Equipment (carrying %d.%d pounds). Command: ",
272 	        total_weight / 10, total_weight % 10);*/
273 
274 	/* Get a command */
275 	/*prt(out_val, 0, 0);*/
276 
277 	/* Get a new command */
278 	/*command_new = inkey();*/
279 
280 	/* Restore the screen */
281 	/*Term_load();*/
282 
283 
284 	/* Process "Escape" */
285 	/*if (command_new == ESCAPE)
286 	{*/
287 		/* Reset stuff */
288 		/*command_new = 0;
289 		command_gap = 50;
290 	}*/
291 
292 	/* Process normal keys */
293 	/*else
294 	{*/
295 		/* Enter "display" mode */
296 		/*command_see = TRUE;
297 	}*/
298 }
299 
300 
301 /*
302  * The "wearable" tester
303  */
item_tester_hook_wear(player_type * p_ptr,object_type * o_ptr)304 static bool item_tester_hook_wear(player_type *p_ptr, object_type *o_ptr)
305 {
306 	/* Check for a usable slot */
307 	if (wield_slot(p_ptr, o_ptr) >= INVEN_WIELD) return (TRUE);
308 
309 	/* Assume not wearable */
310 	return (FALSE);
311 }
312 
313 
314 /*
315  * Wield or wear a single item from the pack or floor
316  */
do_cmd_wield(player_type * p_ptr,int item)317 void do_cmd_wield(player_type *p_ptr, int item)
318 {
319 	int slot;
320 	object_type tmp_obj;
321 	object_type *o_ptr;
322 	object_type *x_ptr;
323 
324 	cptr act;
325 
326 	char o_name[80];
327 
328 
329 	/* Restrict the choices */
330 	/*item_tester_hook = item_tester_hook_wear;*/
331 
332 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_BODY) )
333 	{
334 		msg_print(p_ptr, "You cannot equip yourself!");
335 		return;
336 	}
337 
338 	/* Get the item (in the pack) */
339 	if (item >= 0)
340 	{
341 		o_ptr = &(p_ptr->inventory[item]);
342 	}
343 
344 	/* Get the item (on the floor) */
345 	else
346 	{
347 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
348 		if (item == 0) {
349 			msg_print(p_ptr, "There's nothing on the floor.");
350 			return;
351 		}
352 		o_ptr = &o_list[0 - item];
353 		/* Hack -- wearing from floor is similar to pickup */
354 		__trap(p_ptr, CGI(o_ptr, 'g'));
355 	}
356 
357 	/* Check guard inscription '!w' */
358 	__trap(p_ptr, CGI(o_ptr, 'w'));
359 
360 	if (!item_tester_hook_wear(p_ptr, o_ptr))
361 	{
362 		msg_print(p_ptr, "You may not wield that item.");
363 		return;
364 	}
365 
366 	/* Check the slot */
367 	slot = wield_slot(p_ptr, o_ptr);
368 
369 	/* Paranoia - can't really happen thanks to "item_tester_hook_wear" */
370 	if (slot == -1) return;
371 
372 	/* Prevent wielding into a cursed slot */
373 	if (cursed_p(&(p_ptr->inventory[slot])))
374 	{
375 		/* Describe it */
376 		object_desc(p_ptr, o_name, sizeof(o_name), &(p_ptr->inventory[slot]), FALSE, 0);
377 
378 		/* Message */
379 		msg_format(p_ptr, "The %s you are %s appears to be cursed.",
380 		           o_name, describe_use(p_ptr, slot));
381 
382 		/* Cancel the command */
383 		return;
384 	}
385 
386 	x_ptr = &(p_ptr->inventory[slot]);
387 
388 	/* Check guard inscription '!t' */
389 	__trap(p_ptr, CGI(x_ptr,'t'));
390 
391 	/* Hack -- MAngband-specific: if it is an artifact and pack is full, base depth must match */
392 	if (item < 0 && !inven_drop_okay(p_ptr, x_ptr) && !inven_carry_okay(p_ptr, x_ptr))
393 	{
394 		object_desc(p_ptr, o_name, sizeof(o_name), x_ptr, FALSE, 0);
395 		msg_format(p_ptr, "Your pack is full and you can't drop %s here.", o_name);
396 		return;
397 	}
398 
399 #if 0
400 	/* Verify potential overflow */
401 	if ((p_ptr->inven_cnt >= INVEN_PACK) &&
402 	    ((item < 0) || (o_ptr->number > 1)))
403 	{
404 		/* Verify with the player */
405 		if (other_query_flag &&
406 		    !get_check(p_ptr, "Your pack may overflow.  Continue? ")) return;
407 	}
408 #endif
409 
410 	/* Mega-hack -- prevent anyone but total winners from wielding the Massive Iron
411 	 * Crown of Morgoth or the Mighty Hammer 'Grond'.
412 	 */
413 	if (!p_ptr->total_winner)
414 	{
415 		/* Attempting to wear the crown if you are not a winner is a very, very bad thing
416 		 * to do.
417 		 */
418 		if (o_ptr->name1 == ART_MORGOTH)
419 		{
420 			msg_print(p_ptr, "You are blasted by the Crown's power!");
421 			/* This should pierce invulnerability */
422 			take_hit(p_ptr, 10000, "the Massive Iron Crown of Morgoth");
423 			return;
424 		}
425 		/* Attempting to wield Grond isn't so bad. */
426 		if (o_ptr->name1 == ART_GROND)
427 		{
428 			msg_print(p_ptr, "You are far too weak to wield the mighty Grond.");
429 			return;
430 		}
431 	}
432 
433 	/* Take a turn */
434 	p_ptr->energy -= level_speed(p_ptr->dun_depth);
435 
436 	/* Get a copy of the object to wield */
437 	tmp_obj = *o_ptr;
438 	tmp_obj.number = 1;
439 
440 	/* Decrease the item (from the pack) */
441 	if (item >= 0)
442 	{
443 		inven_item_increase(p_ptr, item, -1);
444 		inven_item_optimize(p_ptr, item);
445 	}
446 
447 	/* Decrease the item (from the floor) */
448 	else
449 	{
450 		floor_item_increase(0 - item, -1);
451 		floor_item_optimize(0 - item);
452 		floor_item_notify(p_ptr, 0 - item, TRUE);
453 	}
454 
455 	/* Access the wield slot */
456 	o_ptr = &(p_ptr->inventory[slot]);
457 
458 	/* Take off the "entire" item if one is there */
459 	if (p_ptr->inventory[slot].k_idx) inven_takeoff(p_ptr, slot, 255);
460 
461 	/*** Could make procedure "inven_wield()" ***/
462 
463 	/* Wear the new stuff */
464 	*o_ptr = tmp_obj;
465 
466 	/* MEGA-HACK -- Wearing from floor changes ownership */
467 	object_own(p_ptr, o_ptr);
468 
469 	/* Increase the weight */
470 	p_ptr->total_weight += o_ptr->weight;
471 
472 	/* Increment the equip counter by hand */
473 	p_ptr->equip_cnt++;
474 
475 	/* Where is the item now */
476 	if (slot == INVEN_WIELD)
477 	{
478 		act = "You are wielding";
479 	}
480 	else if (slot == INVEN_BOW)
481 	{
482 		act = "You are shooting with";
483 	}
484 	else if (slot == INVEN_LITE)
485 	{
486 		act = "Your light source is";
487 	}
488 	else
489 	{
490 		act = "You are wearing";
491 	}
492 
493 	/* Describe the result */
494 	object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, TRUE, 3);
495 
496 	/* Message */
497 	msg_format(p_ptr, "%^s %s (%c).", act, o_name, index_to_label(slot));
498 	sound(p_ptr, MSG_WIELD);
499 
500 	/* Cursed! */
501 	if (cursed_p(o_ptr))
502 	{
503 		/* Warn the player */
504 		msg_print(p_ptr, "Oops! It feels deathly cold!");
505 		sound(p_ptr, MSG_CURSED);
506 
507 		/* Note the curse */
508 		o_ptr->ident |= ID_SENSE;
509 	}
510 
511 	/* Recalculate bonuses */
512 	p_ptr->update |= (PU_BONUS);
513 
514 	/* Recalculate torch */
515 	p_ptr->update |= (PU_TORCH);
516 
517 	/* Recalculate mana */
518 	p_ptr->update |= (PU_MANA);
519 
520 	/* Redraw */
521 	p_ptr->redraw |= (PR_PLUSSES | PR_OFLAGS);
522 
523 	/* Redraw slot */
524 	player_redraw_item(p_ptr, slot);
525 
526 	/* Update fuel items */
527 	if (slot == INVEN_LITE)
528 	{
529 		player_redraw_fuel_items(p_ptr);
530 	}
531 
532 	/* Window stuff */
533 	p_ptr->window |= (PW_PLAYER);
534 }
535 
536 
537 
538 /*
539  * Take off an item
540  */
do_cmd_takeoff(player_type * p_ptr,int item)541 void do_cmd_takeoff(player_type *p_ptr, int item)
542 {
543 	object_type *o_ptr;
544 
545 	/* Restrict ghosts */
546 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_BODY) )
547 	{
548 		msg_print(p_ptr, "You cannot do that!");
549 		return;
550 	}
551 
552 	/* Verify potential overflow */
553 	if (p_ptr->inven_cnt >= INVEN_PACK)
554 	{
555 		msg_print(p_ptr, "Your pack is full and would overflow!");
556 		return;
557 	}
558 
559 	/* Get the item (in the pack) */
560 	if (item >= 0)
561 	{
562 		o_ptr = &(p_ptr->inventory[item]);
563 	}
564 
565 	/* Get the item (on the floor) */
566 	else
567 	{
568 		/* We can't "takeoff" something that is on the floor */
569 		return;
570 	}
571 
572 	/* Check guard inscription '!t' */
573 	__trap(p_ptr, CGI(o_ptr, 't'));
574 
575 	/* Item is cursed */
576 	if (cursed_p(o_ptr))
577 	{
578 		/* Oops */
579 		msg_print(p_ptr, "Hmmm, it seems to be cursed.");
580 
581 		/* Nope */
582 		return;
583 	}
584 
585 
586 	/* Take a partial turn */
587 	p_ptr->energy -= level_speed(p_ptr->dun_depth) / 2;
588 
589 	/* Take off the item */
590 	inven_takeoff(p_ptr, item, 255);
591 }
592 
593 
594 /*
595  * Drop an item
596  */
do_cmd_drop(player_type * p_ptr,int item,int quantity)597 void do_cmd_drop(player_type *p_ptr, int item, int quantity)
598 {
599 	object_type *o_ptr;
600 
601 	/* Check preventive inscription '^d' */
602 	__trap(p_ptr, CPI(p_ptr, 'd'));
603 
604 	/* Restrict ghosts */
605 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_BODY) )
606 	{
607 		msg_print(p_ptr, "You cannot drop items!");
608 		return;
609 	}
610 
611 	/* Handle the newbies_cannot_drop option */
612 	if ((p_ptr->lev == 1) && (cfg_newbies_cannot_drop))
613 	{
614 		msg_print(p_ptr, "You are not experienced enough to drop items.");
615 		return;
616 	}
617 
618 	/* Get the item (in the pack) */
619 	if (item >= 0)
620 	{
621 		o_ptr = &(p_ptr->inventory[item]);
622 	}
623 	else
624 		return;
625 	/* Get the item (on the floor) */
626 	/* Impossible
627 	else
628 	{
629 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
630 		if (item == 0) {
631 			msg_print(p_ptr, "There's nothing on the floor.");
632 			return;
633 		}
634 		o_ptr = &o_list[0 - item];
635 	}
636 	*/
637 
638 	/* Check guard inscription '!d' */
639 	__trap(p_ptr, CGI(o_ptr, 'd'));
640 
641 	/* Cannot remove cursed items */
642 	if ((item >= INVEN_WIELD) && cursed_p(o_ptr))
643 	{
644 		/* Oops */
645 		msg_print(p_ptr, "Hmmm, it seems to be cursed.");
646 
647 		/* Nope */
648 		return;
649 	}
650 
651 	/* Ultimate-Hack -- farmers plant seeds */
652 	if ((o_ptr->tval == TV_FOOD) &&
653 	    ((o_ptr->sval >= SV_FOOD_POTATO) &&
654 	     (o_ptr->sval <= SV_FOOD_EAR_OF_CORN)))
655 	{
656 		if (cave[p_ptr->dun_depth] &&
657 		    cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].feat == FEAT_CROP)
658 		{
659 			do_cmd_plant_seed(p_ptr, item);
660 			return;
661 		}
662 	}
663 
664 #if 0
665 	/* Mega-Hack -- verify "dangerous" drops */
666 	if (cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx)
667 	{
668 		/* XXX XXX Verify with the player */
669 		if (other_query_flag &&
670 		    !get_check(p_ptr, "The item may disappear.  Continue? ")) return;
671 	}
672 #endif
673 
674 
675 	/* Take a partial turn */
676 	p_ptr->energy -= level_speed(p_ptr->dun_depth) / 2;
677 
678 	/* Drop (some of) the item */
679 	inven_drop(p_ptr, item, quantity);
680 }
681 
682 
683 /*
684  * Drop some gold
685  */
do_cmd_drop_gold(player_type * p_ptr,s32b amt)686 void do_cmd_drop_gold(player_type *p_ptr, s32b amt)
687 {
688 	object_type tmp_obj;
689 
690 	/* Restrict ghosts */
691 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_BODY) )
692 	{
693 		msg_print(p_ptr, "You cannot drop items!");
694 		return;
695 	}
696 
697 	/* Handle the newbies_cannot_drop option */
698 	if ((p_ptr->lev == 1) && (cfg_newbies_cannot_drop))
699 	{
700 		msg_print(p_ptr, "You are not experienced enough to drop gold.");
701 		return;
702 	}
703 
704 
705 	/* Error checks */
706 	if (amt <= 0) return;
707 	if (amt > p_ptr->au)
708 	{
709 	    /* Hack - entering 999kk means MAX */
710 	    if (amt != 999000000)
711 	    {
712 		msg_print(p_ptr, "You do not have that much gold.");
713 		return;
714 	    } else
715 		amt = p_ptr->au;
716 	}
717 
718 	/* Use "gold" object kind */
719 	invcopy(&tmp_obj, lookup_kind(TV_GOLD,SV_PLAYER_GOLD));
720 
721 	/* Setup the "worth" */
722 	tmp_obj.pval = amt;
723 
724 	/* MEGA-HACK -- Set "owner" of this pile */
725 	object_own(p_ptr, &tmp_obj);
726 
727 	/* Drop it */
728 	drop_near(&tmp_obj, 0, p_ptr->dun_depth, p_ptr->py, p_ptr->px);
729 
730 	/* Subtract from the player's gold */
731 	p_ptr->au -= amt;
732 
733 	/* Message */
734 	msg_format(p_ptr, "You drop %ld piece%s of gold.", amt, (amt==1?"":"s"));
735 
736 	/* Redraw gold */
737 	p_ptr->redraw |= (PR_GOLD);
738 
739 	/* Window stuff */
740 	p_ptr->window |= (PW_PLAYER);
741 
742 	/* Take a turn */
743 	p_ptr->energy -= level_speed(p_ptr->dun_depth);
744 }
745 
746 
747 /*
748  * Destroy an item
749  */
do_cmd_destroy(player_type * p_ptr,int item,int quantity)750 void do_cmd_destroy(player_type *p_ptr, int item, int quantity)
751 {
752 //	int			old_number;
753 
754 	bool		force = FALSE;
755 
756 	object_type		*o_ptr;
757 
758 	object_type *i_ptr;
759 	object_type object_type_body;
760 
761 	char		o_name[80];
762 
763 	/* Check preventive inscription '^k' */
764 	__trap(p_ptr, CPI(p_ptr, 'k'));
765 
766 	/* Restrict ghosts */
767 	if (p_ptr->ghost || p_ptr->fruit_bat)
768 	{
769 		msg_print(p_ptr, "You cannot destroy items!");
770 		return;
771 	}
772 
773 	/* Hack -- force destruction */
774 	if (p_ptr->command_arg > 0) force = TRUE;
775 
776 	/* Get the item (in the pack) */
777 	if (item >= 0)
778 	{
779 		o_ptr = &(p_ptr->inventory[item]);
780 	}
781 
782 	/* Get the item (on the floor) */
783 	else
784 	{
785 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
786 		if (item == 0) {
787 			msg_print(p_ptr, "There's nothing on the floor.");
788 			return;
789 		}
790 		o_ptr = &o_list[0 - item];
791 	}
792 
793 	/* Get local object */
794 	i_ptr = &object_type_body;
795 
796 	/* Obtain a local object */
797 	COPY(i_ptr, o_ptr, object_type);
798 
799 	if ((o_ptr->tval == TV_WAND) ||
800 	    (o_ptr->tval == TV_STAFF) ||
801 	    (o_ptr->tval == TV_ROD))
802 	{
803 		/* Calculate the amount of destroyed charges */
804 		i_ptr->pval = o_ptr->pval * quantity / o_ptr->number;
805 	}
806 
807 	/* Set quantity */
808 	i_ptr->number = quantity;
809 
810 	/* Describe the destroyed object */
811 	object_desc(p_ptr, o_name, sizeof(o_name), i_ptr, TRUE, 3);
812 
813 	/* Describe the object
814 	old_number = o_ptr->number;
815 	o_ptr->number = quantity;
816 	object_desc(p_ptr, o_name, o_ptr, TRUE, 3);
817 	o_ptr->number = old_number;
818 	*/
819 
820 	/* Check guard inscription '!k' */
821 	__trap(p_ptr, CGI(o_ptr, 'k'));
822 
823 	/* Take a turn */
824 	p_ptr->energy -= level_speed(p_ptr->dun_depth);
825 
826 	/* Artifacts cannot be destroyed */
827 	if (true_artifact_p(o_ptr))
828 	{
829 		cptr feel = "special";
830 
831 		/* Message */
832 		msg_format(p_ptr, "You cannot destroy %s.", o_name);
833 
834 		/* Hack -- Handle icky artifacts */
835 		if (cursed_p(o_ptr) || broken_p(o_ptr)) feel = "terrible";
836 
837 		/* Hack -- inscribe the artifact */
838 		o_ptr->note = quark_add(feel);
839 
840 		/* We have "felt" it (again) */
841 		o_ptr->ident |= (ID_SENSE);
842 
843 		/* Combine the pack */
844 		p_ptr->notice |= (PN_COMBINE);
845 
846 		/* Done */
847 		return;
848 	}
849 
850 	/* Cursed, equipped items cannot be destroyed */
851 	if (item >= INVEN_WIELD && cursed_p(o_ptr))
852 	{
853 		/* Message */
854 		msg_print(p_ptr, "Hmm, that seems to be cursed.");
855 
856 		/* Done */
857 		return;
858 	}
859 
860 	/* Destroying from equipment? Update object flags! */
861 	if (item >= INVEN_WIELD)
862 		p_ptr->redraw |= (PR_OFLAGS);
863 
864 	/* Message */
865 	msg_format(p_ptr, "You destroy %s.", o_name);
866 	sound(p_ptr, MSG_DESTROY);
867 
868 	/* Reduce the charges of rods/wands/staves */
869 	reduce_charges(o_ptr, quantity);
870 
871 	/* Eliminate the item (from the pack) */
872 	if (item >= 0)
873 	{
874 		inven_item_increase(p_ptr, item, -quantity);
875 		inven_item_describe(p_ptr, item);
876 		inven_item_optimize(p_ptr, item);
877 	}
878 
879 	/* Eliminate the item (from the floor) */
880 	else
881 	{
882 		floor_item_increase(0 - item, -quantity);
883 		floor_item_describe(0 - item);
884 		floor_item_optimize(0 - item);
885 		floor_item_notify(p_ptr, 0 - item, TRUE);
886 	}
887 }
888 
889 
890 /*
891  * Observe an item which has been *identify*-ed
892  */
do_cmd_observe(player_type * p_ptr,int item)893 void do_cmd_observe(player_type *p_ptr, int item)
894 {
895 	object_type		tmp_obj;
896 	object_type		*o_ptr;
897 
898 	char		o_name[80];
899 
900 	/* Get the item (in the store) */
901 	if (p_ptr->store_num != -1)
902 	{
903 		/* We have to use temp. object because we're going to identify it */
904 		o_ptr = &tmp_obj;
905 
906 		/* Fill o_ptr with correct item */
907 		if (!get_store_item(p_ptr, item, o_ptr))
908 		{
909 			/* Disguise our bug as a feature */
910 			msg_print(p_ptr, "Sorry, this item is exclusive.");
911 			return;
912 		}
913 		/* HACK -- hide origin */
914 		tmp_obj.origin = ORIGIN_NONE;
915 
916 		/* Get name */
917 		object_desc_store(p_ptr, o_name, o_ptr, TRUE, 3);
918 		/* Identify this store item */
919 		object_known(o_ptr);
920 	}
921 	else
922 	{
923 		/* Get the item (in the pack) */
924 		if (item >= 0)
925 		{
926 			o_ptr = &(p_ptr->inventory[item]);
927 		}
928 
929 		/* Get the item (on the floor) */
930 		else
931 		{
932 			item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
933 			if (item == 0) {
934 				msg_print(p_ptr, "There's nothing on the floor.");
935 				return;
936 			}
937 			o_ptr = &o_list[0 - item];
938 		}
939 
940 		/* Get name */
941 		object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, TRUE, 3);
942 	}
943 
944 	/* Inform */
945 	msg_format(p_ptr, "Examining %s...", o_name);
946 
947 	/* Capitalize object name for header */
948 	o_name[0] = toupper(o_name[0]);
949 
950 	/* Describe it fully */
951 	identify_fully_aux(p_ptr, o_ptr);
952 
953 	/* Notify player */
954 	send_prepared_popup(p_ptr, o_name);
955 }
956 
957 
958 
959 /*
960  * Remove the inscription from an object
961  * XXX Mention item (when done)?
962  */
do_cmd_uninscribe(player_type * p_ptr,int item)963 void do_cmd_uninscribe(player_type *p_ptr, int item)
964 {
965 	object_type *o_ptr;
966 
967 	/* Restrict ghosts */
968 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_HANDS) )
969 	{
970 		msg_print(p_ptr, "You cannot touch items!");
971 		return;
972 	}
973 
974 	/* Get the item (in the pack) */
975 	if (item >= 0)
976 	{
977 		o_ptr = &(p_ptr->inventory[item]);
978 	}
979 
980 	/* Get the item (on the floor) */
981 	else
982 	{
983 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
984 		if (item == 0) {
985 			msg_print(p_ptr, "There's nothing on the floor.");
986 			return;
987 		}
988 		o_ptr = &o_list[0 - item];
989 	}
990 
991 	/* Check guard inscription '!}' */
992 	__trap(p_ptr, protected_p(p_ptr, o_ptr, '}'));
993 
994 	/* Nothing to remove */
995 	if (!o_ptr->note)
996 	{
997 		msg_print(p_ptr, "That item had no inscription to remove.");
998 		return;
999 	}
1000 
1001 	/* Message */
1002 	msg_print(p_ptr, "Inscription removed.");
1003 
1004 	/* Remove the incription */
1005 	o_ptr->note = 0;
1006 
1007 	/* Update global "preventive inscriptions" */
1008 	update_prevent_inscriptions(p_ptr);
1009 
1010 	/* Combine the pack */
1011 	p_ptr->notice |= (PN_COMBINE);
1012 
1013 	/* Redraw item */
1014 	player_redraw_item(p_ptr, item);
1015 }
1016 
1017 
1018 /*
1019  * Inscribe an object with a comment
1020  */
do_cmd_inscribe(player_type * p_ptr,int item,cptr inscription)1021 void do_cmd_inscribe(player_type *p_ptr, int item, cptr inscription)
1022 {
1023 	object_type		*o_ptr;
1024 	char		o_name[80];
1025 	s32b		price;
1026 	const char	*c;
1027 
1028 	/* Restrict ghosts */
1029 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_HANDS) )
1030 	{
1031 		msg_print(p_ptr, "You cannot touch items!");
1032 		return;
1033 	}
1034 
1035 	/* Get the item (in the pack) */
1036 	if (item >= 0)
1037 	{
1038 		o_ptr = &(p_ptr->inventory[item]);
1039 	}
1040 
1041 	/* Get the item (on the floor) */
1042 	else
1043 	{
1044 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
1045 		if (item == 0) {
1046 			msg_print(p_ptr, "There's nothing on the floor.");
1047 			return;
1048 		}
1049 		o_ptr = &o_list[0 - item];
1050 	}
1051 
1052 	/* Check guard inscription '!{' */
1053 	__trap(p_ptr, protected_p(p_ptr, o_ptr, '{'));
1054 
1055 	/* Handle empty inscription as removal */
1056 	if (STRZERO(inscription))
1057 	{
1058 		if (!o_ptr->note)
1059 		{
1060 			msg_print(p_ptr, "You've entered no inscription.");
1061 			return;
1062 		}
1063 		do_cmd_uninscribe(p_ptr, item);
1064 		return;
1065 	}
1066 
1067 	/* Don't allow certain inscriptions when selling */
1068 	if ((c = my_stristr(inscription,"for sale")))
1069 	{
1070 		/* Can't sell unindentified items */
1071 		if (!object_known_p(p_ptr, o_ptr))
1072 		{
1073 			msg_print(p_ptr, "You must identify this item first");
1074 			return;
1075 		}
1076 		/* Can't sell overpriced items */
1077 		c += 8; /* skip "for sale" */
1078 		if( *c == ' ' )
1079 		{
1080 			price = atoi(c);
1081 			if (price > 9999999)
1082 			{
1083 				msg_print(p_ptr, "Your price is too high!");
1084 				return;
1085 			}
1086 		}
1087 	}
1088 
1089 	/* Describe the activity */
1090 	object_desc(p_ptr, o_name, sizeof(o_name), o_ptr, TRUE, 3);
1091 
1092 	/* Message */
1093 	msg_format(p_ptr, "Inscribing %s.", o_name);
1094 	msg_print(p_ptr, NULL);
1095 
1096 	/* Save the inscription */
1097 	o_ptr->note = quark_add(inscription);
1098 
1099 	/* Update global "preventive inscriptions" */
1100 	update_prevent_inscriptions(p_ptr);
1101 
1102 	/* Combine the pack */
1103 	p_ptr->notice |= (PN_COMBINE);
1104 
1105 	/* Redraw item */
1106 	player_redraw_item(p_ptr, item);
1107 }
1108 
1109 
1110 /*
1111  * Attempt to steal from another player
1112  */
do_cmd_steal(player_type * p_ptr,int dir)1113 void do_cmd_steal(player_type *p_ptr, int dir)
1114 {
1115 	player_type *q_ptr;
1116 	cave_type *c_ptr;
1117 
1118 	int success, notice;
1119 	bool fail = TRUE;
1120 
1121 	/* Check preventive inscription '^J' */
1122 	__trap(p_ptr, CPI(p_ptr, 'J'));
1123 
1124 	/* Ghosts cannot steal */
1125 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_BODY) )
1126 	{
1127 	        msg_print(p_ptr, "You cannot steal things!");
1128 	        return;
1129 	}
1130 
1131 	/* Ensure "dir" is in ddx/ddy array bounds */
1132 	if (!VALID_DIR(dir)) dir = 5;
1133 
1134 	/* Examine target grid */
1135 	c_ptr = &cave[p_ptr->dun_depth][p_ptr->py + ddy[dir]][p_ptr->px + ddx[dir]];
1136 
1137 	/* May only steal from players */
1138 	if (c_ptr->m_idx >= 0)
1139 	{
1140 		/* Message */
1141 		msg_print(p_ptr, "You see nothing there to steal from.");
1142 
1143 		return;
1144 	}
1145 
1146 	/* May not steal from yourself */
1147 	if (!dir || dir == 5) return;
1148 
1149 	/* Examine target */
1150 	q_ptr = Players[0 - c_ptr->m_idx];
1151 
1152 	/* May not steal from hostile players */
1153 	if (check_hostile(q_ptr, p_ptr))
1154 	{
1155 		/* Message */
1156 		msg_format(p_ptr, "%^s is on guard against you.", q_ptr->name);
1157 
1158 		return;
1159 	}
1160 
1161 	/* Make sure we have enough room */
1162 	if (p_ptr->inven_cnt >= INVEN_PACK)
1163 	{
1164 		/* Message */
1165 		msg_print(p_ptr, "You have no room to steal anything.");
1166 
1167 		return;
1168 	}
1169 
1170 	/* Compute chance of success */
1171 	success = 3 * (adj_dex_safe[p_ptr->stat_ind[A_DEX]] - adj_dex_safe[q_ptr->stat_ind[A_DEX]]);
1172 
1173 	/* Compute base chance of being noticed */
1174 	notice = 5 * (adj_mag_stat[q_ptr->stat_ind[A_INT]] - p_ptr->skill_stl);
1175 
1176 	/* Hack -- Rogues get bonuses to chances */
1177 	if (p_ptr->cp_ptr->flags & CF_STEALING_IMPROV)
1178 	{
1179 		/* Increase chance by level */
1180 		success += 3 * p_ptr->lev;
1181 		notice -= 3 * p_ptr->lev;
1182 	}
1183 
1184 	/* Hack -- Always small chance to succeed */
1185 	if (success < 2) success = 2;
1186 
1187 	/* Check for success */
1188 	if (randint0(100) < success)
1189 	{
1190 		/* Steal gold 25% of the time */
1191 		if (randint0(100) < 25)
1192 		{
1193 			int amt = q_ptr->au / 10;
1194 
1195 			/* Transfer gold */
1196 			if (amt)
1197 			{
1198 				/* Move from target to thief */
1199 				q_ptr->au -= amt;
1200 				p_ptr->au += amt;
1201 
1202 				/* Redraw */
1203 				p_ptr->redraw |= (PR_GOLD);
1204 				q_ptr->redraw |= (PR_GOLD);
1205 
1206 				/* Tell thief */
1207 				msg_format(p_ptr, "You steal %ld gold.", amt);
1208 
1209 				/* Check for target noticing */
1210 				if (randint0(100) < notice)
1211 				{
1212 					/* Make target hostile */
1213 					add_hostility(q_ptr, p_ptr->name);
1214 
1215 					/* Message */
1216 					msg_format(q_ptr, "You notice %s stealing %ld gold!",
1217 					           p_ptr->name, amt);
1218 				}
1219 				fail = FALSE;
1220 			}
1221 		}
1222 		else
1223 		{
1224 			int item;
1225 			object_type *o_ptr, forge;
1226 			char o_name[80];
1227 
1228 			/* Steal an item */
1229 			item = randint0(q_ptr->inven_cnt);
1230 
1231 			/* Get object */
1232 			o_ptr = &q_ptr->inventory[item];
1233 
1234 			/* Don't steal (nothing)s */
1235 			if (o_ptr->k_idx)
1236 			{
1237 				forge = *o_ptr;
1238 				/* Give one item to thief */
1239 				forge.number = 1;
1240 
1241 				/* Hack -- If a rod, staff, or wand, allocate total
1242 				 * maximum timeouts or charges between those
1243 				 * stolen and those missed. -LM-
1244 				 */
1245 				distribute_charges(o_ptr, &forge, 1);
1246 
1247 				inven_carry(p_ptr, &forge);
1248 
1249 				/* Take one from target */
1250 				inven_item_increase(q_ptr, item, -1);
1251 				inven_item_optimize(q_ptr, item);
1252 
1253 				/* Tell thief what he got */
1254 				object_desc(p_ptr, o_name, sizeof(o_name), &forge, TRUE, 3);
1255 				msg_format(p_ptr, "You stole %s.", o_name);
1256 
1257 				/* Easier to notice heavier objects */
1258 				notice += forge.weight;
1259 
1260 				/* Check for target noticing */
1261 				if (randint0(100) < notice)
1262 				{
1263 					/* Make target hostile */
1264 					add_hostility(q_ptr, p_ptr->name);
1265 
1266 					/* Message */
1267 					msg_format(q_ptr, "You notice %s stealing %s!",
1268 					           p_ptr->name, o_name);
1269 				}
1270 				fail = FALSE;
1271 			}
1272 		}
1273 	}
1274 
1275 	if (fail)
1276 	{
1277 		/* Message */
1278 		msg_print(p_ptr, "You fail to steal anything.");
1279 
1280 		/* Easier to notice a failed attempt */
1281 		if (randint0(100) < notice + 50)
1282 		{
1283 			/* Make target hostile */
1284 			add_hostility(q_ptr, p_ptr->name);
1285 
1286 			/* Message */
1287 			msg_format(q_ptr, "You notice %s try to steal from you!",
1288 			           p_ptr->name);
1289 		}
1290 	}
1291 
1292 	/* Take a turn */
1293 	p_ptr->energy -= level_speed(p_ptr->dun_depth);
1294 }
1295 
1296 
1297 
1298 
1299 
1300 
1301 
1302 /*
1303  * An "item_tester_hook" for refilling lanterns
1304  */
item_tester_refill_lantern(object_type * o_ptr)1305 static bool item_tester_refill_lantern(object_type *o_ptr)
1306 {
1307 	/* Randarts are not refillable */
1308 	if (o_ptr->name3) return (FALSE);
1309 
1310 	/* Flasks of oil are okay */
1311 	if (o_ptr->tval == TV_FLASK) return (TRUE);
1312 
1313 	/* Torches are okay */
1314 	if ((o_ptr->tval == TV_LITE) &&
1315 	    (o_ptr->sval == SV_LITE_LANTERN)) return (TRUE);
1316 
1317 	/* Assume not okay */
1318 	return (FALSE);
1319 }
1320 
1321 
1322 /*
1323  * Refill the players lamp (from the pack or floor)
1324  */
do_cmd_refill_lamp(player_type * p_ptr,int item)1325 static void do_cmd_refill_lamp(player_type *p_ptr, int item)
1326 {
1327 	object_type *o_ptr;
1328 	object_type *j_ptr;
1329 
1330 
1331 	/* Restrict the choices */
1332 	item_tester_hook = item_tester_refill_lantern;
1333 
1334 	/* Get the item (in the pack) */
1335 	if (item >= 0)
1336 	{
1337 		o_ptr = &(p_ptr->inventory[item]);
1338 	}
1339 
1340 	/* Get the item (on the floor) */
1341 	else
1342 	{
1343 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
1344 		if (item == 0) {
1345 			msg_print(p_ptr, "There's nothing on the floor.");
1346 			return;
1347 		}
1348 		o_ptr = &o_list[0 - item];
1349 	}
1350 
1351 	if (!item_tester_hook(o_ptr))
1352 	{
1353 		msg_print(p_ptr, "You cannot refill with that!");
1354 		return;
1355 	}
1356 
1357 
1358 	/* Take a partial turn */
1359 	p_ptr->energy -= level_speed(p_ptr->dun_depth) / 2;
1360 
1361 	/* Access the lantern */
1362 	j_ptr = &(p_ptr->inventory[INVEN_LITE]);
1363 
1364 	/* Refuel */
1365 	j_ptr->pval += o_ptr->pval;
1366 
1367 	/* Message */
1368 	msg_print(p_ptr, "You fuel your lamp.");
1369 
1370 	/* Comment */
1371 	if (j_ptr->pval >= FUEL_LAMP)
1372 	{
1373 		j_ptr->pval = FUEL_LAMP;
1374 		msg_print(p_ptr, "Your lamp is full.");
1375 	}
1376 
1377 	/* Decrease the item (from the pack) */
1378 	if (item >= 0)
1379 	{
1380 		inven_item_increase(p_ptr, item, -1);
1381 		inven_item_describe(p_ptr, item);
1382 		inven_item_optimize(p_ptr, item);
1383 	}
1384 
1385 	/* Decrease the item (from the floor) */
1386 	else
1387 	{
1388 		floor_item_increase(0 - item, -1);
1389 		floor_item_describe(0 - item);
1390 		floor_item_optimize(0 - item);
1391 		floor_item_notify(p_ptr, 0 - item, TRUE);
1392 	}
1393 
1394 	/* Recalculate torch */
1395 	p_ptr->update |= (PU_TORCH);
1396 
1397 	/* Redraw the lantern */
1398 	player_redraw_item(p_ptr, INVEN_LITE);
1399 }
1400 
1401 
1402 
1403 /*
1404  * An "item_tester_hook" for refilling torches
1405  */
item_tester_refill_torch(object_type * o_ptr)1406 static bool item_tester_refill_torch(object_type *o_ptr)
1407 {
1408 	/* Torches are okay */
1409 	if ((o_ptr->tval == TV_LITE) &&
1410 	    (o_ptr->sval == SV_LITE_TORCH)) return (TRUE);
1411 
1412 	/* Assume not okay */
1413 	return (FALSE);
1414 }
1415 
1416 
1417 /*
1418  * Refuel the players torch (from the pack or floor)
1419  */
do_cmd_refill_torch(player_type * p_ptr,int item)1420 static void do_cmd_refill_torch(player_type *p_ptr, int item)
1421 {
1422 	object_type *o_ptr;
1423 	object_type *j_ptr;
1424 
1425 
1426 	/* Restrict the choices */
1427 	item_tester_hook = item_tester_refill_torch;
1428 
1429 	/* Get the item (in the pack) */
1430 	if (item >= 0)
1431 	{
1432 		o_ptr = &(p_ptr->inventory[item]);
1433 	}
1434 
1435 	/* Get the item (on the floor) */
1436 	else
1437 	{
1438 		item = -cave[p_ptr->dun_depth][p_ptr->py][p_ptr->px].o_idx;
1439 		if (item == 0) {
1440 			msg_print(p_ptr, "There's nothing on the floor.");
1441 			return;
1442 		}
1443 		o_ptr = &o_list[0 - item];
1444 	}
1445 
1446 	if (!item_tester_hook(o_ptr))
1447 	{
1448 		msg_print(p_ptr, "You cannot refill with that!");
1449 		return;
1450 	}
1451 
1452 
1453 	/* Take a partial turn */
1454 	p_ptr->energy -= level_speed(p_ptr->dun_depth) / 2;
1455 
1456 	/* Access the primary torch */
1457 	j_ptr = &(p_ptr->inventory[INVEN_LITE]);
1458 
1459 	/* Refuel */
1460 	j_ptr->pval += o_ptr->pval + 5;
1461 
1462 	/* Message */
1463 	msg_print(p_ptr, "You combine the torches.");
1464 
1465 	/* Over-fuel message */
1466 	if (j_ptr->pval >= FUEL_TORCH)
1467 	{
1468 		j_ptr->pval = FUEL_TORCH;
1469 		msg_print(p_ptr, "Your torch is fully fueled.");
1470 	}
1471 
1472 	/* Refuel message */
1473 	else
1474 	{
1475 		msg_print(p_ptr, "Your torch glows more brightly.");
1476 	}
1477 
1478 	/* Decrease the item (from the pack) */
1479 	if (item >= 0)
1480 	{
1481 		inven_item_increase(p_ptr, item, -1);
1482 		inven_item_describe(p_ptr, item);
1483 		inven_item_optimize(p_ptr, item);
1484 	}
1485 
1486 	/* Decrease the item (from the floor) */
1487 	else
1488 	{
1489 		floor_item_increase(0 - item, -1);
1490 		floor_item_describe(0 - item);
1491 		floor_item_optimize(0 - item);
1492 		floor_item_notify(p_ptr, 0 - item, TRUE);
1493 	}
1494 
1495 	/* Recalculate torch */
1496 	p_ptr->update |= (PU_TORCH);
1497 
1498 	/* Redraw the primary torch */
1499 	player_redraw_item(p_ptr, INVEN_LITE);
1500 }
1501 
1502 
1503 
1504 
1505 /*
1506  * Refill the players lamp, or restock his torches
1507  */
do_cmd_refill(player_type * p_ptr,int item)1508 void do_cmd_refill(player_type *p_ptr, int item)
1509 {
1510 	object_type *o_ptr;
1511 
1512 	/* Restrict ghosts */
1513 	if ( (p_ptr->ghost || p_ptr->fruit_bat) && !(p_ptr->dm_flags & DM_GHOST_BODY) )
1514 	{
1515 		msg_print(p_ptr, "You cannot touch items!");
1516 		return;
1517 	}
1518 
1519 	/* Get the light */
1520 	o_ptr = &(p_ptr->inventory[INVEN_LITE]);
1521 
1522 	/* Check guard inscription '!F' */
1523 	__trap(p_ptr, CGI(o_ptr, 'F'));
1524 
1525 	/* It is nothing */
1526 	if (o_ptr->tval != TV_LITE)
1527 	{
1528 		msg_print(p_ptr, "You are not wielding a light.");
1529 	}
1530 
1531 	/* It's a lamp */
1532 	else if (o_ptr->sval == SV_LITE_LANTERN)
1533 	{
1534 		do_cmd_refill_lamp(p_ptr, item);
1535 	}
1536 
1537 	/* It's a torch */
1538 	else if (o_ptr->sval == SV_LITE_TORCH)
1539 	{
1540 		do_cmd_refill_torch(p_ptr, item);
1541 	}
1542 
1543 	/* No torch to refill */
1544 	else
1545 	{
1546 		msg_print(p_ptr, "Your light cannot be refilled.");
1547 	}
1548 }
1549 
1550 
1551 
1552 
1553 
1554 
1555 /*
1556  * Target command
1557  */
do_cmd_target(player_type * p_ptr,char dir)1558 void do_cmd_target(player_type *p_ptr, char dir)
1559 {
1560 	/* Set the target */
1561 	if (target_set_interactive(p_ptr, TARGET_KILL, dir))
1562 	{
1563 		/*msg_print(p_ptr, "Target Selected.");*/
1564 	}
1565 	else
1566 	{
1567 		/*msg_print(p_ptr, "Target Aborted.");*/
1568 	}
1569 }
1570 
do_cmd_target_friendly(player_type * p_ptr,char dir)1571 void do_cmd_target_friendly(player_type *p_ptr, char dir)
1572 {
1573 	/* Set the target */
1574 	if (target_set_interactive(p_ptr, TARGET_FRND, dir))
1575 	{
1576 		/*msg_print(p_ptr, "Target Selected.");*/
1577 	}
1578 	else
1579 	{
1580 		/*msg_print(p_ptr, "Target Aborted.");*/
1581 	}
1582 }
1583 
do_cmd_look(player_type * p_ptr,char dir)1584 void do_cmd_look(player_type *p_ptr, char dir)
1585 {
1586 	/* Look around */
1587 	if (target_set_interactive(p_ptr, TARGET_LOOK, dir))
1588 	{
1589 		/*msg_print(p_ptr, "Target Selected.");*/
1590 	}
1591 }
1592 
1593 /* Give player detailed information about a range of monsters,
1594  * specified by char
1595  */
do_cmd_monster_desc_all(player_type * p_ptr,char c)1596 void do_cmd_monster_desc_all(player_type *p_ptr, char c) {
1597 	int i;
1598 	bool found = FALSE;
1599 
1600 	/* Let the player scroll through this info */
1601 	p_ptr->special_file_type = TRUE;
1602 
1603 	/* Prepare player structure for text */
1604 	text_out_init(p_ptr);
1605 
1606 	for (i = 1; i < z_info->r_max; i++)
1607 	{
1608 		/* Require at least 1 encounter */
1609 		if (p_ptr->l_list[i].sights && r_info[i].d_char == c)
1610 		{
1611 			/* Monster name */
1612 			text_out("\n  ");
1613 
1614 			/* Dump info onto player */
1615 			describe_monster(p_ptr, i, FALSE);
1616 
1617 			/* Track first race */
1618 			if (!found)
1619 				monster_race_track(p_ptr, i);
1620 
1621 			found = TRUE;
1622 		}
1623 	}
1624 
1625 	if (!found)
1626 		text_out("You fail to remember any monsters of this kind.\n");
1627 
1628 	/* Restore height and width of current dungeon level */
1629 	text_out_done();
1630 
1631 	/* Notify player */
1632 	send_term_header(p_ptr, NTERM_BROWSE | NTERM_CLEAR, format("Monster Recall ('%c')", c));
1633 	send_prepared_info(p_ptr, NTERM_WIN_SPECIAL, STREAM_SPECIAL_TEXT, NTERM_BROWSE | NTERM_ICKY);
1634 	return;
1635 }
1636 
1637 /* Give player detailed information about a specified monster */
do_cmd_monster_desc_aux(player_type * p_ptr,int r_idx,bool quiet)1638 void do_cmd_monster_desc_aux(player_type *p_ptr, int r_idx, bool quiet)
1639 {
1640 	/* Prepare player structure for text */
1641 	text_out_init(p_ptr);
1642 
1643 	/* Dump info into player */
1644 	if (r_idx < 0)
1645 		describe_player(p_ptr, Players[0 - r_idx]);
1646 	else
1647 		describe_monster(p_ptr, r_idx, FALSE);
1648 
1649 	/* Restore height and width of current dungeon level */
1650 	text_out_done();
1651 
1652 	/* Send this text */
1653 	if (p_ptr->stream_hgt[STREAM_MONSTER_TEXT])
1654 	{
1655 		send_prepared_info(p_ptr, NTERM_WIN_MONSTER, STREAM_MONSTER_TEXT, 0);
1656 	}
1657 	else /* HACK -- do not send this while user is busy! */ if (p_ptr->special_file_type < SPECIAL_FILE_OTHER+1)
1658 	{
1659 		send_prepared_info(p_ptr, NTERM_WIN_SPECIAL, STREAM_SPECIAL_TEXT, NTERM_ICKY);
1660 	}
1661 
1662 	return;
1663 }
do_cmd_monster_desc(player_type * p_ptr,int m_idx)1664 void do_cmd_monster_desc(player_type *p_ptr, int m_idx) {
1665 	do_cmd_monster_desc_aux(p_ptr, m_list[m_idx].r_idx, FALSE);
1666 }
1667 
1668 
1669 
1670 /*
1671  * Allow the player to examine other sectors on the map
1672  */
do_cmd_locate(player_type * p_ptr,int dir)1673 void do_cmd_locate(player_type *p_ptr, int dir)
1674 {
1675 	int		y1, x1, y2, x2;
1676 
1677 	char	tmp_val[80];
1678 
1679 	char	out_val[160];
1680 
1681 
1682 	/* No direction, recenter */
1683 	if (!dir)
1684 	{
1685 		/* Recenter map around the player */
1686 		verify_panel(p_ptr);
1687 
1688 		/* Reset "old" */
1689 		p_ptr->panel_row_old = p_ptr->panel_col_old = -1;
1690 
1691 		/* Update stuff */
1692 		p_ptr->update |= (PU_MONSTERS);
1693 
1694 		/* Redraw map */
1695 		p_ptr->redraw |= (PR_MAP);
1696 
1697 		/* Window stuff */
1698 		p_ptr->window |= (PW_OVERHEAD);
1699 
1700 		/* Handle stuff */
1701 		handle_stuff(p_ptr);
1702 
1703 		return;
1704 	}
1705 
1706 	/* Initialize */
1707 	if (dir == 5)
1708 	{
1709 		/* Remember current panel */
1710 		p_ptr->panel_row_old = p_ptr->panel_row;
1711 		p_ptr->panel_col_old = p_ptr->panel_col;
1712 	}
1713 
1714 	/* Start at current panel */
1715 	y2 = p_ptr->panel_row;
1716 	x2 = p_ptr->panel_col;
1717 
1718 	/* Initial panel */
1719 	y1 = p_ptr->panel_row_old;
1720 	x1 = p_ptr->panel_col_old;
1721 
1722 	/* Ensure "dir" is in ddy/ddx array bounds */
1723 	if (!VALID_DIR(dir)) dir = 5;
1724 
1725 	/* Apply the motion */
1726 	y2 += ddy[dir];
1727 	x2 += ddx[dir];
1728 
1729 	/* Verify the row */
1730 	if (y2 > p_ptr->max_panel_rows) y2 = p_ptr->max_panel_rows;
1731 	else if (y2 < 0) y2 = 0;
1732 
1733 	/* Verify the col */
1734 	if (x2 > p_ptr->max_panel_cols) x2 = p_ptr->max_panel_cols;
1735 	else if (x2 < 0) x2 = 0;
1736 
1737 	/* Describe the location */
1738 	if ((y2 == y1) && (x2 == x1))
1739 	{
1740 		tmp_val[0] = '\0';
1741 	}
1742 	else
1743 	{
1744 		sprintf(tmp_val, "%s%s of",
1745 		        ((y2 < y1) ? " North" : (y2 > y1) ? " South" : ""),
1746 		        ((x2 < x1) ? " West" : (x2 > x1) ? " East" : ""));
1747 	}
1748 
1749 	/* Prepare to ask which way to look */
1750 	sprintf(out_val,
1751 	        "Map sector [%d,%d], which is%s your sector.  Direction?",
1752 	        y2, x2, tmp_val);
1753 
1754 	msg_print(p_ptr, out_val);
1755 
1756 	/* Set the panel location */
1757 	p_ptr->panel_row = y2;
1758 	p_ptr->panel_col = x2;
1759 
1760 	/* Recalculate the boundaries */
1761 	panel_bounds(p_ptr);
1762 
1763 	/* Update stuff */
1764 	p_ptr->update |= (PU_MONSTERS);
1765 
1766 	/* Redraw map */
1767 	p_ptr->redraw |= (PR_MAP);
1768 
1769 	/* Window stuff */
1770 	p_ptr->window |= (PW_OVERHEAD);
1771 
1772 	/* Handle stuff */
1773 	handle_stuff(p_ptr);
1774 }
1775 
1776 
1777 
1778 
1779 
1780 
1781 /*
1782  * The table of "symbol info" -- each entry is a string of the form
1783  * "X:desc" where "X" is the trigger, and "desc" is the "info".
1784  */
1785 static cptr ident_info[] =
1786 {
1787 	" :A dark grid",
1788 	"!:A potion (or oil)",
1789 	"\":An amulet (or necklace)",
1790 	"#:A wall (or secret door)",
1791 	"$:Treasure (gold or gems)",
1792 	"%:A vein (magma or quartz)",
1793 	/* "&:unused", */
1794 	"':An open door",
1795 	"(:Soft armor",
1796 	"):A shield",
1797 	"*:A vein with treasure",
1798 	"+:A closed door",
1799 	",:Food (or mushroom patch)",
1800 	"-:A wand (or rod)",
1801 	".:Floor",
1802 	"/:A polearm (Axe/Pike/etc)",
1803 	/* "0:unused", */
1804 	"1:Entrance to General Store",
1805 	"2:Entrance to Armory",
1806 	"3:Entrance to Weaponsmith",
1807 	"4:Entrance to Temple",
1808 	"5:Entrance to Alchemy shop",
1809 	"6:Entrance to Magic store",
1810 	"7:Entrance to Black Market",
1811 	"8:Entrance to Tavern",
1812 	/* "9:unused", */
1813 	"::Rubble",
1814 	";:A glyph of warding",
1815 	"<:An up staircase",
1816 	"=:A ring",
1817 	">:A down staircase",
1818 	"?:A scroll",
1819 	"@:You",
1820 	"A:Angel",
1821 	"B:Bird",
1822 	"C:Canine",
1823 	"D:Ancient Dragon/Wyrm",
1824 	"E:Elemental",
1825 	"F:Dragon Fly",
1826 	"G:Ghost",
1827 	"H:Hybrid",
1828 	"I:Insect",
1829 	"J:Snake",
1830 	"K:Killer Beetle",
1831 	"L:Lich",
1832 	"M:Multi-Headed Reptile",
1833 	/* "N:unused", */
1834 	"O:Ogre",
1835 	"P:Giant Humanoid",
1836 	"Q:Quylthulg (Pulsing Flesh Mound)",
1837 	"R:Reptile/Amphibian",
1838 	"S:Spider/Scorpion/Tick",
1839 	"T:Troll",
1840 	"U:Major Demon",
1841 	"V:Vampire",
1842 	"W:Wight/Wraith/etc",
1843 	"X:Xorn/Xaren/etc",
1844 	"Y:Yeti",
1845 	"Z:Zephyr Hound",
1846 	"[:Hard armor",
1847 	"\\:A hafted weapon (mace/whip/etc)",
1848 	"]:Misc. armor",
1849 	"^:A trap",
1850 	"_:A staff",
1851 	/* "`:unused", */
1852 	"a:Ant",
1853 	"b:Bat",
1854 	"c:Centipede",
1855 	"d:Dragon",
1856 	"e:Floating Eye",
1857 	"f:Feline",
1858 	"g:Golem",
1859 	"h:Hobbit/Elf/Dwarf",
1860 	"i:Icky Thing",
1861 	"j:Jelly",
1862 	"k:Kobold",
1863 	"l:Louse",
1864 	"m:Mold",
1865 	"n:Naga",
1866 	"o:Orc",
1867 	"p:Person/Human",
1868 	"q:Quadruped",
1869 	"r:Rodent",
1870 	"s:Skeleton",
1871 	"t:Townsperson",
1872 	"u:Minor Demon",
1873 	"v:Vortex",
1874 	"w:Worm/Worm-Mass",
1875 	/* "x:unused", */
1876 	"y:Yeek",
1877 	"z:Zombie/Mummy",
1878 	"{:A missile (arrow/bolt/shot)",
1879 	"|:An edged weapon (sword/dagger/etc)",
1880 	"}:A launcher (bow/crossbow/sling)",
1881 	"~:A tool (or miscellaneous item)",
1882 	NULL
1883 };
1884 
1885 
1886 
1887 /*
1888  * Sorting hook -- Comp function -- "by monster something"
1889  *
1890  * We use "u" to point to array of monster indexes,
1891  * and "v" to select the type of sorting to perform on "u".
1892  */
ang_sort_comp_monsters(void * player_context,vptr u,vptr v,int a,int b)1893 bool ang_sort_comp_monsters(void *player_context, vptr u, vptr v, int a, int b)
1894 {
1895 	u16b *who = (u16b*)(u);
1896 
1897 	u16b *why = (u16b*)(v);
1898 
1899 	int w1 = who[a];
1900 	int w2 = who[b];
1901 
1902 	int z1, z2;
1903 
1904 	/* Sort by player kills */
1905 	if (*why & SORT_PKILL)
1906 	{
1907 		/* Extract player kills */
1908 		player_type  *p_ptr = (player_type*)player_context;
1909 		monster_lore *l1_ptr = p_ptr->l_list + w1;
1910 		monster_lore *l2_ptr = p_ptr->l_list + w2;
1911 
1912 		z1 = l1_ptr->pkills;
1913 		z2 = l2_ptr->pkills;
1914 
1915 		/* Compare player kills */
1916 		if (z1 < z2) return (TRUE);
1917 		if (z1 > z2) return (FALSE);
1918 	}
1919 
1920 
1921 	/* Sort by total kills */
1922 	if (*why & SORT_TKILL)
1923 	{
1924 		/* Extract total kills */
1925 		z1 = r_info[w1].r_tkills;
1926 		z2 = r_info[w2].r_tkills;
1927 
1928 		/* Compare total kills */
1929 		if (z1 < z2) return (TRUE);
1930 		if (z1 > z2) return (FALSE);
1931 	}
1932 
1933 
1934 	/* Sort by monster unique-ness */
1935 	if (*why & SORT_UNIQUE)
1936 	{
1937 		/* Extract unique-ness */
1938 		z1 = (r_info[w1].flags1 & RF1_UNIQUE);
1939 		z2 = (r_info[w2].flags1 & RF1_UNIQUE);
1940 
1941 		/* Compare unique-ness */
1942 		if (z1 < z2) return (TRUE);
1943 		if (z1 > z2) return (FALSE);
1944 	}
1945 
1946 
1947 	/* Sort by monster quest-ness */
1948 	if (*why & SORT_QUEST)
1949 	{
1950 		/* Extract unique-ness */
1951 		z1 = (r_info[w1].flags1 & RF1_QUESTOR);
1952 		z2 = (r_info[w2].flags1 & RF1_QUESTOR);
1953 
1954 		/* Compare unique-ness */
1955 		if (z1 < z2) return (TRUE);
1956 		if (z1 > z2) return (FALSE);
1957 	}
1958 
1959 
1960 	/* Sort by monster rich-ness */
1961 	if (*why & SORT_RICH)
1962 	{
1963 		/* Extract rich-ness (HACKY) */
1964 		z1 = monster_richness(w1);
1965 		z2 = monster_richness(w2);
1966 
1967 		/* Compare rich-ness */
1968 		if (z1 < z2) return (TRUE);
1969 		if (z1 > z2) return (FALSE);
1970 	}
1971 
1972 
1973 	/* Sort by monster level */
1974 	if (*why & SORT_LEVEL)
1975 	{
1976 		/* Extract levels */
1977 		z1 = r_info[w1].level;
1978 		z2 = r_info[w2].level;
1979 
1980 		/* Compare levels */
1981 		if (z1 < z2) return (TRUE);
1982 		if (z1 > z2) return (FALSE);
1983 	}
1984 
1985 	/* Sort by monster experience */
1986 	if (*why & SORT_EXP)
1987 	{
1988 		/* Extract experience */
1989 		z1 = r_info[w1].mexp;
1990 		z2 = r_info[w2].mexp;
1991 
1992 		/* Compare experience */
1993 		if (z1 < z2) return (TRUE);
1994 		if (z1 > z2) return (FALSE);
1995 	}
1996 
1997 	/* Sort by monster rarity */
1998 	if (*why & SORT_RARITY)
1999 	{
2000 		/* Extract rarity */
2001 		z1 = r_info[w1].rarity;
2002 		z2 = r_info[w2].rarity;
2003 
2004 		/* Compare rarity */
2005 		if (z1 < z2) return (TRUE);
2006 		if (z1 > z2) return (FALSE);
2007 	}
2008 
2009 	/* Compare indexes */
2010 	return (w1 <= w2);
2011 }
2012 
2013 
2014 /*
2015  * Sorting hook -- Swap function -- "for u16b"
2016  *
2017  * We use "u" to point to array of monster indexes,
2018  * and "v" to select the type of sorting to perform.
2019  */
ang_sort_swap_u16b(void * player_context,vptr u,vptr v,int a,int b)2020 void ang_sort_swap_u16b(void* player_context, vptr u, vptr v, int a, int b)
2021 {
2022 	player_type *p_ptr = (player_type*)player_context;
2023 	u16b *who = (u16b*)(u);
2024 	u16b holder;
2025 
2026 	/* XXX XXX */
2027 	v = v ? v : 0;
2028 
2029 	/* Swap */
2030 	holder = who[a];
2031 	who[a] = who[b];
2032 	who[b] = holder;
2033 }
2034 
2035 
2036 /*
2037  * Identify a character
2038  *
2039  * Note that the player ghosts are ignored. XXX XXX XXX
2040  */
do_cmd_query_symbol(player_type * p_ptr,char sym)2041 void do_cmd_query_symbol(player_type *p_ptr, char sym)
2042 {
2043 	int		i;
2044 	char	buf[128];
2045 
2046 
2047 	/* If no symbol, abort --KLJ-- */
2048 	if (!sym)
2049 		return;
2050 
2051 	/* Find that character info, and describe it */
2052 	for (i = 0; ident_info[i]; ++i)
2053 	{
2054 		if (sym == ident_info[i][0]) break;
2055 	}
2056 
2057 	/* Describe */
2058 	if (ident_info[i])
2059 	{
2060 		sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
2061 	}
2062 	else
2063 	{
2064 		sprintf(buf, "%c - %s.", sym, "Unknown Symbol");
2065 	}
2066 
2067 	/* Display the result */
2068 	msg_print(p_ptr, buf);
2069 
2070 	/* MEGA-HACK!! Add monster recall info BASED on letter! This ommits creeping coins and mimics :( */
2071 	if ( (sym >= 'a' && sym <= 'z') || (sym >= 'A' && sym <= 'Z')	)
2072 		do_cmd_monster_desc_all(p_ptr, sym);
2073 }
2074 
2075 /*
2076  * Display monster list as a pop-up on mainscreen.
2077  * See also "fix_monlist()" for windowed version.
2078  */
do_cmd_monlist(player_type * p_ptr)2079 void do_cmd_monlist(player_type *p_ptr)
2080 {
2081 	/* Prepare 'visible monsters' list */
2082 	display_monlist(p_ptr);
2083 
2084 	/* Send it */
2085 	send_prepared_popup(p_ptr, "Visible Monsters (Snapshot)");
2086 
2087 	return;
2088 }
2089 
2090 /*
2091  * Display item list as a pop-up on mainscreen.
2092  * See also "fix_itemlist()" for windowed version.
2093  */
do_cmd_itemlist(player_type * p_ptr)2094 void do_cmd_itemlist(player_type *p_ptr)
2095 {
2096 	/* Prepare 'visible items' list */
2097 	display_itemlist(p_ptr);
2098 
2099 	/* Send it */
2100 	/* (Fits player screen) */
2101 	if (p_ptr->last_info_line < p_ptr->stream_hgt[STREAM_SPECIAL_TEXT] - 2)
2102 	{
2103 		send_prepared_popup(p_ptr, "Visible Items (Snapshot)");
2104 	}
2105 	/* (Doesn't fit, requires browsing) */
2106 	else
2107 	{
2108 		send_term_header(p_ptr, NTERM_BROWSE | NTERM_CLEAR, "Visible Items (Snapshot)");
2109 		send_prepared_info(p_ptr, NTERM_WIN_SPECIAL, STREAM_SPECIAL_TEXT, NTERM_BROWSE);
2110 	}
2111 
2112 	return;
2113 }
2114