The Battle for Wesnoth  1.19.5+dev
game_display.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * During a game, show map & info-panels at top+right.
19  */
20 
21 #include "game_display.hpp"
22 
23 
24 #include "cursor.hpp"
25 #include "display_chat_manager.hpp"
26 #include "fake_unit_manager.hpp"
27 #include "floating_label.hpp"
28 #include "game_board.hpp"
30 #include "log.hpp"
31 #include "map/map.hpp"
32 #include "font/standard_colors.hpp"
33 #include "reports.hpp"
34 #include "resources.hpp"
35 #include "tod_manager.hpp"
36 #include "color.hpp"
37 #include "synced_context.hpp"
38 #include "units/unit.hpp"
39 #include "units/drawer.hpp"
40 #include "utils/general.hpp"
41 #include "whiteboard/manager.hpp"
42 #include "overlay.hpp"
43 #include "draw.hpp"
44 
45 static lg::log_domain log_display("display");
46 #define ERR_DP LOG_STREAM(err, log_display)
47 #define LOG_DP LOG_STREAM(info, log_display)
48 #define DBG_DP LOG_STREAM(debug, log_display)
49 
50 static lg::log_domain log_engine("engine");
51 #define ERR_NG LOG_STREAM(err, log_engine)
52 
53 /**
54  * Function to return 2 half-hex footsteps images for the given location.
55  * Only loc is on the current route set by set_route.
56  *
57  * This function is only used internally by game_display so I have moved it out of the header into the compilaton unit.
58  */
59 std::vector<texture> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_);
60 
62  std::weak_ptr<wb::manager> wb,
63  reports& reports_object,
64  const std::string& theme_id,
65  const config& level)
66  : display(&board, wb, reports_object, theme_id, level)
67  , overlay_map_()
68  , attack_indicator_src_()
69  , attack_indicator_dst_()
70  , route_()
71  , displayedUnitHex_()
72  , first_turn_(true)
73  , in_game_(false)
74  , chat_man_(new display_chat_manager(*this))
75  , mode_(RUNNING)
76  , needs_rebuild_(false)
77 {
78 }
79 
81 {
82  try {
83  chat_man_->prune_chat_messages(true);
84  } catch(...) {
85  DBG_DP << "Caught exception in game_display destructor: " << utils::get_unknown_exception_type();
86  }
87 }
88 
90 {
91  if(!first_turn_) {
94 
95  if(old_tod.image_mask != tod.image_mask) {
96  fade_tod_mask(old_tod.image_mask, tod.image_mask);
97  }
98  }
99 
100  first_turn_ = false;
101 
102  update_tod();
103 }
104 
106 {
107  if(hex.valid() && fogged(hex)) {
108  return;
109  }
110  display::select_hex(hex);
111 
112  display_unit_hex(hex);
113 }
114 
116 {
117  wb::future_map_if future(!synced_context::is_synced()); /**< Lasts for whole method. */
118 
120  if (u) {
121  displayedUnitHex_ = hex;
122  invalidate_unit();
123  } else {
125  if (u) {
126  // mouse moved from unit hex to non-unit hex
127  if (context().units().count(selectedHex_)) {
129  invalidate_unit();
130  }
131  }
132  }
133 
136 }
137 
138 
140 {
141  if (!hex.valid())
142  return;
143 
144  wb::future_map_if future(!synced_context::is_synced()); /**< Lasts for whole method. */
145 
147  if (u) {
148  displayedUnitHex_ = hex;
149  invalidate_unit();
150  }
151 }
152 
154 {
155  if (src == displayedUnitHex_) {
157  invalidate_unit();
158  }
159 }
160 
161 void game_display::scroll_to_leader(int side, SCROLL_TYPE scroll_type,bool force)
162 {
164 
165  if(leader.valid() && leader->is_visible_to_team(viewing_team(), false)) {
166  scroll_to_tile(leader->get_location(), scroll_type, true, force);
167  }
168 }
169 
171 {
172  display::update();
173 
174  if (std::shared_ptr<wb::manager> w = wb_.lock()) {
175  w->pre_draw();
176  }
178  /**
179  * @todo FIXME: must modify changed, but best to do it at the
180  * floating_label level
181  */
182  chat_man_->prune_chat_messages();
183 }
184 
185 
187 {
188  display::render();
189 
190  if (std::shared_ptr<wb::manager> w = wb_.lock()) {
191  w->post_draw();
192  }
193 }
194 
196 {
198  if (fake_unit_man_->empty()) {
199  return;
200  }
201  unit_drawer drawer = unit_drawer(*this);
202 
203  for(const unit* temp_unit : *fake_unit_man_) {
204  const map_location& loc = temp_unit->get_location();
205  if(utils::contains(invalidated_, loc) && unit_can_draw_here(loc, *temp_unit)) {
206  drawer.redraw_unit(*temp_unit);
207  }
208  }
209 }
210 
211 namespace
212 {
213 const std::string mouseover_normal_top = "misc/hover-hex-top.png~RC(magenta>gold)";
214 const std::string mouseover_normal_bot = "misc/hover-hex-bottom.png~RC(magenta>gold)";
215 
216 const std::string mouseover_enemy_top = "misc/hover-hex-enemy-top.png~RC(magenta>red)";
217 const std::string mouseover_enemy_bot = "misc/hover-hex-enemy-bottom.png~RC(magenta>red)";
218 
219 const std::string mouseover_self_top = "misc/hover-hex-top.png~RC(magenta>green)";
220 const std::string mouseover_self_bot = "misc/hover-hex-bottom.png~RC(magenta>green)";
221 
222 const std::string mouseover_ally_top = "misc/hover-hex-top.png~RC(magenta>lightblue)";
223 const std::string mouseover_ally_bot = "misc/hover-hex-bottom.png~RC(magenta>lightblue)";
224 }
225 
227 {
228  const bool on_map = context().map().on_board(loc);
229  const bool is_shrouded = shrouded(loc);
230 
231  display::draw_hex(loc);
232 
233  if(cursor::get() == cursor::WAIT) {
234  // Interaction is disabled, so we don't need anything else
235  return;
236  }
237 
238  if(on_map && loc == mouseoverHex_ && !map_screenshot_) {
240  const unit* u = context().get_visible_unit(loc, viewing_team());
241  if(u != nullptr) {
242  hex_top_layer = drawing_layer::mouseover_top;
243  }
244 
245  const std::string* mo_top_path;
246  const std::string* mo_bot_path;
247 
248  if(u == nullptr) {
249  mo_top_path = &mouseover_normal_top;
250  mo_bot_path = &mouseover_normal_bot;
251  } else if(viewing_team().is_enemy(u->side())) {
252  mo_top_path = &mouseover_enemy_top;
253  mo_bot_path = &mouseover_enemy_bot;
254  } else if(viewing_team().side() == u->side()) {
255  mo_top_path = &mouseover_self_top;
256  mo_bot_path = &mouseover_self_bot;
257  } else {
258  mo_top_path = &mouseover_ally_top;
259  mo_bot_path = &mouseover_ally_bot;
260  }
261 
262  drawing_buffer_add(hex_top_layer, loc,
263  [tex = image::get_texture(*mo_top_path, image::HEXED)](const rect& dest) { draw::blit(tex, dest); });
264 
266  [tex = image::get_texture(*mo_bot_path, image::HEXED)](const rect& dest) { draw::blit(tex, dest); });
267  }
268 
269  // Draw reach_map information.
270  // We remove the reachability mask of the unit that we want to attack.
271  if(!is_shrouded && !reach_map_.empty() && reach_map_.find(loc) != reach_map_.end() && loc != attack_indicator_dst_) {
272  drawing_buffer_add(drawing_layer::fog_shroud, loc, [images = get_reachmap_images(loc)](const rect& dest) {
273  for(const texture& t : images) {
274  draw::blit(t, dest);
275  }
276  });
277  }
278 
279  if(std::shared_ptr<wb::manager> w = wb_.lock()) {
280  w->draw_hex(loc);
281 
282  if(!(w->is_active() && w->has_temp_move())) {
283  std::vector<texture> footstepImages = footsteps_images(loc, route_, dc_);
284  if(!footstepImages.empty()) {
285  drawing_buffer_add(drawing_layer::footsteps, loc, [images = std::move(footstepImages)](const rect& dest) {
286  for(const texture& t : images) {
287  draw::blit(t, dest);
288  }
289  });
290  }
291  }
292  }
293 
294  // Draw the attack direction indicator
295  if(on_map && loc == attack_indicator_src_) {
297  [tex = image::get_texture("misc/attack-indicator-src-" + attack_indicator_direction() + ".png", image::HEXED)](const rect& dest)
298  { draw::blit(tex, dest); }
299  );
300  } else if(on_map && loc == attack_indicator_dst_) {
302  [tex = image::get_texture("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::HEXED)](const rect& dest)
303  { draw::blit(tex, dest); }
304  );
305  }
306 
307  // Linger overlay unconditionally otherwise it might give glitches
308  // so it's drawn over the shroud and fog.
309  if(mode_ != RUNNING) {
312  [tex = image::get_texture(linger, image::TOD_COLORED)](const rect& dest) { draw::blit(tex, dest); });
313  }
314 
315  if(on_map && loc == selectedHex_ && !game_config::images::selected.empty()) {
318  [tex = image::get_texture(selected, image::HEXED)](const rect& dest) { draw::blit(tex, dest); });
319  }
320 
321  // Show def% and turn to reach info
322  if(!is_shrouded && on_map) {
323  draw_movement_info(loc);
324  }
325 }
326 
328 {
330 }
331 
333 {
335 }
336 
338 {
339  display::layout();
340 
341  refresh_report("report_clock");
342  refresh_report("report_battery");
343  refresh_report("report_countdown");
344 
346  {
347  wb::future_map future; // start planned unit map scope
348 
349  // We display the unit the mouse is over if it is over a unit,
350  // otherwise we display the unit that is selected.
351  for (const std::string &name : reports_object_->report_list()) {
352  refresh_report(name);
353  }
354  invalidateGameStatus_ = false;
355  }
356 }
357 
358 
360 {
361  if(mode != mode_) {
362  mode_ = mode;
363  invalidate_all();
364  }
365 }
366 
368 {
369  // Search if there is a mark here
371 
372  std::shared_ptr<wb::manager> wb = wb_.lock();
373 
374  // Don't use empty route or the first step (the unit will be there)
375  if(w != route_.marks.end()
376  && !route_.steps.empty() && route_.steps.front() != loc) {
377  const unit_map::const_iterator un =
378  (wb && wb->get_temp_move_unit().valid()) ?
379  wb->get_temp_move_unit() : context().units().find(route_.steps.front());
380  if(un != context().units().end()) {
381  // Display the def% of this terrain
382  int move_cost = un->movement_cost(context().map().get_terrain(loc));
383  int def = (move_cost == movetype::UNREACHABLE ?
384  0 : 100 - un->defense_modifier(context().map().get_terrain(loc)));
385  std::stringstream def_text;
386  def_text << def << "%";
387 
388  color_t color = game_config::red_to_green(def, false);
389 
390  // simple mark (no turn point) use smaller font
391  int def_font = w->second.turns > 0 ? 18 : 16;
392  draw_text_in_hex(loc, drawing_layer::move_info, def_text.str(), def_font, color);
393 
395  [inv = w->second.invisible, zoc = w->second.zoc, cap = w->second.capture](const rect& dest) {
396  if(inv) {
397  draw::blit(image::get_texture(image::locator{"misc/hidden.png"}, image::HEXED), dest);
398  }
399 
400  if(zoc) {
401  draw::blit(image::get_texture(image::locator{"misc/zoc.png"}, image::HEXED), dest);
402  }
403 
404  if(cap) {
405  draw::blit(image::get_texture(image::locator{"misc/capture.png"}, image::HEXED), dest);
406  }
407  });
408 
409  //we display turn info only if different from a simple last "1"
410  if (w->second.turns > 1 || (w->second.turns == 1 && loc != route_.steps.back())) {
411  std::stringstream turns_text;
412  turns_text << w->second.turns;
413  draw_text_in_hex(loc, drawing_layer::move_info, turns_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
414  }
415 
416  // The hex is full now, so skip the "show enemy moves"
417  return;
418  }
419  }
420  // When out-of-turn, it's still interesting to check out the terrain defs of the selected unit
421  else if (selectedHex_.valid() && loc == mouseoverHex_)
422  {
423  const unit_map::const_iterator selectedUnit = resources::gameboard->find_visible_unit(selectedHex_,viewing_team());
424  const unit_map::const_iterator mouseoveredUnit = resources::gameboard->find_visible_unit(mouseoverHex_,viewing_team());
425  if(selectedUnit != context().units().end() && mouseoveredUnit == context().units().end()) {
426  // Display the def% of this terrain
427  int move_cost = selectedUnit->movement_cost(context().map().get_terrain(loc));
428  int def = (move_cost == movetype::UNREACHABLE ?
429  0 : 100 - selectedUnit->defense_modifier(context().map().get_terrain(loc)));
430  std::stringstream def_text;
431  def_text << def << "%";
432 
433  color_t color = game_config::red_to_green(def, false);
434 
435  // use small font
436  int def_font = 16;
437  draw_text_in_hex(loc, drawing_layer::move_info, def_text.str(), def_font, color);
438  }
439  }
440 
441  if (!reach_map_.empty()) {
442  reach_map::iterator reach = reach_map_.find(loc);
443  if (reach != reach_map_.end() && reach->second > 1) {
444  const std::string num = std::to_string(reach->second);
445  draw_text_in_hex(loc, drawing_layer::move_info, num, 16, font::YELLOW_COLOR);
446  }
447  }
448 }
449 
450 std::vector<texture> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_)
451 {
452  std::vector<texture> res;
453 
454  if (route_.steps.size() < 2) {
455  return res; // no real "route"
456  }
457 
458  std::vector<map_location>::const_iterator i =
459  std::find(route_.steps.begin(),route_.steps.end(),loc);
460 
461  if( i == route_.steps.end()) {
462  return res; // not on the route
463  }
464 
465  // Check which footsteps images of game_config we will use
466  int move_cost = 1;
467  const unit_map::const_iterator u = dc_->units().find(route_.steps.front());
468  if(u != dc_->units().end()) {
469  move_cost = u->movement_cost(dc_->map().get_terrain(loc));
470  }
471  int image_number = std::min<int>(move_cost, game_config::foot_speed_prefix.size());
472  if (image_number < 1) {
473  return res; // Invalid movement cost or no images
474  }
475  const std::string foot_speed_prefix = game_config::foot_speed_prefix[image_number-1];
476 
477  texture teleport;
478 
479  // We draw 2 half-hex (with possibly different directions),
480  // but skip the first for the first step.
481  const int first_half = (i == route_.steps.begin()) ? 1 : 0;
482  // and the second for the last step
483  const int second_half = (i+1 == route_.steps.end()) ? 0 : 1;
484 
485  for (int h = first_half; h <= second_half; ++h) {
486  const std::string sense( h==0 ? "-in" : "-out" );
487 
488  if (!tiles_adjacent(*(i+(h-1)), *(i+h))) {
489  std::string teleport_image =
491  teleport = image::get_texture(teleport_image, image::HEXED);
492  continue;
493  }
494 
495  // In function of the half, use the incoming or outgoing direction
496  map_location::direction dir = (i+(h-1))->get_relative_dir(*(i+h));
497 
498  std::string rotate;
500  // No image, take the opposite direction and do a 180 rotation
501  dir = i->get_opposite_direction(dir);
502  rotate = "~FL(horiz)~FL(vert)";
503  }
504 
505  const std::string image = foot_speed_prefix
506  + sense + "-" + i->write_direction(dir)
507  + ".png" + rotate;
508 
509  res.push_back(image::get_texture(image, image::HEXED));
510  }
511 
512  // we draw teleport image (if any) in last
513  if (teleport != nullptr) res.push_back(teleport);
514 
515  return res;
516 }
517 
518 
519 
521 {
523  highlight_another_reach(paths_list);
524 }
525 
527  const map_location& goal)
528 {
529  // Fold endpoints of routes into reachability map.
530  for (const pathfind::paths::step &dest : paths_list.destinations) {
531  reach_map_[dest.curr]++;
532  }
533  reach_map_changed_ = true;
534 
535  if(goal != map_location::null_location() && paths_list.destinations.contains(goal)) {
536  const auto& path_to_goal = paths_list.destinations.get_path(paths_list.destinations.find(goal));
537  const map_location enemy_unit_location = path_to_goal[0];
538  units_that_can_reach_goal_.insert(enemy_unit_location);
539  }
540 }
541 
543 {
545  if(!reach_map_.empty()) {
546  reach_map_.clear();
547  reach_map_changed_ = true;
548  return true;
549  } else {
550  return false;
551  }
552 }
553 
555 {
556  for(std::vector<map_location>::const_iterator i = route_.steps.begin();
557  i != route_.steps.end(); ++i) {
558  invalidate(*i);
559  }
560 }
561 
563 {
565 
566  if(route != nullptr) {
567  route_ = *route;
568  } else {
569  route_.steps.clear();
570  route_.marks.clear();
571  }
572 
574 }
575 
576 void game_display::float_label(const map_location& loc, const std::string& text, const color_t& color)
577 {
578  if(prefs::get().floating_labels() == false || fogged(loc)) {
579  return;
580  }
581 
582  rect loc_rect = get_location_rect(loc);
583 
584  font::floating_label flabel(text);
586  flabel.set_color(color);
587  flabel.set_position(loc_rect.center().x, loc_rect.y); // middle of top edge
588  flabel.set_move(0, -0.1 * turbo_speed() * get_zoom_factor());
589  flabel.set_lifetime(std::chrono::milliseconds{static_cast<int>(1000 / turbo_speed())});
591 
592  font::add_floating_label(flabel);
593 }
594 
596 {
600 
603 
606  }
607 }
608 
610 {
612 }
613 
615 {
616  in_game_ = true;
617  create_buttons();
618  invalidate_all();
619 }
620 
622  if (b) {
623  needs_rebuild_ = true;
624  }
625 }
626 
628  if (needs_rebuild_) {
629  needs_rebuild_ = false;
631  invalidate_all();
632  rebuild_all();
633  return true;
634  }
635  return false;
636 }
637 
639 {
640  return overlay_map_;
641 }
642 
643 std::vector<texture> game_display::get_reachmap_images(const map_location& loc) const
644 {
645  // Use get_direction() from display.cpp namespace display_direction
646  using namespace display_direction;
647  std::vector<std::string> names;
648  const auto adjacent = get_adjacent_tiles(loc);
649 
650  enum visibility { REACH = 0, CLEAR = 1 };
651  std::array<visibility, 6> tiles;
652 
653  const std::string* image_prefix_ = &game_config::reach_map_prefix;
654  DBG_DP << "Loaded image prefix: " << game_config::reach_map_prefix;
655 
656  for(int i = 0; i < 6; ++i) {
657  if(reach_map_.find(adjacent[i]) != reach_map_.end()) {
658  DBG_DP << "Adjacent " << std::to_string(i) << " to tile " << loc << " is REACHABLE";
659  tiles[i] = REACH;
660  } else {
661  DBG_DP << "Adjacent " << std::to_string(i) << " to tile " << loc << " is NOT REACHABLE";
662  tiles[i] = CLEAR;
663  }
664  }
665 
666  // Find out if location is in the inner part of reachmap (surrounded by reach)
667  int s;
668  for(s = 0; s != 6; ++s) {
669  if(tiles[s] != REACH) {
670  break;
671  }
672  }
673 
674  if(s == 6) {
675  // Completely surrounded by reach. This may have a special graphic.
676  DBG_DP << "Tried completely surrounding";
677  std::string name = *image_prefix_ + "-all.png";
678  if(image::exists(name)) {
679  names.push_back(std::move(name));
680  }
681  }
682  else {
683  // else push the background image, as the rest of the graphics are meant to have it
684  names.push_back(*image_prefix_ + ".png");
685  }
686 
687  // Find all the directions overlap occurs from
688  for(int i = 0, cap1 = 0; cap1 != 6; ++cap1) {
689  DBG_DP << "Testing " << get_direction(i);
690  if(tiles[i] != REACH) {
691  DBG_DP << "Direction " << get_direction(i) << " points to an unreachable hex";
692  std::ostringstream stream;
693  std::string name;
694  stream << *image_prefix_;
695 
696  for(int cap2 = 0; tiles[i] != REACH && cap2 != 6; i = (i + 1) % 6, ++cap2) {
697  stream << get_direction(i);
698  if(!image::exists(stream.str() + ".png")) {
699  DBG_DP << "Image does not exist: " << stream.str() + ".png on " << loc;
700  // If we don't have any surface at all,
701  // then move onto the next overlapped area
702  if(name.empty()) {
703  i = (i + 1) % 6;
704  }
705  break;
706  } else {
707  name = stream.str();
708  }
709  }
710  DBG_DP << "Tried loading image: " << stream.str() + ".png on " << loc;
711 
712  if(!name.empty()) {
713  names.push_back(name + ".png");
714  }
715  } else {
716  i = (i + 1) % 6;
717  }
718  }
719 
720  // now get the textures
721  std::vector<texture> res;
722 
723  for(const std::string& name : names) {
724  if(texture tex = image::get_texture(name, image::HEXED)) {
725  res.push_back(std::move(tex));
726  }
727  }
728 
729  return res;
730 }
const std::vector< map_location > & route_
Definition: move.cpp:327
double t
Definition: astarsearch.cpp:63
std::vector< std::string > names
Definition: build_info.cpp:67
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
Abstract class for exposing game data that doesn't depend on the GUI, however which for historical re...
const unit * get_visible_unit(const map_location &loc, const team &current_team, bool see_all=false) const
virtual const gamemap & map() const =0
virtual const unit_map & units() const =0
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:97
const team & viewing_team() const
Definition: display.cpp:342
bool map_screenshot_
Used to indicate to drawing functions that we are doing a map screenshot.
Definition: display.hpp:883
void draw_text_in_hex(const map_location &loc, const drawing_layer layer, const std::string &text, std::size_t font_size, color_t color, double x_in_hex=0.5, double y_in_hex=0.5)
Draw text on a hex.
Definition: display.cpp:1453
std::map< map_location, std::vector< overlay > > overlay_map
Definition: display.hpp:903
map_location selectedHex_
Definition: display.hpp:782
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.cpp:1576
bool unit_can_draw_here(const map_location &loc, const unit &unit) const
Returns true if there is no exclusive draw request for loc, or if there is, that it's for unit.
Definition: display.cpp:386
virtual void render() override
Update offscreen render buffers.
Definition: display.cpp:2414
void fade_tod_mask(const std::string &old, const std::string &new_)
ToD mask smooth fade.
Definition: display.cpp:2200
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3087
double turbo_speed() const
Definition: display.cpp:2125
bool reach_map_changed_
Definition: display.hpp:900
static double get_zoom_factor()
Returns the current zoom factor.
Definition: display.hpp:270
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
Definition: display.hpp:316
void rebuild_all()
Rebuild all dynamic terrain.
Definition: display.cpp:433
virtual void layout() override
Finalize screen layout.
Definition: display.cpp:2383
virtual void highlight_hex(map_location hex)
Definition: display.cpp:1484
void update_tod(const time_of_day *tod_override=nullptr)
Applies r,g,b coloring to the map.
Definition: display.cpp:392
void process_reachmap_changes()
Definition: display.cpp:3259
void scroll_to_tile(const map_location &loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true, bool force=true)
Scroll such that location loc is on-screen.
Definition: display.cpp:1975
map_location mouseoverHex_
Definition: display.hpp:783
bool fogged(const map_location &loc) const
Returns true if location (x,y) is covered in fog.
Definition: display.cpp:674
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3080
void drawing_buffer_add(const drawing_layer layer, const map_location &loc, decltype(draw_helper::do_draw) draw_func)
Add an item to the drawing buffer.
Definition: display.cpp:1258
const display_context & context() const
Definition: display.hpp:193
rect get_location_rect(const map_location &loc) const
Returns the on-screen rect corresponding to a loc.
Definition: display.cpp:687
std::set< map_location > invalidated_
Definition: display.hpp:772
void create_buttons()
Definition: display.cpp:845
bool invalidateGameStatus_
Definition: display.hpp:753
virtual void draw_invalidated()
Only called when there's actual redrawing to do.
Definition: display.cpp:2567
reports * reports_object_
Definition: display.hpp:755
virtual void update() override
Update animations and internal state.
Definition: display.cpp:2366
virtual void draw_hex(const map_location &loc)
Redraws a single gamemap location.
Definition: display.cpp:2603
const std::unique_ptr< fake_unit_manager > fake_unit_man_
Definition: display.hpp:746
const display_context * dc_
Definition: display.hpp:684
bool shrouded(const map_location &loc) const
Returns true if location (x,y) is covered in shroud.
Definition: display.cpp:669
bool dont_show_all_
Definition: display.hpp:728
void refresh_report(const std::string &report_name, const config *new_cfg=nullptr)
Update the given report.
Definition: display.cpp:2836
std::weak_ptr< wb::manager > wb_
Definition: display.hpp:686
virtual void select_hex(map_location hex)
Definition: display.cpp:1476
reach_map reach_map_
Definition: display.hpp:898
void set_move(double xmove, double ymove)
void set_position(double xpos, double ypos)
void set_lifetime(const std::chrono::milliseconds &lifetime, const std::chrono::milliseconds &fadeout=std::chrono::milliseconds{100})
void set_color(const color_t &color)
void set_scroll_mode(LABEL_SCROLL_MODE scroll)
void set_font_size(int font_size)
Game board class.
Definition: game_board.hpp:47
unit_map::iterator find_visible_unit(const map_location &loc, const team &current_team, bool see_all=false)
Definition: game_board.cpp:185
virtual void draw_invalidated() override
Only called when there's actual redrawing to do.
void draw_movement_info(const map_location &loc)
Draws the movement info (turns available) for a given location.
void display_unit_hex(map_location hex)
Change the unit to be displayed in the sidebar.
void invalidate_unit_after_move(const map_location &src, const map_location &dst)
Same as invalidate_unit() if moving the displayed unit.
std::string attack_indicator_direction() const
Function to get attack direction suffix.
game_mode mode_
virtual void highlight_hex(map_location hex) override
Function to highlight a location.
map_location displayedUnitHex_
void invalidate_route()
std::vector< texture > get_reachmap_images(const map_location &loc) const
void scroll_to_leader(int side, SCROLL_TYPE scroll_type=ONSCREEN, bool force=true)
Scrolls to the leader of a certain side.
void set_game_mode(const game_mode mode)
virtual void draw_hex(const map_location &loc) override
Redraws a single gamemap location.
void set_attack_indicator(const map_location &src, const map_location &dst)
Set the attack direction indicator.
const std::unique_ptr< display_chat_manager > chat_man_
pathfind::marked_route route_
virtual void render() override
TLD render() override.
void set_route(const pathfind::marked_route *route)
Sets the route along which footsteps are drawn to show movement of a unit.
virtual overlay_map & get_overlays() override
Inherited from display.
std::set< map_location > units_that_can_reach_goal_
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
virtual void select_hex(map_location hex) override
Function to display a location as selected.
void highlight_reach(const pathfind::paths &paths_list)
Sets the paths that are currently displayed as available for the unit to move along.
void new_turn()
Update lighting settings.
void clear_attack_indicator()
virtual const time_of_day & get_time_of_day(const map_location &loc) const override
void highlight_another_reach(const pathfind::paths &paths_list, const map_location &goal=map_location::null_location())
Add more paths to highlight.
map_location attack_indicator_dst_
game_mode
Sets the linger mode for the display.
@ RUNNING
no linger overlay, show fog and shroud.
bool unhighlight_reach()
Reset highlighting of paths.
void needs_rebuild(bool b)
Sets whether the screen (map visuals) needs to be rebuilt.
overlay_map overlay_map_
bool maybe_rebuild()
Rebuilds the screen if needs_rebuild(true) was previously called, and resets the flag.
virtual void layout() override
TLD layout() override.
virtual bool has_time_area() const override
game_display(game_board &board, std::weak_ptr< wb::manager > wb, reports &reports_object, const std::string &theme_id, const config &level)
virtual void update() override
TLD update() override.
map_location attack_indicator_src_
void float_label(const map_location &loc, const std::string &text, const color_t &color)
Function to float a label above a tile.
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:302
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:385
Generic locator abstracting the location of an image.
Definition: picture.hpp:59
static const int UNREACHABLE
Magic value that signifies a hex is unreachable.
Definition: movetype.hpp:174
static prefs & get()
const std::set< std::string > & report_list()
Definition: reports.cpp:1842
static bool is_synced()
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
bool has_time_area() const
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
Definition: tod_manager.hpp:56
const time_of_day & get_previous_time_of_day() const
void redraw_unit(const unit &u) const
draw a unit.
Definition: drawer.cpp:164
unit_iterator end()
Definition: map.hpp:428
unit_iterator find(std::size_t id)
Definition: map.cpp:302
unit_iterator find_leader(int side)
Definition: map.cpp:320
This class represents a single unit of a specific type.
Definition: unit.hpp:133
Drawing functions, for drawing things on the screen.
drawing_layer
@ linger_overlay
The overlay used for the linger mode.
@ footsteps
Footsteps showing path from unit to mouse.
@ attack_indicator
Layer which holds the attack indicator.
@ mouseover_top
Top half of image following the mouse.
@ mouseover_bottom
Bottom half of image following the mouse.
@ move_info
Movement info (defense%, etc...)
@ fog_shroud
Fog and shroud.
@ selected_hex
Image on the selected unit.
std::size_t i
Definition: function.cpp:1028
int w
static lg::log_domain log_engine("engine")
std::vector< texture > footsteps_images(const map_location &loc, const pathfind::marked_route &route_, const display_context *dc_)
Function to return 2 half-hex footsteps images for the given location.
static lg::log_domain log_display("display")
#define DBG_DP
int side() const
The side this unit belongs to.
Definition: unit.hpp:343
T end(const std::pair< T, T > &p)
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.cpp:479
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.cpp:507
Standard logging facilities (interface).
bool is_shrouded(const display *disp, const map_location &loc)
Our definition of map labels being obscured is if the tile is obscured, or the tile below is obscured...
Definition: label.cpp:32
CURSOR_TYPE get()
Definition: cursor.cpp:216
@ WAIT
Definition: cursor.hpp:28
const std::string & get_direction(std::size_t n)
Definition: display.cpp:837
void blit(const texture &tex, const SDL_Rect &dst)
Draws a texture, or part of a texture, at the given location.
Definition: draw.cpp:310
const int SIZE_FLOAT_LABEL
Definition: constants.cpp:32
const color_t YELLOW_COLOR
int add_floating_label(const floating_label &flabel)
add a label floating on the screen above everything else.
const color_t NORMAL_COLOR
@ ANCHOR_LABEL_MAP
std::string selected
std::string foot_teleport_enter
std::vector< std::string > foot_speed_prefix
std::string foot_teleport_exit
std::string reach_map_prefix
Definition: game_config.cpp:58
color_t red_to_green(double val, bool for_text)
Return a color corresponding to the value val red for val=0.0 to green for val=100....
Functions to load and save images from/to disk.
bool exists(const image::locator &i_locator)
Returns true if the given image actually exists, without loading it.
Definition: picture.cpp:818
@ HEXED
Standard hexagonal tile mask applied, removing portions that don't fit.
Definition: picture.hpp:166
@ TOD_COLORED
Same as HEXED, but with Time of Day color tint applied.
Definition: picture.hpp:168
texture get_texture(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image texture suitable for hardware-accelerated rendering.
Definition: picture.cpp:920
Unit and team statistics.
::tod_manager * tod_manager
Definition: resources.cpp:29
game_board * gameboard
Definition: resources.cpp:20
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
Definition: general.hpp:80
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
Definition: display.hpp:45
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
Encapsulates the map of the game.
Definition: location.hpp:45
bool valid() const
Definition: location.hpp:110
direction
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:47
static const map_location & null_location()
Definition: location.hpp:102
Structure which holds a single route and marks for special events.
Definition: pathfind.hpp:142
std::vector< map_location > & steps
Definition: pathfind.hpp:187
std::vector< map_location > get_path(const const_iterator &) const
Returns the path going from the source point (included) to the destination point j (excluded).
Definition: pathfind.cpp:497
bool contains(const map_location &) const
Definition: pathfind.cpp:514
const_iterator find(const map_location &) const
Definition: pathfind.cpp:478
map_location curr
Definition: pathfind.hpp:89
Object which contains all the possible locations a unit can move to, with associated best routes to t...
Definition: pathfind.hpp:73
dest_vect destinations
Definition: pathfind.hpp:101
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47
constexpr point center() const
The center point of the rectangle, accounting for origin.
Definition: rect.hpp:104
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:57
std::string image_mask
The image that is to be laid over all images while this time of day lasts.
Definition: time_of_day.hpp:96
bool valid() const
Definition: map.hpp:273
Applies the planned unit map for the duration of the struct's life.
Definition: manager.hpp:253
static map_location::direction s
#define h
#define b