"crawl -seed XXX", for repeatable tests.
[crawl:crawl.git] / crawl-ref / source / main.cc
1 /*
2  *  File:       main.cc
3  *  Summary:    Main entry point, event loop, and some initialization functions
4  *  Written by: Linley Henzell
5  */
6
7 #include "AppHdr.h"
8
9 #include <string>
10 #include <algorithm>
11
12 // I don't seem to need values.h for VACPP..
13 #if !defined(__IBMCPP__)
14 #include <limits.h>
15 #endif
16
17 #include <errno.h>
18 #include <time.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <sstream>
24 #include <iostream>
25
26 #ifdef USE_UNIX_SIGNALS
27 #include <signal.h>
28 #endif
29
30 #include "externs.h"
31
32 #include "abl-show.h"
33 #include "abyss.h"
34 #include "areas.h"
35 #include "artefact.h"
36 #include "arena.h"
37 #include "beam.h"
38 #include "branch.h"
39 #include "chardump.h"
40 #include "cio.h"
41 #include "cloud.h"
42 #include "clua.h"
43 #include "command.h"
44 #include "coord.h"
45 #include "coordit.h"
46 #include "ctest.h"
47 #include "crash.h"
48 #include "database.h"
49 #include "dbg-maps.h"
50 #include "dbg-scan.h"
51 #include "debug.h"
52 #include "delay.h"
53 #include "describe.h"
54 #include "dgn-overview.h"
55 #include "dgn-shoals.h"
56 #include "dlua.h"
57 #include "directn.h"
58 #include "dungeon.h"
59 #include "effects.h"
60 #include "env.h"
61 #include "map_knowledge.h"
62 #include "fprop.h"
63 #include "fight.h"
64 #include "files.h"
65 #include "food.h"
66 #include "godabil.h"
67 #include "godprayer.h"
68 #include "hiscores.h"
69 #include "initfile.h"
70 #include "invent.h"
71 #include "item_use.h"
72 #include "it_use3.h"
73 #include "itemname.h"
74 #include "itemprop.h"
75 #include "items.h"
76 #include "lev-pand.h"
77 #include "los.h"
78 #include "luaterp.h"
79 #include "macro.h"
80 #include "makeitem.h"
81 #include "mapmark.h"
82 #include "maps.h"
83 #include "message.h"
84 #include "misc.h"
85 #include "mon-act.h"
86 #include "mon-cast.h"
87 #include "mon-iter.h"
88 #include "mon-stuff.h"
89 #include "mon-util.h"
90 #include "mutation.h"
91 #include "newgame.h"
92 #include "ng-init.h"
93 #include "notes.h"
94 #include "options.h"
95 #include "ouch.h"
96 #include "output.h"
97 #include "player.h"
98 #include "quiver.h"
99 #include "random.h"
100 #include "religion.h"
101 #include "godconduct.h"
102 #include "shopping.h"
103 #include "skills.h"
104 #include "skills2.h"
105 #include "species.h"
106 #include "spells1.h"
107 #include "spells2.h"
108 #include "spells3.h"
109 #include "spells4.h"
110 #include "spl-book.h"
111 #include "spl-cast.h"
112 #include "spl-util.h"
113 #include "stash.h"
114 #include "state.h"
115 #include "stuff.h"
116 #include "tags.h"
117 #include "terrain.h"
118 #include "transform.h"
119 #include "traps.h"
120 #include "travel.h"
121 #include "tutorial.h"
122 #include "view.h"
123 #include "shout.h"
124 #include "viewchar.h"
125 #include "viewgeom.h"
126 #include "stash.h"
127 #include "wiz-dgn.h"
128 #include "wiz-fsim.h"
129 #include "wiz-item.h"
130 #include "wiz-mon.h"
131 #include "wiz-you.h"
132 #include "xom.h"
133
134 #ifdef USE_TILE
135 #include "tiles.h"
136 #include "tiledef-dngn.h"
137 #endif
138
139 #ifdef DGL_SIMPLE_MESSAGING
140 #include "dgl-message.h"
141 #endif
142
143 // ----------------------------------------------------------------------
144 // Globals whose construction/destruction order needs to be managed
145 // ----------------------------------------------------------------------
146
147 CLua clua(true);
148 CLua dlua(false);      // Lua interpreter for the dungeon builder.
149 crawl_environment env; // Requires dlua.
150 player you;
151 system_environment SysEnv;
152 game_state crawl_state;
153
154
155
156 std::string init_file_error;    // externed in newgame.cc
157
158 char info[ INFO_SIZE ];         // messaging queue extern'd everywhere {dlb}
159
160 int stealth;                    // externed in view.cc
161
162 void world_reacts();
163
164 static key_recorder repeat_again_rec;
165
166 // Clockwise, around the compass from north (same order as enum RUN_DIR)
167 const struct coord_def Compass[8] =
168 {
169     coord_def(0, -1), coord_def(1, -1), coord_def(1, 0), coord_def(1, 1),
170     coord_def(0, 1), coord_def(-1, 1), coord_def(-1, 0), coord_def(-1, -1),
171 };
172
173 // Functions in main module
174 static void _do_berserk_no_combat_penalty(void);
175 static bool _initialise(void);
176 static void _input(void);
177 static void _move_player(int move_x, int move_y);
178 static void _move_player(coord_def move);
179 static int  _check_adjacent(dungeon_feature_type feat, coord_def& delta);
180 static void _open_door(coord_def move, bool check_confused = true);
181 static void _open_door(int x, int y, bool check_confused = true)
182 {
183     _open_door(coord_def(x, y), check_confused);
184 }
185 static void _close_door(coord_def move);
186 static void _start_running(int dir, int mode);
187
188 static void _prep_input();
189 static command_type _get_next_cmd();
190 static keycode_type _get_next_keycode();
191 static command_type _keycode_to_command(keycode_type key);
192 static void _setup_cmd_repeat();
193 static void _do_prev_cmd_again();
194 static void _update_replay_state();
195
196 static void _show_commandline_options_help();
197 static void _wanderer_startup_message();
198 static void _god_greeting_message(bool game_start);
199 static void _take_starting_note();
200 static void _startup_tutorial();
201
202 static void _compile_time_asserts();
203
204 //
205 //  It all starts here. Some initialisations are run first, then straight
206 //  to new_game and then input.
207 //
208
209 #ifdef USE_TILE
210 #include <SDL_main.h>
211 #endif
212
213 int main(int argc, char *argv[])
214 {
215     _compile_time_asserts();  // Just to quiet "unused static function" warning.
216
217     init_crash_handler();
218
219     // Hardcoded initial keybindings.
220     init_keybindings();
221
222     // Load in the system environment variables
223     get_system_environment();
224
225     // Parse command line args -- look only for initfile & crawl_dir entries.
226     if (!parse_args(argc, argv, true))
227     {
228         _show_commandline_options_help();
229         return 1;
230     }
231
232     // Init monsters up front - needed to handle the mon_glyph option right.
233     init_monsters();
234
235     // Init name cache so that we can parse stash_filter by item name.
236     init_properties();
237     init_item_name_cache();
238
239     // Read the init file.
240     init_file_error = read_init_file();
241
242     // Now parse the args again, looking for everything else.
243     parse_args(argc, argv, false);
244
245     if (Options.sc_entries != 0 || !SysEnv.scorefile.empty())
246     {
247         hiscores_print_all(Options.sc_entries, Options.sc_format);
248         return 0;
249     }
250     else
251     {
252         // Don't allow scorefile override for actual gameplay, only for
253         // score listings.
254         SysEnv.scorefile.clear();
255     }
256
257 #ifdef USE_TILE
258     if (!tiles.initialise())
259         return -1;
260 #endif
261
262     const bool game_start = _initialise();
263
264     // Override some options for tutorial.
265     init_tutorial_options();
266
267     msg::stream << "Welcome" << (game_start? "" : " back") << ", "
268                 << you.your_name << " the "
269                 << species_name(you.species,you.experience_level)
270                 << " " << you.class_name << "."
271                 << std::endl;
272
273     // Activate markers only after the welcome message, so the
274     // player can see any resulting messages.
275     env.markers.activate_all();
276
277 #ifdef USE_TILE
278     viewwindow(false);
279 #endif
280
281     if (game_start && you.char_class == JOB_WANDERER)
282         _wanderer_startup_message();
283
284     _god_greeting_message(game_start);
285
286     // Warn player about their weapon, if unsuitable.
287     wield_warning(false);
288
289     mpr("Press <w>?</w> for a list of commands and other information.");
290
291     _prep_input();
292
293     if (game_start)
294     {
295         if (Tutorial.tutorial_left)
296             _startup_tutorial();
297         _take_starting_note();
298     }
299     else
300         tutorial_load_game();
301
302     // Catch up on any experience levels we did not assign last time. This
303     // can happen if Crawl sees SIGHUP while it is waiting for the player
304     // to dismiss a level-up prompt.
305     level_change();
306
307     cursor_control ccon(!Options.use_fake_player_cursor);
308     while (true)
309         _input();
310
311     clear_globals_on_exit();
312
313     return 0;
314 }
315
316 static void _show_commandline_options_help()
317 {
318     puts("Command line options:");
319     puts("  -help                 prints this list of options");
320     puts("  -name <string>        character name");
321     puts("  -species <arg>        preselect character species (by letter, abbreviation, or name)");
322     puts("  -background <arg>     preselect character background (by letter, abbreviation, or name)");
323     puts("  -plain                don't use IBM extended characters");
324     puts("  -seed <num>           init the rng to a given sequence (a hex number > 0)");
325     puts("  -dir <path>           crawl directory");
326     puts("  -rc <file>            init file name");
327     puts("  -rcdir <dir>          directory that contains (included) rc files");
328     puts("  -morgue <dir>         directory to save character dumps");
329     puts("  -macro <dir>          directory to save/find macro.txt");
330     puts("  -version              Crawl version (and compilation info)");
331     puts("  -save-version <name>  Save file version for the given player");
332     puts("");
333     puts("Command line options override init file options, which override");
334     puts("environment options (CRAWL_NAME, CRAWL_DIR, CRAWL_RC).");
335     puts("");
336
337     puts("  -extra-opt-first optname=optval");
338     puts("  -extra-opt-last  optname=optval");
339     puts("");
340     puts("Acts as if 'optname=optval' was at the top or bottom of the init");
341     puts("file.  Can be used multiple times.");
342     puts("");
343
344     puts("Highscore list options: (Can be redirected to more, etc.)");
345     puts("  -scores [N]            highscore list");
346     puts("  -tscores [N]           terse highscore list");
347     puts("  -vscores [N]           verbose highscore list");
348     puts("  -scorefile <filename>  scorefile to report on");
349     puts("");
350     puts("Arena options: (Stage a tournament between various monsters.)");
351     puts("  -arena \"<monster list> v <monster list> arena:<arena map>\"");
352 #ifdef DEBUG_DIAGNOSTICS
353     puts("");
354     puts("  -test            run test cases in ./test");
355     puts("  -script <name>   run script matching <name> in ./scripts");
356 #endif
357 }
358
359 static void _wanderer_startup_message()
360 {
361     int skill_levels = 0;
362     for (int i = 0; i < NUM_SKILLS; ++i)
363         skill_levels += you.skills[ i ];
364
365     if (skill_levels <= 2)
366     {
367         // Some wanderers stand to not be able to see any of their
368         // skills at the start of the game (one or two skills should be
369         // easily guessed from starting equipment).  Anyway, we'll give
370         // the player a message to warn them (and a reason why). - bwr
371         mpr("You wake up in a daze, and can't recall much.");
372     }
373 }
374
375 static void _god_greeting_message(bool game_start)
376 {
377     switch (you.religion)
378     {
379     case GOD_ZIN:
380         simple_god_message(" says: Spread the light, my child.");
381         break;
382     case GOD_SHINING_ONE:
383         simple_god_message(" says: Lead the forces of light to victory!");
384         break;
385     case GOD_KIKUBAAQUDGHA:
386         simple_god_message(" says: Welcome...");
387         break;
388     case GOD_YREDELEMNUL:
389         simple_god_message(" says: Carry the black torch! Rouse the idle dead!");
390         break;
391     case GOD_NEMELEX_XOBEH:
392         simple_god_message(" says: It's all in the cards!");
393         break;
394     case GOD_XOM:
395         if (game_start)
396             simple_god_message(" says: A new plaything!");
397         break;
398     case GOD_VEHUMET:
399         simple_god_message(" says: Let it end in hellfire!");
400         break;
401     case GOD_OKAWARU:
402         simple_god_message(" says: Welcome, disciple.");
403         break;
404     case GOD_MAKHLEB:
405         god_speaks(you.religion, "Blood and souls for Makhleb!");
406         break;
407     case GOD_SIF_MUNA:
408         simple_god_message(" whispers: I know many secrets...");
409         break;
410     case GOD_TROG:
411         simple_god_message(" says: Kill them all!");
412         break;
413     case GOD_ELYVILON:
414         simple_god_message(" says: Go forth and aid the weak!");
415         break;
416     case GOD_LUGONU:
417         simple_god_message(" says: Spread carnage and corruption!");
418         break;
419     case GOD_BEOGH:
420         simple_god_message(" says: Drown the unbelievers in a sea of blood!");
421         break;
422     case GOD_JIYVA:
423         god_speaks(you.religion, "Slime for the Slime God!");
424         break;
425     case GOD_FEDHAS:
426         simple_god_message(" says: Spread life and death.");
427         break;
428     case GOD_CHEIBRIADOS:
429         simple_god_message(" says: Take it easy.");
430         break;
431
432     case GOD_NO_GOD:
433     case NUM_GODS:
434     case GOD_RANDOM:
435     case GOD_NAMELESS:
436         break;
437     }
438 }
439
440 static void _take_starting_note()
441 {
442     std::ostringstream notestr;
443     notestr << you.your_name << ", the "
444             << species_name(you.species,you.experience_level) << " "
445             << you.class_name
446             << ", began the quest for the Orb.";
447     take_note(Note(NOTE_MESSAGE, 0, 0, notestr.str().c_str()));
448
449     notestr.str("");
450     notestr.clear();
451
452 #ifdef WIZARD
453     if (you.wizard)
454     {
455         notestr << "You started the game in wizard mode.";
456         take_note(Note(NOTE_MESSAGE, 0, 0, notestr.str().c_str()));
457
458         notestr.str("");
459         notestr.clear();
460     }
461 #endif
462
463     notestr << "HP: " << you.hp << "/" << you.hp_max
464             << " MP: " << you.magic_points << "/" << you.max_magic_points;
465
466     take_note(Note(NOTE_XP_LEVEL_CHANGE, you.experience_level, 0,
467                    notestr.str().c_str()));
468 }
469
470 static void _startup_tutorial()
471 {
472     // Don't allow triggering at game start.
473     Tutorial.tut_just_triggered = true;
474
475     msg::streams(MSGCH_TUTORIAL)
476         << "Press any key to start the tutorial intro, or Escape to skip it."
477         << std::endl;
478
479     flush_prev_message();
480     const int ch = c_getch();
481     if (ch != ESCAPE)
482         tut_starting_screen();
483 }
484
485 #ifdef WIZARD
486 static void _do_wizard_command(int wiz_command, bool silent_fail)
487 {
488     ASSERT(you.wizard);
489
490     switch (wiz_command)
491     {
492     case '?':
493     {
494         const int key = list_wizard_commands(true);
495         _do_wizard_command(key, true);
496         return;
497     }
498
499     case CONTROL('B'): you.teleport(true, false, true); break;
500     case CONTROL('D'): wizard_edit_durations(); break;
501     case CONTROL('F'): debug_fight_statistics(false, true); break;
502     case CONTROL('G'): debug_ghosts(); break;
503     case CONTROL('H'): wizard_set_hunger_state(); break;
504     case CONTROL('I'): debug_item_statistics(); break;
505     case CONTROL('L'): wizard_set_xl(); break;
506     case CONTROL('T'): debug_terp_dlua(); break;
507     case CONTROL('X'): debug_xom_effects(); break;
508
509     case 'O': debug_test_explore();                  break;
510     case 'S': wizard_set_skill_level();              break;
511     case 'A': wizard_set_all_skills();               break;
512     case 'a': acquirement(OBJ_RANDOM, AQ_WIZMODE);   break;
513     case 'v': wizard_value_artefact();               break;
514     case '+': wizard_make_object_randart();          break;
515     case '|': wizard_create_all_artefacts();         break;
516     case 'C': wizard_uncurse_item();                 break;
517     case 'g': wizard_exercise_skill();               break;
518     case 'G': wizard_dismiss_all_monsters();         break;
519     case 'c': wizard_draw_card();                    break;
520     case 'H': wizard_heal(true);                     break;
521     case 'h': wizard_heal(false);                    break;
522     case 'b': blink(1000, true, true);               break;
523     case '~': wizard_interlevel_travel();            break;
524     case '"': debug_list_monsters();                 break;
525     case 't': wizard_tweak_object();                 break;
526     case 'T': debug_make_trap();                     break;
527     case '\\': debug_make_shop();                    break;
528     case 'f': debug_fight_statistics(false);         break;
529     case 'F': debug_fight_statistics(true);          break;
530     case 'm': wizard_create_spec_monster();          break;
531     case 'M': wizard_create_spec_monster_name();     break;
532     case 'R': wizard_spawn_control();                break;
533     case 'r': wizard_change_species();               break;
534     case '>': wizard_place_stairs(true);             break;
535     case '<': wizard_place_stairs(false);            break;
536     case 'P': wizard_create_portal();                break;
537     case 'L': debug_place_map();                     break;
538     case 'i': wizard_identify_pack();                break;
539     case 'I': wizard_unidentify_pack();              break;
540     case 'Z':
541     case 'z': wizard_cast_spec_spell();              break;
542     case '(': wizard_create_feature();               break;
543     case ')': wizard_mod_tide();                     break;
544     case ':': wizard_list_branches();                break;
545     case '{': wizard_map_level();                    break;
546     case '}': wizard_reveal_traps();                 break;
547     case '@': wizard_set_stats();                    break;
548     case '^': wizard_set_piety();                    break;
549     case '_': wizard_get_religion();                 break;
550     case '-': wizard_get_god_gift();                 break;
551     case '\'': wizard_list_items();                  break;
552     case 'd': wizard_level_travel(true);             break;
553     case 'D': wizard_detect_creatures();             break;
554     case 'u': case 'U': wizard_level_travel(false);  break;
555     case '%': case 'o': wizard_create_spec_object(); break;
556
557     case 'x':
558         you.experience = 1 + exp_needed(2 + you.experience_level);
559         level_change();
560         break;
561
562     case 's':
563         you.exp_available = FULL_EXP_POOL;
564         you.redraw_experience = true;
565         break;
566
567     case '$':
568         you.add_gold(1000);
569         if (!Options.show_gold_turns)
570         {
571             mprf("You now have %d gold piece%s.",
572                  you.gold, you.gold != 1 ? "s" : "");
573         }
574         break;
575
576     case 'B':
577         if (you.level_type != LEVEL_ABYSS)
578             banished(DNGN_ENTER_ABYSS, "wizard command");
579         else
580             down_stairs(you.absdepth0, DNGN_EXIT_ABYSS);
581         break;
582
583     case CONTROL('A'):
584         if (you.level_type == LEVEL_ABYSS)
585             abyss_teleport(true);
586         else
587             mpr("You can only abyss_teleport() inside the Abyss.");
588         break;
589
590     case ']':
591         if (!wizard_add_mutation())
592             mpr("Failure to give mutation.");
593         break;
594
595     case '=':
596         mprf("Cost level: %d  Skill points: %d  Next cost level: %d",
597               you.skill_cost_level, you.total_skill_points,
598               skill_cost_needed(you.skill_cost_level + 1));
599         break;
600
601     case 'X':
602     {
603         int result = 0;
604         do
605         {
606             if (you.religion == GOD_XOM)
607                 result = xom_acts(abs(you.piety - HALF_MAX_PIETY));
608             else
609                 result = xom_acts(coinflip(), random_range(0, HALF_MAX_PIETY));
610         }
611         while (result == 0);
612         break;
613     }
614     case 'p':
615         dungeon_terrain_changed(you.pos(), DNGN_ENTER_PANDEMONIUM, false);
616         break;
617
618     case 'l':
619         dungeon_terrain_changed(you.pos(), DNGN_ENTER_LABYRINTH, false);
620         break;
621
622     case 'k':
623         if (you.level_type == LEVEL_LABYRINTH)
624             change_labyrinth(true);
625         else
626             mpr("This only makes sense in a labyrinth!");
627         break;
628
629
630     default:
631         if (!silent_fail)
632         {
633             formatted_mpr(formatted_string::parse_string(
634                               "Not a <magenta>Wizard</magenta> Command."));
635         }
636         break;
637     }
638     // Force the placement of any delayed monster gifts.
639     you.turn_is_over = true;
640     religion_turn_end();
641
642     you.turn_is_over = false;
643 }
644
645 static void _handle_wizard_command(void)
646 {
647     int wiz_command;
648
649     // WIZ_NEVER gives protection for those who have wiz compiles,
650     // and don't want to risk their characters.
651     if (Options.wiz_mode == WIZ_NEVER)
652         return;
653
654     if (!you.wizard)
655     {
656         mpr("WARNING: ABOUT TO ENTER WIZARD MODE!", MSGCH_WARN);
657
658 #ifndef SCORE_WIZARD_MODE
659         mpr("If you continue, your game will not be scored!", MSGCH_WARN);
660 #endif
661
662         if (!yesno("Do you really want to enter wizard mode?", false, 'n'))
663             return;
664
665         take_note(Note(NOTE_MESSAGE, 0, 0, "Entered wizard mode."));
666
667         you.wizard = true;
668         redraw_screen();
669
670         if (crawl_state.cmd_repeat_start)
671         {
672             crawl_state.cancel_cmd_repeat("Can't repeat entering wizard "
673                                           "mode.");
674             return;
675         }
676     }
677
678     {
679         mpr("Enter Wizard Command (? - help): ", MSGCH_PROMPT);
680         cursor_control con(true);
681         wiz_command = getch();
682     }
683
684     if (crawl_state.cmd_repeat_start)
685     {
686         // Easiest to list which wizard commands *can* be repeated.
687         switch (wiz_command)
688         {
689         case 'x':
690         case '$':
691         case 'a':
692         case 'c':
693         case 'h':
694         case 'H':
695         case 'm':
696         case 'M':
697         case 'X':
698         case '!':
699         case '[':
700         case ']':
701         case '^':
702         case '%':
703         case 'o':
704         case 'z':
705         case 'Z':
706             break;
707
708         default:
709             crawl_state.cant_cmd_repeat("You cannot repeat that "
710                                         "wizard command.");
711             return;
712         }
713     }
714
715     _do_wizard_command(wiz_command, false);
716 }
717 #endif
718
719 // Set up the running variables for the current run.
720 static void _start_running(int dir, int mode)
721 {
722     if (Tutorial.tutorial_events[TUT_SHIFT_RUN] && mode == RMODE_START)
723         Tutorial.tutorial_events[TUT_SHIFT_RUN] = false;
724
725     if (i_feel_safe(true))
726         you.running.initialise(dir, mode);
727 }
728
729 static bool _cmd_is_repeatable(command_type cmd, bool is_again = false)
730 {
731     switch (cmd)
732     {
733     // Informational commands
734     case CMD_LOOK_AROUND:
735     case CMD_INSPECT_FLOOR:
736     case CMD_SHOW_TERRAIN:
737     case CMD_EXAMINE_OBJECT:
738     case CMD_LIST_WEAPONS:
739     case CMD_LIST_ARMOUR:
740     case CMD_LIST_JEWELLERY:
741     case CMD_LIST_EQUIPMENT:
742     case CMD_LIST_GOLD:
743     case CMD_CHARACTER_DUMP:
744     case CMD_DISPLAY_COMMANDS:
745     case CMD_DISPLAY_INVENTORY:
746     case CMD_DISPLAY_KNOWN_OBJECTS:
747     case CMD_DISPLAY_MUTATIONS:
748     case CMD_DISPLAY_SKILLS:
749     case CMD_DISPLAY_OVERMAP:
750     case CMD_DISPLAY_RELIGION:
751     case CMD_DISPLAY_CHARACTER_STATUS:
752     case CMD_DISPLAY_SPELLS:
753     case CMD_EXPERIENCE_CHECK:
754     case CMD_RESISTS_SCREEN:
755     case CMD_READ_MESSAGES:
756     case CMD_SEARCH_STASHES:
757         mpr("You can't repeat informational commands.");
758         return (false);
759
760     // Multi-turn commands
761     case CMD_PICKUP:
762     case CMD_DROP:
763     case CMD_BUTCHER:
764     case CMD_GO_UPSTAIRS:
765     case CMD_GO_DOWNSTAIRS:
766     case CMD_WIELD_WEAPON:
767     case CMD_WEAPON_SWAP:
768     case CMD_WEAR_JEWELLERY:
769     case CMD_REMOVE_JEWELLERY:
770     case CMD_MEMORISE_SPELL:
771     case CMD_EXPLORE:
772     case CMD_INTERLEVEL_TRAVEL:
773         mpr("You can't repeat multi-turn commands.");
774         return (false);
775
776     // Miscellaneous non-repeatable commands.
777     case CMD_TOGGLE_AUTOPICKUP:
778     case CMD_TOGGLE_FRIENDLY_PICKUP:
779     case CMD_ADJUST_INVENTORY:
780     case CMD_QUIVER_ITEM:
781     case CMD_REPLAY_MESSAGES:
782     case CMD_REDRAW_SCREEN:
783     case CMD_MACRO_ADD:
784     case CMD_SAVE_GAME:
785     case CMD_SAVE_GAME_NOW:
786     case CMD_SUSPEND_GAME:
787     case CMD_QUIT:
788     case CMD_DESTROY_ITEM:
789     case CMD_FORGET_STASH:
790     case CMD_FIX_WAYPOINT:
791     case CMD_CLEAR_MAP:
792     case CMD_INSCRIBE_ITEM:
793     case CMD_MAKE_NOTE:
794     case CMD_CYCLE_QUIVER_FORWARD:
795 #ifdef USE_TILE
796     case CMD_EDIT_PLAYER_TILE:
797 #endif
798         mpr("You can't repeat that command.");
799         return (false);
800
801     case CMD_DISPLAY_MAP:
802         mpr("You can't repeat map commands.");
803         return (false);
804
805     case CMD_MOUSE_MOVE:
806     case CMD_MOUSE_CLICK:
807         mpr("You can't repeat mouse clicks or movements.");
808         return (false);
809
810     case CMD_REPEAT_CMD:
811         mpr("You can't repeat the repeat command!");
812         return (false);
813
814     case CMD_RUN_LEFT:
815     case CMD_RUN_DOWN:
816     case CMD_RUN_UP:
817     case CMD_RUN_RIGHT:
818     case CMD_RUN_UP_LEFT:
819     case CMD_RUN_DOWN_LEFT:
820     case CMD_RUN_UP_RIGHT:
821     case CMD_RUN_DOWN_RIGHT:
822         mpr("Why would you want to repeat a run command?");
823         return (false);
824
825     case CMD_PREV_CMD_AGAIN:
826         ASSERT(!is_again);
827         if (crawl_state.prev_cmd == CMD_NO_CMD)
828         {
829             mpr("No previous command to repeat.");
830             return (false);
831         }
832
833         return _cmd_is_repeatable(crawl_state.prev_cmd, true);
834
835     case CMD_MOVE_NOWHERE:
836     case CMD_REST:
837     case CMD_SEARCH:
838         return (i_feel_safe(true));
839
840     case CMD_MOVE_LEFT:
841     case CMD_MOVE_DOWN:
842     case CMD_MOVE_UP:
843     case CMD_MOVE_RIGHT:
844     case CMD_MOVE_UP_LEFT:
845     case CMD_MOVE_DOWN_LEFT:
846     case CMD_MOVE_UP_RIGHT:
847     case CMD_MOVE_DOWN_RIGHT:
848         if (!i_feel_safe())
849         {
850             return yesno("Really repeat movement command while monsters "
851                          "are nearby?", false, 'n');
852         }
853
854         return (true);
855
856     case CMD_NO_CMD:
857     case CMD_NO_CMD_DEFAULT:
858         mpr("Unknown command, not repeating.");
859         return (false);
860
861     default:
862         return (true);
863     }
864
865     return (false);
866 }
867
868 // Used to determine whether to apply the berserk penalty at end of round.
869 bool apply_berserk_penalty = false;
870
871 static void _center_cursor()
872 {
873 #ifndef USE_TILE
874     const coord_def cwhere = grid2view(you.pos());
875     cgotoxy(cwhere.x, cwhere.y);
876 #endif
877 }
878
879
880 // We have to refresh the SH display if the player's incapacitated state
881 // changes (getting confused/paralyzed/etc. sets SH to 0, recovering
882 // from the condition sets SH back to normal).
883 struct disable_check
884 {
885     disable_check(bool current)
886     {
887         was_disabled = current;
888     }
889     ~disable_check()
890     {
891         if (you.incapacitated() != was_disabled)
892             you.redraw_armour_class = true;
893     }
894
895     bool was_disabled;
896 };
897
898 static void _update_place_info()
899 {
900     if (you.num_turns == -1)
901         return;
902
903     PlaceInfo  delta;
904
905     delta.turns_total++;
906     delta.elapsed_total += you.time_taken;
907
908     switch (you.running)
909     {
910     case RMODE_INTERLEVEL:
911         delta.turns_interlevel++;
912         delta.elapsed_interlevel += you.time_taken;
913         break;
914
915     case RMODE_EXPLORE_GREEDY:
916     case RMODE_EXPLORE:
917         delta.turns_explore++;
918         delta.elapsed_explore += you.time_taken;
919         break;
920
921     case RMODE_TRAVEL:
922         delta.turns_travel++;
923         delta.elapsed_travel += you.time_taken;
924         break;
925
926     default:
927         // prev_was_rest is needed so that the turn in which
928         // a player is interrupted from resting is counted
929         // as a resting turn, rather than "other".
930         static bool prev_was_rest = false;
931
932         if (!you.delay_queue.empty()
933             && you.delay_queue.front().type == DELAY_REST)
934         {
935             prev_was_rest = true;
936         }
937
938         if (prev_was_rest)
939         {
940             delta.turns_resting++;
941             delta.elapsed_resting += you.time_taken;
942         }
943         else
944         {
945            delta.turns_other++;
946            delta.elapsed_other += you.time_taken;
947         }
948
949         if (you.delay_queue.empty()
950             || you.delay_queue.front().type != DELAY_REST)
951         {
952             prev_was_rest = false;
953         }
954         break;
955     }
956
957     you.global_info += delta;
958     you.global_info.assert_validity();
959
960     PlaceInfo& curr_PlaceInfo = you.get_place_info();
961     curr_PlaceInfo += delta;
962     curr_PlaceInfo.assert_validity();
963 }
964
965 //
966 //  This function handles the player's input. It's called from main(),
967 //  from inside an endless loop.
968 //
969 static void _input()
970 {
971 #if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE) && defined(USE_CURSES)
972     if (crawl_state.seen_hups)
973         sighup_save_and_exit();
974 #endif
975
976     crawl_state.clear_mon_acting();
977
978     disable_check player_disabled(you.incapacitated());
979     religion_turn_start();
980     god_conduct_turn_start();
981     you.update_beholders();
982
983     // Currently only set if Xom accidentally kills the player.
984     you.reset_escaped_death();
985
986     if (crawl_state.is_replaying_keys() && crawl_state.is_repeating_cmd()
987         && kbhit())
988     {
989         // User pressed a key, so stop repeating commands and discard
990         // the keypress.
991         crawl_state.cancel_cmd_repeat("Key pressed, interrupting command "
992                                       "repetition.");
993         crawl_state.prev_cmd = CMD_NO_CMD;
994         flush_prev_message();
995         getchm();
996         return;
997     }
998
999     _prep_input();
1000
1001     update_monsters_in_view();
1002
1003     tutorial_new_turn();
1004
1005     if (you.cannot_act())
1006     {
1007         if (crawl_state.repeat_cmd != CMD_WIZARD)
1008         {
1009             crawl_state.cancel_cmd_repeat("Cannot move, cancelling command "
1010                                           "repetition.");
1011         }
1012         world_reacts();
1013         return;
1014     }
1015
1016     // Stop autoclearing more now that we have control back.
1017     if (!you_are_delayed())
1018         set_more_autoclear(false);
1019
1020     if (need_to_autopickup())
1021     {
1022         autopickup();
1023         if (you.turn_is_over)
1024         {
1025             world_reacts();
1026             return;
1027         }
1028     }
1029
1030     if (need_to_autoinscribe())
1031         autoinscribe();
1032
1033     if (you_are_delayed() && current_delay_action() != DELAY_MACRO_PROCESS_KEY)
1034     {
1035         handle_delay();
1036
1037         // Some delays reset you.time_taken.
1038         if (you.time_taken || you.turn_is_over)
1039             world_reacts();
1040
1041         return;
1042     }
1043
1044     ASSERT(!you.turn_is_over);
1045
1046     crawl_state.check_term_size();
1047     if (crawl_state.terminal_resized)
1048         handle_terminal_resize();
1049
1050     repeat_again_rec.paused = crawl_state.is_replaying_keys();
1051
1052     crawl_state.input_line_curr = 0;
1053
1054     {
1055         // Flush messages and display message window.
1056         msgwin_new_cmd();
1057
1058         clear_macro_process_key_delay();
1059
1060         crawl_state.waiting_for_command = true;
1061         c_input_reset(true);
1062
1063 #ifdef USE_TILE
1064         cursor_control con(false);
1065 #endif
1066         const command_type cmd = _get_next_cmd();
1067
1068 #if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE) && defined(USE_CURSES)
1069         if (crawl_state.seen_hups)
1070             sighup_save_and_exit();
1071 #endif
1072
1073         crawl_state.waiting_for_command = false;
1074
1075         if (cmd != CMD_PREV_CMD_AGAIN && cmd != CMD_NO_CMD
1076             && !crawl_state.is_replaying_keys())
1077         {
1078             crawl_state.prev_cmd = cmd;
1079             crawl_state.input_line_strs.clear();
1080         }
1081
1082         if (cmd != CMD_MOUSE_MOVE)
1083             c_input_reset(false);
1084
1085         // [dshaligram] If get_next_cmd encountered a Lua macro
1086         // binding, your turn may be ended by the first invoke of the
1087         // macro.
1088         if (!you.turn_is_over && cmd != CMD_NEXT_CMD)
1089             process_command(cmd);
1090
1091         repeat_again_rec.paused = true;
1092
1093         if (cmd != CMD_MOUSE_MOVE)
1094             c_input_reset(false, true);
1095
1096         // If the command was CMD_REPEAT_CMD, then the key for the
1097         // command to repeat has been placed into the macro buffer,
1098         // so return now to let input() be called again while
1099         // the keys to repeat are recorded.
1100         if (cmd == CMD_REPEAT_CMD)
1101             return;
1102
1103         // If the command was CMD_PREV_CMD_AGAIN then _input() has been
1104         // recursively called by _do_prev_cmd_again() via process_command()
1105         // to re-do the command, so there's nothing more to do.
1106         if (cmd == CMD_PREV_CMD_AGAIN)
1107             return;
1108     }
1109
1110     if (need_to_autoinscribe())
1111         autoinscribe();
1112
1113     if (you.turn_is_over)
1114     {
1115         if (apply_berserk_penalty)
1116             _do_berserk_no_combat_penalty();
1117
1118         world_reacts();
1119     }
1120
1121     _update_replay_state();
1122
1123     _update_place_info();
1124
1125     crawl_state.clear_god_acting();
1126 }
1127
1128 static bool _stairs_check_mesmerised()
1129 {
1130     if (you.beheld() && !you.confused())
1131     {
1132         const monsters* beholder = you.get_any_beholder();
1133         mprf("You cannot move away from %s!",
1134              beholder->name(DESC_NOCAP_THE, true).c_str());
1135         return (true);
1136     }
1137
1138     return (false);
1139 }
1140
1141 static bool _marker_vetoes_stair()
1142 {
1143     return marker_vetoes_operation("veto_stair");
1144 }
1145
1146 // Maybe prompt to enter a portal, return true if we should enter the
1147 // portal, false if the user said no at the prompt.
1148 static bool _prompt_dangerous_portal(dungeon_feature_type ftype)
1149 {
1150     switch(ftype)
1151     {
1152     case DNGN_ENTER_PANDEMONIUM:
1153     case DNGN_ENTER_ABYSS:
1154         return yesno("If you enter this portal you will not be able to return "
1155                      "immediately. Continue?", false, 'n');
1156
1157     default:
1158         return (true);
1159     }
1160 }
1161
1162 static void _go_downstairs();
1163 static void _go_upstairs()
1164 {
1165     ASSERT(!crawl_state.game_is_arena() && !crawl_state.arena_suspended);
1166
1167     const dungeon_feature_type ygrd = grd(you.pos());
1168
1169     if (_stairs_check_mesmerised())
1170         return;
1171
1172     if (you.attribute[ATTR_HELD])
1173     {
1174         mpr("You're held in a net!");
1175         return;
1176     }
1177
1178     if (ygrd == DNGN_ENTER_SHOP)
1179     {
1180         if (you.berserk())
1181             canned_msg(MSG_TOO_BERSERK);
1182         else
1183             shop();
1184         return;
1185     }
1186     else if (ygrd == DNGN_ENTER_HELL && you.level_type != LEVEL_DUNGEON)
1187     {
1188         mpr("You can't enter Hell from outside the dungeon!",
1189             MSGCH_ERROR);
1190         return;
1191     }
1192     // Up and down both work for portals.
1193     else if (get_feature_dchar(ygrd) == DCHAR_ARCH
1194              && feat_stair_direction(ygrd) != CMD_NO_CMD
1195              && ygrd != DNGN_ENTER_ZOT)
1196     {
1197         ;
1198     }
1199     else if (feat_stair_direction(ygrd) != CMD_GO_UPSTAIRS)
1200     {
1201         if (ygrd == DNGN_STONE_ARCH)
1202             mpr("There is nothing on the other side of the stone arch.");
1203         else if (ygrd == DNGN_ABANDONED_SHOP)
1204             mpr("This shop appears to be closed.");
1205         else
1206             mpr("You can't go up here!");
1207         return;
1208     }
1209
1210     if (!_prompt_dangerous_portal(ygrd))
1211         return;
1212
1213     // Does the next level have a warning annotation?
1214     if (!check_annotation_exclusion_warning())
1215         return;
1216
1217     if (_marker_vetoes_stair())
1218         return;
1219
1220     if (you.duration[DUR_MISLED])
1221     {
1222         mpr("Away from their source, illusions no longer mislead you.", MSGCH_DURATION);
1223         you.duration[DUR_MISLED] = 0;
1224     }
1225
1226     tag_followers(); // Only those beside us right now can follow.
1227     start_delay(DELAY_ASCENDING_STAIRS,
1228                 1 + (you.burden_state > BS_UNENCUMBERED));
1229 }
1230
1231 static void _go_downstairs()
1232 {
1233     ASSERT(!crawl_state.game_is_arena() && !crawl_state.arena_suspended);
1234
1235     const dungeon_feature_type ygrd = grd(you.pos());
1236
1237     const bool shaft = (get_trap_type(you.pos()) == TRAP_SHAFT
1238                         && ygrd != DNGN_UNDISCOVERED_TRAP);
1239
1240     if (_stairs_check_mesmerised())
1241         return;
1242
1243     if (shaft && you.flight_mode() == FL_LEVITATE)
1244     {
1245         mpr("You can't fall through a shaft while levitating.");
1246         return;
1247     }
1248
1249     // Up and down both work for shops.
1250     if (ygrd == DNGN_ENTER_SHOP)
1251     {
1252         if (you.berserk())
1253             canned_msg(MSG_TOO_BERSERK);
1254         else
1255             shop();
1256         return;
1257     }
1258     else if (ygrd == DNGN_ENTER_HELL && you.level_type != LEVEL_DUNGEON)
1259     {
1260         mpr("You can't enter Hell from outside the dungeon!",
1261             MSGCH_ERROR);
1262         return;
1263     }
1264     // Up and down both work for portals.
1265     else if (get_feature_dchar(ygrd) == DCHAR_ARCH
1266              && feat_stair_direction(ygrd) != CMD_NO_CMD
1267              && ygrd != DNGN_ENTER_ZOT)
1268     {
1269         ;
1270     }
1271     else if (feat_stair_direction(ygrd) != CMD_GO_DOWNSTAIRS
1272              && !shaft)
1273     {
1274         if (ygrd == DNGN_STONE_ARCH)
1275             mpr("There is nothing on the other side of the stone arch.");
1276         else if (ygrd == DNGN_ABANDONED_SHOP)
1277             mpr("This shop appears to be closed.");
1278         else
1279             mpr("You can't go down here!");
1280         return;
1281     }
1282
1283     if (you.attribute[ATTR_HELD])
1284     {
1285         mpr("You're held in a net!");
1286         return;
1287     }
1288
1289     if (!_prompt_dangerous_portal(ygrd))
1290         return;
1291
1292     // Does the next level have a warning annotation?
1293     // Also checks for entering a labyrinth with teleportitis.
1294     if (!check_annotation_exclusion_warning())
1295         return;
1296
1297     if (you.duration[DUR_MISLED])
1298     {
1299         mpr("Away from their source, illusions no longer mislead you.", MSGCH_DURATION);
1300         you.duration[DUR_MISLED] = 0;
1301     }
1302
1303     if (shaft)
1304     {
1305         start_delay(DELAY_DESCENDING_STAIRS, 0, you.absdepth0);
1306     }
1307     else
1308     {
1309         if (_marker_vetoes_stair())
1310             return;
1311
1312         tag_followers(); // Only those beside us right now can follow.
1313         start_delay(DELAY_DESCENDING_STAIRS,
1314                     1 + (you.burden_state > BS_UNENCUMBERED),
1315                     you.absdepth0);
1316     }
1317 }
1318
1319 static void _experience_check()
1320 {
1321     mprf("You are a level %d %s %s.",
1322          you.experience_level,
1323          species_name(you.species,you.experience_level).c_str(),
1324          you.class_name);
1325
1326     if (you.experience_level < 27)
1327     {
1328         int xp_needed = (exp_needed(you.experience_level+2)-you.experience)+1;
1329         mprf("Level %d requires %ld experience (%d point%s to go!)",
1330               you.experience_level + 1,
1331               exp_needed(you.experience_level + 2) + 1,
1332               xp_needed,
1333               (xp_needed > 1) ? "s" : "");
1334     }
1335     else
1336     {
1337         mpr("I'm sorry, level 27 is as high as you can go.");
1338         mpr("With the way you've been playing, I'm surprised you got this far.");
1339     }
1340
1341     if (you.real_time != -1)
1342     {
1343         const time_t curr = you.real_time + (time(NULL) - you.start_time);
1344         msg::stream << "Play time: " << make_time_string(curr)
1345                     << " (" << you.num_turns << " turns)"
1346                     << std::endl;
1347     }
1348 #ifdef DEBUG_DIAGNOSTICS
1349     if (wearing_amulet(AMU_THE_GOURMAND))
1350         mprf(MSGCH_DIAGNOSTICS, "Gourmand charge: %d",
1351              you.duration[DUR_GOURMAND]);
1352
1353     mprf(MSGCH_DIAGNOSTICS, "Turns spent on this level: %d",
1354          env.turns_on_level);
1355 #endif
1356 }
1357
1358 static void _print_friendly_pickup_setting(bool was_changed)
1359 {
1360     std::string now = (was_changed? "now " : "");
1361
1362     if (you.friendly_pickup == FRIENDLY_PICKUP_NONE)
1363     {
1364         mprf("Your intelligent allies are %sforbidden to pick up anything at all.",
1365              now.c_str());
1366     }
1367     else if (you.friendly_pickup == FRIENDLY_PICKUP_FRIEND)
1368     {
1369         mprf("Your intelligent allies may %sonly pick up items dropped by allies.",
1370              now.c_str());
1371     }
1372     else if (you.friendly_pickup == FRIENDLY_PICKUP_PLAYER)
1373     {
1374         mprf("Your intelligent allies may %sonly pick up items dropped by you "
1375              "and your allies.", now.c_str());
1376     }
1377     else if (you.friendly_pickup == FRIENDLY_PICKUP_ALL)
1378     {
1379         mprf("Your intelligent allies may %spick up anything they need.",
1380              now.c_str());
1381     }
1382     else
1383         mprf(MSGCH_ERROR, "Your allies%s are collecting bugs!", now.c_str());
1384 }
1385
1386 static void _do_look_around()
1387 {
1388     dist lmove;   // Will be initialised by direction().
1389     direction_chooser_args args;
1390     args.restricts = DIR_TARGET;
1391     args.just_looking = true;
1392     args.needs_path = false;
1393     args.target_prefix = "Here";
1394     args.may_target_monster = "Move the cursor around to observe a square.";
1395     direction(lmove, args);
1396     if (lmove.isValid && lmove.isTarget && !lmove.isCancel
1397         && !crawl_state.arena_suspended)
1398     {
1399         start_travel(lmove.target);
1400     }
1401 }
1402
1403 static void _do_remove_armour()
1404 {
1405     if (player_in_bat_form())
1406     {
1407         mpr("You can't wear or remove anything in your present form.");
1408         return;
1409     }
1410
1411     int index = 0;
1412     if (armour_prompt("Take off which item?", &index, OPER_TAKEOFF))
1413         takeoff_armour(index);
1414 }
1415
1416 static void _toggle_friendly_pickup()
1417 {
1418     // Toggle pickup mode for friendlies.
1419     _print_friendly_pickup_setting(false);
1420
1421     mpr("Change to (d)efault, (n)othing, (f)riend-dropped, (p)layer, "
1422         "or (a)ll? ", MSGCH_PROMPT);
1423
1424     int type;
1425     {
1426         cursor_control con(true);
1427         type = tolower(getchm(KMC_DEFAULT));
1428     }
1429
1430     switch (type) {
1431     case 'd': you.friendly_pickup = Options.default_friendly_pickup; break;
1432     case 'n': you.friendly_pickup = FRIENDLY_PICKUP_NONE; break;
1433     case 'f': you.friendly_pickup = FRIENDLY_PICKUP_FRIEND; break;
1434     case 'p': you.friendly_pickup = FRIENDLY_PICKUP_PLAYER; break;
1435     case 'a': you.friendly_pickup = FRIENDLY_PICKUP_ALL; break;
1436     default: canned_msg(MSG_OK); return;
1437     }
1438
1439     _print_friendly_pickup_setting(true);
1440 }
1441
1442 static void _do_rest()
1443 {
1444     if (you.hunger_state == HS_STARVING && !you_min_hunger())
1445     {
1446         mpr("You are too hungry to rest.");
1447         return;
1448     }
1449
1450     if (i_feel_safe())
1451     {
1452         if ((you.hp == you.hp_max || you.species == SP_VAMPIRE
1453              && you.hunger_state == HS_STARVING)
1454             && you.magic_points == you.max_magic_points)
1455         {
1456             mpr("You start searching.");
1457         }
1458         else
1459             mpr("You start resting.");
1460     }
1461
1462     _start_running(RDIR_REST, RMODE_REST_DURATION);
1463 }
1464
1465 static bool _do_repeated_cmd()
1466 {
1467     ASSERT(crawl_state.is_repeating_cmd());
1468
1469     if (!crawl_state.cmd_repeat_start
1470         && crawl_state.prev_repetition_turn == you.num_turns
1471         && crawl_state.repeat_cmd != CMD_WIZARD
1472         && (crawl_state.repeat_cmd != CMD_PREV_CMD_AGAIN
1473             || crawl_state.prev_cmd != CMD_WIZARD))
1474     {
1475         // This is a catch-all that shouldn't really happen.
1476         // If the command always takes zero turns, then it
1477         // should be prevented in cmd_is_repeatable().  If
1478         // a command sometimes takes zero turns (because it
1479         // can't be done, for instance), then
1480         // crawl_state.zero_turns_taken() should be called when
1481         // it does take zero turns, to cancel command repetition
1482         // before we reach here.
1483 #ifdef WIZARD
1484         crawl_state.cant_cmd_repeat("Can't repeat a command which "
1485                                     "takes no turns (unless it's a "
1486                                     "wizard command), cancelling ");
1487 #else
1488         crawl_state.cant_cmd_repeat("Can't repeat a command which "
1489                                     "takes no turns, cancelling "
1490                                     "repetitions.");
1491 #endif
1492         crawl_state.cancel_cmd_repeat();
1493         return false;
1494     }
1495
1496     if (crawl_state.cmd_repeat_count >= crawl_state.cmd_repeat_goal)
1497     {
1498         crawl_state.cancel_cmd_repeat();
1499         return false;
1500     }
1501
1502     crawl_state.cmd_repeat_start = false;
1503     crawl_state.cmd_repeat_count++;
1504
1505     ASSERT(crawl_state.repeat_cmd_keys.size() > 0);
1506     repeat_again_rec.paused = true;
1507     macro_buf_add(crawl_state.repeat_cmd_keys);
1508     macro_buf_add(KEY_REPEAT_KEYS);
1509
1510     crawl_state.prev_repetition_turn = you.num_turns;
1511
1512     return true;
1513 }
1514
1515 static void _do_clear_map()
1516 {
1517     if (player_in_mappable_area())
1518     {
1519         mpr("Clearing level map.");
1520         clear_map();
1521         crawl_view.set_player_at(you.pos());
1522     }
1523 }
1524
1525 static void _do_display_map()
1526 {
1527     if (Tutorial.tutorial_events[TUT_MAP_VIEW])
1528         Tutorial.tutorial_events[TUT_MAP_VIEW] = false;
1529
1530 #ifndef DEBUG_DIAGNOSTICS
1531     if (!player_in_mappable_area())
1532     {
1533         mpr("It would help if you knew where you were, first.");
1534         return;
1535     }
1536 #endif
1537
1538 #ifdef USE_TILE
1539     // Since there's no actual overview map, but the functionality
1540     // exists, give a message to explain what's going on.
1541     mpr("Move the cursor to view the level map, or type <w>?</w> for "
1542         "a list of commands.");
1543     flush_prev_message();
1544 #endif
1545
1546     level_pos pos;
1547     show_map(pos, true);
1548     redraw_screen();
1549
1550 #ifdef USE_TILE
1551     mpr("Returning to the game...");
1552 #endif
1553     if (pos.pos.x > 0)
1554         start_translevel_travel(pos);
1555 }
1556
1557 static void _do_cycle_quiver(int dir)
1558 {
1559     const int cur = you.m_quiver->get_fire_item();
1560     const int next = get_next_fire_item(cur, dir);
1561 #ifdef DEBUG_QUIVER
1562     mprf(MSGCH_DIAGNOSTICS, "next slot: %d, item: %s", next,
1563          next == -1 ? "none" : you.inv[next].name(DESC_PLAIN).c_str());
1564 #endif
1565     if (next != -1)
1566     {
1567         // Kind of a hacky way to get quiver to change.
1568         you.m_quiver->on_item_fired(you.inv[next], true);
1569
1570         if (next == cur)
1571             mpr("No other missiles available. Use F to throw any item.");
1572     }
1573     else if (cur == -1)
1574     {
1575         mpr("No missiles available. Use F to throw any item.");
1576     }
1577 }
1578
1579 static void _do_list_gold()
1580 {
1581     if (shopping_list.size() == 0)
1582         mprf("You have %d gold piece%s.", you.gold, you.gold != 1 ? "s" : "");
1583     else
1584         shopping_list.display();
1585 }
1586
1587 // Note that in some actions, you don't want to clear afterwards.
1588 // e.g. list_jewellery, etc.
1589 void process_command(command_type cmd)
1590 {
1591     apply_berserk_penalty = true;
1592     switch (cmd)
1593     {
1594 #ifdef USE_TILE
1595         // Tiles-specific commands.
1596     case CMD_EDIT_PLAYER_TILE: tiles.draw_doll_edit(); break;
1597 #endif
1598
1599         // Movement and running commands.
1600     case CMD_OPEN_DOOR_UP_RIGHT:   _open_door( 1, -1); break;
1601     case CMD_OPEN_DOOR_UP:         _open_door( 0, -1); break;
1602     case CMD_OPEN_DOOR_UP_LEFT:    _open_door(-1, -1); break;
1603     case CMD_OPEN_DOOR_RIGHT:      _open_door( 1,  0); break;
1604     case CMD_OPEN_DOOR_DOWN_RIGHT: _open_door( 1,  1); break;
1605     case CMD_OPEN_DOOR_DOWN:       _open_door( 0,  1); break;
1606     case CMD_OPEN_DOOR_DOWN_LEFT:  _open_door(-1,  1); break;
1607     case CMD_OPEN_DOOR_LEFT:       _open_door(-1,  0); break;
1608
1609     case CMD_MOVE_DOWN_LEFT:  _move_player(-1,  1); break;
1610     case CMD_MOVE_DOWN:       _move_player( 0,  1); break;
1611     case CMD_MOVE_UP_RIGHT:   _move_player( 1, -1); break;
1612     case CMD_MOVE_UP:         _move_player( 0, -1); break;
1613     case CMD_MOVE_UP_LEFT:    _move_player(-1, -1); break;
1614     case CMD_MOVE_LEFT:       _move_player(-1,  0); break;
1615     case CMD_MOVE_DOWN_RIGHT: _move_player( 1,  1); break;
1616     case CMD_MOVE_RIGHT:      _move_player( 1,  0); break;
1617
1618     case CMD_RUN_DOWN_LEFT: _start_running(RDIR_DOWN_LEFT, RMODE_START); break;
1619     case CMD_RUN_DOWN:      _start_running(RDIR_DOWN, RMODE_START);      break;
1620     case CMD_RUN_UP_RIGHT:  _start_running(RDIR_UP_RIGHT, RMODE_START);  break;
1621     case CMD_RUN_UP:        _start_running(RDIR_UP, RMODE_START);        break;
1622     case CMD_RUN_UP_LEFT:   _start_running(RDIR_UP_LEFT, RMODE_START);   break;
1623     case CMD_RUN_LEFT:      _start_running(RDIR_LEFT, RMODE_START);      break;
1624     case CMD_RUN_DOWN_RIGHT:_start_running(RDIR_DOWN_RIGHT, RMODE_START); break;
1625     case CMD_RUN_RIGHT:     _start_running(RDIR_RIGHT, RMODE_START);     break;
1626
1627     case CMD_REST: _do_rest(); break;
1628
1629     case CMD_GO_UPSTAIRS:     _go_upstairs();    break;
1630     case CMD_GO_DOWNSTAIRS:   _go_downstairs();  break;
1631     case CMD_OPEN_DOOR:       _open_door(0, 0);  break;
1632     case CMD_CLOSE_DOOR:      _close_door(coord_def(0, 0)); break;
1633
1634         // Repeat commands.
1635     case CMD_REPEAT_KEYS:    if (!_do_repeated_cmd()) return; break;
1636     case CMD_REPEAT_CMD:     _setup_cmd_repeat(); break;
1637     case CMD_PREV_CMD_AGAIN: _do_prev_cmd_again(); break;
1638     case CMD_MACRO_ADD:      macro_add_query(); break;
1639
1640         // Toggle commands.
1641     case CMD_DISABLE_MORE: crawl_state.show_more_prompt = false; break;
1642     case CMD_ENABLE_MORE:  crawl_state.show_more_prompt = true;  break;
1643
1644     case CMD_TOGGLE_AUTOPICKUP:
1645         if (Options.autopickup_on < 1)
1646             Options.autopickup_on = 1;
1647         else
1648             Options.autopickup_on = 0;
1649         mprf("Autopickup is now %s.", Options.autopickup_on > 0 ? "on" : "off");
1650         break;
1651
1652     case CMD_TOGGLE_FRIENDLY_PICKUP: _toggle_friendly_pickup(); break;
1653
1654         // Map commands.
1655     case CMD_CLEAR_MAP:       _do_clear_map();   break;
1656     case CMD_DISPLAY_OVERMAP: display_overview(); break;
1657     case CMD_DISPLAY_MAP:     _do_display_map(); break;
1658
1659         // Stash commands.
1660     case CMD_SEARCH_STASHES:
1661         if (Tutorial.tut_stashes)
1662             Tutorial.tut_stashes = 0;
1663         StashTrack.search_stashes();
1664         break;
1665
1666     case CMD_FORGET_STASH:
1667         if (Options.stash_tracking >= STM_EXPLICIT)
1668             StashTrack.no_stash();
1669         break;
1670
1671     case CMD_INSPECT_FLOOR: request_autopickup(); break;
1672     case CMD_SHOW_TERRAIN: toggle_show_terrain(); break;
1673     case CMD_ADJUST_INVENTORY: adjust(); break;
1674
1675     case CMD_MOVE_NOWHERE:
1676     case CMD_SEARCH:
1677         search_around();
1678         you.turn_is_over = true;
1679         break;
1680
1681         // Action commands.
1682     case CMD_BUTCHER:              butchery();               break;
1683     case CMD_CAST_SPELL:           do_cast_spell_cmd(false); break;
1684     case CMD_DISPLAY_SPELLS:       inspect_spells();         break;
1685     case CMD_EAT:                  eat_food();               break;
1686     case CMD_EXAMINE_OBJECT:       examine_object();         break;
1687     case CMD_FIRE:                 fire_thing();             break;
1688     case CMD_FORCE_CAST_SPELL:     do_cast_spell_cmd(true);  break;
1689     case CMD_LOOK_AROUND:          _do_look_around();        break;
1690     case CMD_PICKUP:               pickup();                 break;
1691     case CMD_PRAY:                 pray();                   break;
1692     case CMD_QUAFF:                drink();                  break;
1693     case CMD_READ:                 read_scroll();            break;
1694     case CMD_REMOVE_ARMOUR:        _do_remove_armour();      break;
1695     case CMD_REMOVE_JEWELLERY:     remove_ring();            break;
1696     case CMD_SHOUT:                yell();                   break;
1697     case CMD_THROW_ITEM_NO_QUIVER: throw_item_no_quiver();   break;
1698     case CMD_WEAPON_SWAP:          wield_weapon(true);       break;
1699     case CMD_WEAR_ARMOUR:          wear_armour();            break;
1700     case CMD_WEAR_JEWELLERY:       puton_ring(-1);           break;
1701     case CMD_WIELD_WEAPON:         wield_weapon(false);      break;
1702     case CMD_ZAP_WAND:             zap_wand();               break;
1703
1704     case CMD_DROP:
1705         drop();
1706         if (Options.stash_tracking >= STM_DROPPED)
1707             StashTrack.add_stash();
1708         break;
1709
1710     case CMD_EVOKE:
1711         if (!evoke_item())
1712             flush_input_buffer(FLUSH_ON_FAILURE);
1713         break;
1714
1715     case CMD_EVOKE_WIELDED:
1716         if (!evoke_item(you.equip[EQ_WEAPON]))
1717             flush_input_buffer(FLUSH_ON_FAILURE);
1718         break;
1719
1720     case CMD_MEMORISE_SPELL:
1721         if (!learn_spell())
1722             flush_input_buffer(FLUSH_ON_FAILURE);
1723         break;
1724
1725     case CMD_USE_ABILITY:
1726         if (!activate_ability())
1727             flush_input_buffer(FLUSH_ON_FAILURE);
1728         break;
1729
1730         // Informational commands.
1731     case CMD_DISPLAY_CHARACTER_STATUS: display_char_status();          break;
1732     case CMD_DISPLAY_COMMANDS:         list_commands(0, true);         break;
1733     case CMD_DISPLAY_INVENTORY:        get_invent(OSEL_ANY);           break;
1734     case CMD_DISPLAY_KNOWN_OBJECTS:    check_item_knowledge();         break;
1735     case CMD_DISPLAY_MUTATIONS: display_mutations(); redraw_screen();  break;
1736     case CMD_DISPLAY_SKILLS:           show_skills(); redraw_screen(); break;
1737     case CMD_EXPERIENCE_CHECK:         _experience_check();            break;
1738     case CMD_FULL_VIEW:                full_describe_view();           break;
1739     case CMD_INSCRIBE_ITEM:            prompt_inscribe_item();         break;
1740     case CMD_LIST_ARMOUR:              list_armour();                  break;
1741     case CMD_LIST_EQUIPMENT:           get_invent(OSEL_EQUIP);         break;
1742     case CMD_LIST_GOLD:                _do_list_gold();                break;
1743     case CMD_LIST_JEWELLERY:           list_jewellery();               break;
1744     case CMD_LIST_WEAPONS:             list_weapons();                 break;
1745     case CMD_MAKE_NOTE:                make_user_note();               break;
1746     case CMD_REPLAY_MESSAGES: replay_messages(); redraw_screen();      break;
1747     case CMD_RESISTS_SCREEN:           print_overview_screen();        break;
1748
1749     case CMD_DISPLAY_RELIGION:
1750         describe_god(you.religion, true);
1751         redraw_screen();
1752         break;
1753
1754     case CMD_READ_MESSAGES:
1755 #ifdef DGL_SIMPLE_MESSAGING
1756         if (SysEnv.have_messages)
1757             read_messages();
1758 #endif
1759         break;
1760
1761     case CMD_CHARACTER_DUMP:
1762         if (dump_char(you.your_name, false))
1763             mpr("Char dumped successfully.");
1764         else
1765             mpr("Char dump unsuccessful! Sorry about that.");
1766         break;
1767
1768         // Travel commands.
1769     case CMD_FIX_WAYPOINT:      travel_cache.add_waypoint(); break;
1770     case CMD_INTERLEVEL_TRAVEL: do_interlevel_travel();      break;
1771     case CMD_ANNOTATE_LEVEL:    annotate_level();            break;
1772     case CMD_EXPLORE:           do_explore_cmd();            break;
1773
1774         // Mouse commands.
1775     case CMD_MOUSE_MOVE:
1776     {
1777         const coord_def dest = view2grid(crawl_view.mousep);
1778         if (in_bounds(dest))
1779             terse_describe_square(dest);
1780         break;
1781     }
1782
1783     case CMD_MOUSE_CLICK:
1784     {
1785         // XXX: We should probably use specific commands such as
1786         // CMD_MOUSE_TRAVEL and get rid of CMD_MOUSE_CLICK and
1787         // CMD_MOUSE_MOVE.
1788         c_mouse_event cme = get_mouse_event();
1789         if (cme && crawl_view.in_view_viewport(cme.pos))
1790         {
1791             const coord_def dest = view2grid(cme.pos);
1792             if (cme.left_clicked())
1793             {
1794                 if (in_bounds(dest))
1795                     start_travel(dest);
1796             }
1797             else if (cme.right_clicked())
1798             {
1799                 if (you.see_cell(dest))
1800                     full_describe_square(dest);
1801                 else
1802                     mpr("You can't see that place.");
1803             }
1804         }
1805         break;
1806     }
1807
1808
1809         // Quiver commands.
1810     case CMD_QUIVER_ITEM:           choose_item_for_quiver(); break;
1811     case CMD_CYCLE_QUIVER_FORWARD:  _do_cycle_quiver(+1);     break;
1812     case CMD_CYCLE_QUIVER_BACKWARD: _do_cycle_quiver(-1);     break;
1813
1814 #ifdef WIZARD
1815     case CMD_WIZARD: _handle_wizard_command(); break;
1816 #endif
1817
1818         // Game commands.
1819     case CMD_REDRAW_SCREEN: redraw_screen(); break;
1820
1821 #ifdef USE_UNIX_SIGNALS
1822     case CMD_SUSPEND_GAME:
1823         // CTRL-Z suspend behaviour is implemented here,
1824         // because we want to have CTRL-Y available...
1825         // and unfortunately they tend to be stuck together.
1826         clrscr();
1827 #ifndef USE_TILE
1828         unixcurses_shutdown();
1829         kill(0, SIGTSTP);
1830         unixcurses_startup();
1831 #endif
1832         redraw_screen();
1833         break;
1834 #endif
1835
1836     case CMD_SAVE_GAME:
1837         if (yesno("Save game and exit?", true, 'n'))
1838             save_game(true);
1839         break;
1840
1841     case CMD_SAVE_GAME_NOW:
1842         mpr("Saving game... please wait.");
1843         save_game(true);
1844         break;
1845
1846     case CMD_QUIT:
1847         if (yes_or_no("Are you sure you want to quit"))
1848             ouch(INSTANT_DEATH, NON_MONSTER, KILLED_BY_QUITTING);
1849         else
1850             canned_msg(MSG_OK);
1851         break;
1852
1853     case CMD_NO_CMD:
1854     default:
1855         if (Tutorial.tutorial_left)
1856         {
1857            std::string msg = "Unknown command. (For a list of commands type "
1858                              "<w>?\?<lightgrey>.)";
1859            mpr(msg);
1860         }
1861         else // well, not examine, but...
1862            mpr("Unknown command.", MSGCH_EXAMINE_FILTER);
1863         break;
1864     }
1865 }
1866
1867 static void _prep_input()
1868 {
1869     you.turn_is_over = false;
1870     you.time_taken = player_speed();
1871     you.shield_blocks = 0;              // no blocks this round
1872
1873     textcolor(LIGHTGREY);
1874
1875     set_redraw_status(REDRAW_LINE_2_MASK | REDRAW_LINE_3_MASK);
1876     print_stats();
1877
1878     viewwindow(false, true);
1879     maybe_update_stashes();
1880 }
1881
1882 // Decrement a single duration. Print the message if the duration runs out.
1883 // Returns true if the duration ended.
1884 // At midpoint (defined by get_expiration_threshold() in player.cc)
1885 // print midmsg and decrease duration by midloss (a randomised amount so as
1886 // to make it impossible to know the exact remaining duration for sure).
1887 // NOTE: The maximum possible midloss should be smaller than midpoint,
1888 //       otherwise the duration may end in the same turn the warning
1889 //       message is printed which would be a bit late.
1890 static bool _decrement_a_duration(duration_type dur, int delay,
1891                                   const char* endmsg = NULL, int midloss = 0,
1892                                   const char* midmsg = NULL,
1893                                   msg_channel_type chan = MSGCH_DURATION)
1894 {
1895     if (you.duration[dur] < 1)
1896         return (false);
1897
1898     const int midpoint = get_expiration_threshold(dur);
1899
1900
1901     int old_dur = you.duration[dur];
1902
1903     you.duration[dur] -= delay;
1904     if (you.duration[dur] < 0)
1905         you.duration[dur] = 0;
1906
1907     // Did we cross the mid point? (No longer likely to hit it exactly) -cao
1908     if (you.duration[dur] <= midpoint && old_dur > midpoint)
1909     {
1910         if (midmsg)
1911             mpr(midmsg, chan);
1912         you.duration[dur] -= midloss * BASELINE_DELAY;
1913     }
1914
1915     // allow fall-through in case midloss ended the duration (it shouldn't)
1916     if (you.duration[dur] == 0)
1917     {
1918         if (endmsg)
1919             mpr(endmsg, chan);
1920         return true;
1921     }
1922
1923     return false;
1924 }
1925
1926 //  Perhaps we should write functions like: update_liquid_flames(), etc.
1927 //  Even better, we could have a vector of callback functions (or
1928 //  objects) which get installed at some point.
1929 static void _decrement_durations()
1930 {
1931     int delay = you.time_taken;
1932
1933     if (wearing_amulet(AMU_THE_GOURMAND))
1934     {
1935         if (you.duration[DUR_GOURMAND] < GOURMAND_MAX && coinflip())
1936             you.duration[DUR_GOURMAND] += delay;
1937     }
1938     else
1939         you.duration[DUR_GOURMAND] = 0;
1940
1941     if (you.duration[DUR_ICEMAIL_DEPLETED] > 0)
1942     {
1943         if(delay > you.duration[DUR_ICEMAIL_DEPLETED])
1944             you.duration[DUR_ICEMAIL_DEPLETED] = 0;
1945         else
1946             you.duration[DUR_ICEMAIL_DEPLETED] -= delay;
1947
1948         if (!you.duration[DUR_ICEMAIL_DEPLETED])
1949             mpr("Your icy envelope is fully restored.", MSGCH_DURATION);
1950
1951         you.redraw_armour_class = true;
1952     }
1953
1954     // Must come before might/haste/berserk.
1955     if (_decrement_a_duration(DUR_BUILDING_RAGE, delay))
1956         go_berserk(false);
1957
1958     if (_decrement_a_duration(DUR_SLEEP, delay))
1959         you.awake();
1960
1961     dec_napalm_player(delay);
1962
1963     if (_decrement_a_duration(DUR_ICY_ARMOUR, delay,
1964                               "Your icy armour evaporates.", coinflip(),
1965                               "Your icy armour starts to melt."))
1966     {
1967         you.redraw_armour_class = true;
1968     }
1969
1970     if (_decrement_a_duration(DUR_SILENCE, delay, "Your hearing returns."))
1971         you.attribute[ATTR_WAS_SILENCED] = 0;
1972
1973     _decrement_a_duration(DUR_REPEL_MISSILES, delay,
1974                           "You feel less protected from missiles.",
1975                           coinflip(),
1976                           "Your repel missiles spell is about to expire...");
1977
1978     _decrement_a_duration(DUR_DEFLECT_MISSILES, delay,
1979                           "You feel less protected from missiles.",
1980                           coinflip(),
1981                           "Your deflect missiles spell is about to expire...");
1982
1983     if (_decrement_a_duration(DUR_REGENERATION, delay,
1984                               NULL, coinflip(),
1985                               "Your skin is crawling a little less now."))
1986     {
1987         remove_regen(you.attribute[ATTR_DIVINE_REGENERATION]);
1988     }
1989
1990     if (you.duration[DUR_PRAYER] > 1)
1991         you.duration[DUR_PRAYER]--;
1992     else if (you.duration[DUR_PRAYER] == 1)
1993         end_prayer();
1994
1995     if (you.duration[DUR_DIVINE_SHIELD] > 0)
1996     {
1997         if (you.duration[DUR_DIVINE_SHIELD] > 1)
1998         {
1999             you.duration[DUR_DIVINE_SHIELD] -= delay;
2000             if(you.duration[DUR_DIVINE_SHIELD] <= 1)
2001             {
2002                 you.duration[DUR_DIVINE_SHIELD] = 1;
2003                 mpr("Your divine shield starts to fade.", MSGCH_DURATION);
2004             }
2005         }
2006
2007         if (you.duration[DUR_DIVINE_SHIELD] == 1 && !one_chance_in(3))
2008         {
2009             you.redraw_armour_class = true;
2010             if (--you.attribute[ATTR_DIVINE_SHIELD] == 0)
2011             {
2012                 you.duration[DUR_DIVINE_SHIELD] = 0;
2013                 mpr("Your divine shield fades away.", MSGCH_DURATION);
2014             }
2015         }
2016     }
2017
2018     //jmf: More flexible weapon branding code.
2019     int last_value = you.duration[DUR_WEAPON_BRAND];
2020
2021     if (last_value > 0)
2022     {
2023         you.duration[DUR_WEAPON_BRAND] -= delay;
2024
2025         if (you.duration[DUR_WEAPON_BRAND] <= 0)
2026         {
2027             you.duration[DUR_WEAPON_BRAND] = 0;
2028             item_def& weapon = *you.weapon();
2029             const int temp_effect = get_weapon_brand(weapon);
2030
2031             set_item_ego_type(weapon, OBJ_WEAPONS, SPWPN_NORMAL);
2032             std::string msg = weapon.name(DESC_CAP_YOUR);
2033
2034             switch (temp_effect)
2035             {
2036             case SPWPN_VORPAL:
2037                 if (get_vorpal_type(weapon) == DVORP_SLICING)
2038                     msg += " seems blunter.";
2039                 else
2040                     msg += " feels lighter.";
2041                 break;
2042             case SPWPN_FLAME:
2043             case SPWPN_FLAMING:
2044                 msg += " goes out.";
2045                 break;
2046             case SPWPN_FREEZING:
2047                 msg += " stops glowing.";
2048                 break;
2049             case SPWPN_FROST:
2050                 msg += "'s frost melts away.";
2051                 break;
2052             case SPWPN_VENOM:
2053                 msg += " stops dripping with poison.";
2054                 break;
2055             case SPWPN_DRAINING:
2056                 msg += " stops crackling.";
2057                 break;
2058             case SPWPN_DISTORTION:
2059                 msg += " seems straighter.";
2060                 break;
2061             case SPWPN_PAIN:
2062                 msg += " seems less pained.";
2063                 break;
2064             default:
2065                 msg += " seems inexplicably less special.";
2066                 break;
2067             }
2068
2069             mpr(msg.c_str(), MSGCH_DURATION);
2070             you.wield_change = true;
2071         }
2072     }
2073
2074     // FIXME: [ds] Remove this once we've ensured durations can never go < 0?
2075     if (you.duration[DUR_TRANSFORMATION] <= 0
2076         && you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
2077     {
2078         you.duration[DUR_TRANSFORMATION] = 1;
2079     }
2080
2081     // Vampire bat transformations are permanent (until ended).
2082     if (you.species != SP_VAMPIRE || !player_in_bat_form()
2083         || you.duration[DUR_TRANSFORMATION] <= 5 * BASELINE_DELAY)
2084     {
2085         if (_decrement_a_duration(DUR_TRANSFORMATION, delay, NULL, random2(3),
2086                                   "Your transformation is almost over."))
2087         {
2088             untransform();
2089             you.duration[DUR_BREATH_WEAPON] = 0;
2090         }
2091     }
2092
2093     // Must come after transformation duration.
2094     _decrement_a_duration(DUR_BREATH_WEAPON, delay,
2095                           "You have got your breath back.", 0, NULL,
2096                           MSGCH_RECOVERY);
2097
2098     _decrement_a_duration(DUR_SWIFTNESS, delay,
2099                           "You feel sluggish.", coinflip(),
2100                           "You start to feel a little slower.");
2101     _decrement_a_duration(DUR_INSULATION, delay,
2102                           "You feel conductive.", coinflip(),
2103                           "You start to feel a little less insulated.");
2104
2105     if (_decrement_a_duration(DUR_STONEMAIL, delay,
2106                               "Your scaly stone armour disappears.",
2107                               coinflip(),
2108                               "Your scaly stone armour is starting "
2109                               "to flake away."))
2110     {
2111         you.redraw_armour_class = true;
2112         burden_change();
2113     }
2114
2115     if (_decrement_a_duration(DUR_PHASE_SHIFT, delay,
2116                     "You are firmly grounded in the material plane once more.",
2117                     coinflip(),
2118                     "You feel closer to the material plane."))
2119     {
2120         you.redraw_evasion = true;
2121     }
2122
2123     if (_decrement_a_duration(DUR_SEE_INVISIBLE, delay)
2124         && !you.can_see_invisible())
2125     {
2126         mpr("Your eyesight blurs momentarily.", MSGCH_DURATION);
2127     }
2128
2129     _decrement_a_duration(DUR_TELEPATHY, delay, "You feel less empathic.");
2130
2131     if (_decrement_a_duration(DUR_CONDENSATION_SHIELD, delay))
2132         remove_condensation_shield();
2133
2134     if (you.duration[DUR_CONDENSATION_SHIELD] && player_res_cold() < 0)
2135     {
2136         mpr("You feel very cold.");
2137         ouch(2 + random2avg(13, 2), NON_MONSTER, KILLED_BY_FREEZING);
2138     }
2139
2140     if (_decrement_a_duration(DUR_MAGIC_SHIELD, delay,
2141                               "Your magical shield disappears."))
2142     {
2143         you.redraw_armour_class = true;
2144     }
2145
2146     if (_decrement_a_duration(DUR_STONESKIN, delay, "Your skin feels tender."))
2147         you.redraw_armour_class = true;
2148
2149     if (_decrement_a_duration(DUR_TELEPORT, delay))
2150     {
2151         // Only to a new area of the abyss sometimes (for abyss teleports).
2152         you_teleport_now(true, one_chance_in(5));
2153         untag_followers();
2154     }
2155
2156     _decrement_a_duration(DUR_CONTROL_TELEPORT, delay,
2157                           "You feel uncertain.", coinflip(),
2158                           "You start to feel a little uncertain.");
2159
2160     if (_decrement_a_duration(DUR_DEATH_CHANNEL, delay,
2161                               "Your unholy channel expires.", coinflip(),
2162                               "Your unholy channel is weakening."))
2163     {
2164         you.attribute[ATTR_DIVINE_DEATH_CHANNEL] = 0;
2165     }
2166
2167     _decrement_a_duration(DUR_SAGE, delay, "You feel less studious.");
2168     _decrement_a_duration(DUR_STEALTH, delay, "You feel less stealthy.");
2169     _decrement_a_duration(DUR_RESIST_FIRE, delay, "Your fire resistance expires.");
2170     _decrement_a_duration(DUR_RESIST_COLD, delay, "Your cold resistance expires.");
2171     _decrement_a_duration(DUR_RESIST_POISON, delay, "Your poison resistance expires.");
2172     _decrement_a_duration(DUR_SLAYING, delay, "You feel less lethal.");
2173
2174     _decrement_a_duration(DUR_INVIS, delay, "You flicker back into view.",
2175                           coinflip(), "You flicker for a moment.");
2176
2177     _decrement_a_duration(DUR_BARGAIN, delay, "You feel less charismatic.");
2178     _decrement_a_duration(DUR_CONF, delay, "You feel less confused.");
2179     _decrement_a_duration(DUR_LOWERED_MR, delay, "You feel more resistant to magic.");
2180     _decrement_a_duration(DUR_SLIMIFY, delay, "You feel less slimy.",
2181                           coinflip(), "Your slime is starting to congeal.");
2182     _decrement_a_duration(DUR_MISLED, delay, "Your thoughts are your own once more.");
2183
2184     if (you.duration[DUR_PARALYSIS] || you.petrified())
2185     {
2186         _decrement_a_duration(DUR_PARALYSIS, delay);
2187         _decrement_a_duration(DUR_PETRIFIED, delay);
2188
2189         if (!you.duration[DUR_PARALYSIS] && !you.petrified())
2190         {
2191             mpr("You can move again.", MSGCH_DURATION);
2192             you.redraw_evasion = true;
2193         }
2194     }
2195
2196     _decrement_a_duration(DUR_EXHAUSTED, delay, "You feel less fatigued.");
2197
2198     _decrement_a_duration(DUR_CONFUSING_TOUCH, delay,
2199                           ((std::string("Your ") + your_hand(true)) +
2200                           " stop glowing.").c_str());
2201
2202     _decrement_a_duration(DUR_SURE_BLADE, delay,
2203                           "The bond with your blade fades away.");
2204
2205     if (_decrement_a_duration(DUR_MESMERISED, delay,
2206                               "You break out of your daze.",
2207                               0, NULL, MSGCH_RECOVERY))
2208     {
2209         you.clear_beholders();
2210     }
2211
2212     dec_slow_player(delay);
2213     dec_haste_player(delay);
2214
2215     if (_decrement_a_duration(DUR_MIGHT, delay,
2216                               "You feel a little less mighty now."))
2217     {
2218         modify_stat(STAT_STRENGTH, -5, true, "might running out");
2219     }
2220
2221     if (_decrement_a_duration(DUR_AGILITY, delay,
2222                               "You feel a little less agile now."))
2223     {
2224         modify_stat(STAT_DEXTERITY, -5, true, "agility running out");
2225     }
2226
2227     if (_decrement_a_duration(DUR_BRILLIANCE, delay,
2228                               "You feel a little less clever now."))
2229     {
2230         modify_stat(STAT_INTELLIGENCE, -5, true, "brilliance running out");
2231     }
2232
2233     if (_decrement_a_duration(DUR_BERSERKER, delay,
2234                               "You are no longer berserk."))
2235     {
2236         //jmf: Guilty for berserking /after/ berserk.
2237         did_god_conduct(DID_STIMULANTS, 6 + random2(6));
2238
2239         // Sometimes berserk leaves us physically drained.
2240         //
2241         // Chance of passing out:
2242         //     - mutation gives a large plus in order to try and
2243         //       avoid the mutation being a "death sentence" to
2244         //       certain characters.
2245         //     - knowing the spell gives an advantage just
2246         //       so that people who have invested 3 spell levels
2247         //       are better off than the casual potion drinker...
2248         //       this should make it a bit more interesting for
2249         //       Crusaders again.
2250         //     - similarly for the amulet
2251
2252         if (you.berserk_penalty != NO_BERSERK_PENALTY)
2253         {
2254             const int chance =
2255                 10 + player_mutation_level(MUT_BERSERK) * 25
2256                 + (wearing_amulet(AMU_RAGE) ? 10 : 0)
2257                 + (you.has_spell(SPELL_BERSERKER_RAGE) ? 5 : 0);
2258
2259             // Note the beauty of Trog!  They get an extra save that's at
2260             // the very least 20% and goes up to 100%.
2261             if (you.religion == GOD_TROG && x_chance_in_y(you.piety, 150)
2262                 && !player_under_penance())
2263             {
2264                 mpr("Trog's vigour flows through your veins.");
2265             }
2266             else if (one_chance_in(chance))
2267             {
2268                 mpr("You pass out from exhaustion.", MSGCH_WARN);
2269                 you.increase_duration(DUR_PARALYSIS, roll_dice(1,4));
2270             }
2271         }
2272
2273         if (!you.duration[DUR_PARALYSIS] && !you.petrified())
2274             mpr("You are exhausted.", MSGCH_WARN);
2275
2276         // This resets from an actual penalty or from NO_BERSERK_PENALTY.
2277         you.berserk_penalty = 0;
2278
2279         int dur = 12 + roll_dice(2, 12);
2280         // For consistency with slow give exhaustion 2 times the nominal
2281         // duration.
2282         you.increase_duration(DUR_EXHAUSTED, dur * 2);
2283
2284         // Don't trigger too many tutorial messages.
2285         const bool tut_slow = Tutorial.tutorial_events[TUT_YOU_ENCHANTED];
2286         Tutorial.tutorial_events[TUT_YOU_ENCHANTED] = false;
2287
2288         {
2289             // Don't give duplicate 'You feel yourself slow down' messages.
2290             no_messages nm;
2291
2292             // While the amulet of resist slowing does prevent the post-berserk
2293             // slowing, exhaustion still ends haste.
2294             if (you.duration[DUR_HASTE] > 0)
2295             {
2296                 // Silently cancel haste, then slow player.
2297                 you.duration[DUR_HASTE] = 0;
2298             }
2299             slow_player(dur);
2300         }
2301
2302         make_hungry(700, true);
2303         you.hunger = std::max(50, you.hunger);
2304
2305         // 1KB: No berserk healing.
2306         you.hp = (you.hp + 1) * 2 / 3;
2307         calc_hp();
2308
2309         learned_something_new(TUT_POSTBERSERK);
2310         Tutorial.tutorial_events[TUT_YOU_ENCHANTED] = tut_slow;
2311     }
2312
2313     if (you.duration[DUR_CORONA])
2314     {
2315         you.duration[DUR_CORONA] -= delay;
2316         if (you.duration[DUR_CORONA] < 1)
2317             you.duration[DUR_CORONA] = 0;
2318
2319         if (!you.duration[DUR_CORONA] && !you.backlit())
2320             mpr("You are no longer glowing.", MSGCH_DURATION);
2321     }
2322
2323     // Leak piety from the piety pool into actual piety.
2324     // Note that changes of religious status without corresponding actions
2325     // (killing monsters, offering items, ...) might be confusing for
2326     // characters of some religions.
2327     // For now, though, keep information about what happened hidden.
2328     if (you.piety < MAX_PIETY && you.duration[DUR_PIETY_POOL] > 0
2329         && one_chance_in(5))
2330     {
2331         you.duration[DUR_PIETY_POOL]--;
2332         gain_piety(1, false, true);
2333
2334 #if defined(DEBUG_DIAGNOSTICS) || defined(DEBUG_SACRIFICE) || defined(DEBUG_PIETY)
2335         mpr("Piety increases by 1 due to piety pool.", MSGCH_DIAGNOSTICS);
2336
2337         if (you.duration[DUR_PIETY_POOL] == 0)
2338             mpr("Piety pool is now empty.", MSGCH_DIAGNOSTICS);
2339 #endif
2340     }
2341
2342     if (!you.permanent_levitation() && !you.permanent_flight())
2343     {
2344         if (_decrement_a_duration(DUR_LEVITATION, delay,
2345                                   "You float gracefully downwards.",
2346                                   random2(6),
2347                                   "You are starting to lose your buoyancy!"))
2348         {
2349             burden_change();
2350             // Landing kills controlled flight.
2351             you.duration[DUR_CONTROLLED_FLIGHT] = 0;
2352             // Re-enter the terrain.
2353             move_player_to_grid(you.pos(), false, true, true);
2354         }
2355     }
2356
2357     if (!you.permanent_flight()
2358         && _decrement_a_duration(DUR_CONTROLLED_FLIGHT, delay)
2359         && you.airborne())
2360     {
2361             mpr("You lose control over your flight.", MSGCH_DURATION);
2362     }
2363
2364     if (you.rotting > 0)
2365     {
2366         // XXX: Mummies have an ability (albeit an expensive one) that
2367         // can fix rotted HPs now... it's probably impossible for them
2368         // to even start rotting right now, but that could be changed. -- bwr
2369         // It's not normal biology, so Cheibriados won't help.
2370         if (you.species == SP_MUMMY)
2371             you.rotting = 0;
2372         else if (x_chance_in_y(you.rotting, 20))
2373         {
2374             mpr("You feel your flesh rotting away.", MSGCH_WARN);
2375             ouch(1, NON_MONSTER, KILLED_BY_ROTTING);
2376             rot_hp(1);
2377             you.rotting--;
2378         }
2379     }
2380
2381     // ghoul rotting is special, but will deduct from you.rotting
2382     // if it happens to be positive - because this is placed after
2383     // the "normal" rotting check, rotting attacks can be somewhat
2384     // more painful on ghouls - reversing order would make rotting
2385     // attacks somewhat less painful, but that seems wrong-headed {dlb}:
2386     if (you.species == SP_GHOUL)
2387     {
2388         if (one_chance_in((you.religion == GOD_CHEIBRIADOS && you.piety >
2389                            piety_breakpoint(0)) ? 600 : 400))
2390         {
2391             mpr("You feel your flesh rotting away.", MSGCH_WARN);
2392             ouch(1, NON_MONSTER, KILLED_BY_ROTTING);
2393             rot_hp(1);
2394
2395             if (you.rotting > 0)
2396                 you.rotting--;
2397         }
2398     }
2399
2400     dec_disease_player(delay);
2401
2402     dec_poison_player();
2403
2404     if (you.duration[DUR_DEATHS_DOOR])
2405     {
2406         if (you.hp > allowed_deaths_door_hp())
2407         {
2408             mpr("Your life is in your own hands once again.", MSGCH_DURATION);
2409             you.increase_duration(DUR_PARALYSIS, 5 + random2(5));
2410             confuse_player(10 + random2(10));
2411             you.hp_max--;
2412             deflate_hp(you.hp_max, false);
2413             you.duration[DUR_DEATHS_DOOR] = 0;
2414         }
2415         else
2416         {
2417             _decrement_a_duration(DUR_DEATHS_DOOR, delay,
2418                                   "Your life is in your own hands again!",
2419                                   random2(6),
2420                                   "Your time is quickly running out!");
2421         }
2422     }
2423
2424     if (_decrement_a_duration(DUR_DIVINE_VIGOUR, delay))
2425         remove_divine_vigour();
2426
2427     if (_decrement_a_duration(DUR_DIVINE_STAMINA, delay))
2428         remove_divine_stamina();
2429
2430     _decrement_a_duration(DUR_REPEL_STAIRS_MOVE, 1);
2431     _decrement_a_duration(DUR_REPEL_STAIRS_CLIMB, 1);
2432 }
2433
2434 static void _check_banished()
2435 {
2436     if (you.banished)
2437     {
2438         you.banished = false;
2439         if (you.level_type != LEVEL_ABYSS)
2440         {
2441             mpr("You are cast into the Abyss!", MSGCH_BANISHMENT);
2442             more();
2443             banished(DNGN_ENTER_ABYSS, you.banished_by);
2444         }
2445         you.banished_by.clear();
2446     }
2447 }
2448
2449 static void _check_shafts()
2450 {
2451     for (int i = 0; i < MAX_TRAPS; ++i)
2452     {
2453         trap_def &trap = env.trap[i];
2454
2455         if (trap.type != TRAP_SHAFT)
2456             continue;
2457
2458         ASSERT(in_bounds(trap.pos));
2459
2460         handle_items_on_shaft(trap.pos, true);
2461     }
2462 }
2463
2464 static void _check_sanctuary()
2465 {
2466     if (env.sanctuary_time <= 0)
2467         return;
2468
2469     decrease_sanctuary_radius();
2470 }
2471
2472 static void _regenerate_hp_and_mp(int delay)
2473 {
2474     // XXX: using an int tmp to fix the fact that hit_points_regeneration
2475     // is only an unsigned char and is thus likely to overflow. -- bwr
2476     int tmp = you.hit_points_regeneration;
2477
2478     if (you.hp < you.hp_max && !you.disease && !you.duration[DUR_DEATHS_DOOR])
2479     {
2480         int base_val = player_regen();
2481         tmp += div_rand_round(base_val * delay, BASELINE_DELAY);
2482     }
2483
2484     while (tmp >= 100)
2485     {
2486         inc_hp(1, false);
2487         tmp -= 100;
2488     }
2489
2490     // XXX: Don't let DD use guardian spirit for free HP. (due, dpeg)
2491     if (player_spirit_shield() && you.species == SP_DEEP_DWARF)
2492         return;
2493
2494     ASSERT(tmp >= 0 && tmp < 100);
2495     you.hit_points_regeneration = static_cast<unsigned char>(tmp);
2496
2497     // XXX: Doing the same as the above, although overflow isn't an
2498     // issue with magic point regeneration, yet. -- bwr
2499     tmp = you.magic_points_regeneration;
2500
2501     if (you.magic_points < you.max_magic_points)
2502     {
2503         int base_val = 7 + you.max_magic_points / 2;
2504         tmp += div_rand_round(base_val * delay, BASELINE_DELAY);
2505     }
2506
2507     while (tmp >= 100)
2508     {
2509         inc_mp(1, false);
2510         tmp -= 100;
2511     }
2512
2513     ASSERT(tmp >= 0 && tmp < 100);
2514     you.magic_points_regeneration = static_cast<unsigned char>(tmp);
2515 }
2516
2517 void world_reacts()
2518 {
2519     reset_show_terrain();
2520
2521     crawl_state.clear_mon_acting();
2522
2523     if (!crawl_state.game_is_arena())
2524     {
2525         you.turn_is_over = true;
2526         religion_turn_end();
2527         crawl_state.clear_god_acting();
2528     }
2529
2530 #ifdef USE_TILE
2531     if (Tutorial.tutorial_left)
2532     {
2533         tiles.clear_text_tags(TAG_TUTORIAL);
2534         tiles.place_cursor(CURSOR_TUTORIAL, Region::NO_CURSOR);
2535     }
2536 #endif
2537
2538     _check_banished();
2539     _check_shafts();
2540     _check_sanctuary();
2541
2542     run_environment_effects();
2543
2544     if (!you.cannot_act() && !player_mutation_level(MUT_BLURRY_VISION)
2545         && x_chance_in_y(you.skills[SK_TRAPS_DOORS], 50))
2546     {
2547         search_around(false); // Check nonadjacent squares too.
2548     }
2549
2550     if (!crawl_state.game_is_arena())
2551         stealth = check_stealth();
2552
2553 #ifdef DEBUG_STEALTH
2554     // Too annoying for regular diagnostics.
2555     mprf(MSGCH_DIAGNOSTICS, "stealth: %d", stealth);
2556 #endif
2557
2558     if (you.attribute[ATTR_NOISES])
2559         noisy_equipment();
2560
2561     if (you.attribute[ATTR_SHADOWS])
2562         shadow_lantern_effect();
2563
2564     if (you.unrand_reacts != 0)
2565         unrand_reacts();
2566
2567     if (!crawl_state.game_is_arena() && one_chance_in(10))
2568     {
2569         // this is instantaneous
2570         if (player_teleport() > 0 && one_chance_in(100 / player_teleport()))
2571             you_teleport_now(true);
2572         else if (you.level_type == LEVEL_ABYSS && one_chance_in(30))
2573             you_teleport_now(false, true); // to new area of the Abyss
2574     }
2575
2576     if (!crawl_state.game_is_arena() && env.cgrid(you.pos()) != EMPTY_CLOUD)
2577         in_a_cloud();
2578
2579     if (you.level_type == LEVEL_DUNGEON && you.duration[DUR_TELEPATHY])
2580         detect_creatures(1 + you.duration[DUR_TELEPATHY] /
2581                          (2 * BASELINE_DELAY), true);
2582
2583     _decrement_durations();
2584
2585     const int food_use = player_hunger_rate();
2586     if (food_use > 0 && you.hunger >= 40)
2587         make_hungry(food_use, true);
2588
2589     _regenerate_hp_and_mp(you.time_taken);
2590
2591     // If you're wielding a rod, it'll gradually recharge.
2592     recharge_rods(you.time_taken, false);
2593
2594     // Player stealth check.
2595     viewwindow(true);
2596
2597     handle_monsters();
2598
2599     _check_banished();
2600
2601     ASSERT(you.time_taken >= 0);
2602     you.elapsed_time += you.time_taken;
2603     if (you.elapsed_time >= 2*1000*1000*1000)
2604     {
2605         // 2B of 1/10 turns.  A 32-bit signed int can hold 2.1B.
2606         // The worst case of mummy scumming had 92M turns, the second worst
2607         // merely 8M.  This limit is ~200M turns, with an efficient bot that
2608         // keeps resting on a fast machine, it takes ~24 hours to hit it
2609         // on a level with no monsters, at 100% CPU utilization, producing
2610         // a gigabyte of bzipped ttyrec.
2611         // We could extend the counters to 64 bits, but in the light of the
2612         // above, it's an useless exercise.
2613         mpr("Outside, the world ends.");
2614         mpr("Sorry, but your quest for the Orb is now rather pointless.  "
2615             "You quit...");
2616         ouch(INSTANT_DEATH, NON_MONSTER, KILLED_BY_QUITTING);
2617     }
2618
2619     handle_time();
2620     manage_clouds();
2621
2622     if (you.duration[DUR_FIRE_SHIELD] > 0)
2623         manage_fire_shield(you.time_taken);
2624
2625     handle_starvation();
2626
2627     viewwindow(false);
2628
2629     if (you.cannot_act() && any_messages()
2630         && crawl_state.repeat_cmd != CMD_WIZARD)
2631     {
2632         more();
2633     }
2634
2635 #if defined(DEBUG_TENSION) || defined(DEBUG_RELIGION)
2636     if (you.religion != GOD_NO_GOD)
2637         mprf(MSGCH_DIAGNOSTICS, "TENSION = %d", get_tension());
2638 #endif
2639
2640     if (you.num_turns != -1)
2641     {
2642         if (you.num_turns < LONG_MAX)
2643             you.num_turns++;
2644         if (env.turns_on_level < INT_MAX)
2645             env.turns_on_level++;
2646         record_turn_timestamp();
2647         update_turn_count();
2648         msgwin_new_turn();
2649     }
2650 }
2651
2652 static command_type _get_next_cmd()
2653 {
2654 #ifdef DGL_SIMPLE_MESSAGING
2655     check_messages();
2656 #endif
2657
2658 #ifdef DEBUG_DIAGNOSTICS
2659     // Save hunger at start of round for use with hunger "delta-meter"
2660     // in output.cc.
2661     you.old_hunger = you.hunger;
2662 #endif
2663
2664 #ifdef DEBUG_ITEM_SCAN
2665     debug_item_scan();
2666 #endif
2667 #ifdef DEBUG_MONS_SCAN
2668     debug_mons_scan();
2669 #endif
2670
2671     _center_cursor();
2672
2673     const time_t before = time(NULL);
2674     keycode_type keyin = _get_next_keycode();
2675
2676     const time_t after = time(NULL);
2677
2678     // Clamp idle time so that play time is more meaningful.
2679     if (after - before > IDLE_TIME_CLAMP)
2680     {
2681         you.real_time  += int(before - you.start_time) + IDLE_TIME_CLAMP;
2682         you.start_time  = after;
2683     }
2684
2685     if (is_userfunction(keyin))
2686     {
2687         run_macro(get_userfunction(keyin).c_str());
2688         return (CMD_NEXT_CMD);
2689     }
2690
2691     return _keycode_to_command(keyin);
2692 }
2693
2694 // We handle the synthetic keys, key_to_command() handles the
2695 // real ones.
2696 static command_type _keycode_to_command(keycode_type key)
2697 {
2698     switch (key)
2699     {
2700 #ifdef USE_TILE
2701     case CK_MOUSE_CMD:    return CMD_NEXT_CMD;
2702 #endif
2703
2704     case KEY_MACRO_DISABLE_MORE: return CMD_DISABLE_MORE;
2705     case KEY_MACRO_ENABLE_MORE:  return CMD_ENABLE_MORE;
2706     case KEY_REPEAT_KEYS:        return CMD_REPEAT_KEYS;
2707
2708     default:
2709         return key_to_command(key, KMC_DEFAULT);
2710     }
2711 }
2712
2713 static keycode_type _get_next_keycode()
2714 {
2715     keycode_type keyin;
2716
2717     flush_input_buffer(FLUSH_BEFORE_COMMAND);
2718
2719     mouse_control mc(MOUSE_MODE_COMMAND);
2720     keyin = unmangle_direction_keys(getch_with_command_macros());
2721
2722     // This is the main mesclr() with Option.clear_messages.
2723     if (!is_synthetic_key(keyin))
2724         mesclr();
2725
2726     return (keyin);
2727 }
2728
2729 // Check squares adjacent to player for given feature and return how
2730 // many there are.  If there's only one, return the dx and dy.
2731 static int _check_adjacent(dungeon_feature_type feat, coord_def& delta)
2732 {
2733     int num = 0;
2734
2735     for (adjacent_iterator ai(you.pos(), false); ai; ++ai)
2736     {
2737         if (grd(*ai) == feat)
2738         {
2739             num++;
2740             delta = *ai - you.pos();
2741         }
2742     }
2743
2744     return num;
2745 }
2746
2747 // Handles some aspects of untrapping. Returns false if the target is a
2748 // closed door that will need to be opened.
2749 static bool _untrap_target(const coord_def move, bool check_confused)
2750 {
2751     const coord_def target = you.pos() + move;
2752     monsters* mon = monster_at(target);
2753     if (mon && player_can_hit_monster(mon))
2754     {
2755         if (mon->caught() && mon->friendly()
2756             && player_can_open_doors() && !you.confused())
2757         {
2758             const std::string prompt =
2759                 make_stringf("Do you want to try to take the net off %s?",
2760                              mon->name(DESC_NOCAP_THE).c_str());
2761
2762             if (yesno(prompt.c_str(), true, 'n'))
2763             {
2764                 remove_net_from(mon);
2765                 return (true);
2766             }
2767         }
2768
2769         you.turn_is_over = true;
2770         you_attack(mon->mindex(), true);
2771
2772         if (you.berserk_penalty != NO_BERSERK_PENALTY)
2773             you.berserk_penalty = 0;
2774
2775         return (true);
2776     }
2777
2778     if (find_trap(target) && grd(target) != DNGN_UNDISCOVERED_TRAP)
2779     {
2780         if (!you.confused())
2781         {
2782             if (!player_can_open_doors())
2783             {
2784                 mpr("You can't disarm traps in your present form.");
2785                 return (true);
2786             }
2787
2788             const int cloud = env.cgrid(target);
2789             if (cloud != EMPTY_CLOUD
2790                 && is_damaging_cloud(env.cloud[ cloud ].type, true))
2791             {
2792                 mpr("You can't get to that trap right now.");
2793                 return (true);
2794             }
2795         }
2796
2797         // If you're confused, you may attempt it and stumble into the trap.
2798         disarm_trap(target);
2799         return (true);
2800     }
2801
2802     const dungeon_feature_type feat = grd(target);
2803     if (!feat_is_closed_door(feat) || you.confused())
2804     {
2805         switch (feat)
2806         {
2807         case DNGN_OPEN_DOOR:
2808             _close_door(move); // for convenience
2809             return (true);
2810         default:
2811         {
2812             bool do_msg = true;
2813
2814             // Press trigger/switch/button in wall.
2815             if (feat_is_solid(feat))
2816             {
2817                 dgn_event event(DET_WALL_HIT, target);
2818                 event.arg1  = NON_MONSTER;
2819
2820                 // Listener can veto the event to prevent the "You swing at
2821                 // nothing" message.
2822                 do_msg =
2823                     dungeon_events.fire_vetoable_position_event(event,
2824                                                                 target);
2825             }
2826             if (do_msg)
2827                 mpr("You swing at nothing.");
2828             make_hungry(3, true);
2829             you.turn_is_over = true;
2830             return (true);
2831         }
2832         }
2833     }
2834
2835     // Else it's a closed door and needs further handling.
2836     return (false);
2837 }
2838
2839 // Opens doors and may also handle untrapping/attacking, etc.
2840 // If either move_x or move_y are non-zero, the pair carries a specific
2841 // direction for the door to be opened (eg if you type ctrl + dir).
2842 static void _open_door(coord_def move, bool check_confused)
2843 {
2844     ASSERT(!crawl_state.game_is_arena() && !crawl_state.arena_suspended);
2845
2846     if (you.attribute[ATTR_HELD])
2847     {
2848         free_self_from_net();
2849         you.turn_is_over = true;
2850         return;
2851     }
2852
2853     // The player used Ctrl + dir or a variant thereof.
2854     if (!move.origin())
2855     {
2856         if (check_confused && you.confused() && !one_chance_in(3))
2857         {
2858             do
2859                 move = coord_def(random2(3) - 1, random2(3) - 1);
2860             while (move.origin());
2861         }
2862         if (_untrap_target(move, check_confused))
2863             return;
2864     }
2865
2866     // If we get here, the player either hasn't picked a direction yet,
2867     // or the chosen direction actually contains a closed door.
2868     if (!player_can_open_doors())
2869     {
2870         mpr("You can't open doors in your present form.");
2871         return;
2872     }
2873
2874     dist door_move;
2875
2876     // The player hasn't picked a direction yet.
2877     if (move.origin())
2878     {
2879         const int num = _check_adjacent(DNGN_CLOSED_DOOR, move)
2880                         + _check_adjacent(DNGN_DETECTED_SECRET_DOOR, move);
2881
2882         if (num == 0)
2883         {
2884             mpr("There's nothing to open nearby.");
2885             return;
2886         }
2887
2888         // If there's only one door to open, don't ask.
2889         if (num == 1)
2890             door_move.delta = move;
2891         else
2892         {
2893             mpr("Which direction? ", MSGCH_PROMPT);
2894             direction_chooser_args args;
2895             args.restricts = DIR_DIR;
2896             direction(door_move, args);
2897
2898             if (!door_move.isValid)
2899                 return;
2900         }
2901     }
2902     else
2903         door_move.delta = move;
2904
2905     if (check_confused && you.confused() && !one_chance_in(3))
2906     {
2907         do
2908             door_move.delta = coord_def(random2(3) - 1, random2(3) - 1);
2909         while (door_move.delta.origin());
2910     }
2911
2912     // We got a valid direction.
2913     const coord_def doorpos = you.pos() + door_move.delta;
2914     const dungeon_feature_type feat = (in_bounds(doorpos) ? grd(doorpos)
2915                                                           : DNGN_UNSEEN);
2916     std::string door_already_open = "";
2917     if (in_bounds(doorpos))
2918     {
2919         door_already_open = env.markers.property_at(doorpos, MAT_ANY,
2920                                 "door_verb_already_open");
2921     }
2922
2923     if (!feat_is_closed_door(feat))
2924     {
2925         if (you.confused())
2926         {
2927             mpr("You swing at nothing.");
2928             make_hungry(3, true);
2929             you.turn_is_over = true;
2930             return;
2931         }
2932         switch (feat)
2933         {
2934         // This doesn't ever seem to be triggered.
2935         case DNGN_OPEN_DOOR:
2936             if (!door_already_open.empty())
2937                 mpr(door_already_open.c_str());
2938             else
2939                 mpr("It's already open!");
2940             break;
2941         default:
2942             mpr("There isn't anything that you can open there!");
2943             break;
2944         }
2945         // Don't lose a turn.
2946         return;
2947     }
2948
2949     // Finally, open the closed door!
2950     std::set<coord_def> all_door = connected_doors(doorpos);
2951     const char *adj, *noun;
2952     get_door_description(all_door.size(), &adj, &noun);
2953
2954     const std::string door_desc_adj  =
2955         env.markers.property_at(doorpos, MAT_ANY,
2956                                 "door_description_adjective");
2957     const std::string door_desc_noun =
2958         env.markers.property_at(doorpos, MAT_ANY,
2959                                 "door_description_noun");
2960     if (!door_desc_adj.empty())
2961         adj = door_desc_adj.c_str();
2962     if (!door_desc_noun.empty())
2963         noun = door_desc_noun.c_str();
2964
2965     if (!(check_confused && you.confused()))
2966     {
2967         std::string door_open_prompt =
2968             env.markers.property_at(doorpos, MAT_ANY, "door_open_prompt");
2969
2970         bool ignore_exclude = false;
2971
2972         if (!door_open_prompt.empty())
2973         {
2974             door_open_prompt += " (y/N)";
2975             if (!yesno(door_open_prompt.c_str(), true, 'n', true, false))
2976             {
2977                 if (is_exclude_root(doorpos))
2978                     canned_msg(MSG_OK);
2979                 else
2980                 {
2981                     if (yesno("Put travel exclusion on door? (Y/n)",
2982                               true, 'y'))
2983                     {
2984                         // Zero radius exclusion right on top of door.
2985                         set_exclude(doorpos, 0);
2986                     }
2987                 }
2988                 interrupt_activity(AI_FORCE_INTERRUPT);
2989                 return;
2990             }
2991             ignore_exclude = true;
2992         }
2993
2994         if (!ignore_exclude && is_exclude_root(doorpos))
2995         {
2996             std::string prompt =
2997                 make_stringf("This %s%s is marked as excluded! Open it "
2998                              "anyway?", adj, noun);
2999
3000             if (!yesno(prompt.c_str(), true, 'n', true, false))
3001             {
3002                 canned_msg(MSG_OK);
3003                 interrupt_activity(AI_FORCE_INTERRUPT);
3004                 return;
3005             }
3006         }
3007     }
3008
3009     int skill = you.dex
3010                 + (you.skills[SK_TRAPS_DOORS] + you.skills[SK_STEALTH]) / 2;
3011
3012     std::string berserk_open = env.markers.property_at(doorpos, MAT_ANY,
3013                                         "door_berserk_verb_open");
3014     std::string berserk_adjective = env.markers.property_at(doorpos, MAT_ANY,
3015                                         "door_berserk_adjective");
3016     std::string door_open_creak = env.markers.property_at(doorpos, MAT_ANY,
3017                                         "door_noisy_verb_open");
3018     std::string door_airborne = env.markers.property_at(doorpos, MAT_ANY,
3019                                         "door_airborne_verb_open");
3020     std::string door_open_verb = env.markers.property_at(doorpos, MAT_ANY,
3021                                         "door_verb_open");
3022
3023     if (you.berserk())
3024     {
3025         // XXX: Better flavour for larger doors?
3026         if (silenced(you.pos()))
3027         {
3028             if (!berserk_open.empty())
3029             {
3030                 berserk_open += ".";
3031                 mprf(berserk_open.c_str(), adj, noun);
3032             }
3033             else
3034                 mprf("The %s%s flies open!", adj, noun);
3035         }
3036         else
3037         {
3038             if (!berserk_open.empty())
3039             {
3040                 if (!berserk_adjective.empty())
3041                     berserk_open += " " + berserk_adjective;
3042                 else
3043                     berserk_open += ".";
3044                 mprf(MSGCH_SOUND, berserk_open.c_str(), adj, noun);
3045             }
3046             else
3047                 mprf(MSGCH_SOUND, "The %s%s flies open with a bang!", adj, noun);
3048             noisy(15, you.pos());
3049         }
3050     }
3051     else if (one_chance_in(skill) && !silenced(you.pos()))
3052     {
3053         if (!door_open_creak.empty())
3054             mprf(MSGCH_SOUND, door_open_creak.c_str(), adj, noun);
3055         else
3056         {
3057             mprf(MSGCH_SOUND, "As you open the %s%s, it creaks loudly!",
3058                  adj, noun);
3059         }
3060         noisy(10, you.pos());
3061     }
3062     else
3063     {
3064         const char* verb;
3065         if (you.airborne())
3066         {
3067             if (!door_airborne.empty())
3068                 verb = door_airborne.c_str();
3069             else
3070                 verb = "You reach down and open the %s%s.";
3071         }
3072         else
3073         {
3074             if (!door_open_verb.empty())
3075                verb = door_open_verb.c_str();
3076             else
3077                verb = "You open the %s%s.";
3078         }
3079
3080         mprf(verb, adj, noun);
3081     }
3082
3083     bool seen_secret = false;
3084     std::vector<coord_def> excludes;
3085     for (std::set<coord_def>::iterator i = all_door.begin();
3086          i != all_door.end(); ++i)
3087     {
3088         const coord_def& dc = *i;
3089         // Even if some of the door is out of LOS, we want the entire
3090         // door to be updated.  Hitting this case requires a really big
3091         // door!
3092         if (is_terrain_seen(dc))
3093         {
3094             set_map_knowledge_obj(dc, DNGN_OPEN_DOOR);
3095 #ifdef USE_TILE
3096             env.tile_bk_bg(dc) = TILE_DNGN_OPEN_DOOR;
3097 #endif
3098             if (!seen_secret && grd(dc) == DNGN_SECRET_DOOR)
3099             {
3100                 seen_secret = true;
3101                 dungeon_feature_type secret
3102                     = grid_secret_door_appearance(dc);
3103                 mprf("That %s was a secret door!",
3104                      feature_description(secret, NUM_TRAPS, false,
3105                                          DESC_PLAIN, false).c_str());
3106             }
3107         }
3108         grd(dc) = DNGN_OPEN_DOOR;
3109         dungeon_events.fire_position_event(DET_DOOR_OPENED, dc);
3110         if (is_excluded(dc))
3111             excludes.push_back(dc);
3112     }
3113
3114     update_exclusion_los(excludes);
3115
3116     you.turn_is_over = true;
3117 }
3118
3119 static void _close_door(coord_def move)
3120 {
3121     if (!player_can_open_doors())
3122     {
3123         mpr("You can't close doors in your present form.");
3124         return;
3125     }
3126
3127     if (you.attribute[ATTR_HELD])
3128     {
3129         mpr("You can't close doors while held in a net.");
3130         return;
3131     }
3132
3133     dist door_move;
3134
3135     // The player hasn't yet told us a direction.
3136     if (move.origin())
3137     {
3138         // If there's only one door to close, don't ask.
3139         int num = _check_adjacent(DNGN_OPEN_DOOR, move);
3140         if (num == 0)
3141         {
3142             mpr("There's nothing to close nearby.");
3143             return;
3144         }
3145         else if (num == 1)
3146             door_move.delta = move;
3147         else
3148         {
3149             mpr("Which direction? ", MSGCH_PROMPT);
3150             direction_chooser_args args;
3151             args.restricts = DIR_DIR;
3152             direction(door_move, args);
3153
3154             if (!door_move.isValid)
3155                 return;
3156         }
3157     }
3158     else
3159         door_move.delta = move;
3160
3161     if (you.confused() && !one_chance_in(3))
3162     {
3163         do
3164             door_move.delta = coord_def(random2(3) - 1, random2(3) - 1);
3165         while (door_move.delta.origin());
3166     }
3167
3168     if (door_move.delta.origin())
3169     {
3170         mpr("You can't close doors on yourself!");
3171         return;
3172     }
3173
3174     const coord_def doorpos = you.pos() + door_move.delta;
3175     const dungeon_feature_type feat = (in_bounds(doorpos) ? grd(doorpos)
3176                                                           : DNGN_UNSEEN);
3177
3178     std::string berserk_close = env.markers.property_at(doorpos, MAT_ANY,
3179                                         "door_berserk_verb_close");
3180     std::string berserk_adjective = env.markers.property_at(doorpos, MAT_ANY,
3181                                         "door_berserk_adjective");
3182     std::string door_close_creak = env.markers.property_at(doorpos, MAT_ANY,
3183                                         "door_noisy_verb_close");
3184     std::string door_airborne = env.markers.property_at(doorpos, MAT_ANY,
3185                                         "door_airborne_verb_close");
3186     std::string door_close_verb = env.markers.property_at(doorpos, MAT_ANY,
3187                                         "door_verb_close");
3188
3189     if (feat == DNGN_OPEN_DOOR)
3190     {
3191         std::set<coord_def> all_door;
3192         find_connected_identical(doorpos, grd(doorpos), all_door);
3193         const char *adj, *noun;
3194         get_door_description(all_door.size(), &adj, &noun);
3195         const std::string waynoun_str = make_stringf("%sway", noun);
3196         const char *waynoun = waynoun_str.c_str();
3197
3198         const std::string door_desc_adj  =
3199             env.markers.property_at(doorpos, MAT_ANY,
3200                                     "door_description_adjective");
3201         const std::string door_desc_noun =
3202             env.markers.property_at(doorpos, MAT_ANY,
3203                                     "door_description_noun");
3204         if (!door_desc_adj.empty())
3205             adj = door_desc_adj.c_str();
3206         if (!door_desc_noun.empty())
3207         {
3208             noun = door_desc_noun.c_str();
3209             waynoun = noun;
3210         }
3211
3212         for (std::set<coord_def>::const_iterator i = all_door.begin();
3213              i != all_door.end(); ++i)
3214         {
3215             const coord_def& dc = *i;
3216             if (monsters* mon = monster_at(dc))
3217             {
3218                 // Need to make sure that turn_is_over is set if
3219                 // creature is invisible.
3220                 if (!you.can_see(mon))
3221                 {
3222                     mprf("Something is blocking the %s!", waynoun);
3223                     you.turn_is_over = true;
3224                 }
3225                 else
3226                     mprf("There's a creature in the %s!", waynoun);
3227                 return;
3228             }
3229
3230             if (igrd(dc) != NON_ITEM)
3231             {
3232                 mprf("There's something blocking the %s.", waynoun);
3233                 return;
3234             }
3235
3236             if (you.pos() == dc)
3237             {
3238                 mprf("There's a thick-headed creature in the %s!", waynoun);
3239                 return;
3240             }
3241         }
3242
3243         int skill = you.dex
3244                     + (you.skills[SK_TRAPS_DOORS] + you.skills[SK_STEALTH]) / 2;
3245
3246         if (you.berserk())
3247         {
3248             if (silenced(you.pos()))
3249             {
3250                 if (!berserk_close.empty())
3251                 {
3252                     berserk_close += ".";
3253                     mprf(berserk_close.c_str(), adj, noun);
3254                 }
3255                 else
3256                     mprf("You slam the %s%s shut!", adj, noun);
3257             }
3258             else
3259             {
3260                 if (!berserk_close.empty())
3261                 {
3262                     if (!berserk_adjective.empty())
3263                         berserk_close += " " + berserk_adjective;
3264                     else
3265                         berserk_close += ".";
3266                     mprf(MSGCH_SOUND, berserk_close.c_str(), adj, noun);
3267                 }
3268                 else
3269                     mprf(MSGCH_SOUND, "You slam the %s%s shut with a bang!", adj, noun);
3270                 noisy(15, you.pos());
3271             }
3272         }
3273         else if (one_chance_in(skill) && !silenced(you.pos()))
3274         {
3275             if (!door_close_creak.empty())
3276                 mprf(MSGCH_SOUND, door_close_creak.c_str(), adj, noun);
3277             else
3278                 mprf(MSGCH_SOUND, "As you close the %s%s, it creaks loudly!",
3279                      adj, noun);
3280             noisy(10, you.pos());
3281         }
3282         else
3283         {
3284             const char* verb;
3285             if (you.airborne())
3286             {
3287                 if (!door_airborne.empty())
3288                     verb = door_airborne.c_str();
3289                 else
3290                     verb = "You reach down and close the %s%s.";
3291             }
3292             else
3293             {
3294                 if (!door_close_verb.empty())
3295                    verb = door_close_verb.c_str();
3296                 else
3297                     verb = "You close the %s%s.";
3298             }
3299
3300             mprf(verb, adj, noun);
3301         }
3302
3303         std::vector<coord_def> excludes;
3304         for (std::set<coord_def>::const_iterator i = all_door.begin();
3305              i != all_door.end(); ++i)
3306         {
3307             const coord_def& dc = *i;
3308             // Once opened, formerly secret doors become normal doors.
3309             grd(dc) = DNGN_CLOSED_DOOR;
3310
3311             dungeon_events.fire_position_event(DET_DOOR_CLOSED, dc);
3312
3313             // Even if some of the door is out of LOS once it's closed
3314             // (or even if some of it is out of LOS when it's open), we
3315             // want the entire door to be updated.
3316             if (is_terrain_seen(dc))
3317             {
3318                 set_map_knowledge_obj(dc, DNGN_CLOSED_DOOR);
3319 #ifdef USE_TILE
3320                 env.tile_bk_bg(dc) = TILE_DNGN_CLOSED_DOOR;
3321 #endif
3322             }
3323             if (is_excluded(dc))
3324                 excludes.push_back(dc);
3325         }
3326
3327         update_exclusion_los(excludes);
3328         you.turn_is_over = true;
3329     }
3330     else if (you.confused())
3331         _open_door(door_move.delta);
3332     else
3333     {
3334         switch (feat)
3335         {
3336         case DNGN_CLOSED_DOOR:
3337         case DNGN_DETECTED_SECRET_DOOR:
3338             mpr("It's already closed!");
3339             break;
3340         default:
3341             mpr("There isn't anything that you can close there!");
3342             break;
3343         }
3344     }
3345 }
3346
3347 // Initialise a whole lot of stuff...
3348 // Returns true if a new character.
3349 static bool _initialise(void)
3350 {
3351     Options.fixup_options();
3352
3353     // Read the options the player used last time they created a new
3354     // character.
3355     read_startup_prefs();
3356
3357     you.symbol = '@';
3358     you.colour = LIGHTGREY;
3359
3360     if (Options.seed)
3361         seed_rng(Options.seed);
3362     else
3363         seed_rng();
3364     get_typeid_array().init(ID_UNKNOWN_TYPE);
3365     init_char_table(Options.char_set);
3366     init_show_table();
3367     init_monster_symbols();
3368     init_spell_descs();        // This needs to be way up top. {dlb}
3369     init_zap_index();
3370     init_mon_name_cache();
3371     init_mons_spells();
3372
3373     // init_item_name_cache() needs to be redone after init_char_table()
3374     // and init_show_table() have been called, so that the glyphs will
3375     // be set to use with item_names_by_glyph_cache.
3376     init_item_name_cache();
3377
3378     msg::initialise_mpr_streams();
3379
3380     // Init item array.
3381     for (int i = 0; i < MAX_ITEMS; ++i)
3382         init_item(i);
3383
3384     // Empty messaging string.
3385     info[0] = 0;
3386
3387     for (int i = 0; i < MAX_MONSTERS; ++i)
3388         menv[i].reset();
3389
3390     igrd.init(NON_ITEM);
3391     mgrd.init(NON_MONSTER);
3392     env.map_knowledge.init(map_cell());
3393     env.pgrid.init(0);
3394
3395     you.unique_creatures.init(false);
3396     you.unique_items.init(UNIQ_NOT_EXISTS);
3397
3398     // Set up the Lua interpreter for the dungeon builder.
3399     init_dungeon_lua();
3400
3401 #ifdef USE_TILE
3402     // Draw the splash screen before the database gets initialised as that
3403     // may take awhile and it's better if the player can look at a pretty
3404     // screen while this happens.
3405     if (!crawl_state.map_stat_gen && !crawl_state.test
3406         && Options.tile_title_screen)
3407     {
3408         tiles.draw_title();
3409         tiles.update_title_msg("Loading Databases...");
3410     }
3411 #endif
3412
3413     // Initialise internal databases.
3414     databaseSystemInit();
3415 #ifdef USE_TILE
3416     if (Options.tile_title_screen)
3417         tiles.update_title_msg("Loading Spells and Features...");
3418 #endif
3419
3420     init_feat_desc_cache();
3421     init_spell_name_cache();
3422     init_spell_rarities();
3423 #ifdef USE_TILE
3424     if (Options.tile_title_screen)
3425         tiles.update_title_msg("Loading maps...");
3426 #endif
3427
3428     // Read special levels and vaults.
3429     read_maps();
3430
3431     if (crawl_state.build_db)
3432         end(0);
3433
3434     cio_init();
3435
3436     // System initialisation stuff.
3437     textbackground(0);
3438 #ifdef USE_TILE
3439     if (Options.tile_title_screen)
3440     {
3441         tiles.update_title_msg("Loading complete, press any key to start.");
3442         tiles.hide_title();
3443     }
3444 #endif
3445
3446     clrscr();
3447
3448 #ifdef DEBUG_DIAGNOSTICS
3449     if (crawl_state.map_stat_gen)
3450     {
3451         generate_map_stats();
3452         end(0, false);
3453     }
3454 #endif
3455
3456     if (crawl_state.test)
3457     {
3458 #if defined(DEBUG_TESTS) && !defined(DEBUG)
3459 #error "DEBUG must be defined if DEBUG_TESTS is defined"
3460 #endif
3461
3462 #if defined(DEBUG_DIAGNOSTICS) || defined(DEBUG_TESTS)
3463 #ifdef USE_TILE
3464         init_player_doll();
3465         tiles.initialise_items();
3466 #endif
3467         crawl_state.show_more_prompt = false;
3468         crawl_tests::run_tests(true);
3469         // Superfluous, just to make it clear that this is the end of
3470         // the line.
3471         end(0, false);
3472 #else
3473         end(1, false, "Non-debug Crawl cannot run tests. "
3474             "Please use a debug build (defined FULLDEBUG, DEBUG_DIAGNOSTIC "
3475             "or DEBUG_TESTS)");
3476 #endif
3477     }
3478
3479
3480     if (crawl_state.game_is_arena())
3481     {
3482         run_map_preludes();
3483         initialise_item_descriptions();
3484 #ifdef USE_TILE
3485         tiles.initialise_items();
3486 #endif
3487
3488         run_arena();
3489         end(0, false);
3490     }
3491
3492     // Sets up a new game.
3493     const bool newc = new_game();
3494     if (!newc)
3495         restore_game();
3496
3497     // Fix the mutation definitions for the species we're playing.
3498     fixup_mutations();
3499
3500     // Load macros
3501     macro_init();
3502
3503     crawl_state.need_save = true;
3504
3505     calc_hp();
3506     calc_mp();
3507
3508     run_map_preludes();
3509
3510     if (newc && you.char_direction == GDT_GAME_START)
3511     {
3512         // Chaos Knights of Lugonu start out in the Abyss.
3513         you.level_type  = LEVEL_ABYSS;
3514         you.entry_cause = EC_UNKNOWN;
3515     }
3516
3517     load(you.entering_level ? you.transit_stair : DNGN_STONE_STAIRS_DOWN_I,
3518          you.entering_level ? LOAD_ENTER_LEVEL :
3519          newc               ? LOAD_START_GAME : LOAD_RESTART_GAME,
3520          NUM_LEVEL_AREA_TYPES, -1, you.where_are_you);
3521
3522     // Make sure monsters have a valid LOS before the first turn starts.
3523     // This prevents mesmerization from being broken when a game is
3524     // restored.
3525     for (monster_iterator mi; mi; ++mi)
3526         mi->update_los();
3527
3528     if (newc && you.char_direction == GDT_GAME_START)
3529     {
3530         // Randomise colours properly for the Abyss.
3531         init_pandemonium();
3532     }
3533
3534 #ifdef DEBUG_DIAGNOSTICS
3535     // Debug compiles display a lot of "hidden" information, so we auto-wiz.
3536     you.wizard = true;
3537 #endif
3538
3539     init_properties();
3540     burden_change();
3541     make_hungry(0, true);
3542
3543     you.redraw_strength     = true;
3544     you.redraw_intelligence = true;
3545     you.redraw_dexterity    = true;
3546     you.redraw_armour_class = true;
3547     you.redraw_evasion      = true;
3548     you.redraw_experience   = true;
3549     you.redraw_quiver       = true;
3550     you.wield_change        = true;
3551
3552     // Start timer on session.
3553     you.start_time = time(NULL);
3554
3555 #ifdef CLUA_BINDINGS
3556     clua.runhook("chk_startgame", "b", newc);
3557     std::string yname = you.your_name; // XXX: what's this for?
3558     read_init_file(true);
3559     Options.fixup_options();
3560     you.your_name = yname;
3561
3562     // In case Lua changed the character set.
3563     init_char_table(Options.char_set);
3564     init_show_table();
3565     init_monster_symbols();
3566 #endif
3567
3568 #ifdef USE_TILE
3569     // Override inventory weights options for tiled menus.
3570     if (Options.tile_menu_icons && Options.show_inventory_weights)
3571         Options.show_inventory_weights = false;
3572
3573     init_player_doll();
3574
3575     tiles.resize();
3576 #endif
3577
3578     draw_border();
3579     new_level();
3580     update_turn_count();
3581
3582     // Set vision radius to player's current vision.
3583     set_los_radius(you.current_vision);
3584     init_exclusion_los();
3585
3586     trackers_init_new_level(false);
3587
3588     if (newc) // start a new game
3589     {
3590         you.friendly_pickup = Options.default_friendly_pickup;
3591
3592         // Mark items in inventory as of unknown origin.
3593         origin_set_inventory(origin_set_unknown);
3594
3595         // For a new game, wipe out monsters in LOS, and
3596         // for new tutorial games also the items.
3597         zap_los_monsters(Tutorial.tutorial_events[TUT_SEEN_FIRST_OBJECT]);
3598
3599         // For a newly started tutorial, turn secret doors into normal ones.
3600         if (Tutorial.tutorial_left)
3601             tutorial_zap_secret_doors();
3602     }
3603
3604 #ifdef USE_TILE
3605     tiles.initialise_items();
3606     // Must re-run as the feature table wasn't initialised yet.
3607     TileNewLevel(newc);
3608 #endif
3609
3610     // This just puts the view up for the first turn.
3611     viewwindow(false);
3612
3613     activate_notes(true);
3614
3615     add_key_recorder(&repeat_again_rec);
3616
3617     // XXX: And run Lua map postludes for D:1. Kinda hacky, it shouldn't really
3618     // be here.
3619     run_map_epilogues();
3620
3621     return (newc);
3622 }
3623
3624 // An attempt to tone down berserk a little bit. -- bwross
3625 //
3626 // This function does the accounting for not attacking while berserk
3627 // This gives a triangular number function for the additional penalty
3628 // Turn:    1  2  3   4   5   6   7   8
3629 // Penalty: 1  3  6  10  15  21  28  36
3630 //
3631 // Total penalty (including the standard one during upkeep is:
3632 //          2  5  9  14  20  27  35  44
3633 //
3634 static void _do_berserk_no_combat_penalty(void)
3635 {
3636     // Butchering/eating a corpse will maintain a blood rage.
3637     const int delay = current_delay_action();
3638     if (delay == DELAY_BUTCHER || delay == DELAY_EAT)
3639         return;
3640
3641     if (you.berserk_penalty == NO_BERSERK_PENALTY)
3642         return;
3643
3644     if (you.berserk())
3645     {
3646         you.berserk_penalty++;
3647
3648         switch (you.berserk_penalty)
3649         {
3650         case 2:
3651             mpr("You feel a strong urge to attack something.", MSGCH_DURATION);
3652             break;
3653         case 4:
3654             mpr("You feel your anger subside.", MSGCH_DURATION);
3655             break;
3656         case 6:
3657             mpr("Your blood rage is quickly leaving you.", MSGCH_DURATION);
3658             break;
3659         }
3660
3661         // I do these three separately, because the might and
3662         // haste counters can be different.
3663         int berserk_delay_penalty = you.berserk_penalty * BASELINE_DELAY;
3664         you.duration[DUR_BERSERKER] -= berserk_delay_penalty;
3665         if (you.duration[DUR_BERSERKER] < 1)
3666             you.duration[DUR_BERSERKER] = 1;
3667
3668         you.duration[DUR_MIGHT] -= berserk_delay_penalty;
3669         if (you.duration[DUR_MIGHT] < 1)
3670             you.duration[DUR_MIGHT] = 1;
3671
3672         you.duration[DUR_HASTE] -= berserk_delay_penalty;
3673         if (you.duration[DUR_HASTE] < 1)
3674             you.duration[DUR_HASTE] = 1;
3675     }
3676     return;
3677 }                               // end do_berserk_no_combat_penalty()
3678
3679
3680 // Called when the player moves by walking/running. Also calls attack
3681 // function etc when necessary.
3682 static void _move_player(int move_x, int move_y)
3683 {
3684     _move_player(coord_def(move_x, move_y));
3685 }
3686
3687 static void _move_player(coord_def move)
3688 {
3689     ASSERT(!crawl_state.game_is_arena() && !crawl_state.arena_suspended);
3690
3691     bool attacking = false;
3692     bool moving = true;         // used to prevent eventual movement (swap)
3693     bool swap = false;
3694
3695     if (you.attribute[ATTR_HELD])
3696     {
3697         free_self_from_net();
3698         you.turn_is_over = true;
3699         return;