The Battle for Wesnoth  1.19.5+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.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  // FIXME: double check whether the shift amount accounts for zoom level
270  rect unit_rect = disp.get_location_rect(loc).shifted_by(0, adjusted_params.y);
271 
272  // We draw bars only if wanted, visible on the map view
273  if(ac.draw_bars_ && unit_rect.overlaps(disp.map_outside_area())) {
274 
275  // Always show the ellipse for selected units
276  if(prefs::get().show_side_colors() || is_selected_hex) {
277  draw_ellipses(u, adjusted_params);
278  }
279 
280  const auto& type_cfg = u.type().get_cfg();
281  const auto& cfg_offset_x = type_cfg["bar_offset_x"];
282  const auto& cfg_offset_y = type_cfg["bar_offset_y"];
283  int xoff;
284  int yoff;
285  if(cfg_offset_x.empty() && cfg_offset_y.empty()) {
288  );
289  xoff = !s.x ? 0 : (hex_size - s.x)/2;
290  yoff = !s.y ? 0 : (hex_size - s.x)/2;
291  }
292  else {
293  xoff = cfg_offset_x.to_int();
294  yoff = cfg_offset_y.to_int();
295  }
296 
297  using namespace orb_status_helper;
298  std::unique_ptr<image::locator> orb_img = nullptr;
299 
300  if(viewing_team_ref.is_enemy(side)) {
301  if(!u.incapacitated())
302  orb_img = get_orb_image(orb_status::enemy);
303  } else if(side != playing_team_ref.side()) {
304  // We're looking at either the player's own unit or an ally's unit, but either way it
305  // doesn't belong to the playing_team and isn't expected to move until after its next
306  // turn refresh.
307  auto os = orb_status::moved;
308  if(side != viewing_team_ref.side())
309  os = orb_status::allied;
310  orb_img = get_orb_image(os);
311  } else if(side != viewing_team_ref.side()) {
312  // We're looking at an ally's unit, during that ally's turn.
313  auto os = dc.unit_orb_status(u);
314  orb_img = get_playing_ally_orb_image(os);
315  } else {
316  // We're looking at the player's own unit, during the player's turn.
317  auto os = dc.unit_orb_status(u);
318  orb_img = get_orb_image(os);
319  }
320 
321  // All the various overlay textures to draw with the HP/XP bars
322  std::vector<texture> textures;
323 
324  if(orb_img != nullptr) {
325  textures.push_back(image::get_texture(*orb_img));
326  }
327 
328  if(can_recruit) {
329  if(texture tex = image::get_texture(u.leader_crown())) {
330  textures.push_back(std::move(tex));
331  }
332  }
333 
334  for(const std::string& ov : u.overlays()) {
335  if(texture tex = image::get_texture(ov)) {
336  textures.push_back(std::move(tex));
337  }
338  };
339 
340  const std::vector<std::string> overlays_abilities = u.overlays_abilities();
341  for(const std::string& ov : overlays_abilities) {
342  if(texture tex = image::get_texture(ov)) {
343  textures.push_back(std::move(tex));
344  }
345  };
346 
348  textures = std::move(textures),
349  adj_y = adjusted_params.y,
350  //origin = point{xsrc + xoff, ysrc + yoff + adjusted_params.y},
351  bar_hp_height = static_cast<int>(max_hitpoints * u.hp_bar_scaling()),
352  bar_xp_height = static_cast<int>(max_experience * u.xp_bar_scaling() / std::max<int>(u.level(), 1))
353  ](const rect& d) {
354  const point origin { d.x + xoff, d.y + yoff + adj_y };
355 
356  for(const texture& tex : textures) {
357  draw::blit(tex, display::scaled_to_zoom({origin.x, origin.y, tex.w(), tex.h()}));
358  }
359 
360  if(max_hitpoints > 0) {
361  // Offset slightly to make room for the XP bar
362  const int hp_offset = static_cast<int>(-5 * display::get_zoom_factor());
363 
364  double filled = static_cast<double>(hitpoints) / static_cast<double>(max_hitpoints);
365  draw_bar(origin.x + hp_offset, origin.y, bar_hp_height, filled, hp_color);
366  }
367 
368  if(experience > 0 && can_advance) {
369  double filled = static_cast<double>(experience) / static_cast<double>(max_experience);
370  draw_bar(origin.x, origin.y, bar_xp_height, filled, xp_color);
371  }
372  });
373  }
374 
375  // Smooth unit movements from terrain of different elevation.
376  // Do this separately from above so that the health bar doesn't go up and down.
377 
378  const t_translation::terrain_code terrain_dst = map.get_terrain(dst);
379  const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
380 
381  // height_adjust_unit is not scaled by zoom_factor here otherwise it results in a squared offset that results in #5974
382  // It appears the tiles and units are scaled together somewhere else
383  int height_adjust_unit = static_cast<int>(terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
384  terrain_dst_info.unit_height_adjust() * adjusted_params.offset);
385  if (is_flying && height_adjust_unit < 0) {
386  height_adjust_unit = 0;
387  }
388  params.y -= height_adjust_unit - height_adjust;
389  params.halo_y -= height_adjust_unit - height_adjust;
390  // TODO: params.halo_y is not used. Why is it set?
391 
392  const int halo_x =
393  static_cast<int>(
394  adjusted_params.offset * xdst
395  + (1.0 - adjusted_params.offset) * xsrc
396  )
397  + hex_size_by_2;
398  const int halo_y =
399  static_cast<int>(
400  adjusted_params.offset * ydst
401  + (1.0 - adjusted_params.offset) * ysrc
402  )
403  + hex_size_by_2 - height_adjust_unit * zoom_factor;
404 
405  bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
406  if(!has_halo && !u.image_halo().empty()) {
407  ac.unit_halo_ = halo_man.add(
408  halo_x, halo_y,
409  u.image_halo() + u.TC_image_mods(),
410  map_location(-1, -1)
411  );
412  }
413  if(has_halo && u.image_halo().empty()) {
414  halo_man.remove(ac.unit_halo_);
415  ac.unit_halo_.reset();
416  } else if(has_halo) {
417  halo_man.set_location(ac.unit_halo_, halo_x, halo_y);
418  }
419 
420  const std::vector<std::string> halos_abilities = u.halo_abilities();
421  bool has_abil_halo = !ac.abil_halos_.empty() && ac.abil_halos_.front()->valid();
422  if(!has_abil_halo && !halos_abilities.empty()) {
423  for(const std::string& halo_ab : halos_abilities){
424  halo::handle abil_halo = halo_man.add(
425  halo_x, halo_y,
426  halo_ab + u.TC_image_mods(),
427  map_location(-1, -1)
428  );
429  if(abil_halo->valid()){
430  ac.abil_halos_.push_back(abil_halo);
431  }
432  }
433  }
434  if(has_abil_halo && (ac.abil_halos_ref_ != halos_abilities || halos_abilities.empty())){
435  for(halo::handle& abil_halo : ac.abil_halos_){
436  halo_man.remove(abil_halo);
437  }
438  ac.abil_halos_.clear();
439  if(!halos_abilities.empty()){
440  for(const std::string& halo_ab : halos_abilities){
441  halo::handle abil_halo = halo_man.add(
442  halo_x, halo_y,
443  halo_ab + u.TC_image_mods(),
444  map_location(-1, -1)
445  );
446  if(abil_halo->valid()){
447  ac.abil_halos_.push_back(abil_halo);
448  }
449  }
450  }
451  } else if(has_abil_halo){
452  for(halo::handle& abil_halo : ac.abil_halos_){
453  halo_man.set_location(abil_halo, halo_x, halo_y);
454  }
455  }
456 
457  ac.abil_halos_ref_ = halos_abilities;
458 
459  ac.anim_->redraw(params, halo_man);
460  ac.refreshing_ = false;
461 }
462 
463 void unit_drawer::draw_ellipses(const unit& u, const frame_parameters& params) const
464 {
465  std::string ellipse = u.image_ellipse();
466  if(ellipse == "none") {
467  return;
468  }
469 
470  auto path = formatter{};
471  if(!ellipse.empty()) {
472  path << ellipse;
473  } else {
474  path << "misc/ellipse";
475  }
476 
477  // Build the path based on whether the unit has a ZoC can recruit
478  if(u.can_recruit())
479  path << "-leader";
480 
481  if(!u.emits_zoc())
482  path << "-nozoc";
483 
485  path << "-selected";
486 
487  // Load the ellipse parts recolored to match team color
488  const std::string ipf = formatter{} << "~RC(ellipse_red>" << team::get_side_color_id(u.side()) << ")";
489 
490  std::array images {
491  image::get_texture(image::locator{path.str() + "-top.png", ipf}),
492  image::get_texture(image::locator{path.str() + "-bottom.png", ipf})
493  };
494 
495  // The division by 2 seems to have no real meaning,
496  // It just works fine with the current center of ellipse
497  // and prevent a too large adjust if submerge = 1.0
498  const int y_shift = params.submerge > 0.0
499  ? params.y - static_cast<int>(params.submerge * hex_size_by_2)
500  : params.y;
501 
503  [images = std::move(images), y_shift](const rect& dest) {
504  for(const texture& tex : images) {
505  if(tex) {
506  draw::blit(tex, dest.shifted_by(0, y_shift));
507  }
508  }
509  });
510 }
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:97
point get_location(const map_location &loc) const
Functions to get the on-screen positions of hexes.
Definition: display.cpp:679
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:267
static double get_zoom_factor()
Returns the current zoom factor.
Definition: display.hpp:270
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
rect map_outside_area() const
Returns the available area for a map, this may differ from the above.
Definition: display.cpp:521
rect get_location_rect(const map_location &loc) const
Returns the on-screen rect corresponding to a loc.
Definition: display.cpp:687
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:276
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:302
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:98
Generic locator abstracting the location of an image.
Definition: picture.hpp:59
static prefs & get()
int side() const
Definition: team.hpp:175
bool is_enemy(int n) const
Definition: team.hpp:229
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:972
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:463
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:1140
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:2579
bool is_visible_to_team(const team &team, bool const see_all=true) const
Definition: unit.cpp:2622
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:911
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:920
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:902
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:1215
unit_animation_component & anim_comp() const
Definition: unit.hpp:1614
std::vector< std::string > overlays_abilities() const
Get the [overlay] ability overlay images.
Definition: unit.hpp:1683
color_t hp_color() const
Color for this unit's current hitpoints.
Definition: unit.cpp:1171
std::string TC_image_mods() const
Constructs a recolor (RC) IPF string for this unit's team color.
Definition: unit.cpp:2732
std::string image_ellipse() const
Get the unit's ellipse image.
Definition: unit.hpp:1643
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
Definition: unit.cpp:2737
std::string default_anim_image() const
The default image to use for animation frames with no defined image.
Definition: unit.cpp:2561
const std::vector< std::string > & overlays() const
Get the unit's overlay images.
Definition: unit.hpp:1677
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
Definition: unit.hpp:1385
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1404
map_location::direction facing() const
The current direction this unit is facing within its hex.
Definition: unit.hpp:1420
bool is_flying() const
Check if the unit is a flying unit.
Definition: unit.hpp:1513
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:44
utils::optional< color_t > blend_with
Definition: frame.hpp:61
double highlight_ratio
Definition: frame.hpp:64
std::string image_mod
Definition: frame.hpp:50
double submerge
Definition: frame.hpp:66
boost::tribool primary_frame
Definition: frame.hpp:75
image::locator image
Definition: frame.hpp:47
double blend_ratio
Definition: frame.hpp:63
std::string halo_mod
Definition: frame.hpp:56
Encapsulates the map of the game.
Definition: location.hpp:45
map_location get_direction(direction dir, unsigned int n=1u) const
Definition: location.cpp:364
direction
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:47
Holds a 2D point.
Definition: point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition: rect.hpp:47
rect shifted_by(int x, int y) const
Returns a new rectangle shifted by the given relative position.
Definition: rect.cpp:111
bool overlaps(const SDL_Rect &r) const
Whether the given rectangle and this rectangle overlap.
Definition: rect.cpp:73
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