root/trunk/src/cmd2.c

Revision 938, 40.4 kB (checked in by takkaria, 2 months ago)

Remove the "coin_type" global.

  • Property svn:eol-style set to native
Line 
1 /*
2  * File: cmd2.c
3  * Purpose: Chest and door opening/closing, disarming, running, resting, &c.
4  *
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 #include "angband.h"
19 #include "tvalsval.h"
20
21 /*
22  * Go up one level
23  */
24 void do_cmd_go_up(void)
25 {
26         /* Verify stairs */
27         if (cave_feat[p_ptr->py][p_ptr->px] != FEAT_LESS)
28         {
29                 msg_print("I see no up staircase here.");
30                 return;
31         }
32
33         /* Ironman */
34         if (adult_ironman)
35         {
36                 msg_print("Nothing happens!");
37                 return;
38         }
39
40         /* Hack -- take a turn */
41         p_ptr->energy_use = 100;
42
43         /* Success */
44         message(MSG_STAIRS_UP, 0, "You enter a maze of up staircases.");
45
46         /* Create a way back */
47         p_ptr->create_up_stair = FALSE;
48         p_ptr->create_down_stair = TRUE;
49
50         /* New depth */
51         p_ptr->depth--;
52
53         /* Leaving */
54         p_ptr->leaving = TRUE;
55 }
56
57
58 /*
59  * Go down one level
60  */
61 void do_cmd_go_down(void)
62 {
63         /* Verify stairs */
64         if (cave_feat[p_ptr->py][p_ptr->px] != FEAT_MORE)
65         {
66                 msg_print("I see no down staircase here.");
67                 return;
68         }
69
70         /* Hack -- take a turn */
71         p_ptr->energy_use = 100;
72
73         /* Success */
74         message(MSG_STAIRS_DOWN, 0, "You enter a maze of down staircases.");
75
76         /* Create a way back */
77         p_ptr->create_up_stair = TRUE;
78         p_ptr->create_down_stair = FALSE;
79
80         /* New level */
81         p_ptr->depth++;
82
83         /* Leaving */
84         p_ptr->leaving = TRUE;
85 }
86
87
88
89 /*
90  * Simple command to "search" for one turn
91  */
92 void do_cmd_search(void)
93 {
94         /* Allow repeated command */
95         if (p_ptr->command_arg)
96         {
97                 /* Set repeat count */
98                 p_ptr->command_rep = p_ptr->command_arg - 1;
99
100                 /* Redraw the state */
101                 p_ptr->redraw |= (PR_STATE);
102
103                 /* Cancel the arg */
104                 p_ptr->command_arg = 0;
105         }
106
107         /* Take a turn */
108         p_ptr->energy_use = 100;
109
110         /* Search */
111         search();
112 }
113
114
115 /*
116  * Hack -- toggle search mode
117  */
118 void do_cmd_toggle_search(void)
119 {
120         /* Stop searching */
121         if (p_ptr->searching)
122         {
123                 /* Clear the searching flag */
124                 p_ptr->searching = FALSE;
125
126                 /* Recalculate bonuses */
127                 p_ptr->update |= (PU_BONUS);
128
129                 /* Redraw the state */
130                 p_ptr->redraw |= (PR_STATE);
131         }
132
133         /* Start searching */
134         else
135         {
136                 /* Set the searching flag */
137                 p_ptr->searching = TRUE;
138
139                 /* Update stuff */
140                 p_ptr->update |= (PU_BONUS);
141
142                 /* Redraw stuff */
143                 p_ptr->redraw |= (PR_STATE | PR_SPEED);
144         }
145 }
146
147
148
149 /*
150  * Determine if a grid contains a chest
151  */
152 static s16b chest_check(int y, int x)
153 {
154         s16b this_o_idx, next_o_idx = 0;
155
156
157         /* Scan all objects in the grid */
158         for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx)
159         {
160                 object_type *o_ptr;
161
162                 /* Get the object */
163                 o_ptr = &o_list[this_o_idx];
164
165                 /* Get the next object */
166                 next_o_idx = o_ptr->next_o_idx;
167
168                 /* Skip unknown chests XXX XXX */
169                 /* if (!o_ptr->marked) continue; */
170
171                 /* Check for chest */
172                 if (o_ptr->tval == TV_CHEST) return (this_o_idx);
173         }
174
175         /* No chest */
176         return (0);
177 }
178
179
180 /*
181  * Allocate objects upon opening a chest
182  *
183  * Disperse treasures from the given chest, centered at (x,y).
184  *
185  * Small chests often contain "gold", while Large chests always contain
186  * items.  Wooden chests contain 2 items, Iron chests contain 4 items,
187  * and Steel chests contain 6 items.  The "value" of the items in a
188  * chest is based on the "power" of the chest, which is in turn based
189  * on the level on which the chest is generated.
190  */
191 static void chest_death(int y, int x, s16b o_idx)
192 {
193         int number, value;
194
195         bool tiny;
196
197         object_type *o_ptr;
198
199         object_type *i_ptr;
200         object_type object_type_body;
201
202
203         /* Get the chest */
204         o_ptr = &o_list[o_idx];
205
206         /* Small chests often hold "gold" */
207         tiny = (o_ptr->sval < SV_CHEST_MIN_LARGE);
208
209         /* Determine how much to drop (see above) */
210         number = (o_ptr->sval % SV_CHEST_MIN_LARGE) * 2;
211
212         /* Zero pval means empty chest */
213         if (!o_ptr->pval) number = 0;
214
215         /* Opening a chest */
216         opening_chest = TRUE;
217
218         /* Determine the "value" of the items */
219         value = ABS(o_ptr->pval) + 10;
220
221         /* Drop some objects (non-chests) */
222         for (; number > 0; --number)
223         {
224                 /* Get local object */
225                 i_ptr = &object_type_body;
226
227                 /* Wipe the object */
228                 object_wipe(i_ptr);
229
230                 /* Small chests often drop gold */
231                 if (tiny && (randint0(100) < 75))
232                         make_gold(i_ptr, value, SV_GOLD_ANY);
233
234                 /* Otherwise drop an item */
235                 else
236                 {
237                         if (!make_object(i_ptr, value, FALSE, FALSE))
238                                 continue;
239                 }
240
241                 /* Drop it in the dungeon */
242                 drop_near(i_ptr, -1, y, x);
243         }
244
245         /* No longer opening a chest */
246         opening_chest = FALSE;
247
248         /* Empty */
249         o_ptr->pval = 0;
250
251         /* Known */
252         object_known(o_ptr);
253 }
254
255
256 /*
257  * Chests have traps too.
258  *
259  * Exploding chest destroys contents (and traps).
260  * Note that the chest itself is never destroyed.
261  */
262 static void chest_trap(int y, int x, s16b o_idx)
263 {
264         int i, trap;
265
266         object_type *o_ptr = &o_list[o_idx];
267
268
269         /* Ignore disarmed chests */
270         if (o_ptr->pval <= 0) return;
271
272         /* Obtain the traps */
273         trap = chest_traps[o_ptr->pval];
274
275         /* Lose strength */
276         if (trap & (CHEST_LOSE_STR))
277         {
278                 msg_print("A small needle has pricked you!");
279                 take_hit(damroll(1, 4), "a poison needle");
280                 (void)do_dec_stat(A_STR, FALSE);
281         }
282
283         /* Lose constitution */
284         if (trap & (CHEST_LOSE_CON))
285         {
286                 msg_print("A small needle has pricked you!");
287                 take_hit(damroll(1, 4), "a poison needle");
288                 (void)do_dec_stat(A_CON, FALSE);
289         }
290
291         /* Poison */
292         if (trap & (CHEST_POISON))
293         {
294                 msg_print("A puff of green gas surrounds you!");
295                 if (!(p_ptr->resist_pois || p_ptr->timed[TMD_OPP_POIS]))
296                 {
297                         (void)inc_timed(TMD_POISONED, 10 + randint1(20));
298                 }
299         }
300
301         /* Paralyze */
302         if (trap & (CHEST_PARALYZE))
303         {
304                 msg_print("A puff of yellow gas surrounds you!");
305                 if (!p_ptr->free_act)
306                 {
307                         (void)inc_timed(TMD_PARALYZED, 10 + randint1(20));
308                 }
309         }
310
311         /* Summon monsters */
312         if (trap & (CHEST_SUMMON))
313         {
314                 int num = 2 + randint1(3);
315                 msg_print("You are enveloped in a cloud of smoke!");
316                 sound(MSG_SUM_MONSTER);
317                 for (i = 0; i < num; i++)
318                 {
319                         (void)summon_specific(y, x, p_ptr->depth, 0);
320                 }
321         }
322
323         /* Explode */
324         if (trap & (CHEST_EXPLODE))
325         {
326                 msg_print("There is a sudden explosion!");
327                 msg_print("Everything inside the chest is destroyed!");
328                 o_ptr->pval = 0;
329                 take_hit(damroll(5, 8), "an exploding chest");
330         }
331 }
332
333
334 /*
335  * Attempt to open the given chest at the given location
336  *
337  * Assume there is no monster blocking the destination
338  *
339  * Returns TRUE if repeated commands may continue
340  */
341 static bool do_cmd_open_chest(int y, int x, s16b o_idx)
342 {
343         int i, j;
344
345         bool flag = TRUE;
346
347         bool more = FALSE;
348
349         object_type *o_ptr = &o_list[o_idx];
350
351
352         /* Attempt to unlock it */
353         if (o_ptr->pval > 0)
354         {
355                 /* Assume locked, and thus not open */
356                 flag = FALSE;
357
358                 /* Get the "disarm" factor */
359                 i = p_ptr->skills[SKILL_DISARM];
360
361                 /* Penalize some conditions */
362                 if (p_ptr->timed[TMD_BLIND] || no_lite()) i = i / 10;
363                 if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;
364
365                 /* Extract the difficulty */
366                 j = i - o_ptr->pval;
367
368                 /* Always have a small chance of success */
369                 if (j < 2) j = 2;
370
371                 /* Success -- May still have traps */
372                 if (randint0(100) < j)
373                 {
374                         message(MSG_LOCKPICK, 0, "You have picked the lock.");
375                         gain_exp(1);
376                         flag = TRUE;
377                 }
378
379                 /* Failure -- Keep trying */
380                 else
381                 {
382                         /* We may continue repeating */
383                         more = TRUE;
384                         if (flush_failure) flush();
385                         message(MSG_LOCKPICK_FAIL, 0, "You failed to pick the lock.");
386                 }
387         }
388
389         /* Allowed to open */
390         if (flag)
391         {
392                 /* Apply chest traps, if any */
393                 chest_trap(y, x, o_idx);
394
395                 /* Let the Chest drop items */
396                 chest_death(y, x, o_idx);
397
398                 /* Squelch chest if autosquelch calls for it */
399                 p_ptr->notice |= PN_SQUELCH;
400
401                 /* Redraw chest, to be on the safe side (it may have been squelched) */
402                 lite_spot(y, x);
403         }
404
405         /* Result */
406         return (more);
407 }
408
409
410 /*
411  * Attempt to disarm the chest at the given location
412  *
413  * Assume there is no monster blocking the destination
414  *
415  * Returns TRUE if repeated commands may continue
416  */
417 static bool do_cmd_disarm_chest(int y, int x, s16b o_idx)
418 {
419         int i, j;
420
421         bool more = FALSE;
422
423         object_type *o_ptr = &o_list[o_idx];
424
425
426         /* Get the "disarm" factor */
427         i = p_ptr->skills[SKILL_DISARM];
428
429         /* Penalize some conditions */
430         if (p_ptr->timed[TMD_BLIND] || no_lite()) i = i / 10;
431         if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;
432
433         /* Extract the difficulty */
434         j = i - o_ptr->pval;
435
436         /* Always have a small chance of success */
437         if (j < 2) j = 2;
438
439         /* Must find the trap first. */
440         if (!object_known_p(o_ptr))
441         {
442                 msg_print("I don't see any traps.");
443         }
444
445         /* Already disarmed/unlocked */
446         else if (o_ptr->pval <= 0)
447         {
448                 msg_print("The chest is not trapped.");
449         }
450
451         /* No traps to find. */
452         else if (!chest_traps[o_ptr->pval])
453         {
454                 msg_print("The chest is not trapped.");
455         }
456
457         /* Success (get a lot of experience) */
458         else if (randint0(100) < j)
459         {
460                 message(MSG_DISARM, 0, "You have disarmed the chest.");
461                 gain_exp(o_ptr->pval);
462                 o_ptr->pval = (0 - o_ptr->pval);
463         }
464
465         /* Failure -- Keep trying */
466         else if ((i > 5) && (randint1(i) > 5))
467         {
468                 /* We may keep trying */
469                 more = TRUE;
470                 if (flush_failure) flush();
471                 msg_print("You failed to disarm the chest.");
472         }
473
474         /* Failure -- Set off the trap */
475         else
476         {
477                 msg_print("You set off a trap!");
478                 chest_trap(y, x, o_idx);
479         }
480
481         /* Result */
482         return (more);
483 }
484
485
486 /*
487  * Return TRUE if the given feature is an open door
488  */
489 static bool is_open(int feat)
490 {
491         return (feat == FEAT_OPEN);
492 }
493
494
495 /*
496  * Return TRUE if the given feature is a closed door
497  */
498 static bool is_closed(int feat)
499 {
500         return ((feat >= FEAT_DOOR_HEAD) &&
501                 (feat <= FEAT_DOOR_TAIL));
502 }
503
504
505 /*
506  * Return TRUE if the given feature is a trap
507  */
508 static bool is_trap(int feat)
509 {
510         return ((feat >= FEAT_TRAP_HEAD) &&
511                 (feat <= FEAT_TRAP_TAIL));
512 }
513
514
515 /*
516  * Return the number of doors/traps around (or under) the character.
517  */
518 static int count_feats(int *y, int *x, bool (*test)(int feat), bool under)
519 {
520         int d;
521         int xx, yy;
522         int count = 0; /* Count how many matches */
523
524         /* Check around (and under) the character */
525         for (d = 0; d < 9; d++)
526         {
527                 /* if not searching under player continue */
528                 if ((d == 8) && !under) continue;
529
530                 /* Extract adjacent (legal) location */
531                 yy = p_ptr->py + ddy_ddd[d];
532                 xx = p_ptr->px + ddx_ddd[d];
533
534                 /* Paranoia */
535                 if (!in_bounds_fully(yy, xx)) continue;
536
537                 /* Must have knowledge */
538                 if (!(cave_info[yy][xx] & (CAVE_MARK))) continue;
539
540                 /* Not looking for this feature */
541                 if (!((*test)(cave_feat[yy][xx]))) continue;
542
543                 /* Count it */
544                 ++count;
545
546                 /* Remember the location of the last door found */
547                 *y = yy;
548                 *x = xx;
549         }
550
551         /* All done */
552         return count;
553 }
554
555
556 /*
557  * Return the number of chests around (or under) the character.
558  * If requested, count only trapped chests.
559  */
560 static int count_chests(int *y, int *x, bool trapped)
561 {
562         int d, count, o_idx;
563
564         object_type *o_ptr;
565
566         /* Count how many matches */
567         count = 0;
568
569         /* Check around (and under) the character */
570         for (d = 0; d < 9; d++)
571         {
572                 /* Extract adjacent (legal) location */
573                 int yy = p_ptr->py + ddy_ddd[d];
574                 int xx = p_ptr->px + ddx_ddd[d];
575
576                 /* No (visible) chest is there */
577                 if ((o_idx = chest_check(yy, xx)) == 0) continue;
578
579                 /* Grab the object */
580                 o_ptr = &o_list[o_idx];
581
582                 /* Already open */
583                 if (o_ptr->pval == 0) continue;
584
585                 /* No (known) traps here */
586                 if (trapped &&
587                     (!object_known_p(o_ptr) ||
588                      (o_ptr->pval < 0) ||
589                      !chest_traps[o_ptr->pval]))
590                 {
591                         continue;
592                 }
593
594                 /* Count it */
595                 ++count;
596
597                 /* Remember the location of the last chest found */
598                 *y = yy;
599                 *x = xx;
600         }
601
602         /* All done */
603         return count;
604 }
605
606
607 /*
608  * Extract a "direction" which will move one step from the player location
609  * towards the given "target" location (or "5" if no motion necessary).
610  */
611 static int coords_to_dir(int y, int x)
612 {
613         return (motion_dir(p_ptr->py, p_ptr->px, y, x));
614 }
615
616
617 /*
618  * Determine if a given grid may be "opened"
619  */
620 static bool do_cmd_open_test(int y, int x)
621 {
622         /* Must have knowledge */
623         if (!(cave_info[y][x] & (CAVE_MARK)))
624         {
625                 /* Message */
626                 msg_print("You see nothing there.");
627
628                 /* Nope */
629                 return (FALSE);
630         }
631
632         /* Must be a closed door */
633         if (!((cave_feat[y][x] >= FEAT_DOOR_HEAD) &&
634               (cave_feat[y][x] <= FEAT_DOOR_TAIL)))
635         {
636                 /* Message */
637                 message(MSG_NOTHING_TO_OPEN, 0, "You see nothing there to open.");
638
639                 /* Nope */
640                 return (FALSE);
641         }
642
643         /* Okay */
644         return (TRUE);
645 }
646
647
648 /*
649  * Perform the basic "open" command on doors
650  *
651  * Assume there is no monster blocking the destination
652  *
653  * Returns TRUE if repeated commands may continue
654  */
655 static bool do_cmd_open_aux(int y, int x)
656 {
657         int i, j;
658
659         bool more = FALSE;
660
661
662         /* Verify legality */
663         if (!do_cmd_open_test(y, x)) return (FALSE);
664
665
666         /* Jammed door */
667         if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x08)
668         {
669                 /* Stuck */
670                 msg_print("The door appears to be stuck.");
671         }
672
673         /* Locked door */
674         else if (cave_feat[y][x] >= FEAT_DOOR_HEAD + 0x01)
675         {
676                 /* Disarm factor */
677                 i = p_ptr->skills[SKILL_DISARM];
678
679                 /* Penalize some conditions */
680                 if (p_ptr->timed[TMD_BLIND] || no_lite()) i = i / 10;
681                 if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE]) i = i / 10;
682
683                 /* Extract the lock power */
684                 j = cave_feat[y][x] - FEAT_DOOR_HEAD;
685
686                 /* Extract the difficulty XXX XXX XXX */
687                 j = i - (j * 4);
688
689                 /* Always have a small chance of success */
690                 if (j < 2) j = 2;
691
692                 /* Success */
693                 if (randint0(100) < j)
694                 {
695                         /* Message */
696                         message(MSG_LOCKPICK, 0, "You have picked the lock.");
697
698                         /* Open the door */
699                         cave_set_feat(y, x, FEAT_OPEN);
700
701                         /* Update the visuals */
702                         p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS);
703
704                         /* Experience */
705                         gain_exp(1);
706                 }
707
708                 /* Failure */
709                 else
710                 {
711                         /* Failure */
712                         if (flush_failure) flush();
713
714                         /* Message */
715                         message(MSG_LOCKPICK_FAIL, 0, "You failed to pick the lock.");
716
717                         /* We may keep trying */
718                         more = TRUE;
719                 }
720         }
721
722         /* Closed door */
723         else
724         {
725                 /* Open the door */
726                 cave_set_feat(y, x, FEAT_OPEN);
727
728                 /* Update the visuals */
729                 p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS);
730
731                 /* Sound */
732                 sound(MSG_OPENDOOR);
733         }
734
735         /* Result */
736         return (more);
737 }
738
739
740
741 /*
742  * Open a closed/locked/jammed door or a closed/locked chest.
743  *
744  * Unlocking a locked door/chest is worth one experience point.
745  */
746 void do_cmd_open(void)
747 {
748         int y, x, dir;
749
750         s16b o_idx;
751
752         bool more = FALSE;
753
754
755         /* Easy Open */
756         if (easy_open)
757         {
758                 int num_doors, num_chests;
759
760                 /* Count closed doors */
761                 num_doors = count_feats(&y, &x, is_closed, FALSE);
762
763                 /* Count chests (locked) */
764                 num_chests = count_chests(&y, &x, FALSE);
765
766                 /* See if only one target */
767                 if ((num_doors + num_chests) == 1)
768                 {
769                         p_ptr->command_dir = coords_to_dir(y, x);
770                 }
771         }
772
773         /* Get a direction (or abort) */
774         if (!get_rep_dir(&dir)) return;
775
776         /* Get location */
777         y = p_ptr->py + ddy[dir];
778         x = p_ptr->px + ddx[dir];
779
780         /* Check for chests */
781         o_idx = chest_check(y, x);
782
783
784         /* Verify legality */
785         if (!o_idx && !do_cmd_open_test(y, x)) return;
786
787
788         /* Take a turn */
789         p_ptr->energy_use = 100;
790
791         /* Apply confusion */
792         if (confuse_dir(&dir))
793         {
794                 /* Get location */
795                 y = p_ptr->py + ddy[dir];
796                 x = p_ptr->px + ddx[dir];
797
798                 /* Check for chest */
799                 o_idx = chest_check(y, x);
800         }
801
802
803         /* Allow repeated command */
804         if (p_ptr->command_arg)
805         {
806                 /* Set repeat count */
807                 p_ptr->command_rep = p_ptr->command_arg - 1;
808
809                 /* Redraw the state */
810                 p_ptr->redraw |= (PR_STATE);
811
812                 /* Cancel the arg */
813                 p_ptr->command_arg = 0;
814         }
815
816         /* Monster */
817         if (cave_m_idx[y][x] > 0)
818         {
819                 /* Message */
820                 msg_print("There is a monster in the way!");
821
822                 /* Attack */
823                 py_attack(y, x);
824         }
825
826         /* Chest */
827         else if (o_idx)
828         {
829                 /* Open the chest */
830                 more = do_cmd_open_chest(y, x, o_idx);
831         }
832
833         /* Door */
834         else
835         {
836                 /* Open the door */
837                 more = do_cmd_open_aux(y, x);
838         }
839
840         /* Cancel repeat unless we may continue */
841         if (!more) disturb(0, 0);
842 }
843
844
845 /*
846  * Determine if a given grid may be "closed"
847  */
848 static bool do_cmd_close_test(int y, int x)
849 {
850         /* Must have knowledge */
851         if (!(cave_info[y][x] & (CAVE_MARK)))
852         {
853                 /* Message */
854                 msg_print("You see nothing there.");
855
856                 /* Nope */
857                 return (FALSE);
858         }
859
860         /* Require open/broken door */
861         if ((cave_feat[y][x] != FEAT_OPEN) &&
862             (cave_feat[y][x] != FEAT_BROKEN))
863         {
864                 /* Message */
865                 msg_print("You see nothing there to close.");
866
867                 /* Nope */
868                 return (FALSE);
869         }
870
871         /* Okay */
872         return (TRUE);
873 }
874
875
876 /*
877  * Perform the basic "close" command
878  *
879  * Assume there is no monster blocking the destination
880  *
881  * Returns TRUE if repeated commands may continue
882  */
883 static bool do_cmd_close_aux(int y, int x)
884 {
885         bool more = FALSE;
886
887
888         /* Verify legality */
889         if (!do_cmd_close_test(y, x)) return (FALSE);
890
891
892         /* Broken door */
893         if (cave_feat[y][x] == FEAT_BROKEN)
894         {
895                 /* Message */
896                 msg_print("The door appears to be broken.");
897         }
898
899         /* Open door */
900         else
901         {
902                 /* Close the door */
903                 cave_set_feat(y, x, FEAT_DOOR_HEAD + 0x00);
904
905                 /* Update the visuals */
906                 p_ptr->update |= (PU_UPDATE_VIEW | PU_MONSTERS);
907
908                 /* Sound */
909                 sound(MSG_SHUTDOOR);
910         }
911
912         /* Result */
913         return (more);
914 }
915
916
917 /*
918  * Close an open door.
919  */
920 void do_cmd_close(void)
921 {
922         int y, x, dir;
923
924         bool more = FALSE;
925
926
927         /* Easy Close */
928         if (easy_open)
929         {
930                 /* Count open doors */
931                 if (count_feats(&y, &x, is_open, FALSE) == 1)
932                 {
933                         p_ptr->command_dir = coords_to_dir(y, x);
934                 }
935         }
936
937         /* Get a direction (or abort) */
938         if (!get_rep_dir(&dir)) return;
939
940         /* Get location */
941         y = p_ptr->py + ddy[dir];
942         x = p_ptr->px + ddx[dir];
943
944
945         /* Verify legality */
946         if (!do_cmd_close_test(y, x)) return;
947
948
949         /* Take a turn */
950         p_ptr->energy_use = 100;
951
952         /* Apply confusion */
953         if (confuse_dir(&dir))
954         {
955                 /* Get location */
956                 y = p_ptr->py + ddy[dir];
957                 x = p_ptr->px + ddx[dir];
958         }
959
960
961         /* Allow repeated command */
962         if (p_ptr->command_arg)
963         {
964                 /* Set repeat count */
965                 p_ptr->command_rep = p_ptr->command_arg - 1;
966
967                 /* Redraw the state */
968                 p_ptr->redraw |= (PR_STATE);
969
970                 /* Cancel the arg */
971                 p_ptr->command_arg = 0;
972         }
973
974         /* Monster */
975         if (cave_m_idx[y][x] > 0)
976         {
977                 /* Message */
978                 msg_print("There is a monster in the way!");
979
980                 /* Attack */
981                 py_attack(y, x);
982         }
983
984         /* Door */
985         else
986         {
987                 /* Close door */
988                 more = do_cmd_close_aux(y, x);
989         }
990
991