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