diff options
author | haranp <haranp@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-11-26 14:54:48 +0000 |
---|---|---|
committer | haranp <haranp@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-11-26 14:54:48 +0000 |
commit | d131ce057a429833e086b60cebeda46e062d07a1 (patch) | |
tree | 44e28d6b6eaa360a454c6ef5cadd9ffcaaa1af88 | |
parent | f278a501a1598647a72dae0a086d8c7221e34727 (diff) | |
download | crawl-ref-d131ce057a429833e086b60cebeda46e062d07a1.tar.gz crawl-ref-d131ce057a429833e086b60cebeda46e062d07a1.zip |
New overview screen (the 'O' screen.)
This involves changes in quite a few things, so the major savefile version
is now 1, and old savefiles *will not load*!
Lots of conditional loading code has therefore been removed.
Minor savefile version dropped to 0 in everything.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@495 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r-- | crawl-ref/source/acr.cc | 18 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 10 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/files.cc | 30 | ||||
-rw-r--r-- | crawl-ref/source/menu.cc | 75 | ||||
-rw-r--r-- | crawl-ref/source/menu.h | 9 | ||||
-rw-r--r-- | crawl-ref/source/misc.cc | 103 | ||||
-rw-r--r-- | crawl-ref/source/misc.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/overmap.cc | 616 | ||||
-rw-r--r-- | crawl-ref/source/overmap.h | 39 | ||||
-rw-r--r-- | crawl-ref/source/tags.cc | 668 | ||||
-rw-r--r-- | crawl-ref/source/travel.cc | 29 | ||||
-rw-r--r-- | crawl-ref/source/travel.h | 14 | ||||
-rw-r--r-- | crawl-ref/source/version.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 16 |
17 files changed, 579 insertions, 1067 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index ef7bf4b03b..0bafb3b7c5 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -830,22 +830,9 @@ static void recharge_rods() of round */ bool apply_berserk_penalty = false; -/* There is now a distinction between keycodes and commands. - A keycode_type gets mapped through keycode_to_command to - become a command_type. - So a keycode_type could be something like 'H'; - a command_type would be something like COMMAND_RUN_LEFT. -*/ - /* - This function handles the player's input. It's called from main(), from - inside an endless loop. - - It's now undergone major refactoring. The code path is now: - 1. Get next player input item (key) - 2. Translate key to command - 3. Execute the command - 4. Update rest of world if necessary + This function handles the player's input. It's called from main(), from + inside an endless loop. */ static void input() { @@ -2685,7 +2672,6 @@ static bool initialise(void) #endif seed_rng(); - init_overmap(); // in overmap.cc (duh?) clear_ids(); // in itemname.cc init_feature_table(); diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 8b1caa093b..afccb53482 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -2690,6 +2690,16 @@ enum player_size_type PSIZE_PROFILE // profile only (for stealth checks) }; +enum portal_type +{ + PORTAL_NONE = 0, + PORTAL_LABYRINTH, + PORTAL_HELL, + PORTAL_ABYSS, + PORTAL_PANDEMONIUM, + NUM_PORTALS +}; + // [dshaligram] If you edit potion colours/descriptions, also update // itemname.cc. enum potion_description_colour_type diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index dced0b42aa..055dfa26ee 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -109,7 +109,7 @@ struct coord_def int x; int y; - // coord_def( int x_in = 0, int y_in = 0 ) : x(x_in), y(y_in) {}; + // coord_def( int x_in, int y_in ) : x(x_in), y(y_in) {}; bool operator == (const coord_def &other) const { return x == other.x && y == other.y; } @@ -117,6 +117,10 @@ struct coord_def bool operator != (const coord_def &other) const { return x != other.x || y != other.y; } + + bool operator < (const coord_def &other) const { + return (x < other.x) || (x == other.x && y < other.y); + } }; struct dice_def diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 25fc3a39a7..d27bfad7ce 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -1146,20 +1146,7 @@ void save_level(int level_saved, bool was_a_labyrinth, char where_were_you) // nail all items to the ground fix_item_coordinates(); - // 0.0 initial genesis of saved format - // 0.1 added attitude tag - // 0.2 replaced old 'enchantment1' and with 'flags' (bitfield) - // 0.3 changes to make the item structure more sane - // 0.4 changes to the ghost save section - // 0.5 spell and ability letter arrays - // 0.6 inventory slots of items - // 0.7 origin tracking for items - // 0.8 widened env.map to 2 bytes - // 0.9 inscriptions (hp) - // 0.10 Monster colour and spells separated from mons->number. - // 0.11 env colours moved into env.mapcol - - write_tagged_file( saveFile, SAVE_MAJOR_VERSION, 11, TAGTYPE_LEVEL ); + write_tagged_file( saveFile, SAVE_MAJOR_VERSION, 0, TAGTYPE_LEVEL ); fclose(saveFile); @@ -1225,14 +1212,7 @@ void save_game(bool leave_game) end(-1); } - // 0.0 initial genesis of saved format - // 0.1 changes to make the item structure more sane - // 0.2 spell and ability tables - // 0.3 added you.magic_contamination (05/03/05) - // 0.4 added item origins - // 0.5 added num_gifts - // 0.6 inscriptions - write_tagged_file( charf, SAVE_MAJOR_VERSION, 6, TAGTYPE_PLAYER ); + write_tagged_file( charf, SAVE_MAJOR_VERSION, 0, TAGTYPE_PLAYER ); fclose(charf); DO_CHMOD_PRIVATE(charFile.c_str()); @@ -1448,7 +1428,7 @@ static bool determine_version( FILE *restoreFile, if (majorVersion == SAVE_MAJOR_VERSION) return true; - return false; // if its not 0, no idea + return false; // if it's not 0, no idea } static void restore_version( FILE *restoreFile, @@ -1676,9 +1656,7 @@ void save_ghost( bool force ) return; } - // 0.0-0.3 old tagged savefile (values as unsigned char) - // 0.4 new tagged savefile (values as signed short) - write_tagged_file( gfile, SAVE_MAJOR_VERSION, 4, TAGTYPE_GHOST ); + write_tagged_file( gfile, SAVE_MAJOR_VERSION, 0, TAGTYPE_GHOST ); fclose(gfile); diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc index c804c5343b..204ffc5b3a 100644 --- a/crawl-ref/source/menu.cc +++ b/crawl-ref/source/menu.cc @@ -1017,9 +1017,9 @@ void formatted_string::display(int s, int e) const { int size = ops.size(); if (!size) - return ; + return; - cap(s, size); + cap(s, size); cap(e, size); for (int i = s; i <= e && i < size; ++i) @@ -1205,3 +1205,74 @@ void column_composer::compose_formatted_column( flines[f] += lines[i]; } } + +formatted_scroller::formatted_scroller(int _flags, const std::string& s) : + Menu(_flags) +{ + size_t eolpos = 0; + while ( true ) + { + const size_t newpos = s.find( EOL, eolpos ); + add_entry(new MenuEntry(std::string(s, eolpos, newpos-eolpos))); + if ( newpos == std::string::npos ) + break; + else + eolpos = newpos + strlen(EOL); + } +} + +void formatted_scroller::draw_item(int index, const MenuEntry *me) const +{ + formatted_string::parse_string(me->text).display(); +} + +int linebreak_string( std::string& s, int wrapcol, int maxcol ) +{ + size_t loc = 0; + int xpos = 0; + int breakcount = 0; + while ( loc < s.size() ) + { + if ( s[loc] == '<' ) // tag + { + // << escape + if ( loc + 1 < s.size() && s[loc+1] == '<' ) + { + ++xpos; + loc += 2; + // Um, we never break on <<. That's a feature. Right. + continue; + } + // skip tag + while ( loc < s.size() && s[loc] != '>' ) + ++loc; + ++loc; + } + else + { + // user-forced newline + if ( s[loc] == '\n' ) + xpos = 0; + // soft linebreak + else if ( s[loc] == ' ' && xpos > wrapcol ) + { + s.replace(loc, 1, EOL); + xpos = 0; + ++breakcount; + } + // hard linebreak + else if ( xpos > maxcol ) + { + s.insert(loc, EOL); + xpos = 0; + ++breakcount; + } + // bog-standard + else + ++xpos; + + ++loc; + } + } + return breakcount; +} diff --git a/crawl-ref/source/menu.h b/crawl-ref/source/menu.h index 441685e11a..d002912383 100644 --- a/crawl-ref/source/menu.h +++ b/crawl-ref/source/menu.h @@ -404,6 +404,15 @@ private: std::vector<formatted_string> flines; }; +class formatted_scroller : public Menu +{ +public: + formatted_scroller(int flags, const std::string& s); +protected: + virtual void draw_item(int index, const MenuEntry* me) const; +}; + int menu_colour(const std::string &itemtext); +int linebreak_string( std::string& s, int wrapcol, int maxcol ); #endif diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index f08840d5bf..95174bb522 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -2001,6 +2001,45 @@ unsigned short get_packed_place() you.level_type ); } +bool single_level_branch( int branch ) +{ + return + branch == BRANCH_VESTIBULE_OF_HELL || + branch == BRANCH_HALL_OF_BLADES || + branch == BRANCH_ECUMENICAL_TEMPLE; +} + +std::string branch_name( int branch, bool terse ) +{ + const char* names[][2] = { + { "The Dungeon", "D" }, + { "The Iron City of Dis", "Dis" }, + { "Gehenna", "Geh" }, + { "The Vestibule of Hell", "Hell" }, + { "Cocytus", "Coc" }, + { "Tartarus", "Tar" }, + { "Inferno", "Inf" }, + { "The Pit", "Pit" }, + { "", "" }, + { "", "" }, + { "The Orcish Mines", "Orc" }, + { "The Hive", "Hive" }, + { "The Lair", "Lair" }, + { "The Slime Pits", "Slime" }, + { "The Vaults", "Vault" }, + { "The Crypt", "Crypt" }, + { "The Hall of Blades", "Blade" }, + { "The Hall of Zot", "Zot" }, + { "The Ecumenical Temple", "Temple" }, + { "The Snake Pit", "Snake" }, + { "The Elven Halls", "Elf" }, + { "The Tomb", "Tomb" }, + { "The Swamp", "Swamp" }, + { "The Caverns", "Cav" } + }; + return names[branch][terse]; +} + std::string place_name( unsigned short place, bool long_name, bool include_number ) { @@ -2022,68 +2061,10 @@ std::string place_name( unsigned short place, bool long_name, return ( long_name ? "Buggy Badlands" : "Bug" ); } } - else - { - switch (branch) - { - case BRANCH_VESTIBULE_OF_HELL: - return ( long_name ? "The Vestibule of Hell" : "Hell" ); - case BRANCH_HALL_OF_BLADES: - return ( long_name ? "The Hall of Blades" : "Blade" ); - case BRANCH_ECUMENICAL_TEMPLE: - return ( long_name ? "The Ecumenical Temple" : "Temple" ); - case BRANCH_DIS: - result = ( long_name ? "The Iron City of Dis" : "Dis"); - break; - case BRANCH_GEHENNA: - result = ( long_name ? "Gehenna" : "Geh" ); - break; - case BRANCH_COCYTUS: - result = ( long_name ? "Cocytus" : "Coc" ); - break; - case BRANCH_TARTARUS: - result = ( long_name ? "Tartarus" : "Tar" ); - break; - case BRANCH_ORCISH_MINES: - result = ( long_name ? "The Orcish Mines" : "Orc" ); - break; - case BRANCH_HIVE: - result = ( long_name ? "The Hive" : "Hive" ); - break; - case BRANCH_LAIR: - result = ( long_name ? "The Lair" : "Lair" ); - break; - case BRANCH_SLIME_PITS: - result = ( long_name ? "The Slime Pits" : "Slime" ); - break; - case BRANCH_VAULTS: - result = ( long_name ? "The Vaults" : "Vault" ); - break; - case BRANCH_CRYPT: - result = ( long_name ? "The Crypt" : "Crypt" ); - break; - case BRANCH_HALL_OF_ZOT: - result = ( long_name ? "The Hall of Zot" : "Zot" ); - break; - case BRANCH_SNAKE_PIT: - result = ( long_name ? "The Snake Pit" : "Snake" ); - break; - case BRANCH_ELVEN_HALLS: - result = ( long_name ? "The Elven Halls" : "Elf" ); - break; - case BRANCH_TOMB: - result = ( long_name ? "The Tomb" : "Tomb" ); - break; - case BRANCH_SWAMP: - result = ( long_name ? "The Swamp" : "Swamp" ); - break; - default: - result = ( long_name ? "The Dungeon" : "D" ); - break; - } - } - if ( include_number ) { + result = branch_name(branch, !long_name); + + if ( include_number && !single_level_branch(branch) ) { char buf[200]; if ( long_name ) { // decapitalize 'the' diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index 9f6252fd70..be5195e193 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -161,6 +161,7 @@ std::string short_place_name(unsigned short place); std::string short_place_name(level_id id); std::string place_name( unsigned short place, bool long_name = false, bool include_number = true ); +std::string branch_name( int branch, bool terse ); // Prepositional form of branch level name. For example, "in the // Abyss" or "on level 3 of the Main Dungeon". diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 111718ec71..d51d133e38 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1062,13 +1062,6 @@ int exper_value( const struct monsters *monster ) return (x_val); } // end exper_value() -int obsolete_mons_spell_template_index(const monsters *mon) -{ - return (mons_class_flag(mon->type, M_SPELLCASTER)? - mon->number - : MST_NO_SPELLS); -} - void mons_load_spells( monsters *mon, int book ) { int x, y; diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 3ad17c8f11..358e07e1ed 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -331,9 +331,6 @@ unsigned char mons_char(int mc); int mons_class_colour(int mc); int mons_colour(const monsters *m); -// Only for save-compatibility. -int obsolete_mons_spell_template_index(const monsters *mon); - void mons_load_spells( monsters *mon, int book ); // last updated 12may2000 {dlb} diff --git a/crawl-ref/source/overmap.cc b/crawl-ref/source/overmap.cc index e569d90260..707d1c4eba 100644 --- a/crawl-ref/source/overmap.cc +++ b/crawl-ref/source/overmap.cc @@ -27,99 +27,94 @@ // for #definitions of MAX_BRANCHES & MAX_LEVELS #include "files.h" -// for #definitions of MAX_BRANCHES & MAX_LEVELS +#include "menu.h" #include "misc.h" #include "religion.h" +#include "shopping.h" #include "stuff.h" #include "view.h" -enum -{ - NO_FEATURE = 0x00, - FEATURE_SHOP = 0x01, - FEATURE_LABYRINTH = 0x02, - FEATURE_HELL = 0x04, - FEATURE_ABYSS = 0x08, - FEATURE_PANDEMONIUM = 0x10 -}; - -// These variables need to become part of the player struct -// and need to be stored in the .sav file: - -// 0 == no altars; -// 100 == more than one altar; or -// # == which god for remaining numbers. - -FixedArray<unsigned char, MAX_LEVELS, MAX_BRANCHES> altars_present; -FixedVector<char, MAX_BRANCHES> stair_level; -FixedArray<unsigned char, MAX_LEVELS, MAX_BRANCHES> feature; +std::map<branch_type, level_id> stair_level; +std::map<level_pos, shop_type> shops_present; +std::map<level_pos, god_type> altars_present; +std::map<level_pos, portal_type> portals_present; -int map_lines = 0; //mv: number of lines already printed on "over-map" screen +static void seen_altar( god_type god, const coord_def& pos ); +static void seen_staircase(unsigned char which_staircase,const coord_def& pos); +static void seen_other_thing(unsigned char which_thing, const coord_def& pos); -//mv: prints one line in specified colour -// void print_one_map_line( const char *line, int colour ); -// void print_branch_entrance_line( const char *area ); - -void print_one_simple_line( const char *line, int colour ); -void print_one_highlighted_line( const char *pre, const char *text, - const char *post, int colour ); - -static void print_level_name( int branch, int depth, - bool &printed_branch, bool &printed_level ); - -void seen_notable_thing( int which_thing ) +void seen_notable_thing( int which_thing, int x, int y ) { // Don't record in temporary terrain if (you.level_type != LEVEL_DUNGEON) return; + + coord_def pos = {x, y}; const god_type god = grid_altar_god(which_thing); - if (god != GOD_NO_GOD) - seen_altar( god ); + seen_altar( god, pos ); else if (grid_is_branch_stairs( which_thing )) - seen_staircase( which_thing ); + seen_staircase( which_thing, pos ); else - seen_other_thing( which_thing ); + seen_other_thing( which_thing, pos ); } -void init_overmap( void ) +static const char* portaltype_to_string(portal_type p) { - for (int i = 0; i < MAX_LEVELS; i++) + switch ( p ) { - for (int j = 0; j < MAX_BRANCHES; j++) - { - altars_present[i][j] = 0; - feature[i][j] = 0; - } + case PORTAL_LABYRINTH: + return "<cyan>Labyrinth:</cyan>"; + case PORTAL_HELL: + return "<red>Hell:</red>"; + case PORTAL_ABYSS: + return "<magenta>Abyss:</magenta>"; + case PORTAL_PANDEMONIUM: + return "<blue>Pan:</blue>"; + default: + return "<lightred>Buggy:</lightred>"; } +} - for (int i = 0; i < MAX_BRANCHES; i++) - stair_level[i] = -1; -} // end init_overmap() +static char shoptype_to_char(shop_type s) +{ + switch ( s ) + { + case SHOP_WEAPON: + case SHOP_WEAPON_ANTIQUE: + return '('; + case SHOP_ARMOUR: + case SHOP_ARMOUR_ANTIQUE: + return '['; + case SHOP_GENERAL_ANTIQUE: + case SHOP_GENERAL: + return '*'; + case SHOP_JEWELLERY: + return '='; + case SHOP_WAND: + return '/'; + case SHOP_BOOK: + return ':'; + case SHOP_FOOD: + return '%'; + case SHOP_DISTILLERY: + return '!'; + case SHOP_SCROLL: + return '?'; + default: + return 'x'; + } +} void display_overmap() { -#ifdef DOS_TERM - char buffer[4800]; - - window(1, 1, 80, 25); - gettext(1, 1, 80, 25, buffer); -#endif - - //mv: must be set to 0 so "More..." message appears really at the - // bottom of the screen - //Don't forget it could be changed since the last call of display_overmap - map_lines = 0; - - clrscr(); - bool pr_lev = false; - bool output = false; + char buffer[100]; + std::string disp; + bool seen_anything = false; - print_one_simple_line(" Overview of the Dungeon", WHITE); - - // This is a more sensible order than the order of the enums -- bwr - const int list_order[] = + // better put this somewhere central + const branch_type list_order[] = { BRANCH_MAIN_DUNGEON, BRANCH_ECUMENICAL_TEMPLE, @@ -132,267 +127,165 @@ void display_overmap() BRANCH_HALL_OF_ZOT }; - for (unsigned int index = 0; index < sizeof(list_order) / sizeof(int); index++) - { - const int i = list_order[index]; - bool printed_branch = false; + disp += " <white>Overview of the Dungeon</white>" EOL; - for (int j = 0; j < MAX_LEVELS; j++) + // print branches + int branchcount = 0; + for (unsigned int i = 1; i < sizeof(list_order)/sizeof(branch_type); ++i) + { + const branch_type branch = list_order[i]; + if ( stair_level.find(branch) != stair_level.end() ) { - bool printed_level = false; - - if (altars_present[j][i] != 0) + if ( !branchcount ) { - print_level_name( i, j, printed_branch, printed_level ); - output = true; + disp += EOL "<white>Branches:</white>" EOL; + seen_anything = true; + } + + ++branchcount; + + snprintf(buffer, sizeof buffer, "<yellow>%-6s</yellow>: %-7s", + branch_name(branch, true).c_str(), + stair_level[branch].describe(false, true).c_str()); + disp += buffer; + if ( (branchcount % 4) == 0 ) + disp += EOL; + else + disp += " "; + } + } + if ( branchcount && (branchcount % 4) ) + disp += EOL; + + // print altars + // we loop through everything a dozen times, oh well + if ( !altars_present.empty() ) + { + disp += EOL "<white>Altars:</white>" EOL; + seen_anything = true; + } - if (altars_present[j][i] == 100) + level_id last_id; + std::map<level_pos, god_type>::const_iterator ci_altar; + for ( int cur_god = GOD_NO_GOD; cur_god < NUM_GODS; ++cur_god ) + { + last_id.depth = 10000; // fake depth to be sure we don't match + // GOD_NO_GOD becomes your god + int real_god = (cur_god == GOD_NO_GOD ? you.religion : cur_god); + if ( cur_god == you.religion ) + continue; + + for ( ci_altar = altars_present.begin(); + ci_altar != altars_present.end(); + ++ci_altar ) + { + if ( ci_altar->second == real_god ) + { + if ( last_id.depth == 10000 ) { - print_one_highlighted_line( " - some ", - "altars to the gods", ".", - WHITE ); + disp += god_name( ci_altar->second, false ); + disp += ": "; + disp += ci_altar->first.id.describe(false, true); } else { - snprintf( info, INFO_SIZE, "altar to %s", - god_name( altars_present[j][i] ) ); - - print_one_highlighted_line( " - an ", info, ".", WHITE ); + if ( last_id == ci_altar->first.id ) + disp += '*'; + else + { + disp += ", "; + disp += ci_altar->first.id.describe(false, true); + } } + last_id = ci_altar->first.id; } + } + if ( last_id.depth != 10000 ) + disp += EOL; + } - if ( (feature[j][i] & FEATURE_SHOP) ) - { - print_level_name( i, j, printed_branch, printed_level ); - - // print_one_simple_line(" - facilities for the purchase of goods.",LIGHTGREY); - - print_one_highlighted_line( " - facilities for the ", - "purchase of goods", ".", LIGHTGREEN ); - output = true; - } - - if ( (feature[j][i] & FEATURE_ABYSS) ) - { - print_level_name( i, j, printed_branch, printed_level ); - // print_one_simple_line(" - a gateway into the Abyss.", LIGHTRED); - print_one_highlighted_line( " - a gateway into ", - "the Abyss", ".", MAGENTA ); - output = true; - } - - if ( (feature[j][i] & FEATURE_PANDEMONIUM) ) - { - print_level_name( i, j, printed_branch, printed_level ); - // print_one_simple_line(" - a link to Pandemonium.", LIGHTRED); - - print_one_highlighted_line( " - a link to ", "Pandemonium", - ".", LIGHTBLUE ); - output = true; - } - - if ( (feature[j][i] & FEATURE_HELL) ) - { - print_level_name( i, j, printed_branch, printed_level ); - // print_one_simple_line(" - a mouth of Hell.", LIGHTRED); - print_one_highlighted_line( " - a mouth of ", "Hell", ".", RED ); - output = true; - } - - if ( (feature[j][i] & FEATURE_LABYRINTH) ) + // print shops + if (!shops_present.empty()) + { + disp += EOL "<white>Shops:</white>" EOL; + seen_anything = true; + } + last_id.depth = 10000; + std::map<level_pos, shop_type>::const_iterator ci_shops; + int placecount = 0; + for ( ci_shops = shops_present.begin(); + ci_shops != shops_present.end(); + ++ci_shops ) + { + if ( ci_shops->first.id != last_id ) + { + if ( placecount ) { - print_level_name( i, j, printed_branch, printed_level ); - // print_one_simple_line(" - the entrance of a Labyrinth.", LIGHTRED); - print_one_highlighted_line( " - an entrance to ", - "a Labyrinth", ".", CYAN ); - output = true; + // there are at most 5 shops per level, plus 7 chars for + // the level name, plus 4 for the spacing; that makes + // a total of 16 chars per shop or exactly 5 per line. + if ( placecount % 5 == 0 ) + disp += EOL; + else + disp += " "; } + ++placecount; + disp += "<brown>"; + disp += ci_shops->first.id.describe(false, true); + disp += "</brown>"; + disp += ": "; + last_id = ci_shops->first.id; + } + disp += shoptype_to_char(ci_shops->second); + } + disp += EOL; - - // NB: k starts at 1 because there aren't any staircases - // to the main dungeon - for (int k = 1; k < MAX_BRANCHES; k++) + // print portals + if ( !portals_present.empty() ) + { + disp += EOL "<white>Portals:</white>" EOL; + seen_anything = true; + } + for (int cur_portal = PORTAL_NONE; cur_portal < NUM_PORTALS; ++cur_portal) + { + last_id.depth = 10000; + std::map<level_pos, portal_type>::const_iterator ci_portals; + for ( ci_portals = portals_present.begin(); + ci_portals != portals_present.end(); + ++ci_portals ) + { + // one line per region should be enough, they're all of + // the form D:XX, except for labyrinth portals, of which + // you would need 11 (at least) to have a problem. + if ( ci_portals->second == cur_portal ) { - pr_lev = false; - // strcpy(info, " - a staircase leading to "); - info[0] = 0; - - if (stair_level[k] == j) - { - switch (i) - { - case BRANCH_LAIR: - switch (k) - { - case BRANCH_SLIME_PITS: - strcat(info, "the Slime Pits"); - pr_lev = true; - break; - case BRANCH_SNAKE_PIT: - strcat(info, "the Snake Pit"); - pr_lev = true; - break; - case BRANCH_SWAMP: - strcat(info, "the Swamp"); - pr_lev = true; - break; - } - break; - - case BRANCH_VAULTS: - switch (k) - { - case BRANCH_HALL_OF_BLADES: - strcat(info, "the Hall of Blades"); - pr_lev = true; - break; - case BRANCH_CRYPT: - strcat(info, "the Crypt"); - pr_lev = true; - break; - } - break; - - case BRANCH_CRYPT: - switch (k) - { - case BRANCH_TOMB: - strcat(info, "the Tomb"); - pr_lev = true; - break; - } - break; - - case BRANCH_ORCISH_MINES: - switch (k) - { - case BRANCH_ELVEN_HALLS: - strcat(info, "the Elven Halls"); - pr_lev = true; - break; - } - break; - - case BRANCH_MAIN_DUNGEON: - switch (k) - { - case BRANCH_ORCISH_MINES: - strcat(info, "the Orcish Mines"); - pr_lev = true; - break; - case BRANCH_HIVE: - strcat(info, "the Hive"); - pr_lev = true; - break; - case BRANCH_LAIR: - strcat(info, "the Lair"); - pr_lev = true; - break; - case BRANCH_VAULTS: - strcat(info, "the Vaults"); - pr_lev = true; - break; - case BRANCH_HALL_OF_ZOT: - strcat(info, "the Hall of Zot"); - pr_lev = true; - break; - case BRANCH_ECUMENICAL_TEMPLE: - strcat(info, "the Ecumenical Temple"); - pr_lev = true; - break; - } - break; - } - } + if ( last_id.depth == 10000 ) + disp += portaltype_to_string(ci_portals->second); - if (pr_lev) + if ( ci_portals->first.id == last_id ) + disp += '*'; + else { - print_level_name( i, j, printed_branch, printed_level ); - print_one_highlighted_line( " - the entrance to ", info, - ".", YELLOW ); - output = true; + disp += ' '; + disp += ci_portals->first.id.describe(false, true); } + last_id = ci_portals->first.id; } } + if ( last_id.depth != 10000 ) + disp += EOL; } - textcolor( LIGHTGREY ); - - if (!output) - cprintf( EOL "You have yet to discover anything worth noting." EOL ); - - getch(); + if (!seen_anything) + disp += "You haven't discovered anything interesting yet."; + linebreak_string(disp, get_number_of_cols() - 5, get_number_of_cols() - 1); + formatted_scroller(MF_EASY_EXIT | MF_ANYPRINTABLE | MF_NOSELECT, + disp).show(); redraw_screen(); - -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif -} // end display_overmap() - - -static void print_level_name( int branch, int depth, - bool &printed_branch, bool &printed_level ) -{ - if (!printed_branch) - { - printed_branch = true; - - print_one_simple_line( "", YELLOW ); - print_one_simple_line( - (branch == BRANCH_MAIN_DUNGEON) ? "Main Dungeon" : - (branch == BRANCH_ORCISH_MINES) ? "The Orcish Mines" : - (branch == BRANCH_HIVE) ? "The Hive" : - (branch == BRANCH_LAIR) ? "The Lair" : - (branch == BRANCH_SLIME_PITS) ? "The Slime Pits" : - (branch == BRANCH_VAULTS) ? "The Vaults" : - (branch == BRANCH_CRYPT) ? "The Crypt" : - (branch == BRANCH_HALL_OF_BLADES) ? "The Hall of Blades" : - (branch == BRANCH_HALL_OF_ZOT) ? "The Hall of Zot" : - (branch == BRANCH_ECUMENICAL_TEMPLE) ? "The Ecumenical Temple" : - (branch == BRANCH_SNAKE_PIT) ? "The Snake Pit" : - (branch == BRANCH_ELVEN_HALLS) ? "The Elven Halls" : - (branch == BRANCH_TOMB) ? "The Tomb" : - (branch == BRANCH_SWAMP) ? "The Swamp" : - - (branch == BRANCH_DIS) ? "The Iron City of Dis" : - (branch == BRANCH_GEHENNA) ? "Gehenna" : - (branch == BRANCH_VESTIBULE_OF_HELL) ? "The Vestibule of Hell" : - (branch == BRANCH_COCYTUS) ? "Cocytus" : - (branch == BRANCH_TARTARUS) ? "Tartarus" - : "Unknown Area", - - YELLOW ); - } - - if (!printed_level) - { - printed_level = true; - - if (branch == BRANCH_ECUMENICAL_TEMPLE - || branch == BRANCH_HALL_OF_BLADES - || branch == BRANCH_VESTIBULE_OF_HELL) - { - // these areas only have one level... let's save the space - return; - } - - // we need our own buffer in here (info is used): - char buff[INFO_SIZE]; - - if (branch == BRANCH_MAIN_DUNGEON) - depth += 1; - else if (branch >= BRANCH_ORCISH_MINES && branch <= BRANCH_SWAMP) - depth -= you.branch_stairs[ branch - BRANCH_ORCISH_MINES ]; - else // branch is in hell (all of which start at depth 28) - depth -= 26; - - snprintf( buff, INFO_SIZE, " Level %d:", depth ); - print_one_simple_line( buff, LIGHTRED ); - } } -void seen_staircase( unsigned char which_staircase ) +void seen_staircase( unsigned char which_staircase, const coord_def& pos ) { // which_staircase holds the grid value of the stair, must be converted // Only handles stairs, not gates or arches @@ -400,7 +293,7 @@ void seen_staircase( unsigned char which_staircase ) // - stairs returning to dungeon - predictable // - entrances to the hells - always in vestibule - unsigned char which_branch = BRANCH_MAIN_DUNGEON; + branch_type which_branch = BRANCH_MAIN_DUNGEON; switch ( which_staircase ) { @@ -461,110 +354,63 @@ void seen_staircase( unsigned char which_staircase ) ASSERT(which_branch != BRANCH_MAIN_DUNGEON); - stair_level[which_branch] = you.your_level; -} // end seen_staircase() - + stair_level[which_branch] = level_id::get_current_level_id(); +} // if player has seen an altar; record it -void seen_altar( unsigned char which_altar ) +void seen_altar( god_type god, const coord_def& pos ) { // can't record in abyss or pan. if ( you.level_type != LEVEL_DUNGEON ) return; - - // portable; no point in recording - if ( which_altar == GOD_NEMELEX_XOBEH ) + + // no point in recording Temple altars + if ( you.where_are_you == BRANCH_ECUMENICAL_TEMPLE ) return; - // already seen - if ( altars_present[you.your_level][you.where_are_you] == which_altar ) + // portable; no point in recording + if ( god == GOD_NEMELEX_XOBEH ) return; - if ( altars_present[you.your_level][you.where_are_you] == 0 ) - altars_present[you.your_level][you.where_are_you] = which_altar; - else - altars_present[you.your_level][you.where_are_you] = 100; -} // end seen_altar() - + level_pos where(level_id::get_current_level_id(), pos); + altars_present[where] = god; +} -// if player has seen any other thing; record it -void seen_other_thing( unsigned char which_thing ) +portal_type feature_to_portal( unsigned char feat ) { - if ( you.level_type != LEVEL_DUNGEON ) // can't record in abyss or pan. - return; - - switch ( which_thing ) + switch ( feat ) { - case DNGN_ENTER_SHOP: - feature[you.your_level][you.where_are_you] |= FEATURE_SHOP; - break; case DNGN_ENTER_LABYRINTH: - feature[you.your_level][you.where_are_you] |= FEATURE_LABYRINTH; - break; + return PORTAL_LABYRINTH; case DNGN_ENTER_HELL: - feature[you.your_level][you.where_are_you] |= FEATURE_HELL; - break; + return PORTAL_HELL; case DNGN_ENTER_ABYSS: - feature[you.your_level][you.where_are_you] |= FEATURE_ABYSS; - break; + return PORTAL_ABYSS; case DNGN_ENTER_PANDEMONIUM: - feature[you.your_level][you.where_are_you] |= FEATURE_PANDEMONIUM; - break; - } -} // end seen_other_thing() - - -/* mv: this function prints one line at "Over-map screen" in specified colour. - * If map_lines = maximum number of lines (it means the screen is full) it - * prints "More..." message, read key, clear screen and after that prints new - * line - */ -void print_one_simple_line( const char *line, int colour) -{ - if (map_lines == (get_number_of_lines() - 2)) - { - textcolor( LIGHTGREY ); - cprintf(EOL); - cprintf("More..."); - getch(); - clrscr(); - map_lines = 0; + return PORTAL_PANDEMONIUM; + default: + return PORTAL_NONE; } - - textcolor( colour ); - cprintf( "%s" EOL, line ); - map_lines++; } -void print_one_highlighted_line( const char *pre, const char *text, - const char *post, int colour ) +// if player has seen any other thing; record it +void seen_other_thing( unsigned char which_thing, const coord_def& pos ) { - if (map_lines == (get_number_of_lines() - 2)) - { - textcolor( LIGHTGREY ); - cprintf(EOL); - cprintf("More..."); - getch(); - clrscr(); - map_lines = 0; - } - - if (pre[0] != 0) - { - textcolor( LIGHTGREY ); - cprintf( "%s", pre ); - } + if ( you.level_type != LEVEL_DUNGEON ) // can't record in abyss or pan. + return; - textcolor( colour ); - cprintf( "%s", text ); + level_pos where(level_id::get_current_level_id(), pos); - if (post[0] != 0) + switch ( which_thing ) { - textcolor( LIGHTGREY ); - cprintf( "%s", post ); + case DNGN_ENTER_SHOP: + shops_present[where] = + static_cast<shop_type>(get_shop(pos.x, pos.y)->type); + break; + default: + const portal_type portal = feature_to_portal(which_thing); + if ( portal != PORTAL_NONE ) + portals_present[where] = portal; + break; } - - cprintf( EOL ); - - map_lines++; -} +} // end seen_other_thing() diff --git a/crawl-ref/source/overmap.h b/crawl-ref/source/overmap.h index 4ded4e4420..6c8faf17af 100644 --- a/crawl-ref/source/overmap.h +++ b/crawl-ref/source/overmap.h @@ -12,42 +12,7 @@ #ifndef OVERMAP_H #define OVERMAP_H - -void seen_notable_thing( int which_thing ); - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: view - * *********************************************************************** */ -void seen_altar(unsigned char which_altar); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: acr - * *********************************************************************** */ -void init_overmap(void); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: acr - * *********************************************************************** */ -void display_overmap(void); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: view - * *********************************************************************** */ -void seen_staircase(unsigned char which_staircase); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: view - * *********************************************************************** */ -void seen_other_thing(unsigned char which_thing); - +void seen_notable_thing( int which_thing, int x, int y ); +void display_overmap(); #endif diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 1b875ccefb..9289ebeac3 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -80,19 +80,20 @@ #include "skills2.h" #include "stuff.h" #include "tags.h" +#include "travel.h" // THE BIG IMPORTANT TAG CONSTRUCTION/PARSE BUFFER static char *tagBuffer = NULL; -// These three are defined in overmap.cc -extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > altars_present; -extern FixedVector < char, MAX_BRANCHES > stair_level; -extern FixedArray < unsigned char, MAX_LEVELS, MAX_BRANCHES > feature; +// defined in overmap.cc +extern std::map<branch_type, level_id> stair_level; +extern std::map<level_pos, shop_type> shops_present; +extern std::map<level_pos, god_type> altars_present; +extern std::map<level_pos, portal_type> portals_present; // temp file pairs used for file level cleanup FixedArray < bool, MAX_LEVELS, MAX_BRANCHES > tmp_file_pairs; - // static helpers static void tag_construct_you(struct tagHeader &th); static void tag_construct_you_items(struct tagHeader &th); @@ -194,9 +195,82 @@ long unmarshallLong(struct tagHeader &th) return data; } +template<typename T> +void marshall_as_long(struct tagHeader& th, const T& t) +{ + marshallLong( th, static_cast<long>(t) ); +} + +template<typename key, typename value> +void marshallMap(struct tagHeader &th, const std::map<key,value>& data, + void (*key_marshall)(struct tagHeader&, const key&), + void (*value_marshall)(struct tagHeader&, const value&)) +{ + marshallLong( th, data.size() ); + typename std::map<key,value>::const_iterator ci; + for ( ci = data.begin(); ci != data.end(); ++ci ) + { + key_marshall(th, ci->first); + value_marshall(th, ci->second); + } +} + +void marshall_level_id( struct tagHeader& th, const level_id& id ) +{ + marshallByte(th, id.branch ); + marshallLong(th, id.depth ); +} + +void marshall_level_pos( struct tagHeader& th, const level_pos& lpos ) +{ + marshallLong(th, lpos.pos.x); + marshallLong(th, lpos.pos.y); + marshall_level_id(th, lpos.id); +} + +template<typename key, typename value> +void unmarshallMap(struct tagHeader& th, std::map<key,value>& data, + key (*key_unmarshall) (struct tagHeader&), + value (*value_unmarshall)(struct tagHeader&) ) +{ + long i, len = unmarshallLong(th); + key k; + value v; + for ( i = 0; i < len; ++i ) + { + k = key_unmarshall(th); + v = value_unmarshall(th); + data[k] = v; + } +} + +template<typename T> +T unmarshall_long_as( struct tagHeader& th ) +{ + return static_cast<T>(unmarshallLong(th)); +} + +level_id unmarshall_level_id( struct tagHeader& th ) +{ + level_id id; + id.branch = unmarshallByte(th); + id.depth = unmarshallLong(th); + return id; +} + +level_pos unmarshall_level_pos( struct tagHeader& th ) +{ + level_pos lpos; + lpos.pos.x = unmarshallLong(th); + lpos.pos.y = unmarshallLong(th); + lpos.id = unmarshall_level_id(th); + return lpos; +} + union float_marshall_kludge { // [ds] Does ANSI C guarantee that sizeof(float) == sizeof(long)? + // [haranp] no, unfortunately float f_num; long l_num; }; @@ -740,7 +814,6 @@ static void tag_construct_you_items(struct tagHeader &th) marshallShort(th,you.inv[i].plus2); marshallShort(th, you.inv[i].orig_place); marshallShort(th, you.inv[i].orig_monnum); - /*** HP CHANGE ***/ marshallString(th, you.inv[i].inscription.c_str(), 80); } @@ -800,22 +873,21 @@ static void tag_construct_you_dungeon(struct tagHeader &th) // how many branches? marshallByte(th, MAX_BRANCHES); for (j = 0; j < 30; ++j) - { marshallByte(th,you.branch_stairs[j]); - marshallByte(th,stair_level[j]); - } - // how many levels? marshallShort(th, MAX_LEVELS); for (i = 0; i < MAX_LEVELS; ++i) - { for (j = 0; j < MAX_BRANCHES; ++j) - { - marshallByte(th,altars_present[i][j]); - marshallByte(th,feature[i][j]); - marshallBoolean(th,tmp_file_pairs[i][j]); - } - } + marshallBoolean(th, tmp_file_pairs[i][j]); + + marshallMap(th, stair_level, + marshall_as_long<branch_type>, marshall_level_id); + marshallMap(th, shops_present, + marshall_level_pos, marshall_as_long<shop_type>); + marshallMap(th, altars_present, + marshall_level_pos, marshall_as_long<god_type>); + marshallMap(th, portals_present, + marshall_level_pos, marshall_as_long<portal_type>); } static void tag_read_you(struct tagHeader &th, char minorVersion) @@ -910,33 +982,13 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) you.spell_no++; } - if (minorVersion >= 2) - { - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.spell_letter_table[i] = unmarshallByte(th); - - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.ability_letter_table[i] = unmarshallShort(th); - } - else - { - for (i = 0; i < 52; i++) - { - you.spell_letter_table[i] = -1; - you.ability_letter_table[i] = ABIL_NON_ABILITY; - } - - for (i = 0; i < 25; i++) - { - if (you.spells[i] != SPELL_NO_SPELL) - you.spell_letter_table[i] = i; - } - - if (you.religion != GOD_NO_GOD) - set_god_ability_slots(); - } + count_c = unmarshallByte(th); + for (i = 0; i < count_c; i++) + you.spell_letter_table[i] = unmarshallByte(th); + + count_c = unmarshallByte(th); + for (i = 0; i < count_c; i++) + you.ability_letter_table[i] = unmarshallShort(th); // how many skills? count_c = unmarshallByte(th); @@ -946,14 +998,9 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) you.practise_skill[j] = unmarshallByte(th); you.skill_points[j] = unmarshallLong(th); - if (minorVersion >= 2) - you.skill_order[j] = unmarshallByte(th); + you.skill_order[j] = unmarshallByte(th); } - // initialize ordering when we don't read it in: - if (minorVersion < 2) - init_skill_order(); - // set up you.total_skill_points and you.skill_cost_level calc_total_skill_points(); @@ -980,25 +1027,12 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) for (i = 0; i < count_c; i++) you.penance[i] = unmarshallByte(th); - if (minorVersion >= 2) - { - count_c = unmarshallByte(th); - for (i = 0; i < count_c; i++) - you.worshipped[i] = unmarshallByte(th); - - if (minorVersion >= 5) - for (i = 0; i < count_c; i++) - you.num_gifts[i] = unmarshallShort(th); - - } - else - { - for (i = 0; i < count_c; i++) - you.worshipped[i] = false; - - if (you.religion != GOD_NO_GOD) - you.worshipped[you.religion] = true; - } + count_c = unmarshallByte(th); + for (i = 0; i < count_c; i++) + you.worshipped[i] = unmarshallByte(th); + + for (i = 0; i < count_c; i++) + you.num_gifts[i] = unmarshallShort(th); you.gift_timeout = unmarshallByte(th); you.normal_vision = unmarshallByte(th); @@ -1008,260 +1042,17 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) // elapsed time you.elapsed_time = (double)unmarshallFloat(th); - if (minorVersion >= 1) - { - // wizard mode - you.wizard = (bool) unmarshallByte(th); + // wizard mode + you.wizard = (bool) unmarshallByte(th); - // time of character creation - unmarshallString( th, buff, 20 ); - you.birth_time = parse_date_string( buff ); - } + // time of character creation + unmarshallString( th, buff, 20 ); + you.birth_time = parse_date_string( buff ); - if (minorVersion >= 2) - { - you.real_time = unmarshallLong(th); - you.num_turns = unmarshallLong(th); - } - else - { - you.real_time = -1; - you.num_turns = -1; - } + you.real_time = unmarshallLong(th); + you.num_turns = unmarshallLong(th); - // you.magic_contamination 05/03/05 - if (minorVersion >= 3) - { - you.magic_contamination = unmarshallShort(th); - } -} - -static void tag_convert_to_4_3_item( item_def &item ) -{ - const unsigned char plus = item.plus; - const unsigned char plus2 = item.plus2; - const unsigned char ident = item.flags; - const unsigned char special = item.special; - - if (item.quantity <= 0) - return; - - // First, convert ident into flags: - item.flags = (ident == 3) ? ISFLAG_IDENT_MASK : - (ident > 0) ? ISFLAG_KNOW_CURSE - : 0; - - switch (item.base_type) - { - case OBJ_ARMOUR: - if ((ident == 1 && special % 30 >= 25) || ident == 2) - item.flags |= ISFLAG_KNOW_TYPE; - - // Convert special values - item.special %= 30; - if (item.special < 25) - { - if (item.sub_type == ARM_HELMET) - { - item.plus2 = plus2 % 30; - set_helmet_desc( item, (special / 30) << 8 ); - } - else - { - switch (special / 30) - { - case DARM_EMBROIDERED_SHINY: - set_equip_desc( item, ISFLAG_EMBROIDERED_SHINY ); - break; - case DARM_RUNED: - set_equip_desc( item, ISFLAG_RUNED ); - break; - case DARM_GLOWING: - set_equip_desc( item, ISFLAG_GLOWING ); - break; - case DARM_ELVEN: - set_equip_race( item, ISFLAG_ELVEN ); - break; - case DARM_DWARVEN: - set_equip_race( item, ISFLAG_DWARVEN ); - break; - case DARM_ORCISH: - set_equip_race( item, ISFLAG_ORCISH ); - break; - default: - break; - } - } - } - else if (item.special == 25) - { - item.flags |= ISFLAG_UNRANDART; - item.special = 0; - } - else - { - item.flags |= ISFLAG_RANDART; - - // calc old seed - item.special = item.base_type * special - + item.sub_type * (plus % 100) - + plus2 * 100; - } - break; - - case OBJ_WEAPONS: - if ((ident == 1 && (special < 180 && special % 30 >= 25)) || ident == 2) - item.flags |= ISFLAG_KNOW_TYPE; - - // Convert special values - if (special < 181) // don't mangle fixed artefacts - { - item.special %= 30; - if (item.special < 25) - { - switch (special / 30) - { - case DWPN_RUNED: - set_equip_desc( item, ISFLAG_RUNED ); - break; - case DWPN_GLOWING: - set_equip_desc( item, ISFLAG_GLOWING ); - break; - case DWPN_ORCISH: - set_equip_race( item, ISFLAG_ORCISH ); - break; - case DWPN_ELVEN: - set_equip_race( item, ISFLAG_ELVEN ); - break; - case DWPN_DWARVEN: - set_equip_race( item, ISFLAG_DWARVEN ); - break; - default: - break; - } - } - else if (item.special == 25) - { - item.flags |= ISFLAG_UNRANDART; - item.special = 0; - } - else - { - item.flags |= ISFLAG_RANDART; - - // calc old seed - item.special = item.base_type * special - + item.sub_type * (plus % 100) - + plus2 * 100; - } - } - break; - - case OBJ_MISSILES: - // Needles were moved into the bonus eggplant spot. -- bwr - if (item.sub_type == 6) - item.sub_type = MI_NEEDLE; - - if (ident == 2) - item.flags |= ISFLAG_KNOW_TYPE; - - // Convert special values - item.special %= 30; - switch (special / 30) - { - case DAMMO_ORCISH: - set_equip_race( item, ISFLAG_ORCISH ); - break; - case DAMMO_ELVEN: - set_equip_race( item, ISFLAG_ELVEN ); - break; - case DAMMO_DWARVEN: - set_equip_race( item, ISFLAG_DWARVEN ); - break; - default: - break; - } - break; - - case OBJ_WANDS: - if (ident == 2) - item.flags |= ISFLAG_KNOW_PLUSES; - break; - - case OBJ_JEWELLERY: - if (ident == 1 && (special == 200 || special == 201)) - item.flags |= ISFLAG_KNOW_TYPE; - else if (ident == 2) - item.flags |= (ISFLAG_KNOW_TYPE | ISFLAG_KNOW_PLUSES); - - if (special == 201) - { - item.flags |= ISFLAG_UNRANDART; - item.special = 0; - } - else if (special == 200) - { - item.flags |= ISFLAG_RANDART; - - // calc old seed - item.special = item.base_type * special - + item.sub_type * (plus % 100) - + plus2 * 100; - } - break; - - default: - if (ident > 0) - item.flags |= ISFLAG_KNOW_TYPE; - break; - } - - - // Second, convert plus and plus2 - if (item.base_type == OBJ_WEAPONS - || item.base_type == OBJ_MISSILES - || item.base_type == OBJ_ARMOUR - || item.base_type == OBJ_JEWELLERY) - { - item.plus = plus; - - // item is cursed: - if (plus > 100) - { - item.plus -= 100; - item.flags |= ISFLAG_CURSED; - } - - // Weapons use both as pluses. - // Non-artefact jewellery uses both as pluses. - // Artefact jewellery has literal values for both pluses. - // Armour and Missiles only use plus for their plus value. - // Armour has literal usage of plus2 for sub-subtypes. - if (item.base_type != OBJ_JEWELLERY) - { - item.plus -= 50; - - if (item.base_type == OBJ_WEAPONS) - item.plus2 -= 50; - } - else if (special != 200) - { - // regular jewellery & unrandarts -- unused pluses were 0s - if (item.plus) - item.plus -= 50; - - if (item.plus2) - item.plus2 -= 50; - } - else if (special == 200) - { - // Randart jewellery used pluses only as seeds, right now - // they're always zero (since random artefact rings avoid - // base types with pluses). - item.plus = 0; - item.plus2 = 0; - } - } + you.magic_contamination = unmarshallShort(th); } static void tag_read_you_items(struct tagHeader &th, char minorVersion) @@ -1276,44 +1067,21 @@ static void tag_read_you_items(struct tagHeader &th, char minorVersion) { you.inv[i].orig_monnum = you.inv[i].orig_place = 0; you.inv[i].inscription.clear(); - if (minorVersion < 1) - { - you.inv[i].base_type = (unsigned char) unmarshallByte(th); - you.inv[i].sub_type = (unsigned char) unmarshallByte(th); - you.inv[i].plus = (unsigned char) unmarshallByte(th); - you.inv[i].special = (unsigned char) unmarshallByte(th); - you.inv[i].colour = (unsigned char) unmarshallByte(th); - you.inv[i].flags = (unsigned char) unmarshallByte(th); - you.inv[i].quantity = unmarshallShort(th); - you.inv[i].plus2 = (unsigned char) unmarshallByte(th); - - tag_convert_to_4_3_item( you.inv[i] ); - } - else - { - you.inv[i].base_type = (unsigned char) unmarshallByte(th); - you.inv[i].sub_type = (unsigned char) unmarshallByte(th); - you.inv[i].plus = unmarshallShort(th); - you.inv[i].special = unmarshallLong(th); - you.inv[i].colour = (unsigned char) unmarshallByte(th); - you.inv[i].flags = (unsigned long) unmarshallLong(th); - you.inv[i].quantity = unmarshallShort(th); - you.inv[i].plus2 = unmarshallShort(th); - - if (minorVersion >= 4) - { - you.inv[i].orig_place = unmarshallShort(th); - you.inv[i].orig_monnum = unmarshallShort(th); - - if (minorVersion >= 6) - { - /*** HP CHANGE ***/ - char insstring[80]; - unmarshallString(th, insstring, 80); - you.inv[i].inscription = std::string(insstring); - } - } - } + you.inv[i].base_type = (unsigned char) unmarshallByte(th); + you.inv[i].sub_type = (unsigned char) unmarshallByte(th); + you.inv[i].plus = unmarshallShort(th); + you.inv[i].special = unmarshallLong(th); + you.inv[i].colour = (unsigned char) unmarshallByte(th); + you.inv[i].flags = (unsigned long) unmarshallLong(th); + you.inv[i].quantity = unmarshallShort(th); + you.inv[i].plus2 = unmarshallShort(th); + + you.inv[i].orig_place = unmarshallShort(th); + you.inv[i].orig_monnum = unmarshallShort(th); + + char insstring[80]; + unmarshallString(th, insstring, 80); + you.inv[i].inscription = std::string(insstring); // these never need to be saved for items in the inventory -- bwr you.inv[i].x = -1; @@ -1328,10 +1096,8 @@ static void tag_read_you_items(struct tagHeader &th, char minorVersion) // how many subtypes? count_c2 = unmarshallByte(th); for (i = 0; i < count_c; ++i) - { for (j = 0; j < count_c2; ++j) you.item_description[i][j] = unmarshallByte(th); - } // identification status // how many types? @@ -1398,22 +1164,21 @@ static void tag_read_you_dungeon(struct tagHeader &th) // how many branches? count_c = unmarshallByte(th); for (j = 0; j < count_c; ++j) - { you.branch_stairs[j] = unmarshallByte(th); - stair_level[j] = unmarshallByte(th); - } - // how many levels? count_s = unmarshallShort(th); for (i = 0; i < count_s; ++i) - { for (j = 0; j < count_c; ++j) - { - altars_present[i][j] = unmarshallByte(th); - feature[i][j] = unmarshallByte(th); tmp_file_pairs[i][j] = unmarshallBoolean(th); - } - } + + unmarshallMap(th, stair_level, + unmarshall_long_as<branch_type>, unmarshall_level_id); + unmarshallMap(th, shops_present, + unmarshall_level_pos, unmarshall_long_as<shop_type>); + unmarshallMap(th, altars_present, + unmarshall_level_pos, unmarshall_long_as<god_type>); + unmarshallMap(th, portals_present, + unmarshall_level_pos, unmarshall_long_as<portal_type>); } // ------------------------------- level tags ---------------------------- // @@ -1505,7 +1270,6 @@ static void tag_construct_level_items(struct tagHeader &th) marshallShort(th, mitm[i].orig_place); marshallShort(th, mitm[i].orig_monnum); - /*** HP CHANGE ***/ marshallString(th, mitm[i].inscription.c_str(), 80); } } @@ -1592,31 +1356,16 @@ static void tag_read_level( struct tagHeader &th, char minorVersion ) { grd[i][j] = unmarshallByte(th); - if (minorVersion < 8) - env.map[i][j] = (unsigned char) unmarshallByte(th); - else - env.map[i][j] = (unsigned short) unmarshallShort(th); + env.map[i][j] = (unsigned short) unmarshallShort(th); if ((env.map[i][j] & 0xFF) == 201) // what is this?? env.map[i][j] = (env.map[i][j] & 0xFF00U) | 239; - if (minorVersion >= 11) - { - env.map_col[i][j].colour = unmarshallShort(th); - env.map_col[i][j].flags = unmarshallShort(th); - } - else - env.map_col[i][j].clear(); + env.map_col[i][j].colour = unmarshallShort(th); + env.map_col[i][j].flags = unmarshallShort(th); mgrd[i][j] = NON_MONSTER; env.cgrid[i][j] = unmarshallByte(th); - - if (minorVersion < 3) - { - // increased number of clouds to 100 in 4.3 - if (env.cgrid[i][j] > 30) - env.cgrid[i][j] = 101; - } } } @@ -1665,75 +1414,34 @@ static void tag_read_level_items(struct tagHeader &th, char minorVersion) count = unmarshallShort(th); for (i = 0; i < count; ++i) { - if (minorVersion < 3) - { - mitm[i].base_type = (unsigned char) unmarshallByte(th); - mitm[i].sub_type = (unsigned char) unmarshallByte(th); - mitm[i].plus = (unsigned char) unmarshallByte(th); - mitm[i].plus2 = (unsigned char) unmarshallByte(th); - mitm[i].special = (unsigned char) unmarshallByte(th); - mitm[i].quantity = unmarshallLong(th); - mitm[i].colour = (unsigned char) unmarshallByte(th); - mitm[i].x = (unsigned char) unmarshallByte(th); - mitm[i].y = (unsigned char) unmarshallByte(th); - mitm[i].flags = (unsigned char) unmarshallByte(th); - - tag_convert_to_4_3_item( mitm[i] ); - } - else - { - mitm[i].base_type = (unsigned char) unmarshallByte(th); - mitm[i].sub_type = (unsigned char) unmarshallByte(th); - mitm[i].plus = unmarshallShort(th); - mitm[i].plus2 = unmarshallShort(th); - mitm[i].special = unmarshallLong(th); - mitm[i].quantity = unmarshallShort(th); - mitm[i].colour = (unsigned char) unmarshallByte(th); - mitm[i].x = unmarshallShort(th); - mitm[i].y = unmarshallShort(th); - mitm[i].flags = (unsigned long) unmarshallLong(th); - } - + mitm[i].base_type = (unsigned char) unmarshallByte(th); + mitm[i].sub_type = (unsigned char) unmarshallByte(th); + mitm[i].plus = unmarshallShort(th); + mitm[i].plus2 = unmarshallShort(th); + mitm[i].special = unmarshallLong(th); + mitm[i].quantity = unmarshallShort(th); + mitm[i].colour = (unsigned char) unmarshallByte(th); + mitm[i].x = unmarshallShort(th); + mitm[i].y = unmarshallShort(th); + mitm[i].flags = (unsigned long) unmarshallLong(th); + // [dshaligram] FIXME, remove this kludge when ARM_CAP is fully // integrated. if (mitm[i].base_type == OBJ_ARMOUR && mitm[i].sub_type == ARM_CAP) mitm[i].sub_type = ARM_HELMET; - // pre 4.2 files had monster items stacked at (2,2) -- moved to (0,0) - if (minorVersion < 2 && mitm[i].x == 2 && mitm[i].y == 2) - { - mitm[i].x = 0; - mitm[i].y = 0; - } - unmarshallShort(th); // mitm[].link -- unused unmarshallShort(th); // igrd[mitm[i].x][mitm[i].y] -- unused - if (minorVersion >= 6) - { - mitm[i].slot = unmarshallByte(th); - } - + mitm[i].slot = unmarshallByte(th); mitm[i].inscription.clear(); - if (minorVersion >= 7) - { - mitm[i].orig_place = unmarshallShort(th); - mitm[i].orig_monnum = unmarshallShort(th); - - if (minorVersion >= 9) - { - /*** HP CHANGE ***/ - char insstring[80]; - unmarshallString(th, insstring, 80); - mitm[i].inscription = std::string(insstring); - } - } - else - { - mitm[i].orig_place = 0; - mitm[i].orig_monnum = 0; - } + mitm[i].orig_place = unmarshallShort(th); + mitm[i].orig_monnum = unmarshallShort(th); + + char insstring[80]; + unmarshallString(th, insstring, 80); + mitm[i].inscription = std::string(insstring); } } @@ -1777,54 +1485,18 @@ static void tag_read_level_monsters(struct tagHeader &th, char minorVersion) for (j = 0; j < ecount; j++) menv[i].enchantment[j] = unmarshallByte(th); - if (minorVersion < 2) - { - menv[i].flags = 0; - for(j=0; j<NUM_MON_ENCHANTS; j++) - { - if (j>=ecount) - menv[i].enchantment[j] = ENCH_NONE; - else - { - if (menv[i].enchantment[j] == 71) // old ENCH_CREATED_FRIENDLY - { - menv[i].enchantment[j] = ENCH_NONE; - menv[i].flags |= MF_CREATED_FRIENDLY; - } - if (menv[i].enchantment[j] >= 65 // old ENCH_FRIEND_ABJ_I - && menv[i].enchantment[j] <= 70) // old ENCH_FRIEND_ABJ_VI - { - menv[i].enchantment[j] -= (65 - ENCH_ABJ_I); - menv[i].flags |= MF_CREATED_FRIENDLY; - } - } - } - } // end minorversion < 2 - menv[i].type = unmarshallShort(th); menv[i].hit_points = unmarshallShort(th); menv[i].max_hit_points = unmarshallShort(th); menv[i].number = unmarshallShort(th); - if (minorVersion >= 10) - menv[i].colour = unmarshallShort(th); - else - // This will be the wrong colour for many cases, we don't care. - menv[i].colour = mons_class_colour( menv[i].type ); + menv[i].colour = unmarshallShort(th); for (j = 0; j < icount; j++) menv[i].inv[j] = unmarshallShort(th); - if (minorVersion >= 10) - { - for (j = 0; j < NUM_MONSTER_SPELL_SLOTS; ++j) - menv[i].spells[j] = unmarshallShort(th); - } - else if (menv[i].type != -1) - { - const int book = obsolete_mons_spell_template_index( &menv[i] ); - mons_load_spells( &menv[i], book ); - } + for (j = 0; j < NUM_MONSTER_SPELL_SLOTS; ++j) + menv[i].spells[j] = unmarshallShort(th); // place monster if (menv[i].type != -1) @@ -1917,31 +1589,11 @@ static void tag_read_ghost(struct tagHeader &th, char minorVersion) { int i, count_c; - snprintf( info, INFO_SIZE, "minor version = %d", minorVersion ); - unmarshallString(th, ghost.name, 20); // how many ghost values? count_c = unmarshallByte(th); for (i = 0; i < count_c; i++) - { - // for version 4.4 we moved from unsigned char to shorts -- bwr - if (minorVersion < 4) - ghost.values[i] = unmarshallByte(th); - else - ghost.values[i] = unmarshallShort(th); - } - - if (minorVersion < 4) - { - // Getting rid 9of hopefulling the last) of this silliness -- bwr - if (ghost.values[ GVAL_RES_FIRE ] >= 97) - ghost.values[ GVAL_RES_FIRE ] -= 100; - - if (ghost.values[ GVAL_RES_COLD ] >= 97) - ghost.values[ GVAL_RES_COLD ] -= 100; - } + ghost.values[i] = unmarshallShort(th); } - -// ----------------------------------------------------------------------- // diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index fde93fa9c6..49f1002bbd 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -1229,21 +1229,21 @@ unsigned char find_parent_branch(unsigned char br) return 0; } -extern FixedVector<char, MAX_BRANCHES> stair_level; +extern std::map<branch_type, level_id> stair_level; void find_parent_branch(unsigned char br, int depth, unsigned char *pb, int *pd) { - int lev = stair_level[br]; - if (lev <= 0) + const branch_type bran = static_cast<branch_type>(br); + if ( stair_level.find(bran) == stair_level.end() ) { *pb = 0; *pd = 0; // Check depth before using *pb. return ; } - *pb = find_parent_branch(br); - *pd = subdungeon_depth(*pb, lev); + *pb = find_parent_branch(stair_level[bran].branch); + *pd = stair_level[bran].depth; } // Appends the passed in branch/depth to the given vector, then attempts to @@ -1490,14 +1490,7 @@ static bool is_known_branch(unsigned char branch) if (you.where_are_you == branch) return true; // If the overmap knows the stairs to this branch, we know the branch. - unsigned char par; - int pdep; - find_parent_branch(branch, 1, &par, &pdep); - if (pdep) - return true; - - // Do a brute force search in the travel cache for this branch. - return travel_cache.is_known_branch(branch); + return ( stair_level.find(static_cast<branch_type>(branch)) != stair_level.end() ); // Doing this to check for the reachability of a branch is slow enough to // be noticeable. @@ -2333,6 +2326,16 @@ level_id level_id::get_next_level_id(const coord_def &pos) return id; } +unsigned short level_id::packed_place() const +{ + return get_packed_place(branch, depth, LEVEL_DUNGEON); +} + +std::string level_id::describe( bool long_name, bool with_number ) const +{ + return place_name( this->packed_place(), long_name, with_number ); +} + void level_id::save(FILE *file) const { writeByte(file, branch); diff --git a/crawl-ref/source/travel.h b/crawl-ref/source/travel.h index e53aaa8dac..bd6e4221bc 100644 --- a/crawl-ref/source/travel.h +++ b/crawl-ref/source/travel.h @@ -116,6 +116,10 @@ struct level_id level_id(unsigned char br, int dep) : branch(br), depth(dep) { } + unsigned short packed_place() const; + + std::string describe( bool long_name, bool with_number ) const; + // Returns the level_id of the current level. static level_id get_current_level_id(); @@ -133,6 +137,11 @@ struct level_id return branch != id.branch || depth != id.depth; } + bool operator <( const level_id &id ) const + { + return (branch < id.branch) || (branch==id.branch && depth < id.depth); + } + struct less_than { bool operator () (const level_id &first, const level_id &second) const @@ -177,6 +186,11 @@ struct level_pos { return id != lp.id || pos != lp.pos; } + + bool operator < ( const level_pos &lp ) const + { + return (id < lp.id) || (id == lp.id && pos < lp.pos); + } bool is_valid() const { diff --git a/crawl-ref/source/version.h b/crawl-ref/source/version.h index ce898d6603..f523ff50d8 100644 --- a/crawl-ref/source/version.h +++ b/crawl-ref/source/version.h @@ -49,6 +49,6 @@ * *********************************************************************** */ #define BUILD_DATE __DATE__ -#define SAVE_MAJOR_VERSION 0 +#define SAVE_MAJOR_VERSION 1 #endif diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index d222a7484e..a10240decb 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -355,7 +355,8 @@ static int get_viewobj_flags(int object) return (0); } -static void get_symbol( unsigned int object, unsigned short *ch, +static void get_symbol( int x, int y, + unsigned int object, unsigned short *ch, unsigned short *colour ) { ASSERT( ch != NULL ); @@ -371,7 +372,7 @@ static void get_symbol( unsigned int object, unsigned short *ch, // Note anything we see that's notable if (Feature[object].notable) - seen_notable_thing( object ); + seen_notable_thing( object, x, y ); } else { @@ -3284,7 +3285,7 @@ static int get_screen_glyph( int x, int y ) if (object == DNGN_SECRET_DOOR) object = grid_secret_door_appearance( x, y ); - get_symbol( object, &ch, &colour ); + get_symbol( x, y, object, &ch, &colour ); return (ch); } @@ -3339,7 +3340,7 @@ std::string screenshot( bool fullscreen ) if (object == DNGN_SECRET_DOOR) object = grid_secret_door_appearance( gx, gy ); - get_symbol( object, &glych, &glycol ); + get_symbol( gx, gy, object, &glych, &glycol ); ch = glych; } @@ -3484,7 +3485,7 @@ void viewwindow(bool draw_it, bool do_updates) int object = env.show[ex][ey]; unsigned short colour = env.show_col[ex][ey]; unsigned short ch; - get_symbol( object, &ch, &colour ); + get_symbol( gx, gy, object, &ch, &colour ); set_envmap_glyph( gx, gy, ch, colour, object ); set_terrain_seen( gx, gy ); @@ -3517,7 +3518,7 @@ void viewwindow(bool draw_it, bool do_updates) if (object == DNGN_SECRET_DOOR) object = grid_secret_door_appearance( gx, gy ); - get_symbol( object, &ch, &colour ); + get_symbol( gx, gy, object, &ch, &colour ); buffy[bufcount] = ch; buffy[bufcount + 1] = colour; @@ -3553,7 +3554,8 @@ void viewwindow(bool draw_it, bool do_updates) && Show_Backup[ex][ey] && is_terrain_seen( gx, gy )) { - get_symbol( Show_Backup[ex][ey], &ch, &colour ); + get_symbol( gx, gy, + Show_Backup[ex][ey], &ch, &colour ); set_envmap_glyph( gx, gy, ch, colour, Show_Backup[ex][ey] ); } |