38 #define LOG_DP LOG_STREAM(info, log_display)
46 std::unique_ptr<image::locator> get_orb_image(
orb_status os)
53 + moved_color +
")~RC(magenta>" + partial_color +
")");
69 std::unique_ptr<image::locator> get_playing_ally_orb_image(
orb_status os)
86 + allied_color +
")~RC(magenta>" + status_color +
")");
89 void draw_bar(
int xpos,
int ypos,
int bar_height,
double filled,
const color_t& col)
92 static constexpr
unsigned int bar_width = 4;
94 static constexpr
color_t bar_color_bg{0, 0, 0, 80};
95 static constexpr
color_t bar_color_border{213, 213, 213, 200};
113 bar_rect.w = std::clamp<int>(bar_rect.w, 0,
display::hex_size() * 0.80 - offset.x);
114 bar_rect.h = std::clamp<int>(bar_rect.h, 0,
display::hex_size() * 0.80 - offset.y);
116 filled = std::clamp<double>(filled, 0.0, 1.0);
117 const int unfilled =
static_cast<std::size_t
>(bar_rect.h * (1.0 - filled));
120 const rect fill_rect {
122 bar_rect.y + unfilled,
124 bar_rect.h - unfilled
140 , dc(disp.get_disp_context())
142 , halo_man(thedisp.get_halo_manager())
143 , viewing_team_ref(disp.viewing_team())
144 , playing_team_ref(disp.playing_team())
145 , is_blindfolded(disp.is_blindfolded())
146 , show_everything(disp.show_everything())
148 , mouse_hex(disp.mouseover_hex())
149 , zoom_factor(disp.get_zoom_factor())
150 , hex_size(disp.hex_size())
151 , hex_size_by_2(disp.hex_size() / 2)
161 return loc ==
sel_hex || is_highlighted_enemy;
190 xp_color.a = hp_color.a;
195 ac.
anim_->update_last_draw_time();
202 if (!ac.
anim_)
return;
208 ac.
anim_->update_last_draw_time();
225 if (is_flying && height_adjust < 0) {
228 params.
y -= height_adjust;
229 params.
halo_y -= height_adjust;
232 double blend_ratio = 0;
277 if(draw_bars && (
prefs::get().show_side_colors() || is_selected_hex)) {
283 const auto& cfg_offset_x = type_cfg[
"bar_offset_x"];
284 const auto& cfg_offset_y = type_cfg[
"bar_offset_y"];
287 if(cfg_offset_x.empty() && cfg_offset_y.empty()) {
295 xoff = cfg_offset_x.to_int();
296 yoff = cfg_offset_y.to_int();
300 std::unique_ptr<image::locator> orb_img =
nullptr;
312 orb_img = get_orb_image(os);
316 orb_img = get_playing_ally_orb_image(os);
320 orb_img = get_orb_image(os);
324 std::vector<texture> textures;
326 if(orb_img !=
nullptr) {
332 textures.push_back(std::move(tex));
336 for(
const std::string& ov : u.
overlays()) {
338 textures.push_back(std::move(tex));
343 for(
const std::string& ov : overlays_abilities) {
345 textures.push_back(std::move(tex));
350 textures = std::move(textures),
351 adj_y = adjusted_params.y,
353 bar_hp_height =
static_cast<int>(max_hitpoints * u.
hp_bar_scaling()),
354 bar_xp_height =
static_cast<int>(max_experience * u.
xp_bar_scaling() / std::max<int>(u.
level(), 1))
356 const point origin { d.x + xoff, d.y + yoff + adj_y };
358 for(
const texture& tex : textures) {
359 draw::blit(tex, display::scaled_to_zoom({origin.x, origin.y, tex.w(), tex.h()}));
362 if(max_hitpoints > 0) {
366 double filled =
static_cast<double>(hitpoints) /
static_cast<double>(max_hitpoints);
367 draw_bar(origin.x + hp_offset, origin.y, bar_hp_height, filled, hp_color);
370 if(experience > 0 && can_advance) {
371 double filled =
static_cast<double>(experience) /
static_cast<double>(max_experience);
372 draw_bar(origin.x, origin.y, bar_xp_height, filled, xp_color);
381 const terrain_type& terrain_dst_info = map.get_terrain_info(terrain_dst);
385 int height_adjust_unit =
static_cast<int>(terrain_info.unit_height_adjust() * (1.0 - adjusted_params.offset) +
387 if (is_flying && height_adjust_unit < 0) {
388 height_adjust_unit = 0;
390 params.y -= height_adjust_unit - height_adjust;
391 params.halo_y -= height_adjust_unit - height_adjust;
396 adjusted_params.offset * xdst
397 + (1.0 - adjusted_params.offset) * xsrc
402 adjusted_params.offset * ydst
403 + (1.0 - adjusted_params.offset) * ysrc
405 + hex_size_by_2 - height_adjust_unit * zoom_factor;
407 bool has_halo = ac.unit_halo_ && ac.unit_halo_->valid();
408 if(!has_halo && !u.image_halo().empty()) {
409 ac.unit_halo_ = halo_man.add(
411 u.image_halo() + u.TC_image_mods(),
415 if(has_halo && u.image_halo().empty()) {
416 halo_man.remove(ac.unit_halo_);
417 ac.unit_halo_.reset();
418 }
else if(has_halo) {
419 halo_man.set_location(ac.unit_halo_, halo_x, halo_y);
422 const std::vector<std::string> halos_abilities = u.halo_abilities();
423 bool has_abil_halo = !ac.abil_halos_.empty() && ac.abil_halos_.front()->valid();
424 if(!has_abil_halo && !halos_abilities.empty()) {
425 for(
const std::string& halo_ab : halos_abilities){
428 halo_ab + u.TC_image_mods(),
431 if(abil_halo->valid()){
432 ac.abil_halos_.push_back(abil_halo);
436 if(has_abil_halo && (ac.abil_halos_ref_ != halos_abilities || halos_abilities.empty())){
438 halo_man.remove(abil_halo);
440 ac.abil_halos_.clear();
441 if(!halos_abilities.empty()){
442 for(
const std::string& halo_ab : halos_abilities){
445 halo_ab + u.TC_image_mods(),
448 if(abil_halo->valid()){
449 ac.abil_halos_.push_back(abil_halo);
453 }
else if(has_abil_halo){
455 halo_man.set_location(abil_halo, halo_x, halo_y);
459 ac.abil_halos_ref_ = halos_abilities;
461 ac.anim_->redraw(params, halo_man);
462 ac.refreshing_ =
false;
468 if(ellipse ==
"none") {
473 if(!ellipse.empty()) {
476 path <<
"misc/ellipse";
500 const int y_shift = params.
submerge > 0.0
505 [images = std::move(images), y_shift](
const rect& dest) {
506 for(
const texture& tex : images) {
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.
point get_location(const map_location &loc) const
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 ...
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.
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.
bool is_enemy(int n) const
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.
bool selected_or_reachable(const map_location &loc) const
const team & viewing_team_ref
void redraw_unit(const unit &u) const
draw a unit.
const display_context & dc
const team & playing_team_ref
void draw_ellipses(const unit &u, const frame_parameters ¶ms) const
std::set< map_location > units_that_can_reach_goal
unit_drawer(display &thedisp)
const config & get_cfg() const
This class represents a single unit of a specific type.
static const std::string & leader_crown()
The path to the leader crown overlay.
constexpr uint8_t float_to_color(double n)
Convert a double in the range [0.0,1.0] to an 8-bit colour value.
map_display and display: classes which take care of displaying the map and game-data on the screen.
Drawing functions, for drawing things on the screen.
static lg::log_domain log_display("display")
@ unit_bar
Unit bars and overlays are drawn on this layer (for testing here)
@ unit_first
Reserve layers to be selected for wml.
@ selected_hex
Image on the selected unit.
Frame for unit's animation sequence.
bool invisible(const map_location &loc, bool see_all=true) const
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 level() const
The current level of this unit.
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.
const unit_type & type() const
This unit's type, accounting for gender and variation.
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.
double xp_bar_scaling() const
The factor by which the XP bar should be scaled.
double hp_bar_scaling() const
The factor by which the HP bar should be scaled.
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.
const std::vector< std::string > overlays_abilities() const
Get the [overlay] ability overlay images.
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.
const std::vector< std::string > & overlays() const
Get the unit's overlay images.
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
bool show_status_on_ally_orb
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 prefs::get().unmoved_color(), moved_color(), etc methods, using the enum inst...
bool prefs_show_orb(orb_status os)
Wrapper for the various prefs::get().show_..._orb() methods, using the enum instead of exposing a sep...
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.
rect dst
Location on the final composed sheet.
The basic class for representing 8-bit RGB or RGBA colour values.
All parameters from a frame at a given instant.
utils::optional< color_t > blend_with
boost::tribool primary_frame
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