1 /**
2  * @file
3  * @brief Functions used when picking squares.
4 **/
5 
6 #pragma once
7 
8 #include <vector>
9 
10 #include "command-type.h"
11 #include "enum.h"
12 #include "mon-info.h"
13 #include "targ-mode-type.h"
14 #include "targeting-type.h"
15 #include "trap-type.h"
16 #include "view.h"
17 
18 using std::vector;
19 
20 struct describe_info;
21 
22 class range_view_annotator
23 {
24 public:
25     range_view_annotator(targeter *range);
26     virtual ~range_view_annotator();
27 };
28 
29 class monster_view_annotator
30 {
31 public:
32     monster_view_annotator(vector<monster *> *monsters);
33     virtual ~monster_view_annotator();
34 };
35 
36 // An object that modifies the behaviour of the direction prompt.
37 class targeting_behaviour
38 {
39 public:
40     targeting_behaviour(bool just_looking = false);
41     virtual ~targeting_behaviour();
42 
43     virtual command_type get_command(int key);
44 
45     // Should we force a redraw?
should_redraw()46     virtual bool should_redraw() const { return false; }
47     // Clear the bit set above.
clear_redraw()48     virtual void clear_redraw()  { return; }
49 
50     // Update the prompt shown at top.
update_top_prompt(string *)51     virtual void update_top_prompt(string*) {}
52 
targeted()53     virtual bool targeted() { return true; }
54 
get_error()55     virtual string get_error() { return ""; }
56 
57     // Add relevant descriptions to the target status.
58     virtual vector<string> get_monster_desc(const monster_info& mi);
59 private:
60     string prompt;
61 
62 public:
63     bool just_looking;
64     desc_filter get_desc_func; // Function to add relevant descriptions
65     maybe_bool needs_path;
66 };
67 
68 struct direction_chooser_args
69 {
70     targeter *hitfunc;
71     targeting_type restricts;
72     targ_mode_type mode;
73     int range;
74     bool just_looking;
75     bool needs_path;
76     bool prefer_farthest;
77     bool unrestricted; // for wizmode
78     bool allow_shift_dir;
79     confirm_prompt_type self;
80     const char *target_prefix;
81     string top_prompt;
82     targeting_behaviour *behaviour;
83     bool show_floor_desc;
84     bool show_boring_feats;
85     desc_filter get_desc_func;
86     coord_def default_place;
87 
direction_chooser_argsdirection_chooser_args88     direction_chooser_args() :
89         hitfunc(nullptr),
90         restricts(DIR_NONE),
91         mode(TARG_ANY),
92         range(-1),
93         just_looking(false),
94         needs_path(true),
95         prefer_farthest(false),
96         unrestricted(false),
97         allow_shift_dir(true),
98         self(confirm_prompt_type::prompt),
99         target_prefix(nullptr),
100         behaviour(nullptr),
101         show_floor_desc(false),
102         show_boring_feats(true),
103         get_desc_func(nullptr),
104         default_place(0, 0)
105     { }
106 
107 };
108 
109 class direction_chooser;
110 
111 class direction_chooser_renderer : public view_renderer
112 {
113 public:
direction_chooser_renderer(direction_chooser & directn)114     direction_chooser_renderer(direction_chooser &directn) : m_directn(directn) {}
115     void render(crawl_view_buffer& vbuf);
116 private:
117     direction_chooser &m_directn;
118 };
119 
120 class UIDirectionChooserView;
121 
122 class direction_chooser
123 {
124     friend class direction_chooser_renderer;
125     friend class UIDirectionChooserView;
126 public:
127     direction_chooser(dist& moves, const direction_chooser_args& args);
128     bool noninteractive();
129     bool choose_direction();
130 
131 private:
132     void update_validity();
133 
134     bool targets_objects() const;
135     bool targets_enemies() const;
136 
137     // Return the location where targeting should start.
138     coord_def find_default_target() const;
139 
140     bool process_command(command_type command);
141 
142     void handle_mlist_cycle_command(command_type key_command);
143     void handle_wizard_command(command_type key_command, bool* loop_done);
144     void handle_movement_key(command_type key_command, bool* loop_done);
145 
146     bool in_range(const coord_def& p) const;
147 
148     // Jump to the player.
149     void move_to_you();
150 
151     // Cycle to the next (dir == 1) or previous (dir == -1) object.
152     void object_cycle(int dir);
153 
154     // Cycle to the next (dir == 1) or previous (dir == -1) monster.
155     void monster_cycle(int dir);
156 
157     // Cycle to the next feature of the given type.
158     void feature_cycle_forward(int feature);
159 
160     // Set the remembered target to be the current target.
161     void update_previous_target() const;
162 
163     // Finalise the current choice of target. Return true if
164     // successful, false if failed (e.g. out of range.)
165     bool select(bool allow_out_of_range, bool endpoint);
166     bool select_compass_direction(const coord_def& delta);
167     bool select_previous_target();
168 
169     // Mark item for pickup, initiate movement.
170     bool pickup_item();
171 
172     // Return true if we need to abort targeting due to a signal.
173     bool handle_signals();
174 
175     void reinitialize_move_flags();
176 
177     // Return or set the current target.
178     const coord_def& target() const;
179     void set_target(const coord_def& new_target);
180 
181     string build_targeting_hint_string() const;
182 
183     actor* targeted_actor() const;
184     monster* targeted_monster() const;
185 
186     bool find_default_monster_target(coord_def& result) const;
187     // Functions which print things to the user.
188     // Each one is commented with a sample output.
189 
190     // Whatever the caller defines. Typically something like:
191     // Casting: Venom Bolt.
192     // Can be modified by the targeting_behaviour.
193     void print_top_prompt() const;
194 
195     // Press: ? - help, Shift-Dir - straight line, t - megabat
196     void print_key_hints() const;
197 
198     // Here: An orc wizard, wielding a glowing orcish dagger, and wearing
199     // an orcish robe (miasma, silenced, almost dead)
200     // OR:
201     // Apport: A short sword.
202     void print_target_description(bool &did_cloud) const;
203 
204     // Helper functions for the above.
205     void print_target_monster_description(bool &did_cloud) const;
206     void print_target_object_description() const;
207 
208     // You see 2 +3 dwarven bolts here.
209     // There is something else lying underneath.
210     void print_items_description() const;
211 
212     // Lava.
213     //
214     // If boring_too is false, then don't print anything on boring
215     // terrain (i.e. floor.)
216     void print_floor_description(bool boring_too) const;
217 
218     string target_interesting_terrain_description() const;
219     string target_cloud_description() const;
220     string target_sanctuary_description() const;
221     string target_silence_description() const;
222     vector<string> target_cell_description_suffixes() const;
223     vector<string> monster_description_suffixes(const monster_info& mi) const;
224 
225     void describe_cell() const;
226 
227     // Move the target to where the mouse pointer is (on tiles.)
228     // Returns whether the move was valid, i.e., whether the mouse
229     // pointer is in bounds.
230     bool tiles_update_target();
231 
232     // Display the prompt when beginning targeting.
233     void show_initial_prompt();
234 
235     void toggle_beam();
236 
237     void finalize_moves();
238     void do_redraws();
239 
240     void draw_beam(crawl_view_buffer &vbuf);
241     void highlight_summoner(crawl_view_buffer &vbuf);
242     coord_def find_summoner();
243 
244     // Whether the current target is you.
245     bool looking_at_you() const;
246 
247     // Whether the current target is valid.
248     bool move_is_ok() const;
249 
250     void full_describe();
251     void describe_target();
252     void show_help();
253 
254     // Parameters.
255     dist& moves;                // Output.
256     targeting_type restricts;   // What kind of target do we want?
257     targ_mode_type mode;        // Hostiles or friendlies?
258     int range;                  // Max range to consider
259     bool just_looking;
260     bool prefer_farthest;       // Prefer to target the farthest monster.
261     bool allow_shift_dir;       // Allow aiming in cardinal directions.
262     confirm_prompt_type self;   // What do when aiming at yourself
263     const char *target_prefix;  // A string displayed before describing target
264     string top_prompt;          // Shown at the top of the message window
265     targeting_behaviour *behaviour; // Can be nullptr for default
266     bool show_floor_desc;       // Describe the floor of the current target
267     bool show_boring_feats;
268     targeter *hitfunc;         // Determine what would be hit.
269     coord_def default_place;    // Start somewhere other than you.pos()?
270 
271     // Internal data.
272     ray_def beam;               // The (possibly invalid) beam.
273     bool show_beam;             // Does the user want the beam displayed?
274     bool have_beam;             // Is the currently stored beam valid?
275     coord_def objfind_pos, monsfind_pos; // Cycling memory
276 
277     // What we need to redraw.
278     bool need_viewport_redraw;
279     bool need_cursor_redraw;
280     bool need_text_redraw;
281     bool need_all_redraw;       // All of the above.
282 
283     // Default behaviour, saved across instances.
284     static targeting_behaviour stock_behaviour;
285 
286     direction_chooser_renderer renderer;
287 
288     bool unrestricted;
289 public:
290     // TODO: fix the weird behaviour that led to this hack
291     bool needs_path;            // Determine a ray while we're at it?
292 };
293 
294 // Monster equipment description level.
295 enum mons_equip_desc_level_type
296 {
297     DESC_WEAPON,
298     DESC_FULL,
299     DESC_IDENTIFIED,
300     DESC_WEAPON_WARNING, // like DESC_WEAPON but also includes dancing weapons
301 };
302 
303 void direction(dist &moves, const direction_chooser_args& args);
304 
305 string get_terse_square_desc(const coord_def &gc);
306 void terse_describe_square(const coord_def &c, bool in_range = true);
307 void full_describe_square(const coord_def &c, bool cleanup = true);
308 void get_square_desc(const coord_def &c, describe_info &inf);
309 
310 void describe_floor();
311 string get_monster_equipment_desc(const monster_info& mi,
312                                   //bool full_desc = true,
313                                   mons_equip_desc_level_type level = DESC_FULL,
314                                   description_level_type mondtype = DESC_A,
315                                   bool print_attitude = false);
316 
317 string feature_description_at(const coord_def& where, bool covering = false,
318                               description_level_type dtype = DESC_A);
319 string raw_feature_description(const coord_def& where);
320 string feature_description(dungeon_feature_type grid,
321                            trap_type trap = NUM_TRAPS,
322                            const string & cover_desc = "",
323                            description_level_type dtype = DESC_A);
324 
325 vector<dungeon_feature_type> features_by_desc(const base_pattern &pattern);
326 
327 void full_describe_view();
328 void do_look_around(const coord_def &whence = coord_def(0, 0));
329 bool get_look_position(coord_def *c);
330 
331 extern const struct coord_def Compass[9];
332