summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/abyss.cc57
-rw-r--r--crawl-ref/source/items.cc22
-rw-r--r--crawl-ref/source/items.h7
3 files changed, 76 insertions, 10 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index 35001d76e2..4ab9cc92ca 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -73,7 +73,8 @@ void generate_abyss(void)
int temp_rand; // probability determination {dlb}
#if DEBUG_ABYSS
- mpr("generate_abyss().", MSGCH_DIAGNOSTICS);
+ mprf(MSGCH_DIAGNOSTICS,
+ "generate_abyss(); turn_on_level: %d", env.turns_on_level);
#endif
for (i = 5; i < (GXM - 5); i++)
@@ -96,12 +97,51 @@ void generate_abyss(void)
}
}
+// Returns the roll to use to check if we want to create an abyssal rune.
+static int _abyssal_rune_roll()
+{
+ if (you.attribute[ATTR_ABYSSAL_RUNES])
+ return (-1);
+
+ // The longer the player's hung around in the Abyss, the more
+ // likely the rune. Never generate a new rune if the player
+ // already found one, but make the Abyssal rune eligible for
+ // generation again if the player loses it.
+
+ // If the player leaves the Abyss turns_on_level resets to 0. So
+ // hang in there if you want your Abyssal rune fix quick. :P
+
+ // Worshippers of Lugonu with decent piety will attract the rune
+ // to themselves.
+
+ const bool lugonu_favoured =
+ (you.religion == GOD_LUGONU && !player_under_penance()
+ && you.piety > 120);
+
+ const int cutoff = lugonu_favoured ? 50 : 500;
+ const int scale = lugonu_favoured ? 10 : 40;
+
+ const int odds =
+ std::max(200 - std::max((env.turns_on_level - cutoff) / scale, 0), 6);
+#ifdef DEBUG_ABYSS
+ mprf(MSGCH_DIAGNOSTICS, "Abyssal rune odds: 1 in %d", odds);
+#endif
+ return (odds);
+}
+
static void generate_area(int gx1, int gy1, int gx2, int gy2)
{
+ // Any rune on the floor prevents the abyssal rune from being generated.
+ bool placed_abyssal_rune =
+ find_floor_item(OBJ_MISCELLANY, MISC_RUNE_OF_ZOT);
+
#if DEBUG_ABYSS
- mpr("generate_area().", MSGCH_DIAGNOSTICS);
+ mprf(MSGCH_DIAGNOSTICS,
+ "generate_area(). turns_on_level: %d, rune_on_floor: %s",
+ env.turns_on_level, placed_abyssal_rune? "yes" : "no");
#endif
+ const int abyssal_rune_roll = _abyssal_rune_roll();
int items_placed = 0;
const int thickness = random2(70) + 30;
int thing_created;
@@ -166,10 +206,12 @@ static void generate_area(int gx1, int gy1, int gx2, int gy2)
if (items_placed < 150 && one_chance_in(200))
{
- if (one_chance_in(200))
+ if (!placed_abyssal_rune && abyssal_rune_roll != -1
+ && one_chance_in(abyssal_rune_roll))
{
thing_created = items(1, OBJ_MISCELLANY,
MISC_RUNE_OF_ZOT, true, 51, 51);
+ placed_abyssal_rune = true;
#if DEBUG_ABYSS
mpr("Placing an Abyssal rune.", MSGCH_DIAGNOSTICS);
#endif
@@ -269,7 +311,8 @@ static int abyss_rune_nearness()
if (!in_bounds(x, y))
continue;
- // HACK: Why doesn't is_terrain_known() work here?
+ // is_terrain_known() doesn't work on unmappable levels because
+ // mapping flags are not set on such levels.
if (get_screen_glyph(x, y) != ' ')
{
int i = igrd[x][y];
@@ -427,7 +470,8 @@ void area_shift(void)
you.moveto(45, 35);
- generate_area(5, 5, (GXM - 5), (GYM - 5));
+ generate_area(MAPGEN_BORDER, MAPGEN_BORDER,
+ GXM - MAPGEN_BORDER, GYM - MAPGEN_BORDER);
xom_check_nearness();
@@ -529,7 +573,8 @@ void abyss_teleport( bool new_area )
you.moveto(45, 35);
- generate_area( 10, 10, (GXM - 10), (GYM - 10) );
+ generate_area(MAPGEN_BORDER, MAPGEN_BORDER,
+ GXM - MAPGEN_BORDER, GYM - MAPGEN_BORDER);
xom_check_nearness();
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index f97806f52e..40f43c7358 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -748,7 +748,6 @@ static int item_name_specialness(const item_def& item)
void item_check(bool verbose)
{
-
describe_floor();
origin_set(you.x_pos, you.y_pos);
@@ -2344,6 +2343,27 @@ int inv_count(void)
return count;
}
+item_def *find_floor_item(object_class_type cls, int sub_type)
+{
+ int item = NON_ITEM;
+ for (int y = 0; y < GYM; ++y)
+ for (int x = 0; x < GXM; ++x)
+ {
+ item = igrd[x][y];
+ while (item != NON_ITEM)
+ {
+ item_def &i(mitm[item]);
+
+ if (is_valid_item(i) && i.base_type == cls
+ && i.sub_type == sub_type)
+ return (&i);
+
+ item = i.link;
+ }
+ }
+ return (NULL);
+}
+
static bool find_subtype_by_name(item_def &item,
object_class_type base_type, int ntypes,
const std::string &name)
diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h
index 27d0e972da..b9a9311e73 100644
--- a/crawl-ref/source/items.h
+++ b/crawl-ref/source/items.h
@@ -21,9 +21,9 @@
enum acquirement_agent_type
{
AQ_SCROLL = 0,
-
+
// Empty space for the gods
-
+
AQ_CARD_GENIE = 100,
AQ_WIZMODE = 200
@@ -46,6 +46,7 @@ bool items_stack( const item_def &item1, const item_def &item2,
bool force = false );
item_def find_item_type(object_class_type base_type, std::string name);
+item_def *find_floor_item(object_class_type cls, int sub_type);
void init_item( int item );
@@ -93,7 +94,7 @@ void pickup(void);
/* ***********************************************************************
* called from: beam - items - transfor
* *********************************************************************** */
-bool copy_item_to_grid( const item_def &item, int x_plos, int y_plos,
+bool copy_item_to_grid( const item_def &item, int x_plos, int y_plos,
int quant_drop = -1, // item.quantity by default
bool mark_dropped = false);