The Battle for Wesnoth  1.17.0-dev
drawer.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2021
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 fixed_t bar_alpha = (loc == mouse_hex || is_selected_hex) ? ftofxp(1.0): ftofxp(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) {
328  //if(bar_alpha != ftofxp(1.0)) {
329  // crown = adjust_surface_alpha(crown, bar_alpha);
330  //}
332  loc, xsrc+xoff, ysrc+yoff+adjusted_params.y, crown);
333  }
334  }
335 
336  for(const std::string& ov : u.overlays()) {
338  if(ov_img != nullptr) {
340  loc, xsrc+xoff, ysrc+yoff+adjusted_params.y, ov_img);
341  }
342  }
343  }
344 
345  // Smooth unit movements from terrain of different elevation.
346  // Do this separately from above so that the health bar doesn't go up and down.
347 
348  const t_translation::terrain_code terrain_dst = map.get_terrain(dst);
349  const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
350 
351  int height_adjust_unit = static_cast<int>((terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
352  terrain_dst_info.unit_height_adjust() * adjusted_params.offset) *
353  zoom_factor);
354  if (is_flying && height_adjust_unit < 0) {
355  height_adjust_unit = 0;
356  }
357  params.y -= height_adjust_unit - height_adjust;
358  params.halo_y -= height_adjust_unit - height_adjust;
359 
360  ac.anim_->redraw(params, halo_man);
361  ac.refreshing_ = false;
362 }
363 
364 void unit_drawer::draw_bar(const std::string& image, int xpos, int ypos,
365  const map_location& loc, std::size_t height, double filled,
366  const color_t& col, fixed_t alpha) const
367 {
368 
369  filled = std::min<double>(std::max<double>(filled,0.0),1.0);
370  height = static_cast<std::size_t>(height*zoom_factor);
371 
373 
374  // We use UNSCALED because scaling (and bilinear interpolation)
375  // is bad for calculate_energy_bar.
376  // But we will do a geometric scaling later.
377  surface bar_surf(image::get_image(image));
378  if(surf == nullptr || bar_surf == nullptr) {
379  return;
380  }
381 
382  // calculate_energy_bar returns incorrect results if the surface colors
383  // have changed (for example, due to bilinear interpolation)
384  const SDL_Rect& unscaled_bar_loc = calculate_energy_bar(bar_surf);
385 
386  SDL_Rect bar_loc;
387  if (surf->w == bar_surf->w && surf->h == bar_surf->h)
388  bar_loc = unscaled_bar_loc;
389  else {
390  const fixed_t xratio = fxpdiv(surf->w,bar_surf->w);
391  const fixed_t yratio = fxpdiv(surf->h,bar_surf->h);
392  const SDL_Rect scaled_bar_loc {
393  fxptoi(unscaled_bar_loc. x * xratio)
394  , fxptoi(unscaled_bar_loc. y * yratio + 127)
395  , fxptoi(unscaled_bar_loc. w * xratio + 255)
396  , fxptoi(unscaled_bar_loc. h * yratio + 255)
397  };
398  bar_loc = scaled_bar_loc;
399  }
400 
401  if(height > static_cast<std::size_t>(bar_loc.h)) {
402  height = bar_loc.h;
403  }
404 
405  //if(alpha != ftofxp(1.0)) {
406  // surf.assign(adjust_surface_alpha(surf,alpha));
407  // if(surf == nullptr) {
408  // return;
409  // }
410  //}
411 
412  const std::size_t skip_rows = bar_loc.h - height;
413 
414  SDL_Rect top {0, 0, surf->w, bar_loc.y};
415  SDL_Rect bot = sdl::create_rect(0, bar_loc.y + skip_rows, surf->w, 0);
416  bot.h = surf->w - bot.y;
417 
418  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos, surf, top);
419  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos, ypos + top.h, surf, bot);
420 
421  std::size_t unfilled = static_cast<std::size_t>(height * (1.0 - filled));
422 
423  if(unfilled < height && alpha >= ftofxp(0.3)) {
424  const uint8_t r_alpha = std::min<unsigned>(unsigned(fxpmult(alpha,255)),255);
425  surface filled_surf(bar_loc.w, height - unfilled);
426  SDL_Rect filled_area = sdl::create_rect(0, 0, bar_loc.w, height-unfilled);
427  sdl::fill_surface_rect(filled_surf,&filled_area,SDL_MapRGBA(bar_surf->format,col.r,col.g,col.b, r_alpha));
428  disp.drawing_buffer_add(display::LAYER_UNIT_BAR, loc, xpos + bar_loc.x, ypos + bar_loc.y + unfilled, filled_surf);
429  }
430 }
431 
433  bool operator()(uint32_t color) const { return (color&0xFF000000) > 0x10000000 &&
434  (color&0x00FF0000) < 0x00100000 &&
435  (color&0x0000FF00) < 0x00001000 &&
436  (color&0x000000FF) < 0x00000010; }
437 };
438 
439 const SDL_Rect& unit_drawer::calculate_energy_bar(surface surf) const
440 {
441  const std::map<surface,SDL_Rect>::const_iterator i = energy_bar_rects.find(surf);
442  if(i != energy_bar_rects.end()) {
443  return i->second;
444  }
445 
446  int first_row = -1, last_row = -1, first_col = -1, last_col = -1;
447 
448  const_surface_lock image_lock(surf);
449  const uint32_t* const begin = image_lock.pixels();
450 
451  for(int y = 0; y != surf->h; ++y) {
452  const uint32_t* const i1 = begin + surf->w*y;
453  const uint32_t* const i2 = i1 + surf->w;
454  const uint32_t* const itor = std::find_if(i1,i2,is_energy_color());
455  const int count = std::count_if(itor,i2,is_energy_color());
456 
457  if(itor != i2) {
458  if(first_row == -1) {
459  first_row = y;
460  }
461 
462  first_col = itor - i1;
463  last_col = first_col + count;
464  last_row = y;
465  }
466  }
467 
468  const SDL_Rect res {
469  first_col
470  , first_row
471  , last_col-first_col
472  , last_row+1-first_row
473  };
474  energy_bar_rects.emplace(surf, res);
475  return calculate_energy_bar(surf);
476 }
surface get_image(const image::locator &i_locator, TYPE type)
Caches and returns an image.
Definition: picture.cpp:816
bool refreshing_
avoid infinite recursion.
pixel_t * pixels() const
Definition: surface.hpp:162
Reserve layers to be selected for WML.
Definition: display.hpp:833
All parameters from a frame at a given instant.
Definition: frame.hpp:35
image::locator image
Definition: frame.hpp:41
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:121
#define fxptoi(x)
IN: fixed_t - OUT: int.
Definition: math.hpp:327
bool is_flying() const
Check if the unit is a flying unit.
Definition: unit.hpp:1455
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:490
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:50
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:1362
bool draw_bars_
bool indicating whether to draw bars with the unit
const config & get_cfg() const
Definition: types.hpp:285
#define h
Belongs to a friendly side.
std::string image_ellipse() const
Get the unit&#39;s ellipse image.
Definition: unit.hpp:1554
bool show_side_colors()
Definition: game.cpp:760
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:711
double hp_bar_scaling() const
The factor by which the HP bar should be scaled.
Definition: unit.hpp:723
map_location get_direction(DIRECTION dir, unsigned int n=1u) const
Definition: location.cpp:360
bool team_valid() const
Definition: display.cpp:735
const unit_type & type() const
This unit&#39;s type, accounting for gender and variation.
Definition: unit.hpp:346
color_t hp_color() const
Color for this unit&#39;s current hitpoints.
Definition: unit.cpp:1052
bool poisoned() const
Check if the unit has been poisoned.
Definition: unit.hpp:885
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:1004
void clear_haloes()
Clear the haloes associated to the unit.
int unit_height_adjust() const
Definition: terrain.hpp:137
#define fxpmult(x, y)
IN: unsigned and fixed_t - OUT: unsigned.
Definition: math.hpp:321
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:439
color_t xp_color() const
Color for this unit&#39;s XP.
Definition: unit.cpp:1106
#define fxpdiv(x, y)
IN: unsigned and int - OUT: fixed_t.
Definition: math.hpp:324
Unit bars and overlays are drawn on this layer (for testing here).
Definition: display.hpp:858
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:520
uint8_t r
Red value.
Definition: color.hpp:178
bool is_enemy(int n) const
Definition: team.hpp:255
int level() const
The current level of this unit.
Definition: unit.hpp:550
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:2388
const std::vector< std::string > & overlays() const
Get the unit&#39;s overlay images.
Definition: unit.hpp:1588
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, fixed_t alpha) const
draw a health/xp bar of a unit
Definition: drawer.cpp:364
int32_t fixed_t
Definition: math.hpp:313
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:973
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
#define ftofxp(x)
IN: float or int - OUT: fixed_t.
Definition: math.hpp:318
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:2406
double highlight_ratio
Definition: frame.hpp:58
std::size_t i
Definition: function.cpp:967
unit_animation_component & anim_comp() const
Definition: unit.hpp:1533
int max_hitpoints() const
The max number of hitpoints this unit can have.
Definition: unit.hpp:496
std::string moved_color()
Definition: general.cpp:343
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:603
int get_location_y(const map_location &loc) const
Definition: display.cpp:755
const SDL_Rect & map_outside_area() const
Returns the available area for a map, this may differ from the above.
Definition: display.hpp:242
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
int w
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:2449
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:732
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:1545
std::string partial_color()
Definition: general.cpp:363
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:1209
int get_location_x(const map_location &loc) const
Functions to get the on-screen positions of hexes.
Definition: display.cpp:750
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:514
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:1346
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:263
bool incapacitated() const
Check if the unit has been petrified.
Definition: unit.hpp:894
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:433
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
Definition: unit.hpp:1327
int side() const
The side this unit belongs to.
Definition: unit.hpp:334
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
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:903
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:2557
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:2562
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