diff options
author | Nicholas Feinberg <pleasingfung@gmail.com> | 2014-07-28 00:03:07 -0700 |
---|---|---|
committer | Nicholas Feinberg <pleasingfung@gmail.com> | 2014-07-28 00:03:07 -0700 |
commit | 0cf3be7fc50ee2a4b594955e8c93fc3438213e7a (patch) | |
tree | 2c79555d95c3ff642f586c07c9646eb0d6206c45 /crawl-ref/source | |
parent | cb645b5eded55d35986b82356164bcc9e8542cd0 (diff) | |
download | crawl-ref-0cf3be7fc50ee2a4b594955e8c93fc3438213e7a.tar.gz crawl-ref-0cf3be7fc50ee2a4b594955e8c93fc3438213e7a.zip |
Add end.cc
Diffstat (limited to 'crawl-ref/source')
34 files changed, 459 insertions, 399 deletions
diff --git a/crawl-ref/source/MSVC/crawl.vcxproj b/crawl-ref/source/MSVC/crawl.vcxproj index 50e1ff2213..4bb41b5ae0 100644 --- a/crawl-ref/source/MSVC/crawl.vcxproj +++ b/crawl-ref/source/MSVC/crawl.vcxproj @@ -284,6 +284,7 @@ perl.exe "util/gen-cflg.pl" compflag.h "<UNKNOWN>" "<UNKNOWN>" <ClCompile Include="..\dlua.cc" />
<ClCompile Include="..\dungeon.cc" />
<ClCompile Include="..\effects.cc" />
+ <ClCompile Include="..\end.cc" />
<ClCompile Include="..\errors.cc" />
<ClCompile Include="..\evoke.cc" />
<ClCompile Include="..\exclude.cc" />
@@ -669,6 +670,7 @@ perl.exe "util/gen-cflg.pl" compflag.h "<UNKNOWN>" "<UNKNOWN>" <ClInclude Include="..\dungeon.h" />
<ClInclude Include="..\duration-data.h" />
<ClInclude Include="..\effects.h" />
+ <ClCompile Include="..\end.h" />
<ClInclude Include="..\endianness.h" />
<ClInclude Include="..\enum.h" />
<ClInclude Include="..\env.h" />
diff --git a/crawl-ref/source/MSVC/crawl.vcxproj.filters b/crawl-ref/source/MSVC/crawl.vcxproj.filters index 8068c80db7..a571299b78 100644 --- a/crawl-ref/source/MSVC/crawl.vcxproj.filters +++ b/crawl-ref/source/MSVC/crawl.vcxproj.filters @@ -53,6 +53,7 @@ <ClCompile Include="..\dlua.cc" />
<ClCompile Include="..\dungeon.cc" />
<ClCompile Include="..\effects.cc" />
+ <ClCompile Include="..\end.cc" />
<ClCompile Include="..\errors.cc" />
<ClCompile Include="..\evoke.cc" />
<ClCompile Include="..\exclude.cc" />
@@ -360,6 +361,7 @@ <ClInclude Include="..\dlua.h" />
<ClInclude Include="..\dungeon.h" />
<ClInclude Include="..\effects.h" />
+ <ClCompile Include="..\end.h" />
<ClInclude Include="..\endianness.h" />
<ClInclude Include="..\enum.h" />
<ClInclude Include="..\env.h" />
diff --git a/crawl-ref/source/Makefile.obj b/crawl-ref/source/Makefile.obj index e6851dd5fa..62254d2a42 100644 --- a/crawl-ref/source/Makefile.obj +++ b/crawl-ref/source/Makefile.obj @@ -53,6 +53,7 @@ directn.o \ dlua.o \ dungeon.o \ effects.o \ +end.o \ errors.o \ evoke.o \ exclude.o \ diff --git a/crawl-ref/source/arena.cc b/crawl-ref/source/arena.cc index 157d9859aa..2302e9adde 100644 --- a/crawl-ref/source/arena.cc +++ b/crawl-ref/source/arena.cc @@ -12,6 +12,7 @@ #include "colour.h" #include "command.h" #include "dungeon.h" +#include "end.h" #include "env.h" #include "externs.h" #include "food.h" @@ -33,7 +34,6 @@ #include "spl-miscast.h" #include "spl-util.h" #include "state.h" -#include "stuff.h" #include "teleport.h" #include "terrain.h" #ifdef USE_TILE diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index ef8c177c58..4f504dd4ad 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -6,6 +6,7 @@ #include "dlua.h" #include "l_libs.h" +#include "end.h" #include "files.h" #include "libutil.h" #include "state.h" diff --git a/crawl-ref/source/ctest.cc b/crawl-ref/source/ctest.cc index cdb8314926..07b3924200 100644 --- a/crawl-ref/source/ctest.cc +++ b/crawl-ref/source/ctest.cc @@ -21,6 +21,7 @@ #include "cluautil.h" #include "coordit.h" #include "dlua.h" +#include "end.h" #include "errors.h" #include "files.h" #include "libutil.h" @@ -30,7 +31,6 @@ #include "mon-util.h" #include "ng-init.h" #include "state.h" -#include "stuff.h" #include "zotdef.h" #include <algorithm> diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc index a1a70536ad..0cd1ad85a1 100644 --- a/crawl-ref/source/database.cc +++ b/crawl-ref/source/database.cc @@ -14,6 +14,7 @@ #include <unistd.h> #endif +#include "end.h" #include "clua.h" #include "database.h" #include "errors.h" @@ -21,7 +22,6 @@ #include "libutil.h" #include "options.h" #include "random.h" -#include "stuff.h" #include "syscalls.h" #include "threads.h" #include "unicode.h" diff --git a/crawl-ref/source/dbg-scan.cc b/crawl-ref/source/dbg-scan.cc index f417f32136..e3ab7698de 100644 --- a/crawl-ref/source/dbg-scan.cc +++ b/crawl-ref/source/dbg-scan.cc @@ -21,6 +21,7 @@ #include "dbg-util.h" #include "decks.h" #include "dungeon.h" +#include "end.h" #include "env.h" #include "godabil.h" #include "items.h" diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 7e0a8d06ee..5ee872d692 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -32,6 +32,7 @@ #include "dgn-labyrinth.h" #include "dgn-overview.h" #include "effects.h" +#include "end.h" #include "env.h" #include "enum.h" #include "map_knowledge.h" diff --git a/crawl-ref/source/end.cc b/crawl-ref/source/end.cc new file mode 100644 index 0000000000..f7d0ee6e59 --- /dev/null +++ b/crawl-ref/source/end.cc @@ -0,0 +1,404 @@ +/** + * @file + * @brief Handle cleanup during shutdown. + **/ + +#include "AppHdr.h" +#include "end.h" + +#include <errno.h> + +#include "abyss.h" +#include "chardump.h" +#include "colour.h" +#include "crash.h" +#include "database.h" +#include "describe.h" +#include "dungeon.h" +#include "env.h" +#include "hints.h" +#include "hiscores.h" +#include "invent.h" +#include "itemname.h" +#include "itemprop.h" +#include "libutil.h" +#include "los.h" +#include "macro.h" +#include "message.h" +#include "ouch.h" +#include "prompt.h" +#include "religion.h" +#include "state.h" +#include "stuff.h" +#include "view.h" +#include "xom.h" + +void cio_cleanup() +{ + if (!crawl_state.io_inited) + return; + + console_shutdown(); + crawl_state.io_inited = false; +} + +// Clear some globally defined variables. +static void _clear_globals_on_exit() +{ + clear_rays_on_exit(); + clear_zap_info_on_exit(); + clear_colours_on_exit(); + dgn_clear_vault_placements(env.level_vaults); + destroy_abyss(); +} + +#if (defined(TARGET_OS_WINDOWS) && !defined(USE_TILE_LOCAL)) \ +|| defined(DGL_PAUSE_AFTER_ERROR) +// Print error message on the screen. +// Ugly, but better than not showing anything at all. (jpeg) +static bool _print_error_screen(const char *message, ...) +{ + if (!crawl_state.io_inited || crawl_state.seen_hups) + return false; + + // Get complete error message. + string error_msg; + { + va_list arg; + va_start(arg, message); + char buffer[1024]; + vsnprintf(buffer, sizeof buffer, message, arg); + va_end(arg); + + error_msg = string(buffer); + } + if (error_msg.empty()) + return false; + + // Escape '<'. + // NOTE: This assumes that the error message doesn't contain + // any formatting! + error_msg = replace_all(error_msg, "<", "<<"); + + error_msg += "\n\n\nHit any key to exit...\n"; + + // Break message into correctly sized lines. + int width = 80; +#ifdef USE_TILE_LOCAL + width = crawl_view.msgsz.x; +#else + width = min(80, get_number_of_cols()); +#endif + linebreak_string(error_msg, width); + + // And finally output the message. + clrscr(); + formatted_string::parse_string(error_msg, false).display(); + getchm(); + return true; +} +#endif + +// Used by do_crash_dump() to tell if the crash happened during exit() hooks. +// Not a part of crawl_state, since that's a global C++ instance which is +// free'd by exit() hooks when exit() is called, and we don't want to reference +// free'd memory. +bool CrawlIsExiting = false; +bool CrawlIsCrashing = false; + +NORETURN void end(int exit_code, bool print_error, const char *format, ...) +{ + bool need_pause = true; + disable_other_crashes(); + + // Let "error" go out of scope for valgrind's sake. + { + string error = print_error? strerror(errno) : ""; + if (format) + { + va_list arg; + va_start(arg, format); + char buffer[1024]; + vsnprintf(buffer, sizeof buffer, format, arg); + va_end(arg); + + if (error.empty()) + error = string(buffer); + else + error = string(buffer) + ": " + error; + + if (!error.empty() && error[error.length() - 1] != '\n') + error += "\n"; + } + +#if (defined(TARGET_OS_WINDOWS) && !defined(USE_TILE_LOCAL)) \ +|| defined(DGL_PAUSE_AFTER_ERROR) + if (exit_code && !error.empty()) + { + if (_print_error_screen("%s", error.c_str())) + need_pause = false; + } +#endif + +#ifdef USE_TILE_WEB + tiles.shutdown(); +#endif + + cio_cleanup(); + msg::deinitialise_mpr_streams(); + _clear_globals_on_exit(); + databaseSystemShutdown(); +#ifdef DEBUG_PROPS + dump_prop_accesses(); +#endif + + if (!error.empty()) + { +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_INFO, "Crawl", "%s", error.c_str()); +#endif + fprintf(stderr, "%s", error.c_str()); + error.clear(); + } + } + +#if (defined(TARGET_OS_WINDOWS) && !defined(USE_TILE_LOCAL)) \ +|| defined(DGL_PAUSE_AFTER_ERROR) + if (need_pause && exit_code && !crawl_state.game_is_arena() + && !crawl_state.seen_hups && !crawl_state.test) + { + fprintf(stderr, "Hit Enter to continue...\n"); + getchar(); + } +#else + UNUSED(need_pause); +#endif + + CrawlIsExiting = true; + if (exit_code) + CrawlIsCrashing = true; + +#ifdef DEBUG_GLOBALS + delete real_env; real_env = 0; + delete real_crawl_state; real_crawl_state = 0; + delete real_dlua; real_dlua = 0; + delete real_clua; real_clua = 0; + delete real_you; real_you = 0; + delete real_Options; real_Options = 0; +#endif + + exit(exit_code); +} + +// Delete save files on game end. +static void _delete_files() +{ + crawl_state.need_save = false; + you.save->unlink(); + delete you.save; + you.save = 0; +} + +NORETURN void screen_end_game(string text) +{ + crawl_state.cancel_cmd_all(); + _delete_files(); + + if (!text.empty()) + { + clrscr(); + linebreak_string(text, get_number_of_cols()); + display_tagged_block(text); + + if (!crawl_state.seen_hups) + get_ch(); + } + + game_ended(); +} + +NORETURN void end_game(scorefile_entry &se) +{ + for (int i = 0; i < ENDOFPACK; i++) + if (you.inv[i].defined() && item_type_unknown(you.inv[i])) + add_inscription(you.inv[i], "unknown"); + + for (int i = 0; i < ENDOFPACK; i++) + { + if (!you.inv[i].defined()) + continue; + set_ident_flags(you.inv[i], ISFLAG_IDENT_MASK); + set_ident_type(you.inv[i], ID_KNOWN_TYPE); + } + + _delete_files(); + + // death message + if (se.get_death_type() != KILLED_BY_LEAVING + && se.get_death_type() != KILLED_BY_QUITTING + && se.get_death_type() != KILLED_BY_WINNING) + { + canned_msg(MSG_YOU_DIE); + xom_death_message((kill_method_type) se.get_death_type()); + + switch (you.religion) + { + case GOD_FEDHAS: + simple_god_message(" appreciates your contribution to the " + "ecosystem."); + break; + + case GOD_NEMELEX_XOBEH: + nemelex_death_message(); + break; + + case GOD_KIKUBAAQUDGHA: + { + const mon_holy_type holi = you.holiness(); + + if (holi == MH_NONLIVING || holi == MH_UNDEAD) + { + simple_god_message(" rasps: \"You have failed me! " + "Welcome... oblivion!\""); + } + else + { + simple_god_message(" rasps: \"You have failed me! " + "Welcome... death!\""); + } + break; + } + + case GOD_YREDELEMNUL: + if (you.is_undead) + simple_god_message(" claims you as an undead slave."); + else if (se.get_death_type() != KILLED_BY_DISINT + && se.get_death_type() != KILLED_BY_LAVA) + { + mprf(MSGCH_GOD, "Your body rises from the dead as a mindless zombie."); + } + // No message if you're not undead and your corpse is lost. + break; + + case GOD_GOZAG: + if (se.get_death_type() != KILLED_BY_DISINT + && se.get_death_type() != KILLED_BY_LAVA) + { + mprf(MSGCH_GOD, "Your body crumbles into a pile of gold."); + } + break; + + default: + break; + } + + flush_prev_message(); + viewwindow(); // don't do for leaving/winning characters + + if (crawl_state.game_is_hints()) + hints_death_screen(); + } + + string fname = morgue_name(you.your_name, se.get_death_time()); + if (!dump_char(fname, true, true, &se)) + { + mpr("Char dump unsuccessful! Sorry about that."); + if (!crawl_state.seen_hups) + more(); + clrscr(); + } +#ifdef USE_TILE_WEB + else + tiles.send_dump_info("morgue", fname); +#endif + +#if defined(DGL_WHEREIS) || defined(USE_TILE_WEB) + string reason = se.get_death_type() == KILLED_BY_QUITTING? "quit" : + se.get_death_type() == KILLED_BY_WINNING ? "won" : + se.get_death_type() == KILLED_BY_LEAVING ? "bailed out" + : "dead"; +#ifdef DGL_WHEREIS + whereis_record(reason.c_str()); +#endif +#endif + + if (!crawl_state.seen_hups) + more(); + + if (!crawl_state.disables[DIS_CONFIRMATIONS]) + get_invent(OSEL_ANY); + textcolor(LIGHTGREY); + + // Prompt for saving macros. + if (crawl_state.unsaved_macros && yesno("Save macros?", true, 'n')) + macro_save(); + + clrscr(); + cprintf("Goodbye, %s.", you.your_name.c_str()); + cprintf("\n\n "); // Space padding where # would go in list format + + string hiscore = hiscores_format_single_long(se, true); + + const int lines = count_occurrences(hiscore, "\n") + 1; + + cprintf("%s", hiscore.c_str()); + + cprintf("\nBest Crawlers - %s\n", + crawl_state.game_type_name().c_str()); + + // "- 5" gives us an extra line in case the description wraps on a line. + hiscores_print_list(get_number_of_lines() - lines - 5); + +#ifndef DGAMELAUNCH + cprintf("\nYou can find your morgue file in the '%s' directory.", + morgue_directory().c_str()); +#endif + + // just to pause, actual value returned does not matter {dlb} + if (!crawl_state.seen_hups && !crawl_state.disables[DIS_CONFIRMATIONS]) + get_ch(); + + if (se.get_death_type() == KILLED_BY_WINNING) + crawl_state.last_game_won = true; + +#ifdef USE_TILE_WEB + tiles.send_exit_reason(reason, hiscore); +#endif + + game_ended(); +} + +NORETURN void game_ended() +{ + if (!crawl_state.seen_hups) + throw game_ended_condition(); + else + end(0); +} + +NORETURN void game_ended_with_error(const string &message) +{ + if (crawl_state.seen_hups) + end(1); + +#ifdef USE_TILE_WEB + tiles.send_exit_reason("error", message); +#endif + + if (Options.restart_after_game) + { + if (crawl_state.io_inited) + { + mprf(MSGCH_ERROR, "%s", message.c_str()); + more(); + } + else + { + fprintf(stderr, "%s\nHit Enter to continue...\n", message.c_str()); + getchar(); + } + game_ended(); + } + else + end(1, false, "%s", message.c_str()); +} diff --git a/crawl-ref/source/end.h b/crawl-ref/source/end.h new file mode 100644 index 0000000000..27d1aed529 --- /dev/null +++ b/crawl-ref/source/end.h @@ -0,0 +1,22 @@ +/** + * @file + * @brief Handle shutdown. + **/ + +#ifndef END_H +#define END_H + +#include "hiscores.h" // scorefile_entry + +NORETURN void end(int exit_code, bool print_err = false, PRINTF(2, = NULL)); +NORETURN void end_game(scorefile_entry &se); +NORETURN void game_ended(); +NORETURN void game_ended_with_error(const string &message); +NORETURN void screen_end_game(string text); +void cio_cleanup(); + +class game_ended_condition : public exception +{ +}; + +#endif diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 99517a5397..89a09001a3 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -47,6 +47,7 @@ #include "directn.h" #include "dungeon.h" #include "effects.h" +#include "end.h" #include "env.h" #include "errors.h" #include "fineff.h" @@ -79,7 +80,6 @@ #include "spl-summoning.h" #include "stash.h" #include "state.h" -#include "stuff.h" #include "syscalls.h" #include "tags.h" #ifdef USE_TILE diff --git a/crawl-ref/source/hints.cc b/crawl-ref/source/hints.cc index a6d02815cb..5b5d4a5435 100644 --- a/crawl-ref/source/hints.cc +++ b/crawl-ref/source/hints.cc @@ -20,6 +20,7 @@ #include "database.h" #include "decks.h" #include "describe.h" +#include "end.h" #include "files.h" #include "food.h" #include "format.h" diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc index 6e503f95d4..93fbd2266a 100644 --- a/crawl-ref/source/hiscores.cc +++ b/crawl-ref/source/hiscores.cc @@ -26,6 +26,7 @@ #include "chardump.h" #include "files.h" #include "dungeon.h" +#include "end.h" #include "initfile.h" #include "itemname.h" #include "itemprop.h" diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index ec5b0e9a83..d74bce1b87 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -26,6 +26,7 @@ #include "dlua.h" #include "delay.h" #include "directn.h" +#include "end.h" #include "errors.h" #include "kills.h" #include "files.h" diff --git a/crawl-ref/source/l_crawl.cc b/crawl-ref/source/l_crawl.cc index 08a952b19f..c6b24e482f 100644 --- a/crawl-ref/source/l_crawl.cc +++ b/crawl-ref/source/l_crawl.cc @@ -20,6 +20,7 @@ module "crawl" #include "command.h" #include "delay.h" #include "directn.h" +#include "end.h" #include "format.h" #include "hiscores.h" #include "hints.h" diff --git a/crawl-ref/source/main.cc b/crawl-ref/source/main.cc index 33cf5489b9..4339cfb48f 100644 --- a/crawl-ref/source/main.cc +++ b/crawl-ref/source/main.cc @@ -60,6 +60,7 @@ #include "dlua.h" #include "dungeon.h" #include "effects.h" +#include "end.h" #include "env.h" #include "errors.h" #include "evoke.h" diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index 7bdd658c02..47d7416c03 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -24,6 +24,7 @@ #include "directn.h" #include "dungeon.h" #include "dgn-height.h" +#include "end.h" #include "exclude.h" #include "files.h" #include "initfile.h" @@ -44,7 +45,6 @@ #include "shopping.h" #include "spl-util.h" #include "spl-book.h" -#include "stuff.h" #include "env.h" #include "tags.h" #include "terrain.h" diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc index 892b9744a2..4d6a3ffac2 100644 --- a/crawl-ref/source/mapmark.cc +++ b/crawl-ref/source/mapmark.cc @@ -14,10 +14,10 @@ #include "coordit.h" #include "directn.h" #include "dlua.h" +#include "end.h" +#include "env.h" #include "libutil.h" #include "l_libs.h" -#include "stuff.h" -#include "env.h" #include "tags.h" #include "terrain.h" #include "unwind.h" diff --git a/crawl-ref/source/maps.cc b/crawl-ref/source/maps.cc index 07329a200b..8031268460 100644 --- a/crawl-ref/source/maps.cc +++ b/crawl-ref/source/maps.cc @@ -22,6 +22,7 @@ #include "dbg-maps.h" #include "dungeon.h" #include "endianness.h" +#include "end.h" #include "env.h" #include "enum.h" #include "files.h" @@ -34,7 +35,6 @@ #include "coord.h" #include "random.h" #include "state.h" -#include "stuff.h" #include "syscalls.h" #include "tags.h" #include "terrain.h" diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index aaf1b9ceee..00b4537eeb 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -10,6 +10,7 @@ #include "cio.h" #include "command.h" #include "database.h" +#include "end.h" #include "files.h" #include "hints.h" #include "initfile.h" diff --git a/crawl-ref/source/ng-init.cc b/crawl-ref/source/ng-init.cc index b03fb08fcc..5da7edb42e 100644 --- a/crawl-ref/source/ng-init.cc +++ b/crawl-ref/source/ng-init.cc @@ -13,6 +13,7 @@ #include "branch.h" #include "describe.h" #include "dungeon.h" +#include "end.h" #include "itemname.h" #include "libutil.h" #include "maps.h" @@ -23,7 +24,6 @@ #include "spl-util.h" #include "state.h" #include "store.h" -#include "stuff.h" #include "version.h" #ifdef DEBUG_DIAGNOSTICS diff --git a/crawl-ref/source/ng-input.cc b/crawl-ref/source/ng-input.cc index 47f953fb8f..4cf567b6a6 100644 --- a/crawl-ref/source/ng-input.cc +++ b/crawl-ref/source/ng-input.cc @@ -4,11 +4,11 @@ #include "ng-input.h" #include "cio.h" +#include "end.h" #include "files.h" #include "format.h" #include "libutil.h" #include "options.h" -#include "stuff.h" #include "unicode.h" #include "version.h" diff --git a/crawl-ref/source/ng-setup.cc b/crawl-ref/source/ng-setup.cc index dd402a856d..e80e0b4fd9 100644 --- a/crawl-ref/source/ng-setup.cc +++ b/crawl-ref/source/ng-setup.cc @@ -5,6 +5,7 @@ #include "ability.h" #include "decks.h" #include "dungeon.h" +#include "end.h" #include "files.h" #include "food.h" #include "godcompanions.h" diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 63e3a6e1a3..7a4ff0f7b8 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -32,6 +32,7 @@ #include "describe.h" #include "dgnevent.h" #include "effects.h" +#include "end.h" #include "env.h" #include "files.h" #include "fight.h" @@ -73,8 +74,6 @@ #include "shout.h" #include "xom.h" -static NORETURN void _end_game(scorefile_entry &se); - void maybe_melt_player_enchantments(beam_type flavour, int damage) { if (flavour == BEAM_FIRE || flavour == BEAM_LAVA @@ -1093,7 +1092,7 @@ void ouch(int dam, int death_source, kill_method_type death_type, if (!non_death && !crawl_state.game_is_tutorial() && !you.wizard) save_ghost(); - _end_game(se); + end_game(se); } string morgue_name(string char_name, time_t when_crawl_got_even) @@ -1107,184 +1106,6 @@ string morgue_name(string char_name, time_t when_crawl_got_even) return name; } -// Delete save files on game end. -static void _delete_files() -{ - crawl_state.need_save = false; - you.save->unlink(); - delete you.save; - you.save = 0; -} - -NORETURN void screen_end_game(string text) -{ - crawl_state.cancel_cmd_all(); - _delete_files(); - - if (!text.empty()) - { - clrscr(); - linebreak_string(text, get_number_of_cols()); - display_tagged_block(text); - - if (!crawl_state.seen_hups) - get_ch(); - } - - game_ended(); -} - -static NORETURN void _end_game(scorefile_entry &se) -{ - for (int i = 0; i < ENDOFPACK; i++) - if (you.inv[i].defined() && item_type_unknown(you.inv[i])) - add_inscription(you.inv[i], "unknown"); - - for (int i = 0; i < ENDOFPACK; i++) - { - if (!you.inv[i].defined()) - continue; - set_ident_flags(you.inv[i], ISFLAG_IDENT_MASK); - set_ident_type(you.inv[i], ID_KNOWN_TYPE); - } - - _delete_files(); - - // death message - if (se.get_death_type() != KILLED_BY_LEAVING - && se.get_death_type() != KILLED_BY_QUITTING - && se.get_death_type() != KILLED_BY_WINNING) - { - canned_msg(MSG_YOU_DIE); - xom_death_message((kill_method_type) se.get_death_type()); - - switch (you.religion) - { - case GOD_FEDHAS: - simple_god_message(" appreciates your contribution to the " - "ecosystem."); - break; - - case GOD_NEMELEX_XOBEH: - nemelex_death_message(); - break; - - case GOD_KIKUBAAQUDGHA: - { - const mon_holy_type holi = you.holiness(); - - if (holi == MH_NONLIVING || holi == MH_UNDEAD) - { - simple_god_message(" rasps: \"You have failed me! " - "Welcome... oblivion!\""); - } - else - { - simple_god_message(" rasps: \"You have failed me! " - "Welcome... death!\""); - } - break; - } - - case GOD_YREDELEMNUL: - if (you.is_undead) - simple_god_message(" claims you as an undead slave."); - else if (se.get_death_type() != KILLED_BY_DISINT - && se.get_death_type() != KILLED_BY_LAVA) - { - mprf(MSGCH_GOD, "Your body rises from the dead as a mindless zombie."); - } - // No message if you're not undead and your corpse is lost. - break; - - case GOD_GOZAG: - if (se.get_death_type() != KILLED_BY_DISINT - && se.get_death_type() != KILLED_BY_LAVA) - { - mprf(MSGCH_GOD, "Your body crumbles into a pile of gold."); - } - break; - - default: - break; - } - - flush_prev_message(); - viewwindow(); // don't do for leaving/winning characters - - if (crawl_state.game_is_hints()) - hints_death_screen(); - } - - string fname = morgue_name(you.your_name, se.get_death_time()); - if (!dump_char(fname, true, true, &se)) - { - mpr("Char dump unsuccessful! Sorry about that."); - if (!crawl_state.seen_hups) - more(); - clrscr(); - } -#ifdef USE_TILE_WEB - else - tiles.send_dump_info("morgue", fname); -#endif - -#if defined(DGL_WHEREIS) || defined(USE_TILE_WEB) - string reason = se.get_death_type() == KILLED_BY_QUITTING? "quit" : - se.get_death_type() == KILLED_BY_WINNING ? "won" : - se.get_death_type() == KILLED_BY_LEAVING ? "bailed out" - : "dead"; -#ifdef DGL_WHEREIS - whereis_record(reason.c_str()); -#endif -#endif - - if (!crawl_state.seen_hups) - more(); - - if (!crawl_state.disables[DIS_CONFIRMATIONS]) - get_invent(OSEL_ANY); - textcolor(LIGHTGREY); - - // Prompt for saving macros. - if (crawl_state.unsaved_macros && yesno("Save macros?", true, 'n')) - macro_save(); - - clrscr(); - cprintf("Goodbye, %s.", you.your_name.c_str()); - cprintf("\n\n "); // Space padding where # would go in list format - - string hiscore = hiscores_format_single_long(se, true); - - const int lines = count_occurrences(hiscore, "\n") + 1; - - cprintf("%s", hiscore.c_str()); - - cprintf("\nBest Crawlers - %s\n", - crawl_state.game_type_name().c_str()); - - // "- 5" gives us an extra line in case the description wraps on a line. - hiscores_print_list(get_number_of_lines() - lines - 5); - -#ifndef DGAMELAUNCH - cprintf("\nYou can find your morgue file in the '%s' directory.", - morgue_directory().c_str()); -#endif - - // just to pause, actual value returned does not matter {dlb} - if (!crawl_state.seen_hups && !crawl_state.disables[DIS_CONFIRMATIONS]) - get_ch(); - - if (se.get_death_type() == KILLED_BY_WINNING) - crawl_state.last_game_won = true; - -#ifdef USE_TILE_WEB - tiles.send_exit_reason(reason, hiscore); -#endif - - game_ended(); -} - int actor_to_death_source(const actor* agent) { if (agent->is_player()) diff --git a/crawl-ref/source/ouch.h b/crawl-ref/source/ouch.h index 869b2be1f8..5b0aff82e2 100644 --- a/crawl-ref/source/ouch.h +++ b/crawl-ref/source/ouch.h @@ -91,6 +91,5 @@ bool drain_player(int power = 25, bool announce_full = true, void expose_player_to_element(beam_type flavour, int strength = 0, bool slow_cold_blooded = true); -NORETURN void screen_end_game(string text); int timescale_damage(const actor *act, int damage); #endif diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index e355964792..29a1e5d561 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -21,6 +21,7 @@ #include "describe.h" #include "directn.h" #include "effects.h" +#include "end.h" #include "externs.h" #include "food.h" #include "format.h" diff --git a/crawl-ref/source/sqldbm.cc b/crawl-ref/source/sqldbm.cc index 8f589806c4..a72b968f99 100644 --- a/crawl-ref/source/sqldbm.cc +++ b/crawl-ref/source/sqldbm.cc @@ -5,8 +5,8 @@ #include "AppHdr.h" +#include "end.h" #include "sqldbm.h" -#include "stuff.h" #include "syscalls.h" #include <fcntl.h> #include <unistd.h> diff --git a/crawl-ref/source/startup.cc b/crawl-ref/source/startup.cc index 7c65d79c30..375a971ad1 100644 --- a/crawl-ref/source/startup.cc +++ b/crawl-ref/source/startup.cc @@ -18,6 +18,7 @@ #include "defines.h" #include "dlua.h" #include "dungeon.h" +#include "end.h" #include "env.h" #include "exclude.h" #include "files.h" diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 78bce2f4f8..19d1c281f8 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -93,198 +93,6 @@ void set_redraw_status(uint64_t flags) you.redraw_status_flags |= flags; } -void cio_cleanup() -{ - if (!crawl_state.io_inited) - return; - - console_shutdown(); - crawl_state.io_inited = false; -} - -// Clear some globally defined variables. -static void _clear_globals_on_exit() -{ - clear_rays_on_exit(); - clear_zap_info_on_exit(); - clear_colours_on_exit(); - dgn_clear_vault_placements(env.level_vaults); - destroy_abyss(); -} - -#if (defined(TARGET_OS_WINDOWS) && !defined(USE_TILE_LOCAL)) \ - || defined(DGL_PAUSE_AFTER_ERROR) -// Print error message on the screen. -// Ugly, but better than not showing anything at all. (jpeg) -static bool _print_error_screen(const char *message, ...) -{ - if (!crawl_state.io_inited || crawl_state.seen_hups) - return false; - - // Get complete error message. - string error_msg; - { - va_list arg; - va_start(arg, message); - char buffer[1024]; - vsnprintf(buffer, sizeof buffer, message, arg); - va_end(arg); - - error_msg = string(buffer); - } - if (error_msg.empty()) - return false; - - // Escape '<'. - // NOTE: This assumes that the error message doesn't contain - // any formatting! - error_msg = replace_all(error_msg, "<", "<<"); - - error_msg += "\n\n\nHit any key to exit...\n"; - - // Break message into correctly sized lines. - int width = 80; -#ifdef USE_TILE_LOCAL - width = crawl_view.msgsz.x; -#else - width = min(80, get_number_of_cols()); -#endif - linebreak_string(error_msg, width); - - // And finally output the message. - clrscr(); - formatted_string::parse_string(error_msg, false).display(); - getchm(); - return true; -} -#endif - -// Used by do_crash_dump() to tell if the crash happened during exit() hooks. -// Not a part of crawl_state, since that's a global C++ instance which is -// free'd by exit() hooks when exit() is called, and we don't want to reference -// free'd memory. -bool CrawlIsExiting = false; -bool CrawlIsCrashing = false; - -NORETURN void end(int exit_code, bool print_error, const char *format, ...) -{ - bool need_pause = true; - disable_other_crashes(); - - // Let "error" go out of scope for valgrind's sake. - { - string error = print_error? strerror(errno) : ""; - if (format) - { - va_list arg; - va_start(arg, format); - char buffer[1024]; - vsnprintf(buffer, sizeof buffer, format, arg); - va_end(arg); - - if (error.empty()) - error = string(buffer); - else - error = string(buffer) + ": " + error; - - if (!error.empty() && error[error.length() - 1] != '\n') - error += "\n"; - } - -#if (defined(TARGET_OS_WINDOWS) && !defined(USE_TILE_LOCAL)) \ - || defined(DGL_PAUSE_AFTER_ERROR) - if (exit_code && !error.empty()) - { - if (_print_error_screen("%s", error.c_str())) - need_pause = false; - } -#endif - -#ifdef USE_TILE_WEB - tiles.shutdown(); -#endif - - cio_cleanup(); - msg::deinitialise_mpr_streams(); - _clear_globals_on_exit(); - databaseSystemShutdown(); -#ifdef DEBUG_PROPS - dump_prop_accesses(); -#endif - - if (!error.empty()) - { -#ifdef __ANDROID__ - __android_log_print(ANDROID_LOG_INFO, "Crawl", "%s", error.c_str()); -#endif - fprintf(stderr, "%s", error.c_str()); - error.clear(); - } - } - -#if (defined(TARGET_OS_WINDOWS) && !defined(USE_TILE_LOCAL)) \ - || defined(DGL_PAUSE_AFTER_ERROR) - if (need_pause && exit_code && !crawl_state.game_is_arena() - && !crawl_state.seen_hups && !crawl_state.test) - { - fprintf(stderr, "Hit Enter to continue...\n"); - getchar(); - } -#else - UNUSED(need_pause); -#endif - - CrawlIsExiting = true; - if (exit_code) - CrawlIsCrashing = true; - -#ifdef DEBUG_GLOBALS - delete real_env; real_env = 0; - delete real_crawl_state; real_crawl_state = 0; - delete real_dlua; real_dlua = 0; - delete real_clua; real_clua = 0; - delete real_you; real_you = 0; - delete real_Options; real_Options = 0; -#endif - - exit(exit_code); -} - -NORETURN void game_ended() -{ - if (!crawl_state.seen_hups) - throw game_ended_condition(); - else - end(0); -} - -NORETURN void game_ended_with_error(const string &message) -{ - if (crawl_state.seen_hups) - end(1); - -#ifdef USE_TILE_WEB - tiles.send_exit_reason("error", message); -#endif - - if (Options.restart_after_game) - { - if (crawl_state.io_inited) - { - mprf(MSGCH_ERROR, "%s", message.c_str()); - more(); - } - else - { - fprintf(stderr, "%s\nHit Enter to continue...\n", message.c_str()); - getchar(); - } - game_ended(); - } - else - end(1, false, "%s", message.c_str()); -} - void redraw_screen() { if (!crawl_state.need_save) diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h index f30b6d8b23..b8443f89c2 100644 --- a/crawl-ref/source/stuff.h +++ b/crawl-ref/source/stuff.h @@ -34,17 +34,6 @@ int stepdown(int value, int step, rounding_type = ROUND_CLOSE, int max = 0); int stepdown_value(int base_value, int stepping, int first_step, int last_step, int ceiling_value); -// ending - -NORETURN void end(int exit_code, bool print_err = false, PRINTF(2, = NULL)); -NORETURN void game_ended(); -NORETURN void game_ended_with_error(const string &message); -void cio_cleanup(); - -class game_ended_condition : public exception -{ -}; - // letter <-> index mapping char index_to_letter(int the_index); diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 13d4e6b30c..1916e720ad 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -40,6 +40,7 @@ #include "dbg-scan.h" #include "dgn-overview.h" #include "dungeon.h" +#include "end.h" #include "enum.h" #include "errors.h" #include "map_knowledge.h" @@ -66,7 +67,6 @@ #include "skills.h" #include "skills2.h" #include "state.h" -#include "stuff.h" #include "env.h" #include "spl-wpnench.h" #include "syscalls.h" diff --git a/crawl-ref/source/util/levcomp.lpp b/crawl-ref/source/util/levcomp.lpp index a032fc0b12..b876448b64 100644 --- a/crawl-ref/source/util/levcomp.lpp +++ b/crawl-ref/source/util/levcomp.lpp @@ -9,9 +9,9 @@ #include <algorithm> #include <cstring> #include <queue> +#include "end.h" #include "mapdef.h" #include "levcomp.tab.h" -#include "stuff.h" static bool alloced = false; diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp index ba36a809da..be72e0b7e6 100644 --- a/crawl-ref/source/util/levcomp.ypp +++ b/crawl-ref/source/util/levcomp.ypp @@ -4,11 +4,11 @@ #include "AppHdr.h" #include <map> #include <algorithm> +#include "end.h" #include "l_defs.h" #include "libutil.h" #include "mapdef.h" #include "maps.h" -#include "stuff.h" #define YYERROR_VERBOSE 1 #define YYENABLE_NLS 0 |