summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/overmap.cc
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-26 14:54:48 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-26 14:54:48 +0000
commitd131ce057a429833e086b60cebeda46e062d07a1 (patch)
tree44e28d6b6eaa360a454c6ef5cadd9ffcaaa1af88 /crawl-ref/source/overmap.cc
parentf278a501a1598647a72dae0a086d8c7221e34727 (diff)
downloadcrawl-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
Diffstat (limited to 'crawl-ref/source/overmap.cc')
-rw-r--r--crawl-ref/source/overmap.cc616
1 files changed, 231 insertions, 385 deletions
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()