39 #define LOG_DP LOG_STREAM(info, log_display)
47 std::unique_ptr<image::locator> get_orb_image(
orb_status os)
70 std::unique_ptr<image::locator> get_playing_ally_orb_image(
orb_status os)
90 void draw_bar(
int xpos,
int ypos,
int bar_height,
double filled,
const color_t& col)
93 static constexpr
unsigned int bar_width = 4;
95 static constexpr
color_t bar_color_bg{0, 0, 0, 80};
96 static constexpr
color_t bar_color_border{213, 213, 213, 200};
114 bar_rect.w = std::clamp<int>(bar_rect.w, 0,
display::hex_size() * 0.80 - offset.x);
115 bar_rect.h = std::clamp<int>(bar_rect.h, 0,
display::hex_size() * 0.80 - offset.y);
117 filled = std::clamp<double>(filled, 0.0, 1.0);
118 const int unfilled =
static_cast<std::size_t
>(bar_rect.h * (1.0 - filled));
121 const rect fill_rect {
123 bar_rect.y + unfilled,
125 bar_rect.h - unfilled
141 , dc(disp.get_disp_context())
144 , halo_man(thedisp.get_halo_manager())
145 , viewing_team(disp.viewing_team())
146 , playing_team(disp.playing_team())
147 , viewing_team_ref(teams[viewing_team])
148 , playing_team_ref(teams[playing_team])
149 , is_blindfolded(disp.is_blindfolded())
150 , show_everything(disp.show_everything())
151 , sel_hex(disp.selected_hex())
152 , mouse_hex(disp.mouseover_hex())
153 , zoom_factor(disp.get_zoom_factor())
154 , hex_size(disp.hex_size())
155 , hex_size_by_2(disp.hex_size() / 2)
194 const bool is_selected_hex = (loc ==
sel_hex || is_highlighted_enemy);
198 xp_color.a = hp_color.a;
203 ac.
anim_->update_last_draw_time();
210 if (!ac.
anim_)
return;
216 ac.
anim_->update_last_draw_time();
233 if (is_flying && height_adjust < 0) {
236 params.
y -= height_adjust;
237 params.
halo_y -= height_adjust;
239 int red = 0,green = 0,blue = 0,tints = 0;
240 double blend_ratio = 0;
288 int ellipse_floating = 0;
291 if(adjusted_params.submerge > 0.0) {
295 ellipse_floating =
static_cast<int>(adjusted_params.submerge *
hex_size_by_2);
299 ellipse=
"misc/ellipse";
302 if(ellipse !=
"none") {
304 const std::string nozoc = !emit_zoc ?
"nozoc-" :
"";
305 const std::string leader = can_recruit ?
"leader-" :
"";
306 const std::string
selected = is_selected_hex?
"selected-" :
"";
309 const std::string ellipse_top =
formatter() << ellipse <<
"-" << leader << nozoc <<
selected <<
"top.png~RC(ellipse_red>" << tc <<
")";
310 const std::string ellipse_bot =
formatter() << ellipse <<
"-" << leader << nozoc <<
selected <<
"bottom.png~RC(ellipse_red>" << tc <<
")";
320 const point origin { d.x, d.y + adj_y - ellipse_floating };
323 draw::blit(ellipse_back, display::scaled_to_zoom({origin.x, origin.y, ellipse_back.w(), ellipse_back.h()}));
332 const auto& type_cfg = u.type().get_cfg();
333 const auto& cfg_offset_x = type_cfg[
"bar_offset_x"];
334 const auto& cfg_offset_y = type_cfg[
"bar_offset_y"];
337 if(cfg_offset_x.empty() && cfg_offset_y.empty()) {
341 xoff = !
s.x ? 0 : (hex_size -
s.x)/2;
342 yoff = !
s.y ? 0 : (hex_size -
s.x)/2;
345 xoff = cfg_offset_x.to_int();
346 yoff = cfg_offset_y.to_int();
350 std::unique_ptr<image::locator> orb_img =
nullptr;
352 if(viewing_team_ref.is_enemy(side)) {
353 if(!u.incapacitated())
355 }
else if(
static_cast<std::size_t
>(side) != playing_team + 1) {
360 if(
static_cast<std::size_t
>(side) != viewing_team + 1)
362 orb_img = get_orb_image(os);
363 }
else if(
static_cast<std::size_t
>(side) != viewing_team + 1) {
365 auto os = dc.unit_orb_status(u);
366 orb_img = get_playing_ally_orb_image(os);
369 auto os = dc.unit_orb_status(u);
370 orb_img = get_orb_image(os);
374 std::vector<texture> textures;
376 if(orb_img !=
nullptr) {
382 textures.push_back(std::move(tex));
386 for(
const std::string& ov : u.overlays()) {
388 textures.push_back(std::move(tex));
392 const std::vector<std::string> overlays_abilities = u.overlays_abilities();
393 for(
const std::string& ov : overlays_abilities) {
395 textures.push_back(std::move(tex));
400 textures = std::move(textures),
401 adj_y = adjusted_params.y,
403 bar_hp_height =
static_cast<int>(max_hitpoints * u.hp_bar_scaling()),
404 bar_xp_height =
static_cast<int>(max_experience * u.xp_bar_scaling() / std::max<int>(u.level(), 1))
406 const point origin { d.x + xoff, d.y + yoff + adj_y };
408 for(
const texture& tex : textures) {
409 draw::blit(tex, display::scaled_to_zoom({origin.x, origin.y, tex.w(), tex.h()}));
412 if(max_hitpoints > 0) {
416 double filled =
static_cast<double>(hitpoints) /
static_cast<double>(max_hitpoints);
417 draw_bar(origin.x + hp_offset, origin.y, bar_hp_height, filled, hp_color);
420 if(experience > 0 && can_advance) {
421 double filled =
static_cast<double>(experience) /
static_cast<double>(max_experience);
422 draw_bar(origin.x, origin.y, bar_xp_height, filled, xp_color);
431 const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
435 int height_adjust_unit =
static_cast<int>(terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
437 if (is_flying && height_adjust_unit < 0) {
438 height_adjust_unit = 0;
440 params.y -= height_adjust_unit - height_adjust;
441 params.halo_y -= height_adjust_unit - height_adjust;
446 adjusted_params.offset * xdst
447 + (1.0 - adjusted_params.offset) * xsrc
452 adjusted_params.offset * ydst
453 + (1.0 - adjusted_params.offset) * ysrc
455 + hex_size_by_2 - height_adjust_unit * zoom_factor;
457 bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
458 if(!has_halo && !u.image_halo().empty()) {
459 ac.unit_halo_ = halo_man.add(
461 u.image_halo() + u.TC_image_mods(),
465 if(has_halo && u.image_halo().empty()) {
466 halo_man.remove(ac.unit_halo_);
467 ac.unit_halo_.reset();
468 }
else if(has_halo) {
469 halo_man.set_location(ac.unit_halo_, halo_x, halo_y);
472 const std::vector<std::string> halos_abilities = u.halo_abilities();
473 bool has_abil_halo = !ac.abil_halos_.empty() && ac.abil_halos_.front()->valid();
474 if(!has_abil_halo && !halos_abilities.empty()) {
475 for(
const std::string& halo_ab : halos_abilities){
478 halo_ab + u.TC_image_mods(),
481 if(abil_halo->valid()){
482 ac.abil_halos_.push_back(abil_halo);
486 if(has_abil_halo && (ac.abil_halos_ref_ != halos_abilities || halos_abilities.empty())){
488 halo_man.remove(abil_halo);
490 ac.abil_halos_.clear();
491 if(!halos_abilities.empty()){
492 for(
const std::string& halo_ab : halos_abilities){
495 halo_ab + u.TC_image_mods(),
498 if(abil_halo->valid()){
499 ac.abil_halos_.push_back(abil_halo);
503 }
else if(has_abil_halo){
505 halo_man.set_location(abil_halo, halo_x, halo_y);
509 ac.abil_halos_ref_ = halos_abilities;
511 ac.anim_->redraw(params, halo_man);
512 ac.refreshing_ =
false;
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
@ LAYER_UNIT_FIRST
Reserve layers to be selected for WML.
@ LAYER_UNIT_BAR
Unit bars and overlays are drawn on this layer (for testing here).
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 ...
int get_location_x(const map_location &loc) const
Functions to get the on-screen positions of hexes.
static double get_zoom_factor()
Returns the current zoom factor.
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.
rect map_outside_area() const
Returns the available area for a map, this may differ from the above.
int get_location_y(const map_location &loc) const
static rect scaled_to_zoom(const SDL_Rect &r)
Scale the width and height of a rect by the current zoom factor.
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.
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Generic locator abstracting the location of an image.
static std::string get_side_color_id(unsigned side)
int unit_height_adjust() const
double unit_submerge() const
Wrapper class to encapsulate creation and management of an SDL_Texture.
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.
const team & viewing_team_ref
void redraw_unit(const unit &u) const
draw a unit.
std::set< map_location > units_that_can_reach_goal
unit_drawer(display &thedisp)
This class represents a single unit of a specific type.
constexpr uint8_t float_to_color(double n)
Convert a double in the range [0.0,1.0] to an 8-bit colour value.
Drawing functions, for drawing things on the screen.
static lg::log_domain log_display("display")
Frame for unit's animation sequence.
bool invisible(const map_location &loc, bool see_all=true) const
bool is_visible_to_team(const team &team, bool const see_all=true) const
int max_hitpoints() const
The max number of hitpoints this unit can have.
bool incapacitated() const
Check if the unit has been petrified.
int hitpoints() const
The current number of hitpoints this unit has.
bool slowed() const
Check if the unit has been slowed.
bool get_hidden() const
Gets whether this unit is currently hidden on the map.
int experience() const
The current number of experience points this unit has.
bool can_recruit() const
Whether this unit can recruit other units - ie, are they a leader unit.
int side() const
The side this unit belongs to.
bool poisoned() const
Check if the unit has been poisoned.
int max_experience() const
The max number of experience points this unit can have.
bool can_advance() const
Checks whether this unit has any options to advance to.
color_t xp_color() const
Color for this unit's XP.
unit_animation_component & anim_comp() const
color_t hp_color() const
Color for this unit's current hitpoints.
std::string TC_image_mods() const
Constructs a recolor (RC) IPF string for this unit's team color.
std::string image_ellipse() const
Get the unit's ellipse image.
std::string image_mods() const
Gets an IPF string containing all IPF image mods.
std::string default_anim_image() const
The default image to use for animation frames with no defined image.
bool emits_zoc() const
Tests whether the unit has a zone-of-control, considering incapacitated.
const map_location & get_location() const
The current map location this unit is at.
map_location::DIRECTION facing() const
The current direction this unit is facing within its hex.
bool is_flying() const
Check if the unit is a flying unit.
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.
void blit(const texture &tex, const SDL_Rect &dst)
Draws a texture, or part of a texture, at the given location.
void rect(const SDL_Rect &rect)
Draw a rectangle.
std::string orb_two_color
std::shared_ptr< halo_record > handle
texture get_texture(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image texture suitable for hardware-accelerated rendering.
point get_size(const locator &i_locator, bool skip_cache)
Returns the width and height of an image.
std::string get_orb_color(orb_status os)
Wrapper for the various preferences::unmoved_color(), moved_color(), etc methods, using the enum inst...
bool prefs_show_orb(orb_status os)
Wrapper for the various preferences::show_..._orb() methods, using the enum instead of exposing a sep...
std::string moved_color()
std::string partial_color()
bool show_status_on_ally_orb()
std::string allied_color()
orb_status
Corresponds to the colored orbs displayed above units' hp-bar and xp-bar.
@ 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.
The basic class for representing 8-bit RGB or RGBA colour values.
All parameters from a frame at a given instant.
boost::tribool primary_frame
std::optional< color_t > blend_with
Encapsulates the map of the game.
DIRECTION
Valid directions which can be moved in our hexagonal world.
map_location get_direction(DIRECTION dir, unsigned int n=1u) const
An abstract description of a rectangle with integer coordinates.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
static map_location::DIRECTION s