Apply the new ground_level method.
[crawl.git] / crawl-ref / source / map_knowledge.cc
blobec2fa6e4cd3781eae6e8511d204ce3e69e1c4a8d
1 #include "AppHdr.h"
3 #include "map_knowledge.h"
5 #include "coordit.h"
6 #include "dgn-overview.h"
7 #include "dgnevent.h"
8 #include "directn.h"
9 #include "env.h"
10 #include "feature.h"
11 #include "los.h"
12 #include "mon-util.h"
13 #include "notes.h"
14 #include "options.h"
15 #include "show.h"
16 #include "showsymb.h"
17 #include "stuff.h"
18 #include "terrain.h"
19 #ifdef USE_TILE
20 #include "tilepick.h"
21 #include "tileview.h"
22 #endif
23 #include "view.h"
25 void map_knowledge_forget_mons(const coord_def& c)
27 if (!env.map_knowledge(c).detected_monster())
28 return;
30 env.map_knowledge(c).clear_monster();
33 // Used to mark dug out areas, unset when terrain is seen or mapped again.
34 void set_terrain_changed(int x, int y)
36 env.map_knowledge[x][y].flags |= MAP_CHANGED_FLAG;
38 dungeon_events.fire_position_event(DET_FEAT_CHANGE, coord_def(x, y));
40 los_terrain_changed(coord_def(x,y));
42 check_clinging();
45 void set_terrain_mapped(int x, int y)
47 const coord_def gc(x, y);
48 map_cell* cell = &env.map_knowledge(gc);
49 cell->flags &= (~MAP_CHANGED_FLAG);
50 cell->flags |= MAP_MAGIC_MAPPED_FLAG;
51 #ifdef USE_TILE
52 tiles.update_minimap(gc);
53 #endif
56 int count_detected_mons()
58 int count = 0;
59 for (rectangle_iterator ri(BOUNDARY_BORDER - 1); ri; ++ri)
61 // Don't expose new dug out areas:
62 // Note: assumptions are being made here about how
63 // terrain can change (eg it used to be solid, and
64 // thus monster/item free).
65 if (env.map_knowledge(*ri).changed())
66 continue;
68 if (env.map_knowledge(*ri).detected_monster())
69 count++;
72 return (count);
75 void clear_map(bool clear_detected_items, bool clear_detected_monsters)
77 for (rectangle_iterator ri(BOUNDARY_BORDER - 1); ri; ++ri)
79 const coord_def p = *ri;
80 map_cell& cell = env.map_knowledge(p);
81 if (!cell.known() || cell.visible())
82 continue;
84 if (!clear_detected_items || !cell.detected_item())
85 cell.clear_item();
87 if ((!clear_detected_monsters || !cell.detected_monster())
88 && !mons_class_is_stationary(cell.monster()))
89 cell.clear_monster();
93 static void _automap_from(int x, int y, int mutated)
95 if (mutated)
96 magic_mapping(8 * mutated, 25, true, you.religion == GOD_ASHENZARI,
97 true, true, coord_def(x,y));
100 static int _map_quality()
102 int passive = player_mutation_level(MUT_PASSIVE_MAPPING);
103 // the explanation of this 51 vs max_piety of 200 is left as
104 // an exercise to the reader
105 if (you.religion == GOD_ASHENZARI && !player_under_penance())
106 passive = std::max(passive, you.piety / 51);
107 return passive;
110 void reautomap_level()
112 int passive = _map_quality();
114 for (int x = X_BOUND_1; x <= X_BOUND_2; ++x)
115 for (int y = Y_BOUND_1; y <= Y_BOUND_2; ++y)
116 if (env.map_knowledge[x][y].flags & MAP_SEEN_FLAG)
117 _automap_from(x, y, passive);
120 void set_terrain_seen(int x, int y)
122 const dungeon_feature_type feat = grd[x][y];
123 map_cell* cell = &env.map_knowledge[x][y];
125 // First time we've seen a notable feature.
126 // In unmappable areas, this doesn't work since
127 // map knowledge gets wiped each turn.
128 if (!(cell->flags & MAP_SEEN_FLAG) && player_in_mappable_area())
130 _automap_from(x, y, _map_quality());
132 const bool boring = !is_notable_terrain(feat)
133 // A portal deeper into the Ziggurat is boring.
134 || (feat == DNGN_ENTER_PORTAL_VAULT
135 && you.level_type == LEVEL_PORTAL_VAULT)
136 // Altars in the temple are boring.
137 || (feat_is_altar(feat)
138 && player_in_branch(BRANCH_ECUMENICAL_TEMPLE))
139 // Only note the first entrance to the Abyss/Pan/Hell
140 // which is found.
141 || ((feat == DNGN_ENTER_ABYSS || feat == DNGN_ENTER_PANDEMONIUM
142 || feat == DNGN_ENTER_HELL)
143 && overview_knows_num_portals(feat) > 1)
144 // There are at least three Zot entrances, and they're always
145 // on D:27, so ignore them.
146 || feat == DNGN_ENTER_ZOT;
148 if (!boring)
150 coord_def pos(x, y);
151 std::string desc =
152 feature_description(pos, false, DESC_NOCAP_A);
154 take_note(Note(NOTE_SEEN_FEAT, 0, 0, desc.c_str()));
158 cell->flags &= (~MAP_CHANGED_FLAG);
159 cell->flags |= MAP_SEEN_FLAG;
161 #ifdef USE_TILE
162 coord_def pos(x, y);
163 tiles.update_minimap(pos);
164 #endif
167 void set_terrain_visible(const coord_def &c)
169 map_cell* cell = &env.map_knowledge(c);
170 set_terrain_seen(c);
171 if (!(cell->flags & MAP_VISIBLE_FLAG))
173 cell->flags |= MAP_VISIBLE_FLAG;
174 env.visible.insert(c);
176 cell->flags &=~ (MAP_DETECTED_MONSTER | MAP_DETECTED_ITEM);
179 void clear_terrain_visibility()
181 for (std::set<coord_def>::iterator i = env.visible.begin(); i != env.visible.end(); ++i)
182 env.map_knowledge(*i).flags &=~ MAP_VISIBLE_FLAG;
183 env.visible.clear();
186 void map_cell::set_detected_item()
188 clear_item();
189 flags |= MAP_DETECTED_ITEM;
190 _item = new item_info();
191 _item->base_type = OBJ_DETECTED;
192 _item->colour = Options.detected_item_colour;