summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/place.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/place.cc')
-rw-r--r--crawl-ref/source/place.cc172
1 files changed, 172 insertions, 0 deletions
diff --git a/crawl-ref/source/place.cc b/crawl-ref/source/place.cc
new file mode 100644
index 0000000000..b5b8587f20
--- /dev/null
+++ b/crawl-ref/source/place.cc
@@ -0,0 +1,172 @@
+/*
+ * File: place.cc
+ * Summary: Place related functions.
+ * Written by: Linley Henzell
+ *
+ * Modified for Crawl Reference by $Author: j-p-e-g $ on $Date: 2007-09-03 06:41:30 -0700 (Mon, 03 Sep 2007) $
+ *
+ * Change History (most recent first):
+ *
+ * <1> 9/11/07 MPC Split from misc.cc
+ */
+
+#include "externs.h"
+#include "place.h"
+
+#include "branch.h"
+#include "travel.h"
+
+// Do not attempt to use level_id if level_type != LEVEL_DUNGEON
+std::string short_place_name(level_id id)
+{
+ return id.describe();
+}
+
+int place_branch(unsigned short place)
+{
+ const unsigned branch = (unsigned) ((place >> 8) & 0xFF);
+ const int lev = place & 0xFF;
+ return lev == 0xFF? -1 : (int) branch;
+}
+
+int place_depth(unsigned short place)
+{
+ const int lev = place & 0xFF;
+ return lev == 0xFF? -1 : lev;
+}
+
+unsigned short get_packed_place( branch_type branch, int subdepth,
+ level_area_type level_type )
+{
+ unsigned short place = (unsigned short)
+ ( (static_cast<int>(branch) << 8) | (subdepth & 0xFF) );
+ if (level_type != LEVEL_DUNGEON)
+ place = (unsigned short) ( (static_cast<int>(level_type) << 8) | 0xFF );
+ return place;
+}
+
+unsigned short get_packed_place()
+{
+ return get_packed_place( you.where_are_you,
+ subdungeon_depth(you.where_are_you, you.your_level),
+ you.level_type );
+}
+
+bool single_level_branch( branch_type branch )
+{
+ return
+ branch >= 0 && branch < NUM_BRANCHES
+ && branches[branch].depth == 1;
+}
+
+std::string place_name( unsigned short place, bool long_name,
+ bool include_number )
+{
+
+ unsigned char branch = (unsigned char) ((place >> 8) & 0xFF);
+ int lev = place & 0xFF;
+
+ std::string result;
+ if (lev == 0xFF)
+ {
+ switch (branch)
+ {
+ case LEVEL_ABYSS:
+ return ( long_name ? "The Abyss" : "Abyss" );
+ case LEVEL_PANDEMONIUM:
+ return ( long_name ? "Pandemonium" : "Pan" );
+ case LEVEL_LABYRINTH:
+ return ( long_name ? "a Labyrinth" : "Lab" );
+ case LEVEL_PORTAL_VAULT:
+ return ( long_name ? "a Portal Chamber" : "Port" );
+ default:
+ return ( long_name ? "Buggy Badlands" : "Bug" );
+ }
+ }
+
+ result = (long_name ?
+ branches[branch].longname : branches[branch].abbrevname);
+
+ if ( include_number && branches[branch].depth != 1 )
+ {
+ char buf[200];
+ if ( long_name )
+ {
+ // decapitalize 'the'
+ if ( result.find("The") == 0 )
+ result[0] = 't';
+ snprintf( buf, sizeof buf, "Level %d of %s",
+ lev, result.c_str() );
+ }
+ else if (lev)
+ snprintf( buf, sizeof buf, "%s:%d", result.c_str(), lev );
+ else
+ snprintf( buf, sizeof buf, "%s:$", result.c_str() );
+
+ result = buf;
+ }
+ return result;
+}
+
+// Takes a packed 'place' and returns a compact stringified place name.
+// XXX: This is done in several other places; a unified function to
+// describe places would be nice.
+std::string short_place_name(unsigned short place)
+{
+ return place_name( place, false, true );
+}
+
+// Prepositional form of branch level name. For example, "in the
+// Abyss" or "on level 3 of the Main Dungeon".
+std::string prep_branch_level_name(unsigned short packed_place)
+{
+ std::string place = place_name( packed_place, true, true );
+ if (place.length() && place != "Pandemonium")
+ place[0] = tolower(place[0]);
+ return (place.find("level") == 0?
+ "on " + place
+ : "in " + place);
+}
+
+// Use current branch and depth
+std::string prep_branch_level_name()
+{
+ return prep_branch_level_name( get_packed_place() );
+}
+
+int absdungeon_depth(branch_type branch, int subdepth)
+{
+ if (branch >= BRANCH_VESTIBULE_OF_HELL && branch <= BRANCH_THE_PIT)
+ return subdepth + 27 - (branch == BRANCH_VESTIBULE_OF_HELL);
+ else
+ {
+ --subdepth;
+ while ( branch != BRANCH_MAIN_DUNGEON )
+ {
+ subdepth += branches[branch].startdepth;
+ branch = branches[branch].parent_branch;
+ }
+ }
+ return subdepth;
+}
+
+int subdungeon_depth(branch_type branch, int depth)
+{
+ return depth - absdungeon_depth(branch, 0);
+}
+
+int player_branch_depth()
+{
+ return subdungeon_depth(you.where_are_you, you.your_level);
+}
+
+// Returns true if exits from this type of level involve going upstairs.
+bool level_type_exits_up(level_area_type type)
+{
+ return (type == LEVEL_LABYRINTH || type == LEVEL_PORTAL_VAULT);
+}
+
+bool level_type_exits_down(level_area_type type)
+{
+ return (type == LEVEL_PANDEMONIUM || type == LEVEL_ABYSS);
+}