The Battle for Wesnoth  1.17.4+dev
drawer.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2022
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 "formatter.hpp"
22 #include "game_display.hpp"
23 #include "halo.hpp"
24 #include "map/location.hpp"
25 #include "map/map.hpp"
26 #include "picture.hpp"
27 #include "preferences/game.hpp"
28 #include "sdl/surface.hpp"
29 #include "team.hpp"
30 #include "units/animation.hpp"
32 #include "units/frame.hpp"
33 #include "units/types.hpp"
34 #include "units/unit.hpp"
35 
36 // Map of different energy bar surfaces and their dimensions.
37 static std::map<surface, SDL_Rect> energy_bar_rects;
38 
39 namespace
40 {
41 /**
42  * Wrapper which will assemble the image path (including IPF for the color from get_orb_color) for a given orb.
43  * Returns nullptr if the preferences have been configured to hide this orb.
44  */
45 std::unique_ptr<image::locator> get_orb_image(orb_status os)
46 {
47  if(os == orb_status::disengaged) {
51  return std::make_unique<image::locator>(game_config::images::orb_two_color + "~RC(ellipse_red>"
52  + moved_color + ")~RC(magenta>" + partial_color + ")");
53  }
55  }
56 
58  return nullptr;
59  auto color = orb_status_helper::get_orb_color(os);
60  return std::make_unique<image::locator>(game_config::images::orb + "~RC(magenta>" + color + ")");
61 }
62 }
63 
65  disp(thedisp),
66  dc(disp.get_disp_context()),
67  map(dc.map()),
68  teams(dc.teams()),
69  halo_man(thedisp.get_halo_manager()),
70  viewing_team(disp.viewing_team()),
71  playing_team(disp.playing_team()),
72  viewing_team_ref(teams[viewing_team]),
73  playing_team_ref(teams[playing_team]),
74  is_blindfolded(disp.is_blindfolded()),
75  show_everything(disp.show_everything()),
76  sel_hex(disp.selected_hex()),
77  mouse_hex(disp.mouseover_hex()),
78  zoom_factor(disp.get_zoom_factor()),
79  hex_size(disp.hex_size()),
80  hex_size_by_2(disp.hex_size()/2)
81 {
82  if(const game_display* game_display = dynamic_cast<class game_display*>(&disp)) {
84  }
85 
86  // This used to be checked in the drawing code, where it simply triggered skipping some logic.
87  // However, I think it's obsolete, and that the initialization of viewing_team_ref would already
88  // be undefined behavior in the situation where this assert fails.
89  assert(disp.team_valid());
90 }
91 
92 void unit_drawer::redraw_unit (const unit & u) const
93 {
95  map_location loc = u.get_location();
96 
97  int side = u.side();
98 
99  bool hidden = u.get_hidden();
100  bool is_flying = u.is_flying();
101  map_location::DIRECTION facing = u.facing();
102  int hitpoints = u.hitpoints();
103  int max_hitpoints = u.max_hitpoints();
104 
105  bool can_recruit = u.can_recruit();
106  bool can_advance = u.can_advance();
107 
108  int experience = u.experience();
109  int max_experience = u.max_experience();
110 
111  bool emit_zoc = u.emits_zoc();
112 
113  color_t hp_color=u.hp_color();
114  color_t xp_color=u.xp_color();
115 
116  std::string ellipse=u.image_ellipse();
117 
118  const bool is_highlighted_enemy = units_that_can_reach_goal.count(loc) > 0;
119  const bool is_selected_hex = (loc == sel_hex || is_highlighted_enemy);
120 
122  ac.clear_haloes();
123  if(ac.anim_) {
124  ac.anim_->update_last_draw_time();
125  }
126  return;
127  }
128 
129  if (!ac.anim_) {
130  ac.set_standing();
131  if (!ac.anim_) return;
132  }
133 
134  if (ac.refreshing_) return;
135  ac.refreshing_ = true;
136 
137  ac.anim_->update_last_draw_time();
138  frame_parameters params;
139  const t_translation::terrain_code terrain = map.get_terrain(loc);
140  const terrain_type& terrain_info = map.get_terrain_info(terrain);
141 
142  // do not set to 0 so we can distinguish the flying from the "not on submerge terrain"
143  // instead use -1.0 (as in "negative depth", it will be ignored by rendering)
144  params.submerge= is_flying ? -1.0 : terrain_info.unit_submerge();
145 
146  if(u.invisible(loc) && params.highlight_ratio > 0.6) {
147  params.highlight_ratio = 0.6;
148  }
149  if (is_selected_hex && params.highlight_ratio == 1.0) {
150  params.highlight_ratio = 1.5;
151  }
152 
153  int height_adjust = static_cast<int>(terrain_info.unit_height_adjust() * zoom_factor);
154  if (is_flying && height_adjust < 0) {
155  height_adjust = 0;
156  }
157  params.y -= height_adjust;
158  params.halo_y -= height_adjust;
159 
160  int red = 0,green = 0,blue = 0,tints = 0;
161  double blend_ratio = 0;
162  // Add future colored states here
163  if(u.poisoned()) {
164  green += 255;
165  blend_ratio += 0.25;
166  tints += 1;
167  }
168  if(u.slowed()) {
169  red += 191;
170  green += 191;
171  blue += 255;
172  blend_ratio += 0.25;
173  tints += 1;
174  }
175  if(tints > 0) {
176  params.blend_with = color_t((red/tints),(green/tints),(blue/tints));
177  params.blend_ratio = ((blend_ratio/tints));
178  }
179 
180  //hackish : see unit_frame::merge_parameters
181  // we use image_mod on the primary image
182  // and halo_mod on secondary images and all haloes
183  params.image_mod = u.image_mods();
184  params.halo_mod = u.TC_image_mods();
185  params.image= u.default_anim_image();
186 
187 
188  if(u.incapacitated()) params.image_mod +="~GS()";
189  params.primary_frame = true;
190 
191 
192  const frame_parameters adjusted_params = ac.anim_->get_current_params(params);
193 
194  const map_location dst = loc.get_direction(facing);
195  const int xsrc = disp.get_location_x(loc);
196  const int ysrc = disp.get_location_y(loc);
197  const int xdst = disp.get_location_x(dst);
198  const int ydst = disp.get_location_y(dst);
199 
200  const int x = static_cast<int>(adjusted_params.offset * xdst + (1.0-adjusted_params.offset) * xsrc) + hex_size_by_2;
201  const int y = static_cast<int>(adjusted_params.offset * ydst + (1.0-adjusted_params.offset) * ysrc) + hex_size_by_2;
202 
203  bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
204  if(!has_halo && !u.image_halo().empty()) {
205  ac.unit_halo_ = halo_man.add(x, y - height_adjust, u.image_halo()+u.TC_image_mods(), map_location(-1, -1));
206  }
207  if(has_halo && u.image_halo().empty()) {
209  ac.unit_halo_.reset();
210  } else if(has_halo) {
211  halo_man.set_location(ac.unit_halo_, x, y - height_adjust);
212  }
213 
214  // We draw bars only if wanted, visible on the map view
215  bool draw_bars = ac.draw_bars_ ;
216  if (draw_bars) {
217  SDL_Rect unit_rect {xsrc, ysrc +adjusted_params.y, hex_size, hex_size};
218  draw_bars = sdl::rects_overlap(unit_rect, disp.map_outside_area());
219  }
220  surface ellipse_front(nullptr);
221  surface ellipse_back(nullptr);
222  int ellipse_floating = 0;
223  // Always show the ellipse for selected units
224  if(draw_bars && (preferences::show_side_colors() || is_selected_hex)) {
225  if(adjusted_params.submerge > 0.0) {
226  // The division by 2 seems to have no real meaning,
227  // It just works fine with the current center of ellipse
228  // and prevent a too large adjust if submerge = 1.0
229  ellipse_floating = static_cast<int>(adjusted_params.submerge * hex_size_by_2);
230  }
231 
232  if(ellipse.empty()){
233  ellipse="misc/ellipse";
234  }
235 
236  if(ellipse != "none") {
237  // check if the unit has a ZoC or can recruit
238  const std::string nozoc = !emit_zoc ? "nozoc-" : "";
239  const std::string leader = can_recruit ? "leader-" : "";
240  const std::string selected = is_selected_hex? "selected-" : "";
241  const std::string tc = team::get_side_color_id(side);
242 
243  const std::string ellipse_top = formatter() << ellipse << "-" << leader << nozoc << selected << "top.png~RC(ellipse_red>" << tc << ")";
244  const std::string ellipse_bot = formatter() << ellipse << "-" << leader << nozoc << selected << "bottom.png~RC(ellipse_red>" << tc << ")";
245 
246  // Load the ellipse parts recolored to match team color
247  ellipse_back = image::get_image(image::locator(ellipse_top), image::SCALED_TO_ZOOM);
248  ellipse_front = image::get_image(image::locator(ellipse_bot), image::SCALED_TO_ZOOM);
249  }
250  }
251  if (ellipse_back != nullptr) {
252  //disp.drawing_buffer_add(display::LAYER_UNIT_BG, loc,
254  xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_back);
255  }
256 
257  if (ellipse_front != nullptr) {
258  //disp.drawing_buffer_add(display::LAYER_UNIT_FG, loc,
260  xsrc, ysrc +adjusted_params.y-ellipse_floating, ellipse_front);
261  }
262  if(draw_bars) {
263  const auto& type_cfg = u.type().get_cfg();
264  const auto& cfg_offset_x = type_cfg["bar_offset_x"];
265  const auto& cfg_offset_y = type_cfg["bar_offset_y"];
266  int xoff;
267  int yoff;
268  if(cfg_offset_x.empty() && cfg_offset_y.empty()) {
270  xoff = !unit_img ? 0 : (hex_size - unit_img->w)/2;
271  yoff = !unit_img ? 0 : (hex_size - unit_img->h)/2;
272  }
273  else {
274  xoff = cfg_offset_x.to_int();
275  yoff = cfg_offset_y.to_int();
276  }
277 
278  const std::string* energy_file = &game_config::images::energy;
279 
280  using namespace orb_status_helper;
281  std::unique_ptr<image::locator> orb_img = nullptr;
282  if(viewing_team_ref.is_enemy(side)) {
283  if(!u.incapacitated())
284  orb_img = get_orb_image(orb_status::enemy);
285  } else if(static_cast<std::size_t>(side) != playing_team + 1) {
286  // We're looking at either the player's own unit or an ally's unit, but either way it
287  // doesn't belong to the playing_team and isn't expected to move until after its next
288  // turn refresh.
289  auto os = orb_status::moved;
290  if(static_cast<std::size_t>(side) != viewing_team + 1)
291  os = orb_status::allied;
292  orb_img = get_orb_image(os);
293  } else {
294  // We're looking at either the player's own unit, or an ally's unit, during the unit's
295  // owner's turn.
296  auto os = dc.unit_orb_status(u);
297  orb_img = get_orb_image(os);
298  }
299 
300  if(orb_img != nullptr) {
302  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xsrc + xoff, ysrc + yoff + adjusted_params.y, orb);
303  }
304 
305  double unit_energy = 0.0;
306  if(max_hitpoints > 0) {
307  unit_energy = static_cast<double>(hitpoints)/static_cast<double>(max_hitpoints);
308  }
309  const int bar_shift = static_cast<int>(-5*zoom_factor);
310  const int hp_bar_height = static_cast<int>(max_hitpoints * u.hp_bar_scaling());
311 
312  const int32_t bar_alpha = (loc == mouse_hex || is_selected_hex) ? floating_to_fixed_point(1.0): floating_to_fixed_point(0.8);
313 
314  draw_bar(*energy_file, xsrc+xoff+bar_shift, ysrc+yoff+adjusted_params.y,
315  loc, hp_bar_height, unit_energy,hp_color, bar_alpha);
316 
317  if(experience > 0 && can_advance) {
318  const double filled = static_cast<double>(experience) / static_cast<double>(max_experience);
319  const int xp_bar_height = static_cast<int>(max_experience * u.xp_bar_scaling() / std::max<int>(u.level(),1));
320 
321  draw_bar(*energy_file, xsrc+xoff, ysrc+yoff+adjusted_params.y,
322  loc, xp_bar_height, filled, xp_color, bar_alpha);
323  }
324 
325  if (can_recruit) {
327  if(crown) {
329  loc, xsrc+xoff, ysrc+yoff+adjusted_params.y, crown);
330  }
331  }
332 
333  for(const std::string& ov : u.overlays()) {
335  if(ov_img != nullptr) {
337  loc, xsrc+xoff, ysrc+yoff+adjusted_params.y, ov_img);
338  }
339  }
340  }
341 
342  // Smooth unit movements from terrain of different elevation.
343  // Do this separately from above so that the health bar doesn't go up and down.
344 
345  const t_translation::terrain_code terrain_dst = map.get_terrain(dst);
346  const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
347 
348  // height_adjust_unit is not scaled by zoom_factor here otherwise it results in a squared offset that results in #5974
349  // It appears the tiles and units are scaled together somewhere else
350  int height_adjust_unit = static_cast<int>(terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
351  terrain_dst_info.unit_height_adjust() * adjusted_params.offset);
352  if (is_flying && height_adjust_unit < 0) {
353  height_adjust_unit = 0;
354  }
355  params.y -= height_adjust_unit - height_adjust;
356  params.halo_y -= height_adjust_unit - height_adjust;
357 
358  ac.anim_->redraw(params, halo_man);
359  ac.refreshing_ = false;
360 }
361 
362 void unit_drawer::draw_bar(const std::string& image, int xpos, int ypos,
363  const map_location& loc, std::size_t height, double filled,
364  const color_t& col, int32_t alpha) const
365 {
366 
367  filled = std::min<double>(std::max<double>(filled,0.0),1.0);
368  height = static_cast<std::size_t>(height*zoom_factor);
369 
371 
372  // We use UNSCALED because scaling (and bilinear interpolation)
373  // is bad for calculate_energy_bar.
374  // But we will do a geometric scaling later.
375  surface bar_surf(image::get_image(image));
376  if(surf == nullptr || bar_surf == nullptr) {
377  return;
378  }
379 
380  // calculate_energy_bar returns incorrect results if the surface colors
381  // have changed (for example, due to bilinear interpolation)
382  const SDL_Rect& unscaled_bar_loc = calculate_energy_bar(bar_surf);
383 
384  SDL_Rect bar_loc;
385  if (surf->w == bar_surf->w && surf->h == bar_surf->h)
386  bar_loc = unscaled_bar_loc;
387  else {
388  const int32_t xratio = fixed_point_divide(surf->w,bar_surf->w);
389  const int32_t yratio = fixed_point_divide(surf->h,bar_surf->h);
390  const SDL_Rect scaled_bar_loc {
391  fixed_point_to_int(unscaled_bar_loc.x * xratio)
392  , fixed_point_to_int(unscaled_bar_loc.y * yratio + 127)
393  , fixed_point_to_int(unscaled_bar_loc.w * xratio + 255)
394  , fixed_point_to_int(unscaled_bar_loc.h * yratio + 255)
395  };
396  bar_loc = scaled_bar_loc;
397  }
398 
399  if(height > static_cast<std::size_t>(bar_loc.h)) {
400  height = bar_loc.h;
401  }
402 
403  const std::size_t skip_rows = bar_loc.h - height;
404 
405  SDL_Rect top {0, 0, surf->w, bar_loc.y};
406  SDL_Rect bot = sdl::create_rect(0, bar_loc.y + skip_rows, surf->w, 0);
407  bot.h = surf->w - bot.y;
408 
409  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos, surf, top);
410  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf, bot);
411 
412  std::size_t unfilled = static_cast<std::size_t>(height * (1.0 - filled));
413 
414  if(unfilled < height && alpha >= floating_to_fixed_point(0.3)) {
415  const uint8_t r_alpha = std::min<unsigned>(fixed_point_multiply(alpha,255),255);
416  surface filled_surf(bar_loc.w, height - unfilled);
417  SDL_Rect filled_area = sdl::create_rect(0, 0, bar_loc.w, height-unfilled);
418  sdl::fill_surface_rect(filled_surf,&filled_area,SDL_MapRGBA(bar_surf->format,col.r,col.g,col.b, r_alpha));
419  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf);
420  }
421 }
422 
424  bool operator()(uint32_t color) const { return (color&0xFF000000) > 0x10000000 &&
425  (color&0x00FF0000) < 0x00100000 &&
426  (color&0x0000FF00) < 0x00001000 &&
427  (color&0x000000FF) < 0x00000010; }
428 };
429 
430 const SDL_Rect& unit_drawer::calculate_energy_bar(surface surf) const
431 {
432  const std::map<surface,SDL_Rect>::const_iterator i = energy_bar_rects.find(surf);
433  if(i != energy_bar_rects.end()) {
434  return i->second;
435  }
436 
437  int first_row = -1, last_row = -1, first_col = -1, last_col = -1;
438 
439  const_surface_lock image_lock(surf);
440  const uint32_t* const begin = image_lock.pixels();
441 
442  for(int y = 0; y != surf->h; ++y) {
443  const uint32_t* const i1 = begin + surf->w*y;
444  const uint32_t* const i2 = i1 + surf->w;
445  const uint32_t* const itor = std::find_if(i1,i2,is_energy_color());
446  const int count = std::count_if(itor,i2,is_energy_color());
447 
448  if(itor != i2) {
449  if(first_row == -1) {
450  first_row = y;
451  }
452 
453  first_col = itor - i1;
454  last_col = first_col + count;
455  last_row = y;
456  }
457  }
458 
459  const SDL_Rect res {
460  first_col
461  , first_row
462  , last_col-first_col
463  , last_row+1-first_row
464  };
465  energy_bar_rects.emplace(surf, res);
466  return calculate_energy_bar(surf);
467 }
surface get_image(const image::locator &i_locator, TYPE type)
Caches and returns an image.
Definition: picture.cpp:830
bool refreshing_
avoid infinite recursion.
pixel_t * pixels() const
Definition: surface.hpp:162
Reserve layers to be selected for WML.
Definition: display.hpp:807
All parameters from a frame at a given instant.
Definition: frame.hpp:35
image::locator image
Definition: frame.hpp:41
constexpr int fixed_point_to_int(int32_t n)
If positive, just bit shift.
Definition: math.hpp:227
bool is_blindfolded
Definition: drawer.hpp:59
std::optional< color_t > blend_with
Definition: frame.hpp:55
This class represents a single unit of a specific type.
Definition: unit.hpp:120
bool is_flying() const
Check if the unit is a flying unit.
Definition: unit.hpp:1454
bool rects_overlap(const SDL_Rect &rect1, const SDL_Rect &rect2)
Tests whether two rectangles overlap.
Definition: rect.cpp:34
const std::set< map_location > & units_that_can_reach_goal() const
Return the locations of units that can reach goal (.
std::unique_ptr< unit_animation > anim_
The current animation.
double unit_submerge() const
Definition: terrain.hpp:138
int hitpoints() const
The current number of hitpoints this unit has.
Definition: unit.hpp:489
Frame for unit&#39;s animation sequence.
int hex_size
Definition: drawer.hpp:66
halo::manager & halo_man
Definition: drawer.hpp:54
void fill_surface_rect(surface &dst, SDL_Rect *dst_rect, const uint32_t color)
Fill a rectangle on a given surface.
Definition: rect.hpp:115
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
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:98
map_location::DIRECTION facing() const
The current direction this unit is facing within its hex.
Definition: unit.hpp:1361
bool draw_bars_
bool indicating whether to draw bars with the unit
const config & get_cfg() const
Definition: types.hpp:283
Belongs to a friendly side.
std::string image_ellipse() const
Get the unit&#39;s ellipse image.
Definition: unit.hpp:1553
bool show_side_colors()
Definition: game.cpp:753
orb_status
Corresponds to the colored orbs displayed above units&#39; hp-bar and xp-bar.
Definition: orb_status.hpp:24
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
Definition: unit.hpp:710
double hp_bar_scaling() const
The factor by which the HP bar should be scaled.
Definition: unit.hpp:722
map_location get_direction(DIRECTION dir, unsigned int n=1u) const
Definition: location.cpp:360
bool team_valid() const
Definition: display.cpp:722
const unit_type & type() const
This unit&#39;s type, accounting for gender and variation.
Definition: unit.hpp:345
color_t hp_color() const
Color for this unit&#39;s current hitpoints.
Definition: unit.cpp:1085
bool poisoned() const
Check if the unit has been poisoned.
Definition: unit.hpp:884
Belongs to a non-friendly side; normally visualised by not displaying an orb.
static const std::string & leader_crown()
The path to the leader crown overlay.
Definition: unit.cpp:1037
void clear_haloes()
Clear the haloes associated to the unit.
int unit_height_adjust() const
Definition: terrain.hpp:137
std::string halo_mod
Definition: frame.hpp:50
std::ostringstream wrapper.
Definition: formatter.hpp:39
std::string get_orb_color(orb_status os)
Wrapper for the various preferences::unmoved_color(), moved_color(), etc methods, using the enum inst...
Definition: orb_status.cpp:40
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:302
const SDL_Rect & calculate_energy_bar(surface surf) const
Finds the start and end rows on the energy bar image.
Definition: drawer.cpp:430
color_t xp_color() const
Color for this unit&#39;s XP.
Definition: unit.cpp:1139
Unit bars and overlays are drawn on this layer (for testing here).
Definition: display.hpp:832
std::string selected
int hex_size_by_2
Definition: drawer.hpp:67
const gamemap & map
Definition: drawer.hpp:52
int max_experience() const
The max number of experience points this unit can have.
Definition: unit.hpp:519
uint8_t r
Red value.
Definition: color.hpp:178
bool is_enemy(int n) const
Definition: team.hpp:231
int level() const
The current level of this unit.
Definition: unit.hpp:549
map_display and display: classes which take care of displaying the map and game-data on the screen...
display & disp
Definition: drawer.hpp:50
std::string default_anim_image() const
The default image to use for animation frames with no defined image.
Definition: unit.cpp:2421
const std::vector< std::string > & overlays() const
Get the unit&#39;s overlay images.
Definition: unit.hpp:1587
constexpr unsigned fixed_point_multiply(int32_t n1, int32_t n2)
Definition: math.hpp:205
std::set< map_location > units_that_can_reach_goal
Definition: drawer.hpp:64
Generic locator abstracting the location of an image.
Definition: picture.hpp:60
static std::string get_side_color_id(unsigned side)
Definition: team.cpp:972
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 &#39;image centered on (x,y).
Definition: halo.cpp:453
Image rescaled according to the zoom settings.
Definition: picture.hpp:234
Encapsulates the map of the game.
Definition: location.hpp:38
bool invisible(const map_location &loc, bool see_all=true) const
Definition: unit.cpp:2439
double highlight_ratio
Definition: frame.hpp:58
std::size_t i
Definition: function.cpp:967
unit_animation_component & anim_comp() const
Definition: unit.hpp:1532
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:495
std::string moved_color()
Definition: general.cpp:349
std::string image_mod
Definition: frame.hpp:44
Helper class for pinning SDL surfaces into memory.
Definition: surface.hpp:142
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
Definition: unit.hpp:602
int get_location_y(const map_location &loc) const
Definition: display.cpp:742
const SDL_Rect & map_outside_area() const
Returns the available area for a map, this may differ from the above.
Definition: display.hpp:246
const team & viewing_team_ref
Definition: drawer.hpp:57
DIRECTION
Valid directions which can be moved in our hexagonal world.
Definition: location.hpp:40
const display_context & dc
Definition: drawer.hpp:51
All moves and possible attacks have been done.
std::size_t viewing_team
Definition: drawer.hpp:55
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:461
bool is_visible_to_team(const team &team, bool const see_all=true) const
Definition: unit.cpp:2482
double blend_ratio
Definition: frame.hpp:57
double xp_bar_scaling() const
The factor by which the XP bar should be scaled.
Definition: unit.hpp:731
double submerge
Definition: frame.hpp:60
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an SDL_Rect with the given dimensions.
Definition: rect.hpp:40
std::string image_halo() const
Get the unit&#39;s halo image.
Definition: unit.hpp:1544
std::string partial_color()
Definition: general.cpp:369
void drawing_buffer_add(const drawing_layer layer, const map_location &loc, int x, int y, const surface &surf, const SDL_Rect &clip=SDL_Rect())
Add an item to the drawing buffer.
Definition: display.cpp:1196
int get_location_x(const map_location &loc) const
Functions to get the on-screen positions of hexes.
Definition: display.cpp:737
Image rescaled to fit into a hexagonal tile according to the zoom settings.
Definition: picture.hpp:238
void redraw_unit(const unit &u) const
draw a unit.
Definition: drawer.cpp:92
unit_drawer(display &thedisp)
Definition: drawer.cpp:64
int experience() const
The current number of experience points this unit has.
Definition: unit.hpp:513
orb_status unit_orb_status(const unit &u) const
Returns an enumurated summary of whether this unit can move and/or attack.
const map_location & get_location() const
The current map location this unit is at.
Definition: unit.hpp:1345
Functions to load and save images from/to disk.
bool can_advance() const
Checks whether this unit has any options to advance to.
Definition: unit.hpp:262
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:893
The unit can move but can&#39;t attack, and wouldn&#39;t be able to attack even if it was moved to a hex adja...
halo::handle unit_halo_
handle to the halo of this unit
bool operator()(uint32_t color) const
Definition: drawer.cpp:424
void draw_bar(const std::string &image, int xpos, int ypos, const map_location &loc, std::size_t height, double filled, const color_t &col, int32_t alpha) const
draw a health/xp bar of a unit
Definition: drawer.cpp:362
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
Definition: unit.hpp:1326
int side() const
The side this unit belongs to.
Definition: unit.hpp:333
bool prefs_show_orb(orb_status os)
Wrapper for the various preferences::show_..._orb() methods, using the enum instead of exposing a sep...
Definition: orb_status.cpp:19
constexpr int32_t fixed_point_divide(int n1, int n2)
Definition: math.hpp:215
void set_standing(bool with_bars=true)
Sets the animation state to standing.
std::size_t playing_team
Definition: drawer.hpp:56
There are still moves and/or attacks possible, but the unit doesn&#39;t fit in the "unmoved" status...
uint8_t g
Green value.
Definition: color.hpp:181
std::string orb_two_color
uint8_t b
Blue value.
Definition: color.hpp:184
bool slowed() const
Check if the unit has been slowed.
Definition: unit.hpp:902
double zoom_factor
Definition: drawer.hpp:63
bool show_everything
Definition: drawer.hpp:60
std::string TC_image_mods() const
Constructs a recolor (RC) IPF string for this unit&#39;s team color.
Definition: unit.cpp:2590
constexpr int32_t floating_to_fixed_point(double n)
Converts a double to a fixed point.
Definition: math.hpp:195
boost::tribool primary_frame
Definition: frame.hpp:69
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
Definition: unit.cpp:2595
static std::map< surface, SDL_Rect > energy_bar_rects
Definition: drawer.cpp:37
map_location mouse_hex
Definition: drawer.hpp:62
void remove(const handle &h)
Remove the halo with the given handle.
Definition: halo.cpp:467
map_location sel_hex
Definition: drawer.hpp:61