diff options
Diffstat (limited to 'crawl-ref')
-rw-r--r-- | crawl-ref/source/abyss.cc | 57 | ||||
-rw-r--r-- | crawl-ref/source/items.cc | 22 | ||||
-rw-r--r-- | crawl-ref/source/items.h | 7 |
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); |