The Battle for Wesnoth  1.19.8+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 "global.hpp"
25 #include "halo.hpp"
26 #include "log.hpp"
27 #include "map/location.hpp"
28 #include "map/map.hpp"
29 #include "picture.hpp"
31 #include "team.hpp"
32 #include "units/animation.hpp"
34 #include "units/frame.hpp"
35 #include "units/types.hpp"
36 #include "units/unit.hpp"
37 
38 static lg::log_domain log_display("display");
39 #define LOG_DP LOG_STREAM(info, log_display)
40 
41 namespace
42 {
43 /**
44  * Wrapper which will assemble the image path (including IPF for the color from get_orb_color) for a given orb.
45  * Returns nullptr if the preferences have been configured to hide this orb.
46  */
47 std::unique_ptr<image::locator> get_orb_image(orb_status os)
48 {
49  if(os == orb_status::disengaged) {
53  return std::make_unique<image::locator>(game_config::images::orb_two_color + "~RC(ellipse_red>"
54  + moved_color + ")~RC(magenta>" + partial_color + ")");
55  }
57  }
58 
60  return nullptr;
61  auto color = orb_status_helper::get_orb_color(os);
62  return std::make_unique<image::locator>(game_config::images::orb + "~RC(magenta>" + color + ")");
63 }
64 
65 /**
66  * Assemble a two-color orb for an ally's unit, during that ally's turn.
67  * Returns nullptr if the preferences both of these orbs and ally orbs in general are off.
68  * Returns a one-color orb (using the ally color) in several circumstances.
69  */
70 std::unique_ptr<image::locator> get_playing_ally_orb_image(orb_status os)
71 {
73  return get_orb_image(orb_status::allied);
74 
75  // This is conditional on prefs_show_orb, because a user might want to disable the standard
76  // partial orb, but keep it enabled as a reminder for units in the disengaged state.
79  }
80 
82  return get_orb_image(orb_status::allied);
83 
85  auto status_color = orb_status_helper::get_orb_color(os);
86  return std::make_unique<image::locator>(game_config::images::orb_two_color + "~RC(ellipse_red>"
87  + allied_color + ")~RC(magenta>" + status_color + ")");
88 }
89 
90 struct energy_bar
91 {
92  /** Bar height in pixels. */
93  int bar_h{};
94 
95  /** The extent to which the bar is filled, ranging [0, 1]. */
96  float filled{};
97 
98  /** Color for the bar's filled area. */
99  color_t fill_color{};
100 
101  /** Initial coordinates for the first bar drawn. */
102  static constexpr point def_origin{14, 13};
103 
104  /** Default width for all bars. */
105  static constexpr int def_w = 4;
106 
107  /** Distance between the top left corner of subsequent bars. */
108  static constexpr int spacing = def_w + 1;
109 
110  /** Background color for the unfilled bar area. */
111  static constexpr color_t background_color{0, 0, 0, 80};
112 
113  /** Border color surrounding the whole bar. */
114  static constexpr color_t border_color{213, 213, 213, 200};
115 
116  /** Returns the height of the bar in pixels. */
117  static constexpr auto get_height(int size, double scaling)
118  {
119  return int(size * scaling);
120  };
121 
122  /** Returns the relative amount of the bar to be filled. */
123  static constexpr auto get_filled(int size, int max)
124  {
125  return std::clamp(float(size) / max, 0.0f, 1.0f);
126  };
127 
128  /** Returns the fill color with the appropriate alpha depending on the focused state. */
129  static constexpr auto get_color(const color_t& c, bool focused)
130  {
131  return color_t{c.r, c.g, c.b, float_to_color(focused ? 1.0 : 0.8)};
132  }
133 };
134 
135 void draw_bar(int index, const energy_bar& data, const rect& bounds)
136 {
137  // All absolute bar coordinates are normalized relative to the standard 72px hex.
139 
140  SDL_FPoint p1{
141  float(energy_bar::def_origin.x + energy_bar::spacing * index) / tile_size,
142  float(energy_bar::def_origin.y ) / tile_size,
143  };
144 
145  // If the top of the bar sits 13px from the top of the scaled hex rect, the bottom
146  // of the bar should extend no closer than 13px from the bottom.
147  SDL_FPoint p2{
148  std::min(p1.x + float(data.def_w) / tile_size, 1.0f - p1.x),
149  std::min(p1.y + float(data.bar_h) / tile_size, 1.0f - p1.y)
150  };
151 
152  // Full bar dimensions
153  const SDL_FRect bar_rect = sdl::precise_subrect(bounds, p1, p2);
154  draw::fill(bar_rect, energy_bar::border_color);
155 
156  // Size of a single pixel relative to the standard hex
157  const float one_pixel = 1.0f / tile_size;
158 
159  SDL_FPoint bg1{ p1.x + one_pixel, p1.y + one_pixel };
160  SDL_FPoint bg2{ p2.x - one_pixel, p2.y - one_pixel };
161 
162  // Full inner dimensions
163  const SDL_FRect inner_rect = sdl::precise_subrect(bounds, bg1, bg2);
164  draw::fill(inner_rect, energy_bar::background_color);
165 
166  SDL_FPoint fill1{ 0.0f, 1.0f - data.filled };
167  SDL_FPoint fill2{ 1.0f, 1.0f };
168 
169  // Filled area, relative to the bottom of the inner bar area
170  const SDL_FRect fill_rect = sdl::precise_subrect(inner_rect, fill1, fill2);
171  draw::fill(fill_rect, data.fill_color);
172 }
173 
174 } // anon namespace
175 
177  : disp(thedisp)
178  , dc(disp.context())
179  , map(dc.map())
180  , halo_man(thedisp.get_halo_manager())
181  , viewing_team_ref(disp.viewing_team())
182  , playing_team_ref(disp.playing_team())
183  , is_blindfolded(disp.is_blindfolded())
184  , show_everything(disp.show_everything())
185  , sel_hex(disp.selected_hex())
186  , mouse_hex(disp.mouseover_hex())
187  , zoom_factor(disp.get_zoom_factor())
188  , hex_size(disp.hex_size())
189  , hex_size_by_2(disp.hex_size() / 2)
190 {
191  if(const game_display* game_display = dynamic_cast<class game_display*>(&disp)) {
193  }
194 }
195 
197 {
198  const bool is_highlighted_enemy = units_that_can_reach_goal.count(loc) > 0;
199  return loc == sel_hex || is_highlighted_enemy;
200 }
201 
202 void unit_drawer::redraw_unit(const unit& u) const
203 {
206 
207  int side = u.side();
208 
209  bool hidden = u.get_hidden();
210  bool is_flying = u.is_flying();
211  map_location::direction facing = u.facing();
212 
213  bool can_recruit = u.can_recruit();
214 
215  const bool is_selected_hex = selected_or_reachable(loc);
216 
218  ac.clear_haloes();
219  if(ac.anim_) {
220  ac.anim_->update_last_draw_time();
221  }
222  return;
223  }
224 
225  if (!ac.anim_) {
226  ac.set_standing();
227  if (!ac.anim_) return;
228  }
229 
230  if (ac.refreshing_) return;
231  ac.refreshing_ = true;
232 
233  ac.anim_->update_last_draw_time();
234  frame_parameters params;
236  const terrain_type& terrain_info = map.get_terrain_info(terrain);
237 
238  // do not set to 0 so we can distinguish the flying from the "not on submerge terrain"
239  // instead use -1.0 (as in "negative depth", it will be ignored by rendering)
240  params.submerge= is_flying ? -1.0 : terrain_info.unit_submerge();
241 
242  if(u.invisible(loc) && params.highlight_ratio > 0.6) {
243  params.highlight_ratio = 0.6;
244  }
245  if (is_selected_hex && params.highlight_ratio == 1.0) {
246  params.highlight_ratio = 1.5;
247  }
248 
249  int height_adjust = static_cast<int>(terrain_info.unit_height_adjust() * zoom_factor);
250  if (is_flying && height_adjust < 0) {
251  height_adjust = 0;
252  }
253  params.y -= height_adjust;
254  params.halo_y -= height_adjust;
255 
256  int red = 0,green = 0,blue = 0,tints = 0;
257  double blend_ratio = 0;
258  // Add future colored states here
259  if(u.poisoned()) {
260  green += 255;
261  blend_ratio += 0.25;
262  tints += 1;
263  }
264  if(u.slowed()) {
265  red += 191;
266  green += 191;
267  blue += 255;
268  blend_ratio += 0.25;
269  tints += 1;
270  }
271  if(tints > 0) {
272  params.blend_with = color_t((red/tints),(green/tints),(blue/tints));
273  params.blend_ratio = ((blend_ratio/tints));
274  }
275 
276  //hackish : see unit_frame::merge_parameters
277  // we use image_mod on the primary image
278  // and halo_mod on secondary images and all haloes
279  params.image_mod = u.image_mods();
280  params.halo_mod = u.TC_image_mods();
281  params.image= u.default_anim_image();
282 
283 
284  if(u.incapacitated()) params.image_mod +="~GS()";
285  params.primary_frame = true;
286 
287 
288  const frame_parameters adjusted_params = ac.anim_->get_current_params(params);
289 
290  const map_location dst = loc.get_direction(facing);
291  const auto [xsrc, ysrc] = disp.get_location(loc);
292  const auto [xdst, ydst] = disp.get_location(dst);
293 
294  // FIXME: double check whether the shift amount accounts for zoom level
295  rect unit_rect = disp.get_location_rect(loc).shifted_by(0, adjusted_params.y);
296 
297  // We draw bars only if wanted, visible on the map view
298  if(ac.draw_bars_ && unit_rect.overlaps(disp.map_outside_area())) {
299 
300  // Always show the ellipse for selected units
301  if(prefs::get().show_side_colors() || is_selected_hex) {
302  draw_ellipses(u, adjusted_params);
303  }
304 
305  const auto& type_cfg = u.type().get_cfg();
306  const auto& cfg_offset_x = type_cfg["bar_offset_x"];
307  const auto& cfg_offset_y = type_cfg["bar_offset_y"];
308  int xoff;
309  int yoff;
310  if(cfg_offset_x.empty() && cfg_offset_y.empty()) {
313  );
314  xoff = !s.x ? 0 : (hex_size - s.x)/2;
315  yoff = !s.y ? 0 : (hex_size - s.x)/2;
316  }
317  else {
318  xoff = cfg_offset_x.to_int();
319  yoff = cfg_offset_y.to_int();
320  }
321 
322  using namespace orb_status_helper;
323  std::unique_ptr<image::locator> orb_img = nullptr;
324 
325  if(viewing_team_ref.is_enemy(side)) {
326  if(!u.incapacitated())
327  orb_img = get_orb_image(orb_status::enemy);
328  } else if(side != playing_team_ref.side()) {
329  // We're looking at either the player's own unit or an ally's unit, but either way it
330  // doesn't belong to the playing_team and isn't expected to move until after its next
331  // turn refresh.
332  auto os = orb_status::moved;
333  if(side != viewing_team_ref.side())
334  os = orb_status::allied;
335  orb_img = get_orb_image(os);
336  } else if(side != viewing_team_ref.side()) {
337  // We're looking at an ally's unit, during that ally's turn.
338  auto os = dc.unit_orb_status(u);
339  orb_img = get_playing_ally_orb_image(os);
340  } else {
341  // We're looking at the player's own unit, during the player's turn.
342  auto os = dc.unit_orb_status(u);
343  orb_img = get_orb_image(os);
344  }
345 
346  // All the various overlay textures to draw with the HP/XP bars
347  std::vector<texture> textures;
348 
349  if(orb_img) {
350  textures.push_back(image::get_texture(*orb_img));
351  }
352 
353  if(can_recruit) {
354  if(texture tex = image::get_texture(u.leader_crown())) {
355  textures.push_back(std::move(tex));
356  }
357  }
358 
359  for(const std::string& ov : u.overlays()) {
360  if(texture tex = image::get_texture(ov)) {
361  textures.push_back(std::move(tex));
362  }
363  };
364 
365  for(const std::string& ov : u.overlays_abilities()) {
366  if(texture tex = image::get_texture(ov)) {
367  textures.push_back(std::move(tex));
368  }
369  };
370 
371  const bool bar_focus = (loc == mouse_hex || is_selected_hex);
372  std::vector<energy_bar> bars;
373 
374  if(u.max_hitpoints() > 0) {
375  bars.AGGREGATE_EMPLACE(
376  energy_bar::get_height(u.max_hitpoints(), u.hp_bar_scaling()),
377  energy_bar::get_filled(u.hitpoints(), u.max_hitpoints()),
378  energy_bar::get_color(u.hp_color(), bar_focus)
379  );
380  }
381 
382  if(u.experience() > 0 && u.can_advance()) {
383  bars.AGGREGATE_EMPLACE(
384  energy_bar::get_height(u.max_experience(), u.xp_bar_scaling() / std::max(u.level(), 1)),
385  energy_bar::get_filled(u.experience(), u.max_experience()),
386  energy_bar::get_color(u.xp_color(), bar_focus)
387  );
388  }
389 
391  [textures = std::move(textures), bars = std::move(bars), shift = point{xoff, yoff + adjusted_params.y}](
392  const rect& dest) {
393  const rect shifted = dest.shifted_by(shift);
394 
395  for(const texture& tex : textures) {
396  draw::blit(tex, shifted);
397  }
398 
399  for(std::size_t i = 0; i < bars.size(); ++i) { // bar bar bar
400  draw_bar(i, bars[i], shifted);
401  }
402  });
403  }
404 
405  // Smooth unit movements from terrain of different elevation.
406  // Do this separately from above so that the health bar doesn't go up and down.
407 
408  const t_translation::terrain_code terrain_dst = map.get_terrain(dst);
409  const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
410 
411  // height_adjust_unit is not scaled by zoom_factor here otherwise it results in a squared offset that results in #5974
412  // It appears the tiles and units are scaled together somewhere else
413  int height_adjust_unit = static_cast<int>(terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
414  terrain_dst_info.unit_height_adjust() * adjusted_params.offset);
415  if (is_flying && height_adjust_unit < 0) {
416  height_adjust_unit = 0;
417  }
418  params.y -= height_adjust_unit - height_adjust;
419  params.halo_y -= height_adjust_unit - height_adjust;
420  // TODO: params.halo_y is not used. Why is it set?
421 
422  const int halo_x =
423  static_cast<int>(
424  adjusted_params.offset * xdst
425  + (1.0 - adjusted_params.offset) * xsrc
426  )
427  + hex_size_by_2;
428  const int halo_y =
429  static_cast<int>(
430  adjusted_params.offset * ydst
431  + (1.0 - adjusted_params.offset) * ysrc
432  )
433  + hex_size_by_2 - height_adjust_unit * zoom_factor;
434 
435  bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
436  if(!has_halo && !u.image_halo().empty()) {
437  ac.unit_halo_ = halo_man.add(
438  halo_x, halo_y,
439  u.image_halo() + u.TC_image_mods(),
440  map_location(-1, -1)
441  );
442  }
443  if(has_halo && u.image_halo().empty()) {
445  ac.unit_halo_.reset();
446  } else if(has_halo) {
447  halo_man.set_location(ac.unit_halo_, halo_x, halo_y);
448  }
449 
450  const std::vector<std::string> halos_abilities = u.halo_abilities();
451  bool has_abil_halo = !ac.abil_halos_.empty() && ac.abil_halos_.front()->valid();
452  if(!has_abil_halo && !halos_abilities.empty()) {
453  for(const std::string& halo_ab : halos_abilities){
454  halo::handle abil_halo = halo_man.add(
455  halo_x, halo_y,
456  halo_ab + u.TC_image_mods(),
457  map_location(-1, -1)
458  );
459  if(abil_halo->valid()){
460  ac.abil_halos_.push_back(abil_halo);
461  }
462  }
463  }
464  if(has_abil_halo && (ac.abil_halos_ref_ != halos_abilities || halos_abilities.empty())){
465  for(halo::handle& abil_halo : ac.abil_halos_){
466  halo_man.remove(abil_halo);
467  }
468  ac.abil_halos_.clear();
469  if(!halos_abilities.empty()){
470  for(const std::string& halo_ab : halos_abilities){
471  halo::handle abil_halo = halo_man.add(
472  halo_x, halo_y,
473  halo_ab + u.TC_image_mods(),
474  map_location(-1, -1)
475  );
476  if(abil_halo->valid()){
477  ac.abil_halos_.push_back(abil_halo);
478  }
479  }
480  }
481  } else if(has_abil_halo){
482  for(halo::handle& abil_halo : ac.abil_halos_){
483  halo_man.set_location(abil_halo, halo_x, halo_y);
484  }
485  }
486 
487  ac.abil_halos_ref_ = halos_abilities;
488 
489  ac.anim_->redraw(params, halo_man);
490  ac.refreshing_ = false;
491 }
492 
493 void unit_drawer::draw_ellipses(const unit& u, const frame_parameters& params) const
494 {
495  std::string ellipse = u.image_ellipse();
496  if(ellipse == "none") {
497  return;
498  }
499 
500  auto path = formatter{};
501  if(!ellipse.empty()) {
502  path << ellipse;
503  } else {
504  path << "misc/ellipse";
505  }
506 
507  // Build the path based on whether the unit has a ZoC can recruit
508  if(u.can_recruit())
509  path << "-leader";
510 
511  if(!u.emits_zoc())
512  path << "-nozoc";
513 
515  path << "-selected";
516 
517  // Load the ellipse parts recolored to match team color
518  const std::string ipf = formatter{} << "~RC(ellipse_red>" << team::get_side_color_id(u.side()) << ")";
519 
520  std::array images {
521  image::get_texture(image::locator{path.str() + "-top.png", ipf}),
522  image::get_texture(image::locator{path.str() + "-bottom.png", ipf})
523  };
524 
525  // The division by 2 seems to have no real meaning,
526  // It just works fine with the current center of ellipse
527  // and prevent a too large adjust if submerge = 1.0
528  const int y_shift = params.submerge > 0.0
529  ? params.y - static_cast<int>(params.submerge * hex_size_by_2)
530  : params.y;
531 
533  [images = std::move(images), y_shift](const rect& dest) {
534  for(const texture& tex : images) {
535  if(tex) {
536  draw::blit(tex, dest.shifted_by(0, y_shift));
537  }
538  }
539  });
540 }
map_location loc
Definition: move.cpp:172
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:680
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:1259
rect map_outside_area() const
Returns the available area for a map, this may differ from the above.
Definition: display.cpp:522
rect get_location_rect(const map_location &loc) const
Returns the on-screen rect corresponding to a loc.
Definition: display.cpp:688
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
void set_location(const handle &h, int x, int y)
Set the position of an existing haloing effect, according to its handle.
Definition: halo.cpp:428
handle add(int x, int y, const std::string &image, const map_location &loc, halo::ORIENTATION orientation=NORMAL, bool infinite=true)
Add a haloing effect using 'image centered on (x,y).
Definition: halo.cpp:420
void remove(const handle &h)
Remove the halo with the given handle.
Definition: halo.cpp:434
Generic locator abstracting the location of an image.
Definition: picture.hpp:59
static prefs & get()
int side() const
Definition: team.hpp:180
bool is_enemy(int n) const
Definition: team.hpp:234
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:961
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::vector< halo::handle > abil_halos_
handle to the abilities halos of this unit
std::unique_ptr< unit_animation > anim_
The current animation.
halo::handle unit_halo_
handle to the halo of this unit
void set_standing(bool with_bars=true)
Sets the animation state to standing.
std::vector< std::string > abil_halos_ref_
vector used to check that halo_abilities vector isn't modified between each read
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:196
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:202
const display_context & dc
Definition: drawer.hpp:47
bool show_everything
Definition: drawer.hpp:53
const team & playing_team_ref
Definition: drawer.hpp:51
halo::manager & halo_man
Definition: drawer.hpp:49
void draw_ellipses(const unit &u, const frame_parameters &params) const
Definition: drawer.cpp:493
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:176
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:1133
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.
std::size_t i
Definition: function.cpp:1029
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2572
bool is_visible_to_team(const team &team, bool const see_all=true) const
Definition: unit.cpp:2615
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:904
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:913
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:895
double xp_bar_scaling() const
The factor by which the XP bar should be scaled.
Definition: unit.cpp:2786
double hp_bar_scaling() const
The factor by which the HP bar should be scaled.
Definition: unit.cpp:2782
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:1208
unit_animation_component & anim_comp() const
Definition: unit.hpp:1607
std::vector< std::string > overlays_abilities() const
Get the [overlay] ability overlay images.
Definition: unit.hpp:1676
color_t hp_color() const
Color for this unit's current hitpoints.
Definition: unit.cpp:1164
std::vector< std::string > halo_abilities() const
Get the [halo] abilities halo image(s).
Definition: unit.hpp:1627
std::string TC_image_mods() const
Constructs a recolor (RC) IPF string for this unit's team color.
Definition: unit.cpp:2725
std::string image_ellipse() const
Get the unit's ellipse image.
Definition: unit.hpp:1636
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
Definition: unit.cpp:2730
std::string default_anim_image() const
The default image to use for animation frames with no defined image.
Definition: unit.cpp:2554
std::string image_halo() const
Get the unit's halo image.
Definition: unit.hpp:1619
const std::vector< std::string > & overlays() const
Get the unit's overlay images.
Definition: unit.hpp:1670
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
Definition: unit.hpp:1378
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1397
map_location::direction facing() const
The current direction this unit is facing within its hex.
Definition: unit.hpp:1413
bool is_flying() const
Check if the unit is a flying unit.
Definition: unit.hpp:1506
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:317
std::string orb_two_color
std::string path
Definition: filesystem.cpp:92
bool show_status_on_ally_orb
unsigned int tile_size
Definition: game_config.cpp:55
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
constexpr SDL_FRect precise_subrect(const Rect &base, const SDL_FPoint &tl, const SDL_FPoint &br)
Definition: rect.hpp:191
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
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.
std::string_view data
Definition: picture.cpp:178
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:49
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
mock_char c
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