The Battle for Wesnoth  1.19.12+dev
game_display.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
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 #include <utility>
24 
25 
26 #include "cursor.hpp"
27 #include "display_chat_manager.hpp"
28 #include "fake_unit_manager.hpp"
29 #include "floating_label.hpp"
30 #include "game_board.hpp"
32 #include "log.hpp"
33 #include "map/map.hpp"
34 #include "font/standard_colors.hpp"
35 #include "reports.hpp"
36 #include "resources.hpp"
37 #include "tod_manager.hpp"
38 #include "color.hpp"
39 #include "synced_context.hpp"
40 #include "units/unit.hpp"
41 #include "units/drawer.hpp"
42 #include "utils/general.hpp"
43 #include "whiteboard/manager.hpp"
44 #include "overlay.hpp"
45 #include "draw.hpp"
46 
47 static lg::log_domain log_display("display");
48 #define ERR_DP LOG_STREAM(err, log_display)
49 #define LOG_DP LOG_STREAM(info, log_display)
50 #define DBG_DP LOG_STREAM(debug, log_display)
51 
52 static lg::log_domain log_engine("engine");
53 #define ERR_NG LOG_STREAM(err, log_engine)
54 
55 
57  std::weak_ptr<wb::manager> wb,
58  reports& reports_object,
59  const std::string& theme_id,
60  const config& level)
61  : display(&board, std::move(wb), reports_object, theme_id, level)
62  , overlay_map_()
63  , attack_indicator_src_()
64  , attack_indicator_dst_()
65  , route_()
66  , displayedUnitHex_()
67  , first_turn_(true)
68  , in_game_(false)
69  , chat_man_(new display_chat_manager(*this))
70  , mode_(RUNNING)
71  , needs_rebuild_(false)
72 {
73 }
74 
76 {
77  try {
78  chat_man_->prune_chat_messages(true);
79  } catch(...) {
80  DBG_DP << "Caught exception in game_display destructor: " << utils::get_unknown_exception_type();
81  }
82 }
83 
85 {
86  if(!first_turn_) {
89 
90  if(old_tod.image_mask != tod.image_mask) {
91  fade_tod_mask(old_tod.image_mask, tod.image_mask);
92  }
93  }
94 
95  first_turn_ = false;
96 
97  update_tod();
98 }
99 
101 {
102  if(hex.valid() && fogged(hex)) {
103  return;
104  }
105  display::select_hex(hex);
106 
107  display_unit_hex(hex);
108 }
109 
111 {
112  wb::future_map_if future(!synced_context::is_synced()); /**< Lasts for whole method. */
113 
115  if (u) {
116  displayedUnitHex_ = hex;
117  invalidate_unit();
118  } else {
120  if (u) {
121  // mouse moved from unit hex to non-unit hex
122  if (context().units().count(selectedHex_)) {
124  invalidate_unit();
125  }
126  }
127  }
128 
131 }
132 
133 
135 {
136  if (!hex.valid())
137  return;
138 
139  wb::future_map_if future(!synced_context::is_synced()); /**< Lasts for whole method. */
140 
142  if (u) {
143  displayedUnitHex_ = hex;
144  invalidate_unit();
145  }
146 }
147 
149 {
150  if (src == displayedUnitHex_) {
152  invalidate_unit();
153  }
154 }
155 
156 void game_display::scroll_to_leader(int side, SCROLL_TYPE scroll_type,bool force)
157 {
159 
160  if(leader.valid() && leader->is_visible_to_team(viewing_team(), false)) {
161  scroll_to_tile(leader->get_location(), scroll_type, true, force);
162  }
163 }
164 
166 {
167  display::update();
168 
169  if (std::shared_ptr<wb::manager> w = wb_.lock()) {
170  w->pre_draw();
171  }
173  /**
174  * @todo FIXME: must modify changed, but best to do it at the
175  * floating_label level
176  */
177  chat_man_->prune_chat_messages();
178 }
179 
180 
182 {
183  display::render();
184 
185  if (std::shared_ptr<wb::manager> w = wb_.lock()) {
186  w->post_draw();
187  }
188 }
189 
191 {
193  if (fake_unit_man_->empty()) {
194  return;
195  }
196  unit_drawer drawer = unit_drawer(*this);
197 
198  for(const unit* temp_unit : *fake_unit_man_) {
199  const map_location& loc = temp_unit->get_location();
200  if(utils::contains(invalidated_, loc) && unit_can_draw_here(loc, *temp_unit)) {
201  drawer.redraw_unit(*temp_unit);
202  }
203  }
204 }
205 
206 namespace
207 {
208 const image::locator mouseover_normal_top
209  {"misc/hover-hex-top.png", "~RC(magenta>gold)"};
210 const image::locator mouseover_normal_bot
211  {"misc/hover-hex-bottom.png", "~RC(magenta>gold)"};
212 
213 const image::locator mouseover_enemy_top
214  {"misc/hover-hex-enemy-top.png", "~RC(magenta>red)"};
215 const image::locator mouseover_enemy_bot
216  {"misc/hover-hex-enemy-bottom.png", "~RC(magenta>red)"};
217 
218 const image::locator mouseover_self_top
219  {"misc/hover-hex-top.png", "~RC(magenta>green)"};
220 const image::locator mouseover_self_bot
221  {"misc/hover-hex-bottom.png", "~RC(magenta>green)"};
222 
223 const image::locator mouseover_ally_top
224  {"misc/hover-hex-top.png", "~RC(magenta>lightblue)"};
225 const image::locator mouseover_ally_bot
226  {"misc/hover-hex-bottom.png", "~RC(magenta>lightblue)"};
227 
228 /**
229  * Function to return 2 half-hex footsteps images for the given location.
230  * Only loc is on the current route set by set_route.
231  */
232 std::vector<texture> footsteps_images(const map_location& loc, const pathfind::marked_route& route, const display_context* dc)
233 {
234  std::vector<texture> res;
235 
236  if (route.steps.size() < 2) {
237  return res; // no real "route"
238  }
239 
240  std::vector<map_location>::const_iterator i =
241  std::find(route.steps.begin(),route.steps.end(),loc);
242 
243  if( i == route.steps.end()) {
244  return res; // not on the route
245  }
246 
247  // Check which footsteps images of game_config we will use
248  int move_cost = 1;
249  const unit_map::const_iterator u = dc->units().find(route.steps.front());
250  if(u != dc->units().end()) {
251  move_cost = u->movement_cost(dc->map().get_terrain(loc));
252  }
253  int image_number = std::min<int>(move_cost, game_config::foot_speed_prefix.size());
254  if (image_number < 1) {
255  return res; // Invalid movement cost or no images
256  }
257  const std::string foot_speed_prefix = game_config::foot_speed_prefix[image_number-1];
258 
259  texture teleport;
260 
261  // We draw 2 half-hex (with possibly different directions),
262  // but skip the first for the first step.
263  const int first_half = (i == route.steps.begin()) ? 1 : 0;
264  // and the second for the last step
265  const int second_half = (i+1 == route.steps.end()) ? 0 : 1;
266 
267  for (int h = first_half; h <= second_half; ++h) {
268  const std::string sense( h==0 ? "-in" : "-out" );
269 
270  if (!tiles_adjacent(*(i+(h-1)), *(i+h))) {
271  std::string teleport_image =
273  teleport = image::get_texture(teleport_image, image::HEXED);
274  continue;
275  }
276 
277  // In function of the half, use the incoming or outgoing direction
278  map_location::direction dir = (i+(h-1))->get_relative_dir(*(i+h));
279 
280  std::string rotate;
282  // No image, take the opposite direction and do a 180 rotation
283  dir = i->get_opposite_direction(dir);
284  rotate = "~FL(horiz)~FL(vert)";
285  }
286 
287  const std::string image = foot_speed_prefix
288  + sense + "-" + i->write_direction(dir)
289  + ".png" + rotate;
290 
291  res.push_back(image::get_texture(image, image::HEXED));
292  }
293 
294  // we draw teleport image (if any) in last
295  if (teleport != nullptr) res.push_back(teleport);
296 
297  return res;
298 }
299 } //anonymous namespace
300 
302 {
303  const bool on_map = context().map().on_board(loc);
304  const bool is_shrouded = shrouded(loc);
305 
307 
308  if(cursor::get() == cursor::WAIT) {
309  // Interaction is disabled, so we don't need anything else
310  return;
311  }
312 
313  if(on_map && loc == mouseoverHex_ && !map_screenshot_) {
315  const unit* u = context().get_visible_unit(loc, viewing_team());
316  if(u != nullptr) {
317  hex_top_layer = drawing_layer::mouseover_top;
318  }
319 
320  const image::locator* mo_top_path;
321  const image::locator* mo_bot_path;
322 
323  if(u == nullptr) {
324  mo_top_path = &mouseover_normal_top;
325  mo_bot_path = &mouseover_normal_bot;
326  } else if(viewing_team().is_enemy(u->side())) {
327  mo_top_path = &mouseover_enemy_top;
328  mo_bot_path = &mouseover_enemy_bot;
329  } else if(viewing_team().side() == u->side()) {
330  mo_top_path = &mouseover_self_top;
331  mo_bot_path = &mouseover_self_bot;
332  } else {
333  mo_top_path = &mouseover_ally_top;
334  mo_bot_path = &mouseover_ally_bot;
335  }
336 
337  drawing_buffer_add(hex_top_layer, loc,
338  [tex = image::get_texture(*mo_top_path, image::HEXED)](const rect& dest) { draw::blit(tex, dest); });
339 
341  [tex = image::get_texture(*mo_bot_path, image::HEXED)](const rect& dest) { draw::blit(tex, dest); });
342  }
343 
344  // Draw reach_map information.
345  if(!is_shrouded && !reach_map_.empty() && reach_map_.find(loc) != reach_map_.end()) {
346  // draw the reachmap tint below units and high terrain graphics
347  std::string color = prefs::get().reach_map_color();
348  std::string tint_opacity = std::to_string(prefs::get().reach_map_tint_opacity());
349 
350  drawing_buffer_add(drawing_layer::reachmap_highlight, loc, [tex = image::get_texture(game_config::reach_map_prefix + ".png~RC(magenta>"+color+")~O("+tint_opacity+"%)", image::HEXED)](const rect& dest) {
351  draw::blit(tex, dest);
352  });
353  // We remove the reachmap border mask of the hovered hex to avoid weird interactions with other visual objects.
354  if(loc != mouseoverHex_) {
355  // draw the highlight borders on top of units and terrain
357  for(const texture& t : images) {
358  draw::blit(t, dest);
359  }
360  });
361  }
362  }
363 
364  if(std::shared_ptr<wb::manager> w = wb_.lock()) {
365  w->draw_hex(loc);
366 
367  if(!(w->is_active() && w->has_temp_move())) {
368  std::vector<texture> footstepImages = footsteps_images(loc, route_, dc_);
369  if(!footstepImages.empty()) {
370  drawing_buffer_add(drawing_layer::footsteps, loc, [images = std::move(footstepImages)](const rect& dest) {
371  for(const texture& t : images) {
372  draw::blit(t, dest);
373  }
374  });
375  }
376  }
377  }
378 
379  // Draw the attack direction indicator
380  if(on_map && loc == attack_indicator_src_) {
382  [tex = image::get_texture("misc/attack-indicator-src-" + attack_indicator_direction() + ".png", image::HEXED)](const rect& dest)
383  { draw::blit(tex, dest); }
384  );
385  } else if(on_map && loc == attack_indicator_dst_) {
387  [tex = image::get_texture("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::HEXED)](const rect& dest)
388  { draw::blit(tex, dest); }
389  );
390  }
391 
392  // Linger overlay unconditionally otherwise it might give glitches
393  // so it's drawn over the shroud and fog.
394  if(mode_ != RUNNING) {
397  [tex = image::get_texture(linger, image::TOD_COLORED)](const rect& dest) { draw::blit(tex, dest); });
398  }
399 
400  if(on_map && loc == selectedHex_ && !game_config::images::selected.empty()) {
403  [tex = image::get_texture(selected, image::HEXED)](const rect& dest) { draw::blit(tex, dest); });
404  }
405 
406  // Show def% and turn to reach info
407  if(!is_shrouded && on_map) {
409  }
410 }
411 
413 {
415 }
416 
418 {
420 }
421 
423 {
424  display::layout();
425 
426  // We need teams for the reports below
427  if(context().teams().empty()) {
428  return;
429  }
430 
431  refresh_report("report_clock");
432  refresh_report("report_battery");
433  refresh_report("report_countdown");
434 
436  {
437  wb::future_map future; // start planned unit map scope
438 
439  // We display the unit the mouse is over if it is over a unit,
440  // otherwise we display the unit that is selected.
441  for (const std::string &name : reports_object_->report_list()) {
442  refresh_report(name);
443  }
444  invalidateGameStatus_ = false;
445  }
446 }
447 
448 
450 {
451  if(mode != mode_) {
452  mode_ = mode;
453  invalidate_all();
454  }
455 }
456 
458 {
459  // Search if there is a mark here
461 
462  std::shared_ptr<wb::manager> wb = wb_.lock();
463 
464  // Don't use empty route or the first step (the unit will be there)
465  if(w != route_.marks.end()
466  && !route_.steps.empty() && route_.steps.front() != loc) {
467  const unit_map::const_iterator un =
468  (wb && wb->get_temp_move_unit().valid()) ?
469  wb->get_temp_move_unit() : context().units().find(route_.steps.front());
470  if(un != context().units().end()) {
471  // Display the def% of this terrain
472  int move_cost = un->movement_cost(context().map().get_terrain(loc));
473  int def = (move_cost == movetype::UNREACHABLE ?
474  0 : 100 - un->defense_modifier(context().map().get_terrain(loc)));
475  std::stringstream def_text;
476  def_text << def << "%";
477 
478  color_t color = game_config::red_to_green(def, false);
479 
480  // simple mark (no turn point) use smaller font
481  int def_font = w->second.turns > 0 ? 18 : 16;
482  draw_text_in_hex(loc, drawing_layer::move_info, def_text.str(), def_font, color);
483 
485  [inv = w->second.invisible, zoc = w->second.zoc, cap = w->second.capture](const rect& dest) {
486  if(inv) {
487  draw::blit(image::get_texture(image::locator{"misc/hidden.png"}, image::HEXED), dest);
488  }
489 
490  if(zoc) {
491  draw::blit(image::get_texture(image::locator{"misc/zoc.png"}, image::HEXED), dest);
492  }
493 
494  if(cap) {
495  draw::blit(image::get_texture(image::locator{"misc/capture.png"}, image::HEXED), dest);
496  }
497  });
498 
499  //we display turn info only if different from a simple last "1"
500  if (w->second.turns > 1 || (w->second.turns == 1 && loc != route_.steps.back())) {
501  std::stringstream turns_text;
502  turns_text << w->second.turns;
503  draw_text_in_hex(loc, drawing_layer::move_info, turns_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
504  }
505 
506  // The hex is full now, so skip the "show enemy moves"
507  return;
508  }
509  }
510  // When out-of-turn, it's still interesting to check out the terrain defs of the selected unit
511  else if (selectedHex_.valid() && loc == mouseoverHex_)
512  {
513  const unit_map::const_iterator selectedUnit = resources::gameboard->find_visible_unit(selectedHex_,viewing_team());
514  const unit_map::const_iterator mouseoveredUnit = resources::gameboard->find_visible_unit(mouseoverHex_,viewing_team());
515  if(selectedUnit != context().units().end() && mouseoveredUnit == context().units().end()) {
516  // Display the def% of this terrain
517  int move_cost = selectedUnit->movement_cost(context().map().get_terrain(loc));
518  int def = (move_cost == movetype::UNREACHABLE ?
519  0 : 100 - selectedUnit->defense_modifier(context().map().get_terrain(loc)));
520  std::stringstream def_text;
521  def_text << def << "%";
522 
523  color_t color = game_config::red_to_green(def, false);
524 
525  // use small font
526  int def_font = 16;
527  draw_text_in_hex(loc, drawing_layer::move_info, def_text.str(), def_font, color);
528  }
529  }
530 
531  if (!reach_map_.empty()) {
532  reach_map::iterator reach = reach_map_.find(loc);
533  if (reach != reach_map_.end() && reach->second > 1) {
534  const std::string num = std::to_string(reach->second);
535  draw_text_in_hex(loc, drawing_layer::move_info, num, 16, font::YELLOW_COLOR);
536  }
537  }
538 }
539 
541 {
543  highlight_another_reach(paths_list);
544 }
545 
547  const map_location& goal)
548 {
549  // Fold endpoints of routes into reachability map.
550  for (const pathfind::paths::step &dest : paths_list.destinations) {
551  reach_map_[dest.curr]++;
552  }
553  reach_map_changed_ = true;
554 
555  if(goal != map_location::null_location() && paths_list.destinations.contains(goal)) {
556  const auto& path_to_goal = paths_list.destinations.get_path(paths_list.destinations.find(goal));
557  const map_location enemy_unit_location = path_to_goal[0];
558  units_that_can_reach_goal_.insert(enemy_unit_location);
559  }
560 }
561 
563 {
565  if(!reach_map_.empty()) {
566  reach_map_.clear();
567  reach_map_changed_ = true;
568  return true;
569  } else {
570  return false;
571  }
572 }
573 
575 {
576  for(std::vector<map_location>::const_iterator i = route_.steps.begin();
577  i != route_.steps.end(); ++i) {
578  invalidate(*i);
579  }
580 }
581 
583 {
585 
586  if(route != nullptr) {
587  route_ = *route;
588  } else {
589  route_.steps.clear();
590  route_.marks.clear();
591  }
592 
594 }
595 
596 void game_display::float_label(const map_location& loc, const std::string& text, const color_t& color)
597 {
598  if(prefs::get().floating_labels() == false || fogged(loc)) {
599  return;
600  }
601 
602  rect loc_rect = get_location_rect(loc);
603 
604  font::floating_label flabel(text);
606  flabel.set_color(color);
607  flabel.set_position(loc_rect.center().x, loc_rect.y); // middle of top edge
608  flabel.set_move(0, -0.1 * turbo_speed() * get_zoom_factor());
609  flabel.set_lifetime(std::chrono::milliseconds{static_cast<int>(1000 / turbo_speed())});
611 
612  font::add_floating_label(flabel);
613 }
614 
616 {
620 
623 
626  }
627 }
628 
630 {
632 }
633 
635 {
636  in_game_ = true;
637  create_buttons();
638  invalidate_all();
639 }
640 
642  if (b) {
643  needs_rebuild_ = true;
644  }
645 }
646 
648  if (needs_rebuild_) {
649  needs_rebuild_ = false;
651  invalidate_all();
652  rebuild_all();
653  return true;
654  }
655  return false;
656 }
657 
659 {
660  return overlay_map_;
661 }
662 
663 std::vector<texture> game_display::get_reachmap_images(const map_location& loc) const
664 {
665  std::vector<std::string> names;
666  const auto adjacent = get_adjacent_tiles(loc);
667 
668  enum visibility { REACH = 0, ENEMY = 1, CLEAR = 2 };
669  std::array<visibility, 6> tiles;
670 
671  for(int i = 0; i < 6; ++i) {
672  // look for units adjacent to loc
673  std::string test_location = std::to_string(adjacent[i].x) + "," + std::to_string(adjacent[i].y);
674  const unit *u = context().get_visible_unit(adjacent[i], viewing_team());
675  if(reach_map_.find(adjacent[i]) != reach_map_.end()) {
676  DBG_DP << test_location << " is REACHABLE";
677  tiles[i] = REACH;
678  }
679  /**
680  * Make sure there is a unit selected or displayed when drawing the reachmap with enemy detection.
681  * Enemy detection needs to be "disabled" when the reach_map_team_index_ failsafes to viewing_team_index.
682  */
684  DBG_DP << test_location << " is NOT REACHABLE";
685  tiles[i] = CLEAR;
686  }
687  // Grab the reachmap-context team index updated in "display::process_reachmap_changes()" and test for adjacent enemy units
688  else if(u != nullptr && resources::gameboard->get_team(display::reach_map_team_index_).is_enemy(u->side())) {
689  DBG_DP << test_location << " has an ENEMY";
690  tiles[i] = ENEMY;
691  } else {
692  DBG_DP << test_location << " is NOT REACHABLE";
693  tiles[i] = CLEAR;
694  }
695  }
696 
697  // Find out if location is in the inner part of reachmap (surrounded by reach)
698  int s;
699  for(s = 0; s != 6; ++s) {
700  if(tiles[s] != REACH) {
701  break;
702  }
703  }
704 
705  if(s == 6) {
706  // Completely surrounded by reach. This may have a special graphic.
707  DBG_DP << "Tried completely surrounding";
708  std::string name = game_config::reach_map_prefix + "-all.png";
709  if(image::exists(name)) {
710  names.push_back(std::move(name));
711  }
712  }
713 
714  // Find all the directions overlap occurs from
715  for(int i = 0, cap1 = 0; cap1 != 6; ++cap1) {
716  if(tiles[i] != REACH) {
717  std::ostringstream stream;
718  std::string suffix;
719  std::string name;
721 
722  std::string color = prefs::get().reach_map_color();
723  std::string enemy_color = prefs::get().reach_map_enemy_color();
724  std::string border_opacity = std::to_string(prefs::get().reach_map_border_opacity());
725 
726  if(tiles[i] == ENEMY) {
727  suffix = ".png~RC(magenta>"+enemy_color+")~O("+border_opacity+"%)";
728  } else {
729  suffix = ".png~RC(magenta>"+color+")~O("+border_opacity+"%)";
730  }
731 
732  for(int cap2 = 0; tiles[i] != REACH && cap2 != 6; i = (i + 1) % 6, ++cap2) {
734  if(!image::exists(stream.str() + ".png")) {
735  DBG_DP << "Image does not exist: " << stream.str() + ".png on " << loc;
736  // If we don't have any surface at all,
737  // then move onto the next overlapped area
738  if(name.empty()) {
739  i = (i + 1) % 6;
740  }
741  break;
742  } else {
743  name = stream.str();
744  }
745  }
746 
747  if(!name.empty()) {
748  names.push_back(name + suffix);
749  }
750  } else {
751  i = (i + 1) % 6;
752  }
753  }
754 
755  // now get the textures
756  std::vector<texture> res;
757 
758  for(const std::string& name : names) {
759  DBG_DP << "Pushing: " << name;
760  if(texture tex = image::get_texture(name, image::HEXED)) {
761  res.push_back(std::move(tex));
762  }
763  }
764 
765  return res;
766 }
map_location loc
Definition: move.cpp:172
const std::vector< map_location > & route_
Definition: move.cpp:386
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:158
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:88
const team & viewing_team() const
Definition: display.cpp:335
bool map_screenshot_
Used to indicate to drawing functions that we are doing a map screenshot.
Definition: display.hpp:863
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:1354
std::size_t viewing_team_index_
Definition: display.hpp:714
std::map< map_location, std::vector< overlay > > overlay_map
Definition: display.hpp:885
map_location selectedHex_
Definition: display.hpp:762
void recalculate_minimap()
Schedule the minimap for recalculation.
Definition: display.cpp:1461
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:379
virtual void render() override
Update offscreen render buffers.
Definition: display.cpp:2290
void fade_tod_mask(const std::string &old, const std::string &new_)
ToD mask smooth fade.
Definition: display.cpp:2085
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:2966
double turbo_speed() const
Definition: display.cpp:2010
bool reach_map_changed_
Definition: display.hpp:880
static double get_zoom_factor()
Returns the current zoom factor.
Definition: display.hpp:261
void invalidate_game_status()
Function to invalidate the game status displayed on the sidebar.
Definition: display.hpp:307
void rebuild_all()
Rebuild all dynamic terrain.
Definition: display.cpp:426
virtual void layout() override
Finalize screen layout.
Definition: display.cpp:2259
virtual void highlight_hex(map_location hex)
Definition: display.cpp:1385
void update_tod(const time_of_day *tod_override=nullptr)
Applies r,g,b coloring to the map.
Definition: display.cpp:385
void process_reachmap_changes()
Definition: display.cpp:3138
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:1860
map_location mouseoverHex_
Definition: display.hpp:763
bool fogged(const map_location &loc) const
Returns true if location (x,y) is covered in fog.
Definition: display.cpp:667
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:2959
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:1237
std::size_t reach_map_team_index_
Definition: display.hpp:882
const display_context & context() const
Definition: display.hpp:184
rect get_location_rect(const map_location &loc) const
Returns the on-screen rect corresponding to a loc.
Definition: display.cpp:680
std::set< map_location > invalidated_
Definition: display.hpp:752
void create_buttons()
Definition: display.cpp:826
bool invalidateGameStatus_
Definition: display.hpp:740
virtual void draw_invalidated()
Only called when there's actual redrawing to do.
Definition: display.cpp:2446
reports * reports_object_
Definition: display.hpp:742
virtual void update() override
Update animations and internal state.
Definition: display.cpp:2242
virtual void draw_hex(const map_location &loc)
Redraws a single gamemap location.
Definition: display.cpp:2482
const std::unique_ptr< fake_unit_manager > fake_unit_man_
Definition: display.hpp:733
const display_context * dc_
Definition: display.hpp:671
bool shrouded(const map_location &loc) const
Returns true if location (x,y) is covered in shroud.
Definition: display.cpp:662
bool dont_show_all_
Definition: display.hpp:715
void refresh_report(const std::string &report_name, const config *new_cfg=nullptr)
Update the given report.
Definition: display.cpp:2715
std::weak_ptr< wb::manager > wb_
Definition: display.hpp:673
virtual void select_hex(map_location hex)
Definition: display.cpp:1377
reach_map reach_map_
Definition: display.hpp:878
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:301
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:384
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()
std::string reach_map_color()
std::string reach_map_enemy_color()
const std::set< std::string > & report_list()
Definition: reports.cpp:1843
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:202
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.
@ reachmap_highlight
Overlay on reachable hexes.
@ footsteps
Footsteps showing path from unit to mouse.
@ attack_indicator
Layer which holds the attack indicator.
@ reachmap_border
Overlay border of reachable hexes.
@ mouseover_top
Top half of image following the mouse.
@ mouseover_bottom
Bottom half of image following the mouse.
@ move_info
Movement info (defense%, etc...)
@ selected_hex
Image on the selected unit.
std::size_t i
Definition: function.cpp:1030
int w
static lg::log_domain log_engine("engine")
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:512
bool tiles_adjacent(const map_location &a, const map_location &b)
Function which tells if two locations are adjacent.
Definition: location.cpp:540
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:218
@ WAIT
Definition: cursor.hpp:28
void blit(const texture &tex, const SDL_Rect &dst)
Draws a texture, or part of a texture, at the given location.
Definition: draw.cpp:380
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
int reach_map_border_opacity
std::string reach_map_prefix
Definition: game_config.cpp:58
int reach_map_tint_opacity
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:840
@ HEXED
Standard hexagonal tile mask applied, removing portions that don't fit.
Definition: picture.hpp:175
@ TOD_COLORED
Same as HEXED, but with Time of Day color tint applied.
Definition: picture.hpp:177
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:942
Unit and team statistics.
::tod_manager * tod_manager
Definition: resources.cpp:29
game_board * gameboard
Definition: resources.cpp:20
std::size_t size(std::string_view 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:86
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
auto * find(Container &container, const Value &value)
Convenience wrapper for using find on a container without needing to comare to end()
Definition: general.hpp:140
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:61
Encapsulates the map of the game.
Definition: location.hpp:45
static std::string write_direction(direction dir)
Definition: location.cpp:154
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:49
constexpr point center() const
The center point of the rectangle, accounting for origin.
Definition: rect.hpp:106
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