1 /* 2 Copyright (C) 2003 - 2018 by David White <dave@whitevine.net> 3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/ 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY. 11 12 See the COPYING file for more details. 13 */ 14 15 /** @file */ 16 17 #pragma once 18 19 class config; 20 class team; 21 class game_board; 22 23 #include "chat_events.hpp" 24 #include "display.hpp" 25 #include "display_chat_manager.hpp" 26 #include "pathfind/pathfind.hpp" 27 28 #include <deque> 29 30 // This needs to be separate from display.h because of the static 31 // singleton member, which will otherwise trigger link failure 32 // when building the editor. 33 34 class game_display : public display 35 { 36 public: 37 game_display(game_board& board, 38 std::weak_ptr<wb::manager> wb, 39 reports & reports_object, 40 const config& theme_cfg, 41 const config& level, 42 bool dummy=false); 43 44 ~game_display(); get_singleton()45 static game_display* get_singleton() 46 { 47 return static_cast<game_display*>(singleton_); 48 } 49 50 /** 51 * Update lighting settings. 52 * 53 * Should be called on every new turn. 54 */ 55 void new_turn(); 56 observers() const57 virtual const std::set<std::string>& observers() const override { return chat_man_->observers(); } 58 /** 59 * Scrolls to the leader of a certain side. 60 * 61 * This will normally be the playing team. 62 */ 63 void scroll_to_leader(int side, SCROLL_TYPE scroll_type = ONSCREEN,bool force = true); 64 65 /** 66 * Function to display a location as selected. 67 * 68 * If a unit is in the location, and there is no unit in the currently 69 * highlighted hex, the unit will be displayed in the sidebar. 70 */ 71 virtual void select_hex(map_location hex) override; 72 73 /** 74 * Function to highlight a location. 75 * 76 * If a unit is in the location, it will be displayed in the sidebar. 77 * Selection is used when a unit has been clicked on, while highlighting is 78 * used when a location has been moused over. 79 */ 80 virtual void highlight_hex(map_location hex) override; 81 82 /** 83 * Change the unit to be displayed in the sidebar. 84 * 85 * This is used when selecting or highlighting is not wanted. 86 */ 87 void display_unit_hex(map_location hex); 88 89 /** 90 * Sets the paths that are currently displayed as available 91 * for the unit to move along. 92 * All other paths will be grayed out. 93 */ 94 void highlight_reach(const pathfind::paths &paths_list); 95 96 /** 97 * Add more paths to highlight. Print numbers where they overlap. 98 * Used by Show Enemy Moves. If @a goal is not @c null_location, highlight 99 * enemy units that can reach @a goal. 100 */ 101 void highlight_another_reach(const pathfind::paths &paths_list, 102 const map_location& goal = map_location::null_location()); 103 /** 104 * Return the locations of units that can reach @a goal (@see highlight_another_reach()). 105 */ units_that_can_reach_goal() const106 const std::set<map_location>& units_that_can_reach_goal() const { return units_that_can_reach_goal_; } 107 108 /** Reset highlighting of paths. */ 109 bool unhighlight_reach(); 110 111 /** 112 * Sets the route along which footsteps are drawn to show movement of a 113 * unit. If nullptr, no route is displayed. @a route does not have to remain 114 * valid after being set. 115 */ 116 void set_route(const pathfind::marked_route *route); 117 118 /** Function to float a label above a tile */ 119 void float_label(const map_location& loc, const std::string& text, const color_t& color); 120 121 /** Draws the movement info (turns available) for a given location. */ 122 void draw_movement_info(const map_location& loc); 123 124 /** Function to invalidate that unit status displayed on the sidebar. */ invalidate_unit()125 void invalidate_unit() { invalidateGameStatus_ = true; } 126 127 /** Same as invalidate_unit() if moving the displayed unit. */ 128 void invalidate_unit_after_move(const map_location& src, const map_location& dst); 129 130 virtual const time_of_day& get_time_of_day(const map_location& loc) const override; 131 132 virtual bool has_time_area() const override; 133 134 protected: 135 /** 136 * game_display pre_draw does specific things related e.g. to unit rendering 137 * and calls the whiteboard pre-draw method. 138 */ 139 virtual void pre_draw() override; 140 /** 141 * Calls the whiteboard's post-draw method. 142 */ 143 virtual void post_draw() override; 144 145 virtual void draw_invalidated() override; 146 147 virtual void post_commit() override; 148 149 virtual void draw_hex(const map_location& loc) override; 150 151 std::set<map_location> units_that_can_reach_goal_; 152 153 public: 154 /** Set the attack direction indicator. */ 155 void set_attack_indicator(const map_location& src, const map_location& dst); 156 void clear_attack_indicator(); 157 // TODO: compare reports::context::mhb()->current_unit_attacks_from() get_attack_indicator_src()158 const map_location& get_attack_indicator_src() { return attack_indicator_src_; } 159 160 /** Function to get attack direction suffix. */ attack_indicator_direction() const161 std::string attack_indicator_direction() const { 162 return map_location::write_direction( 163 attack_indicator_src_.get_relative_dir(attack_indicator_dst_)); 164 } 165 166 // Functions used in the editor: 167 168 //void draw_terrain_palette(int x, int y, terrain_type::TERRAIN selected); 169 t_translation::terrain_code get_terrain_on(int palx, int paly, int x, int y); 170 displayed_unit_hex() const171 virtual const map_location &displayed_unit_hex() const override { return displayedUnitHex_; } 172 173 /** 174 * annotate hex with number, useful for debugging or UI prototype 175 */ 176 static int& debug_highlight(const map_location& loc); clear_debug_highlights()177 static void clear_debug_highlights() { debugHighlights_.clear(); } 178 179 180 /** The playing team is the team whose turn it is. */ playing_side() const181 virtual int playing_side() const override { return activeTeam_ + 1; } 182 183 184 std::string current_team_name() const; 185 get_chat_manager()186 display_chat_manager & get_chat_manager() { return *chat_man_; } 187 188 void begin_game(); 189 in_game() const190 virtual bool in_game() const override { return in_game_; } 191 192 /** 193 * Sets the linger mode for the display. 194 * There have been some discussions on what to do with fog and shroud 195 * the extra variables make it easier to modify the behavior. There 196 * might even be a split between victory and defeat. 197 * 198 * @todo if the current implementation is wanted we can change 199 * the stuff back to a boolean 200 */ 201 enum game_mode { 202 RUNNING, /**< no linger overlay, show fog and shroud. */ 203 LINGER }; /**< linger overlay, show fog and shroud. */ 204 205 void set_game_mode(const game_mode mode); 206 207 /// Sets whether the screen (map visuals) needs to be rebuilt. This is typically after the map has been changed by wml. 208 void needs_rebuild(bool b); 209 210 /// Rebuilds the screen if needs_rebuild(true) was previously called, and resets the flag. 211 bool maybe_rebuild(); 212 213 private: 214 game_display(const game_display&); 215 void operator=(const game_display&); 216 217 virtual void draw_sidebar() override; 218 219 overlay_map overlay_map_; 220 221 // Locations of the attack direction indicator's parts 222 map_location attack_indicator_src_; 223 map_location attack_indicator_dst_; 224 225 pathfind::marked_route route_; 226 227 void invalidate_route(); 228 229 map_location displayedUnitHex_; 230 231 double sidebarScaling_; 232 233 bool first_turn_, in_game_; 234 235 const std::unique_ptr<display_chat_manager> chat_man_; 236 237 game_mode mode_; 238 239 // For debug mode 240 static std::map<map_location, int> debugHighlights_; 241 242 bool needs_rebuild_; 243 244 }; 245