1 #include "AppHdr.h"
2
3 #ifdef USE_TILE_LOCAL
4
5 #include "tilereg-mon.h"
6
7 #include <algorithm>
8
9 #include "cio.h"
10 #include "directn.h"
11 #include "env.h"
12 #include "tile-env.h"
13 #include "libutil.h"
14 #include "monster.h"
15 #include "output.h"
16 #include "describe.h"
17 #include "tile-inventory-flags.h"
18 #include "rltiles/tiledef-dngn.h"
19 #include "rltiles/tiledef-icons.h"
20 #include "rltiles/tiledef-player.h"
21 #include "tilepick.h"
22 #include "tilereg-dgn.h"
23 #include "tiles-build-specific.h"
24 #include "tileview.h"
25 #include "viewgeom.h"
26
MonsterRegion(const TileRegionInit & init)27 MonsterRegion::MonsterRegion(const TileRegionInit &init) : GridRegion(init)
28 {
29 }
30
update()31 void MonsterRegion::update()
32 {
33 m_items.clear();
34 m_mon_info.clear();
35 m_dirty = true;
36
37 const size_t max_mons = mx * my;
38
39 if (max_mons == 0)
40 return;
41
42 get_monster_info(m_mon_info);
43 sort(m_mon_info.begin(), m_mon_info.end(),
44 monster_info::less_than_wrapper);
45
46 unsigned int num_mons = min(max_mons, m_mon_info.size());
47 for (size_t i = 0; i < num_mons; ++i)
48 {
49 InventoryTile desc;
50 desc.idx = i;
51
52 m_items.push_back(desc);
53 }
54 }
55
handle_mouse(wm_mouse_event & event)56 int MonsterRegion::handle_mouse(wm_mouse_event &event)
57 {
58 int cx, cy;
59 if (!mouse_pos(event.px, event.py, cx, cy))
60 {
61 place_cursor(NO_CURSOR);
62 return 0;
63 }
64
65 const coord_def cursor(cx, cy);
66 place_cursor(cursor);
67
68 if (mouse_control::current_mode() != MOUSE_MODE_COMMAND)
69 return 0;
70
71 unsigned int item_idx = cursor_index();
72 const monster_info* mon = get_monster(item_idx);
73 if (!mon)
74 return 0;
75
76 const coord_def &gc = mon->pos;
77 tiles.place_cursor(CURSOR_MOUSE, gc);
78
79 if (event.event != wm_mouse_event::PRESS)
80 return 0;
81
82 if (event.button == wm_mouse_event::LEFT)
83 {
84 m_last_clicked_item = item_idx;
85 return tile_click_cell(gc, event.mod);
86 }
87 else if (event.button == wm_mouse_event::RIGHT)
88 {
89 full_describe_square(gc);
90 redraw_screen();
91 update_screen();
92 return CK_MOUSE_CMD;
93 }
94
95 return 0;
96 }
97
update_tip_text(string & tip)98 bool MonsterRegion::update_tip_text(string &tip)
99 {
100 if (m_cursor == NO_CURSOR)
101 return false;
102
103 unsigned int item_idx = cursor_index();
104 const monster_info* mon = get_monster(item_idx);
105 if (!mon)
106 return false;
107
108 return tile_dungeon_tip(mon->pos, tip);
109 }
110
update_tab_tip_text(string &,bool)111 bool MonsterRegion::update_tab_tip_text(string &/*tip*/, bool /*active*/)
112 {
113 return false;
114 }
115
update_alt_text(string & alt)116 bool MonsterRegion::update_alt_text(string &alt)
117 {
118 if (m_cursor == NO_CURSOR)
119 return false;
120
121 unsigned int item_idx = cursor_index();
122 if (m_last_clicked_item >= 0
123 && item_idx == (unsigned int) m_last_clicked_item)
124 {
125 return false;
126 }
127
128 const monster_info* mon = get_monster(item_idx);
129 if (!mon)
130 return false;
131
132 const coord_def &gc = mon->pos;
133
134 describe_info inf;
135 if (!you.see_cell(gc))
136 return false;
137
138 get_square_desc(gc, inf);
139
140 alt = process_description(inf);
141 return true;
142 }
143
get_monster(unsigned int idx) const144 const monster_info* MonsterRegion::get_monster(unsigned int idx) const
145 {
146 if (idx >= m_items.size())
147 return nullptr;
148
149 const InventoryTile &item = m_items[idx];
150 if (item.idx >= static_cast<int>(m_mon_info.size()))
151 return nullptr;
152
153 return &(m_mon_info[item.idx]);
154 }
155
pack_buffers()156 void MonsterRegion::pack_buffers()
157 {
158 update();
159 const int num_floor = tile_dngn_count(tile_env.default_flavour.floor);
160
161 unsigned int i = 0;
162 for (int y = 0; y < my; y++)
163 {
164 for (int x = 0; x < mx; x++)
165 {
166 bool cursor = (i < m_items.size()) ?
167 (m_items[i].flag & TILEI_FLAG_CURSOR) : false;
168
169 const monster_info* mon = get_monster(i++);
170 if (mon)
171 {
172 const coord_def gc = mon->pos;
173 const coord_def ep = grid2show(gc);
174
175 if (crawl_view.in_los_bounds_g(gc))
176 {
177 packed_cell cell;
178 cell.fg = tile_env.fg(ep);
179 cell.bg = tile_env.bg(ep);
180 cell.flv = tile_env.flv(gc);
181 tile_apply_properties(gc, cell);
182
183 m_buf.add(cell, x, y);
184
185 if (cursor)
186 m_buf.add_icons_tile(TILEI_CURSOR, x, y);
187 continue;
188 }
189 }
190
191 // Fill the rest of the space with out of sight floor tiles.
192 int tileidx = tile_env.default_flavour.floor + i % num_floor;
193 m_buf.add_dngn_tile(tileidx, x, y);
194 m_buf.add_icons_tile(TILEI_MESH, x, y);
195 }
196 }
197 }
198
draw_tag()199 void MonsterRegion::draw_tag()
200 {
201 if (m_cursor == NO_CURSOR)
202 return;
203
204 int curs_index = cursor_index();
205 if (curs_index >= (int)m_items.size())
206 return;
207 int idx = m_items[curs_index].idx;
208 if (idx == -1)
209 return;
210
211 const monster_info* mon = get_monster(idx);
212 if (!mon)
213 return;
214
215 string desc = mon->proper_name(DESC_A);
216 draw_desc(desc.c_str());
217 }
218
activate()219 void MonsterRegion::activate()
220 {
221 }
222
223 #endif
224