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