summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dungeon.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/dungeon.cc')
-rw-r--r--crawl-ref/source/dungeon.cc110
1 files changed, 93 insertions, 17 deletions
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 61b09b2717..5cae7491fe 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -13,6 +13,7 @@
#include <set>
#include <sstream>
#include <algorithm>
+#include <cmath>
#include "abyss.h"
#include "artefact.h"
@@ -233,6 +234,8 @@ typedef std::list<coord_def> coord_list;
static void _dgn_set_floor_colours();
static bool _fixup_interlevel_connectivity();
+void dgn_postprocess_level();
+
//////////////////////////////////////////////////////////////////////////
// Static data
@@ -374,6 +377,8 @@ bool builder(int level_number, int level_type)
vault_names.push_back(you.level_type_name);
}
+ dgn_postprocess_level();
+
dgn_Layout_Type.clear();
Level_Unique_Maps.clear();
Level_Unique_Tags.clear();
@@ -398,6 +403,13 @@ bool builder(int level_number, int level_type)
return (false);
}
+// Should be called after a level is constructed to perform any final
+// fixups.
+void dgn_postprocess_level()
+{
+ shoals_postprocess_level();
+}
+
void level_welcome_messages()
{
for (int i = 0, size = Level_Vaults.size(); i < size; ++i)
@@ -823,7 +835,17 @@ void dgn_register_place(const vault_placement &place, bool register_vault)
dgn_register_vault(place.map);
if (!place.map.has_tag("layout"))
- _mask_vault(place, MMT_VAULT | MMT_NO_DOOR);
+ {
+ if (place.map.orient == MAP_ENCOMPASS)
+ {
+ for (rectangle_iterator ri(0); ri; ++ri)
+ dgn_Map_Mask(*ri) |= MMT_VAULT | MMT_NO_DOOR;
+ }
+ else
+ {
+ _mask_vault(place, MMT_VAULT | MMT_NO_DOOR);
+ }
+ }
if (place.map.has_tag("no_monster_gen"))
_mask_vault(place, MMT_NO_MONS);
@@ -876,8 +898,8 @@ void dgn_register_place(const vault_placement &place, bool register_vault)
#endif
}
-static bool _ensure_vault_placed(bool vault_success,
- bool disable_further_vaults)
+bool dgn_ensure_vault_placed(bool vault_success,
+ bool disable_further_vaults)
{
if (!vault_success)
dgn_level_vetoed = true;
@@ -888,9 +910,9 @@ static bool _ensure_vault_placed(bool vault_success,
static bool _ensure_vault_placed_ex( bool vault_success, const map_def *vault )
{
- return _ensure_vault_placed( vault_success,
- (!vault->has_tag("extra")
- && vault->orient == MAP_ENCOMPASS) );
+ return dgn_ensure_vault_placed( vault_success,
+ (!vault->has_tag("extra")
+ && vault->orient == MAP_ENCOMPASS) );
}
static coord_def _find_level_feature(int feat)
@@ -1745,7 +1767,7 @@ static void _build_overflow_temples(int level_number)
// find the overflow temple map, so don't veto the level.
return;
- if (!_ensure_vault_placed(_build_vaults(level_number, vault), false))
+ if (!dgn_ensure_vault_placed(_build_vaults(level_number, vault), false))
{
#ifdef DEBUG_TEMPLES
mprf(MSGCH_DIAGNOSTICS, "Couldn't place overlfow temple '%s', "
@@ -2224,7 +2246,7 @@ static builder_rc_type _builder_by_type(int level_number, char level_type)
pandemon_level_names[which_demon]);
}
- _ensure_vault_placed( _build_vaults(level_number, vault), true );
+ dgn_ensure_vault_placed( _build_vaults(level_number, vault), true );
}
else
{
@@ -2301,7 +2323,7 @@ static void _portal_vault_level(int level_number)
dgn_replace_area(0, 0, GXM-1, GYM-1, DNGN_ROCK_WALL,
vault->border_fill_type);
- _ensure_vault_placed( _build_vaults(level_number, vault), true );
+ dgn_ensure_vault_placed( _build_vaults(level_number, vault), true );
}
else
{
@@ -4063,8 +4085,11 @@ void _fixup_after_vault()
// clobber: If true, assumes the newly placed vault can clobber existing
// items and monsters (items may be destroyed, monsters may be
// teleported).
-bool dgn_place_map(const map_def *mdef, bool clobber, bool make_no_exits,
- const coord_def &where)
+bool dgn_place_map(const map_def *mdef,
+ bool clobber,
+ bool make_no_exits,
+ const coord_def &where,
+ int rune_subst)
{
const dgn_colour_override_manager colour_man;
@@ -4092,8 +4117,7 @@ bool dgn_place_map(const map_def *mdef, bool clobber, bool make_no_exits,
}
}
- int rune_subst = -1;
- if (mdef->has_tag_suffix("_entry"))
+ if (rune_subst == -1 && mdef->has_tag_suffix("_entry"))
rune_subst = _dgn_find_rune_subst_tags(mdef->tags);
did_map = _build_secondary_vault(you.your_level, mdef, rune_subst,
clobber, make_no_exits, where);
@@ -4122,6 +4146,7 @@ bool dgn_place_map(const map_def *mdef, bool clobber, bool make_no_exits,
}
setup_environment_effects();
+ dgn_postprocess_level();
}
return (did_map);
@@ -4523,6 +4548,11 @@ static void _dgn_give_mon_spec_items(mons_spec &mspec,
if (item_made != NON_ITEM && item_made != -1)
{
item_def &item(mitm[item_made]);
+
+ // Mark items on summoned monsters as such.
+ if (mspec.abjuration_duration != 0)
+ item.flags |= ISFLAG_SUMMONED;
+
if (!mon.pickup_item(item, 0, true))
destroy_item(item_made, true);
}
@@ -4910,6 +4940,11 @@ static void _vault_grid(vault_placement &place,
int which_depth;
int spec = 250;
+ // If rune_subst is set to 0, the rune was already placed,
+ // take appropriate steps.
+ if (place.rune_subst == 0 && vgrid == 'O')
+ place.num_runes++;
+
if (vgrid == '$')
{
which_class = OBJ_GOLD;
@@ -5975,7 +6010,7 @@ static bool _plan_1(int level_number)
ASSERT(vault);
bool success = _build_vaults(level_number, vault);
- _ensure_vault_placed(success, false);
+ dgn_ensure_vault_placed(success, false);
return false;
}
@@ -5989,7 +6024,7 @@ static bool _plan_2(int level_number)
ASSERT(vault);
bool success = _build_vaults(level_number, vault);
- _ensure_vault_placed(success, false);
+ dgn_ensure_vault_placed(success, false);
return false;
}
@@ -6003,7 +6038,7 @@ static bool _plan_3(int level_number)
ASSERT(vault);
bool success = _build_vaults(level_number, vault);
- _ensure_vault_placed(success, false);
+ dgn_ensure_vault_placed(success, false);
return true;
}
@@ -6147,7 +6182,7 @@ static bool _plan_6(int level_number)
ASSERT(vault);
bool success = _build_vaults(level_number, vault);
- _ensure_vault_placed(success, false);
+ dgn_ensure_vault_placed(success, false);
// This "back door" is often one of the easier ways to get out of
// pandemonium... the easiest is to use the banish spell.
@@ -7592,6 +7627,47 @@ static coord_def _dgn_find_closest_to_stone_stairs(coord_def base_pos)
return (np.nearest);
}
+
+double dgn_degrees_to_radians(int degrees)
+{
+ return degrees * M_PI / 180;
+}
+
+coord_def dgn_random_point_from(const coord_def &c, int radius, int margin)
+{
+ int attempts = 70;
+ while (attempts-- > 0)
+ {
+ const double angle = dgn_degrees_to_radians(random2(360));
+ const coord_def res =
+ c + coord_def(static_cast<int>(radius * cos(angle)),
+ static_cast<int>(radius * sin(angle)));
+ if (res.x >= margin && res.x < GXM - margin
+ && res.y >= margin && res.y < GYM - margin)
+ {
+ return res;
+ }
+ }
+ return coord_def();
+}
+
+coord_def dgn_random_point_visible_from(const coord_def &c,
+ int radius,
+ int margin,
+ int tries)
+{
+ while (tries-- > 0)
+ {
+ const coord_def point = dgn_random_point_from(c, radius, margin);
+ if (point.origin())
+ continue;
+ if (!cell_see_cell(c, point))
+ continue;
+ return point;
+ }
+ return coord_def();
+}
+
coord_def dgn_find_feature_marker(dungeon_feature_type feat)
{
std::vector<map_marker*> markers = env.markers.get_all();