The Battle for Wesnoth  1.19.3+dev
drawer.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2024
3  by Chris Beck <render787@gmail.com>
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 #include "units/drawer.hpp"
17 
18 #include "color.hpp"
19 #include "display.hpp"
20 #include "display_context.hpp"
21 #include "draw.hpp"
22 #include "formatter.hpp"
23 #include "game_display.hpp"
24 #include "halo.hpp"
25 #include "log.hpp"
26 #include "map/location.hpp"
27 #include "map/map.hpp"
28 #include "picture.hpp"
30 #include "team.hpp"
31 #include "units/animation.hpp"
33 #include "units/frame.hpp"
34 #include "units/types.hpp"
35 #include "units/unit.hpp"
36 
37 static lg::log_domain log_display("display");
38 #define LOG_DP LOG_STREAM(info, log_display)
39 
40 namespace
41 {
42 /**
43  * Wrapper which will assemble the image path (including IPF for the color from get_orb_color) for a given orb.
44  * Returns nullptr if the preferences have been configured to hide this orb.
45  */
46 std::unique_ptr<image::locator> get_orb_image(orb_status os)
47 {
48  if(os == orb_status::disengaged) {
52  return std::make_unique<image::locator>(game_config::images::orb_two_color + "~RC(ellipse_red>"
53  + moved_color + ")~RC(magenta>" + partial_color + ")");
54  }
56  }
57 
59  return nullptr;
60  auto color = orb_status_helper::get_orb_color(os);
61  return std::make_unique<image::locator>(game_config::images::orb + "~RC(magenta>" + color + ")");
62 }
63 
64 /**
65  * Assemble a two-color orb for an ally's unit, during that ally's turn.
66  * Returns nullptr if the preferences both of these orbs and ally orbs in general are off.
67  * Returns a one-color orb (using the ally color) in several circumstances.
68  */
69 std::unique_ptr<image::locator> get_playing_ally_orb_image(orb_status os)
70 {
72  return get_orb_image(orb_status::allied);
73 
74  // This is conditional on prefs_show_orb, because a user might want to disable the standard
75  // partial orb, but keep it enabled as a reminder for units in the disengaged state.
78  }
79 
81  return get_orb_image(orb_status::allied);
82 
84  auto status_color = orb_status_helper::get_orb_color(os);
85  return std::make_unique<image::locator>(game_config::images::orb_two_color + "~RC(ellipse_red>"
86  + allied_color + ")~RC(magenta>" + status_color + ")");
87 }
88 
89 void draw_bar(int xpos, int ypos, int bar_height, double filled, const color_t& col)
90 {
91  // Magic width number
92  static constexpr unsigned int bar_width = 4;
93 
94  static constexpr color_t bar_color_bg{0, 0, 0, 80};
95  static constexpr color_t bar_color_border{213, 213, 213, 200};
96 
97  // We used to use an image for the bar instead of drawing it procedurally. Its x,y position
98  // within the file was 19,13, so we offset the origin by that much to make it line up with
99  // the crowns as before. Should probably compensate for this better in the future.
100  const point offset = display::scaled_to_zoom(point{19, 13});
101 
102  // Full bar dimensions.
103  rect bar_rect = display::scaled_to_zoom({
104  xpos + offset.x,
105  ypos + offset.y,
106  bar_width,
107  bar_height
108  });
109 
110  // Bar dimensions should not overflow 80% of the scaled hex dimensions.
111  // The 80% comes from an approximation of the length of a segment drawn
112  // inside a regular hexagon that runs parallel to its outer left side.
113  bar_rect.w = std::clamp<int>(bar_rect.w, 0, display::hex_size() * 0.80 - offset.x);
114  bar_rect.h = std::clamp<int>(bar_rect.h, 0, display::hex_size() * 0.80 - offset.y);
115 
116  filled = std::clamp<double>(filled, 0.0, 1.0);
117  const int unfilled = static_cast<std::size_t>(bar_rect.h * (1.0 - filled));
118 
119  // Filled area dimensions.
120  const rect fill_rect {
121  bar_rect.x,
122  bar_rect.y + unfilled,
123  bar_rect.w,
124  bar_rect.h - unfilled
125  };
126 
127  // Tinted background.
128  draw::fill(bar_rect, bar_color_bg);
129 
130  // Filled area.
131  draw::fill(fill_rect, col);
132 
133  // Bar outline.
134  draw::rect(bar_rect, bar_color_border);
135 }
136 }
137 
139  : disp(thedisp)
140  , dc(disp.get_disp_context())
141  , map(dc.map())
142  , halo_man(thedisp.get_halo_manager())
143  , viewing_team_ref(disp.viewing_team())
144  , playing_team_ref(disp.playing_team())
145  , is_blindfolded(disp.is_blindfolded())
146  , show_everything(disp.show_everything())
147  , sel_hex(disp.selected_hex())
148  , mouse_hex(disp.mouseover_hex())
149  , zoom_factor(disp.get_zoom_factor())
150  , hex_size(disp.hex_size())
151  , hex_size_by_2(disp.hex_size() / 2)
152 {
153  if(const game_display* game_display = dynamic_cast<class game_display*>(&disp)) {
155  }
156 }
157 
159 {
160  const bool is_highlighted_enemy = units_that_can_reach_goal.count(loc) > 0;
161  return loc == sel_hex || is_highlighted_enemy;
162 }
163 
164 void unit_drawer::redraw_unit(const unit& u) const
165 {
167  map_location loc = u.get_location();
168 
169  int side = u.side();
170 
171  bool hidden = u.get_hidden();
172  bool is_flying = u.is_flying();
173  map_location::DIRECTION facing = u.facing();
174  int hitpoints = u.hitpoints();
175  int max_hitpoints = u.max_hitpoints();
176 
177  bool can_recruit = u.can_recruit();
178  bool can_advance = u.can_advance();
179 
180  int experience = u.experience();
181  int max_experience = u.max_experience();
182 
183  color_t hp_color=u.hp_color();
184  color_t xp_color=u.xp_color();
185 
186  const bool is_selected_hex = selected_or_reachable(loc);
187 
188  // Override the filled area's color's alpha.
189  hp_color.a = (loc == mouse_hex || is_selected_hex) ? 255u : float_to_color(0.8);
190  xp_color.a = hp_color.a;
191 
193  ac.clear_haloes();
194  if(ac.anim_) {
195  ac.anim_->update_last_draw_time();
196  }
197  return;
198  }
199 
200  if (!ac.anim_) {
201  ac.set_standing();
202  if (!ac.anim_) return;
203  }
204 
205  if (ac.refreshing_) return;
206  ac.refreshing_ = true;
207 
208  ac.anim_->update_last_draw_time();
209  frame_parameters params;
210  const t_translation::terrain_code terrain = map.get_terrain(loc);
211  const terrain_type& terrain_info = map.get_terrain_info(terrain);
212 
213  // do not set to 0 so we can distinguish the flying from the "not on submerge terrain"
214  // instead use -1.0 (as in "negative depth", it will be ignored by rendering)
215  params.submerge= is_flying ? -1.0 : terrain_info.unit_submerge();
216 
217  if(u.invisible(loc) && params.highlight_ratio > 0.6) {
218  params.highlight_ratio = 0.6;
219  }
220  if (is_selected_hex && params.highlight_ratio == 1.0) {
221  params.highlight_ratio = 1.5;
222  }
223 
224  int height_adjust = static_cast<int>(terrain_info.unit_height_adjust() * zoom_factor);
225  if (is_flying && height_adjust < 0) {
226  height_adjust = 0;
227  }
228  params.y -= height_adjust;
229  params.halo_y -= height_adjust;
230 
231  int red = 0,green = 0,blue = 0,tints = 0;
232  double blend_ratio = 0;
233  // Add future colored states here
234  if(u.poisoned()) {
235  green += 255;
236  blend_ratio += 0.25;
237  tints += 1;
238  }
239  if(u.slowed()) {
240  red += 191;
241  green += 191;
242  blue += 255;
243  blend_ratio += 0.25;
244  tints += 1;
245  }
246  if(tints > 0) {
247  params.blend_with = color_t((red/tints),(green/tints),(blue/tints));
248  params.blend_ratio = ((blend_ratio/tints));
249  }
250 
251  //hackish : see unit_frame::merge_parameters
252  // we use image_mod on the primary image
253  // and halo_mod on secondary images and all haloes
254  params.image_mod = u.image_mods();
255  params.halo_mod = u.TC_image_mods();
256  params.image= u.default_anim_image();
257 
258 
259  if(u.incapacitated()) params.image_mod +="~GS()";
260  params.primary_frame = true;
261 
262 
263  const frame_parameters adjusted_params = ac.anim_->get_current_params(params);
264 
265  const map_location dst = loc.get_direction(facing);
266  const auto [xsrc, ysrc] = disp.get_location(loc);
267  const auto [xdst, ydst] = disp.get_location(dst);
268 
269  // We draw bars only if wanted, visible on the map view
270  bool draw_bars = ac.draw_bars_ ;
271  if (draw_bars) {
272  rect unit_rect {xsrc, ysrc +adjusted_params.y, hex_size, hex_size};
273  draw_bars = unit_rect.overlaps(disp.map_outside_area());
274  }
275 
276  // Always show the ellipse for selected units
277  if(draw_bars && (prefs::get().show_side_colors() || is_selected_hex)) {
278  draw_ellipses(u, adjusted_params);
279  }
280 
281  if(draw_bars) {
282  const auto& type_cfg = u.type().get_cfg();
283  const auto& cfg_offset_x = type_cfg["bar_offset_x"];
284  const auto& cfg_offset_y = type_cfg["bar_offset_y"];
285  int xoff;
286  int yoff;
287  if(cfg_offset_x.empty() && cfg_offset_y.empty()) {
290  );
291  xoff = !s.x ? 0 : (hex_size - s.x)/2;
292  yoff = !s.y ? 0 : (hex_size - s.x)/2;
293  }
294  else {
295  xoff = cfg_offset_x.to_int();
296  yoff = cfg_offset_y.to_int();
297  }
298 
299  using namespace orb_status_helper;
300  std::unique_ptr<image::locator> orb_img = nullptr;
301 
302  if(viewing_team_ref.is_enemy(side)) {
303  if(!u.incapacitated())
304  orb_img = get_orb_image(orb_status::enemy);
305  } else if(side != playing_team_ref.side()) {
306  // We're looking at either the player's own unit or an ally's unit, but either way it
307  // doesn't belong to the playing_team and isn't expected to move until after its next
308  // turn refresh.
309  auto os = orb_status::moved;
310  if(side != viewing_team_ref.side())
311  os = orb_status::allied;
312  orb_img = get_orb_image(os);
313  } else if(side != viewing_team_ref.side()) {
314  // We're looking at an ally's unit, during that ally's turn.
315  auto os = dc.unit_orb_status(u);
316  orb_img = get_playing_ally_orb_image(os);
317  } else {
318  // We're looking at the player's own unit, during the player's turn.
319  auto os = dc.unit_orb_status(u);
320  orb_img = get_orb_image(os);
321  }
322 
323  // All the various overlay textures to draw with the HP/XP bars
324  std::vector<texture> textures;
325 
326  if(orb_img != nullptr) {
327  textures.push_back(image::get_texture(*orb_img));
328  }
329 
330  if(can_recruit) {
331  if(texture tex = image::get_texture(u.leader_crown())) {
332  textures.push_back(std::move(tex));
333  }
334  }
335 
336  for(const std::string& ov : u.overlays()) {
337  if(texture tex = image::get_texture(ov)) {
338  textures.push_back(std::move(tex));
339  }
340  };
341 
342  const std::vector<std::string> overlays_abilities = u.overlays_abilities();
343  for(const std::string& ov : overlays_abilities) {
344  if(texture tex = image::get_texture(ov)) {
345  textures.push_back(std::move(tex));
346  }
347  };
348 
350  textures = std::move(textures),
351  adj_y = adjusted_params.y,
352  //origin = point{xsrc + xoff, ysrc + yoff + adjusted_params.y},
353  bar_hp_height = static_cast<int>(max_hitpoints * u.hp_bar_scaling()),
354  bar_xp_height = static_cast<int>(max_experience * u.xp_bar_scaling() / std::max<int>(u.level(), 1))
355  ](const rect& d) {
356  const point origin { d.x + xoff, d.y + yoff + adj_y };
357 
358  for(const texture& tex : textures) {
359  draw::blit(tex, display::scaled_to_zoom({origin.x, origin.y, tex.w(), tex.h()}));
360  }
361 
362  if(max_hitpoints > 0) {
363  // Offset slightly to make room for the XP bar
364  const int hp_offset = static_cast<int>(-5 * display::get_zoom_factor());
365 
366  double filled = static_cast<double>(hitpoints) / static_cast<double>(max_hitpoints);
367  draw_bar(origin.x + hp_offset, origin.y, bar_hp_height, filled, hp_color);
368  }
369 
370  if(experience > 0 && can_advance) {
371  double filled = static_cast<double>(experience) / static_cast<double>(max_experience);
372  draw_bar(origin.x, origin.y, bar_xp_height, filled, xp_color);
373  }
374  });
375  }
376 
377  // Smooth unit movements from terrain of different elevation.
378  // Do this separately from above so that the health bar doesn't go up and down.
379 
380  const t_translation::terrain_code terrain_dst = map.get_terrain(dst);
381  const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
382 
383  // height_adjust_unit is not scaled by zoom_factor here otherwise it results in a squared offset that results in #5974
384  // It appears the tiles and units are scaled together somewhere else
385  int height_adjust_unit = static_cast<int>(terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
386  terrain_dst_info.unit_height_adjust() * adjusted_params.offset);
387  if (is_flying && height_adjust_unit < 0) {
388  height_adjust_unit = 0;
389  }
390  params.y -= height_adjust_unit - height_adjust;
391  params.halo_y -= height_adjust_unit - height_adjust;
392  // TODO: params.halo_y is not used. Why is it set?
393 
394  const int halo_x =
395  static_cast<int>(
396  adjusted_params.offset * xdst
397  + (1.0 - adjusted_params.offset) * xsrc
398  )
399  + hex_size_by_2;
400  const int halo_y =
401  static_cast<int>(
402  adjusted_params.offset * ydst
403  + (1.0 - adjusted_params.offset) * ysrc
404  )
405  + hex_size_by_2 - height_adjust_unit * zoom_factor;
406 
407  bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
408  if(!has_halo && !u.image_halo().empty()) {
409  ac.unit_halo_ = halo_man.add(
410  halo_x, halo_y,
411  u.image_halo() + u.TC_image_mods(),
412  map_location(-1, -1)
413  );
414  }
415  if(has_halo && u.image_halo().empty()) {
416  halo_man.remove(ac.unit_halo_);
417  ac.unit_halo_.reset();
418  } else if(has_halo) {
419  halo_man.set_location(ac.unit_halo_, halo_x, halo_y);
420  }
421 
422  const std::vector<std::string> halos_abilities = u.halo_abilities();
423  bool has_abil_halo = !ac.abil_halos_.empty() && ac.abil_halos_.front()->valid();
424  if(!has_abil_halo && !halos_abilities.empty()) {
425  for(const std::string& halo_ab : halos_abilities){
426  halo::handle abil_halo = halo_man.add(
427  halo_x, halo_y,
428  halo_ab + u.TC_image_mods(),
429  map_location(-1, -1)
430  );
431  if(abil_halo->valid()){
432  ac.abil_halos_.push_back(abil_halo);
433  }
434  }
435  }
436  if(has_abil_halo && (ac.abil_halos_ref_ != halos_abilities || halos_abilities.empty())){
437  for(halo::handle& abil_halo : ac.abil_halos_){
438  halo_man.remove(abil_halo);
439  }
440  ac.abil_halos_.clear();
441  if(!halos_abilities.empty()){
442  for(const std::string& halo_ab : halos_abilities){
443  halo::handle abil_halo = halo_man.add(
444  halo_x, halo_y,
445  halo_ab + u.TC_image_mods(),
446  map_location(-1, -1)
447  );
448  if(abil_halo->valid()){
449  ac.abil_halos_.push_back(abil_halo);
450  }
451  }
452  }
453  } else if(has_abil_halo){
454  for(halo::handle& abil_halo : ac.abil_halos_){
455  halo_man.set_location(abil_halo, halo_x, halo_y);
456  }
457  }
458 
459  ac.abil_halos_ref_ = halos_abilities;
460 
461  ac.anim_->redraw(params, halo_man);
462  ac.refreshing_ = false;
463 }
464 
465 void unit_drawer::draw_ellipses(const unit& u, const frame_parameters& params) const
466 {
467  std::string ellipse = u.image_ellipse();
468  if(ellipse == "none") {
469  return;
470  }
471 
472  auto path = formatter{};
473  if(!ellipse.empty()) {
474  path << ellipse;
475  } else {
476  path << "misc/ellipse";
477  }
478 
479  // Build the path based on whether the unit has a ZoC can recruit
480  if(u.can_recruit())
481  path << "-leader";
482 
483  if(!u.emits_zoc())
484  path << "-nozoc";
485 
487  path << "-selected";
488 
489  // Load the ellipse parts recolored to match team color
490  const std::string ipf = formatter{} << "~RC(ellipse_red>" << team::get_side_color_id(u.side()) << ")";
491 
492  std::array images {
493  image::get_texture(image::locator{path.str() + "-top.png", ipf}),
494  image::get_texture(image::locator{path.str() + "-bottom.png", ipf})
495  };
496 
497  // The division by 2 seems to have no real meaning,
498  // It just works fine with the current center of ellipse
499  // and prevent a too large adjust if submerge = 1.0
500  const int y_shift = params.submerge > 0.0
501  ? params.y - static_cast<int>(params.submerge * hex_size_by_2)
502  : params.y;
503 
505  [images = std::move(images), y_shift](const rect& dest) {
506  for(const texture& tex : images) {
507  if(tex) {
508  draw::blit(tex, dest.shifted_by(0, y_shift));
509  }
510  }
511  });
512 }
orb_status unit_orb_status(const unit &u) const
Returns an enumurated summary of whether this unit can move and/or attack.
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:89
point get_location(const map_location &loc) const
Definition: display.cpp:694
static int hex_size()
Function which returns the size of a hex in pixels (from top tip to bottom tip or left edge to right ...
Definition: display.hpp:262
static double get_zoom_factor()
Returns the current zoom factor.
Definition: display.hpp:265
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:1264
rect map_outside_area() const
Returns the available area for a map, this may differ from the above.
Definition: display.cpp:522
static rect scaled_to_zoom(const SDL_Rect &r)
Scale the width and height of a rect by the current zoom factor.
Definition: display.hpp:271
std::ostringstream wrapper.
Definition: formatter.hpp:40
const std::set< map_location > & units_that_can_reach_goal() const
Return the locations of units that can reach goal (.
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:301
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:97
Generic locator abstracting the location of an image.
Definition: picture.hpp:59
static prefs & get()
int side() const
Definition: team.hpp:174
bool is_enemy(int n) const
Definition: team.hpp:229
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:971
int unit_height_adjust() const
Definition: terrain.hpp:137
double unit_submerge() const
Definition: terrain.hpp:138
Wrapper class to encapsulate creation and management of an SDL_Texture.
Definition: texture.hpp:33
bool draw_bars_
bool indicating whether to draw bars with the unit
std::unique_ptr< unit_animation > anim_
The current animation.
void set_standing(bool with_bars=true)
Sets the animation state to standing.
bool refreshing_
avoid infinite recursion.
void clear_haloes()
Clear the haloes associated to the unit.
bool selected_or_reachable(const map_location &loc) const
Definition: drawer.cpp:158
const team & viewing_team_ref
Definition: drawer.hpp:50
const gamemap & map
Definition: drawer.hpp:48
double zoom_factor
Definition: drawer.hpp:56
void redraw_unit(const unit &u) const
draw a unit.
Definition: drawer.cpp:164
const display_context & dc
Definition: drawer.hpp:47
bool show_everything
Definition: drawer.hpp:53
const team & playing_team_ref
Definition: drawer.hpp:51
void draw_ellipses(const unit &u, const frame_parameters &params) const
Definition: drawer.cpp:465
display & disp
Definition: drawer.hpp:46
std::set< map_location > units_that_can_reach_goal
Definition: drawer.hpp:57
int hex_size
Definition: drawer.hpp:59
map_location sel_hex
Definition: drawer.hpp:54
int hex_size_by_2
Definition: drawer.hpp:60
unit_drawer(display &thedisp)
Definition: drawer.cpp:138
map_location mouse_hex
Definition: drawer.hpp:55
bool is_blindfolded
Definition: drawer.hpp:52
const config & get_cfg() const
Definition: types.hpp:281
This class represents a single unit of a specific type.
Definition: unit.hpp:133
static const std::string & leader_crown()
The path to the leader crown overlay.
Definition: unit.cpp:1076
constexpr uint8_t float_to_color(double n)
Convert a double in the range [0.0,1.0] to an 8-bit colour value.
Definition: color.hpp:280
map_display and display: classes which take care of displaying the map and game-data on the screen.
Drawing functions, for drawing things on the screen.
static lg::log_domain log_display("display")
@ unit_bar
Unit bars and overlays are drawn on this layer (for testing here)
@ unit_first
Reserve layers to be selected for wml.
@ selected_hex
Image on the selected unit.
Frame for unit's animation sequence.
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2482
bool is_visible_to_team(const team &team, bool const see_all=true) const
Definition: unit.cpp:2525
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:505
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:905
int level() const
The current level of this unit.
Definition: unit.hpp:559
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:499
bool slowed() const
Check if the unit has been slowed.
Definition: unit.hpp:914
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
Definition: unit.hpp:720
const unit_type & type() const
This unit's type, accounting for gender and variation.
Definition: unit.hpp:355
int experience() const
The current number of experience points this unit has.
Definition: unit.hpp:523
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition: unit.hpp:612
int side() const
The side this unit belongs to.
Definition: unit.hpp:343
bool poisoned() const
Check if the unit has been poisoned.
Definition: unit.hpp:896
double xp_bar_scaling() const
The factor by which the XP bar should be scaled.
Definition: unit.hpp:741
double hp_bar_scaling() const
The factor by which the HP bar should be scaled.
Definition: unit.hpp:732
int max_experience() const
The max number of experience points this unit can have.
Definition: unit.hpp:529
bool can_advance() const
Checks whether this unit has any options to advance to.
Definition: unit.hpp:272
color_t xp_color() const
Color for this unit's XP.
Definition: unit.cpp:1151
unit_animation_component & anim_comp() const
Definition: unit.hpp:1608
color_t hp_color() const
Color for this unit's current hitpoints.
Definition: unit.cpp:1107
std::string TC_image_mods() const
Constructs a recolor (RC) IPF string for this unit's team color.
Definition: unit.cpp:2635
const std::vector< std::string > overlays_abilities() const
Get the [overlay] ability overlay images.
Definition: unit.hpp:1677
std::string image_ellipse() const
Get the unit's ellipse image.
Definition: unit.hpp:1637
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
Definition: unit.cpp:2640
std::string default_anim_image() const
The default image to use for animation frames with no defined image.
Definition: unit.cpp:2464
const std::vector< std::string > & overlays() const
Get the unit's overlay images.
Definition: unit.hpp:1671
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
Definition: unit.hpp:1379
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1398
map_location::DIRECTION facing() const
The current direction this unit is facing within its hex.
Definition: unit.hpp:1414
bool is_flying() const
Check if the unit is a flying unit.
Definition: unit.hpp:1507
Standard logging facilities (interface).
void fill(const SDL_Rect &rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Fill an area with the given colour.
Definition: draw.cpp:50
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
void rect(const SDL_Rect &rect)
Draw a rectangle.
Definition: draw.cpp:150
std::string orb_two_color
std::string path
Definition: filesystem.cpp:90
bool show_status_on_ally_orb
std::shared_ptr< halo_record > handle
Definition: halo.hpp:31
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
point get_size(const locator &i_locator, bool skip_cache)
Returns the width and height of an image.
Definition: picture.cpp:777
std::string get_orb_color(orb_status os)
Wrapper for the various prefs::get().unmoved_color(), moved_color(), etc methods, using the enum inst...
Definition: orb_status.cpp:40
bool prefs_show_orb(orb_status os)
Wrapper for the various prefs::get().show_..._orb() methods, using the enum instead of exposing a sep...
Definition: orb_status.cpp:19
orb_status
Corresponds to the colored orbs displayed above units' hp-bar and xp-bar.
Definition: orb_status.hpp:23
@ partial
There are still moves and/or attacks possible, but the unit doesn't fit in the "unmoved" status.
@ moved
All moves and possible attacks have been done.
@ disengaged
The unit can move but can't attack, and wouldn't be able to attack even if it was moved to a hex adja...
@ allied
Belongs to a friendly side.
@ enemy
Belongs to a non-friendly side; normally visualised by not displaying an orb.
rect dst
Location on the final composed sheet.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
All parameters from a frame at a given instant.
Definition: frame.hpp:42
utils::optional< color_t > blend_with
Definition: frame.hpp:59
double highlight_ratio
Definition: frame.hpp:62
std::string image_mod
Definition: frame.hpp:48
double submerge
Definition: frame.hpp:64
boost::tribool primary_frame
Definition: frame.hpp:73
image::locator image
Definition: frame.hpp:45
double blend_ratio
Definition: frame.hpp:61
std::string halo_mod
Definition: frame.hpp:54
Encapsulates the map of the game.
Definition: location.hpp:38
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
map_location get_direction(DIRECTION dir, unsigned int n=1u) const
Definition: location.cpp:359
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:49
static map_location::DIRECTION s
constexpr uint32_t red
Definition: test_sdl.cpp:24
constexpr uint32_t green
Definition: test_sdl.cpp:25
constexpr uint32_t blue
Definition: test_sdl.cpp:26
#define d