Another large batch of progress, primarily in game_display
This is primarily focused on getting various areas of the game display drawing, such as footstep images and the terrain defense indicators. To facilitate the last, I've refactored draw_text_in_hex to utilize floating labels instead of drawing to hex directly with surfaces. This probably isn't the most optimal solution, since labels are continuously created and destroyed, but since their text is usually short and cached in the rendered text cache it does for now. Also includes some cleanup of deprecated functions in display, and slight reordering of drawing order of certain elements.
This commit is contained in:
parent
92d51b866d
commit
3376ef04e3
8 changed files with 221 additions and 286 deletions
|
@ -1153,29 +1153,36 @@ static void draw_background(const SDL_Rect& area, const std::string& image)
|
|||
CVideo::get_singleton().render_copy(background, nullptr, &a);
|
||||
}
|
||||
|
||||
void display::draw_text_in_hex(const map_location& loc,
|
||||
const drawing_queue::layer layer, const std::string& text,
|
||||
size_t font_size, color_t color, double x_in_hex, double y_in_hex)
|
||||
int display::draw_text_in_hex(const map_location& loc,
|
||||
const std::string& text,
|
||||
size_t font_size,
|
||||
color_t color,
|
||||
int fl_label_id,
|
||||
double x_in_hex,
|
||||
double y_in_hex)
|
||||
{
|
||||
if (text.empty()) return;
|
||||
if(text.empty()) {
|
||||
return fl_label_id;
|
||||
}
|
||||
|
||||
const size_t font_sz = static_cast<size_t>(font_size * get_zoom_factor());
|
||||
|
||||
surface text_surf = font::get_rendered_text(text, font_sz, color);
|
||||
surface back_surf = font::get_rendered_text(text, font_sz, font::BLACK_COLOR);
|
||||
const int x = get_location_x(loc) - text_surf->w/2
|
||||
+ static_cast<int>(x_in_hex* hex_size());
|
||||
const int y = get_location_y(loc) - text_surf->h/2
|
||||
+ static_cast<int>(y_in_hex* hex_size());
|
||||
for (int dy=-1; dy <= 1; ++dy) {
|
||||
for (int dx=-1; dx <= 1; ++dx) {
|
||||
if (dx!=0 || dy!=0) {
|
||||
drawing_queue_add(layer, loc, x + dx, y + dy, back_surf);
|
||||
}
|
||||
}
|
||||
const int x = get_location_x(loc) /*- text_surf->w / 2*/ + static_cast<int>(x_in_hex * hex_size());
|
||||
const int y = get_location_y(loc) /*- text_surf->h / 2*/ + static_cast<int>(y_in_hex * hex_size());
|
||||
|
||||
// We were given a label id, remove it.
|
||||
if(fl_label_id != 0) {
|
||||
font::remove_floating_label(fl_label_id);
|
||||
}
|
||||
|
||||
drawing_queue_add(layer, loc, x, y, text_surf);
|
||||
font::floating_label flabel(text);
|
||||
flabel.set_font_size(font_sz);
|
||||
flabel.set_color(color);
|
||||
flabel.set_position(x, y);
|
||||
flabel.set_alignment(font::CENTER_ALIGN);
|
||||
flabel.set_scroll_mode(font::ANCHOR_LABEL_MAP);
|
||||
|
||||
return font::add_floating_label(flabel);
|
||||
}
|
||||
|
||||
void display::select_hex(map_location hex)
|
||||
|
@ -2579,18 +2586,16 @@ void display::draw_gamemap()
|
|||
//
|
||||
draw_visible_hexes(visible_hexes, FOREGROUND);
|
||||
|
||||
//
|
||||
// Draws various overlays, such as reach maps, etc.
|
||||
//
|
||||
draw_hex_overlays();
|
||||
|
||||
//
|
||||
// Hex cursor (TODO: split into layers?)
|
||||
//
|
||||
draw_hex_cursor(mouseoverHex_);
|
||||
|
||||
//
|
||||
// Right now just handles halos - see game_display
|
||||
//
|
||||
post_commit();
|
||||
|
||||
draw_hex_overlays();
|
||||
|
||||
//
|
||||
// Shroud and fog
|
||||
//
|
||||
|
@ -2750,16 +2755,16 @@ void display::draw()
|
|||
draw_gamemap();
|
||||
}
|
||||
|
||||
// Draw map labels.
|
||||
// Draw debugging aids such as the FPS counter.
|
||||
draw_debugging_aids();
|
||||
|
||||
// Draw floating labels (includes map labels).
|
||||
font::draw_floating_labels();
|
||||
|
||||
// TODO: what dis?
|
||||
//events::raise_volatile_draw_event();
|
||||
//events::raise_volatile_undraw_event();
|
||||
|
||||
// Draw debugging aids such as the FPS counter.
|
||||
draw_debugging_aids();
|
||||
|
||||
// Call any redraw observers.
|
||||
// FIXME: makes the editor slow.
|
||||
#if 0
|
||||
|
|
|
@ -859,14 +859,6 @@ protected:
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for actions to take right after draw() renders the drawing buffer.
|
||||
* No action here by default.
|
||||
*/
|
||||
DEPRECATED("") virtual void post_commit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called at the end of each draw cycle.
|
||||
* Derived classes can use this to add extra actions after all drawing takes place.
|
||||
|
@ -900,11 +892,6 @@ private:
|
|||
void draw_gamemap();
|
||||
|
||||
protected:
|
||||
/** Draws a single gamemap location. */
|
||||
DEPRECATED("") virtual void draw_hex(const map_location& /*loc*/)
|
||||
{
|
||||
}
|
||||
|
||||
/** Draws the map's hex cursor. No action here by default. */
|
||||
virtual void draw_hex_cursor(const map_location& /*loc*/)
|
||||
{
|
||||
|
@ -927,7 +914,7 @@ public:
|
|||
* This should not contain the texture or source/destination rects.
|
||||
*/
|
||||
template<typename... T>
|
||||
void render_scaled_to_zoom(const texture& tex, const int x_pos, const int y_pos, T&&... extra_args)
|
||||
void render_scaled_to_zoom(const texture& tex, const int x_pos, const int y_pos, T&&... extra_args) const
|
||||
{
|
||||
texture::info info = tex.get_info();
|
||||
|
||||
|
@ -954,7 +941,7 @@ public:
|
|||
* This should not contain the texture or source/destination rects.
|
||||
*/
|
||||
template<typename... T>
|
||||
void render_scaled_to_zoom(const texture& tex, const map_location& loc, T&&... extra_args)
|
||||
void render_scaled_to_zoom(const texture& tex, const map_location& loc, T&&... extra_args) const
|
||||
{
|
||||
SDL_Point origin = get_loc_drawing_origin(loc);
|
||||
|
||||
|
@ -963,14 +950,25 @@ public:
|
|||
|
||||
map_location get_middle_location() const;
|
||||
/**
|
||||
* Draw text on a hex. (0.5, 0.5) is the center.
|
||||
* The font size is adjusted to the zoom factor.
|
||||
* Adds a floating label with the specified text at the given location.
|
||||
*
|
||||
* @param loc The map location to draw the label.
|
||||
* @param text The label's text.
|
||||
* @param font_size The label's font size. Will be adjusted by the zoom factor.
|
||||
* @param color The label's color.
|
||||
* @param fl_label_id The label's existing id. If not 0 the given label will be moved as
|
||||
* the label with that id will be moved to @a loc.
|
||||
* @param x_in_hex The relative x location within the hex to draw the label.
|
||||
* @param y_in_hex The relative y location within the hex to draw the label.
|
||||
* Note that (0.5, 0.5) indicates the center of the hex.
|
||||
*
|
||||
* @returns The new floating label's id.
|
||||
*/
|
||||
void draw_text_in_hex(const map_location& loc,
|
||||
const drawing_queue::layer layer,
|
||||
int draw_text_in_hex(const map_location& loc,
|
||||
const std::string& text,
|
||||
size_t font_size,
|
||||
color_t color,
|
||||
int fl_label_id = 0,
|
||||
double x_in_hex = 0.5,
|
||||
double y_in_hex = 0.5);
|
||||
|
||||
|
|
|
@ -54,14 +54,6 @@ static lg::log_domain log_engine("engine");
|
|||
|
||||
std::map<map_location,fixed_t> game_display::debugHighlights_;
|
||||
|
||||
/**
|
||||
* Function to return 2 half-hex footsteps images for the given location.
|
||||
* Only loc is on the current route set by set_route.
|
||||
*
|
||||
* This function is only used internally by game_display so I have moved it out of the header into the compilaton unit.
|
||||
*/
|
||||
std::vector<surface> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_);
|
||||
|
||||
game_display::game_display(game_board& board, std::weak_ptr<wb::manager> wb,
|
||||
reports & reports_object,
|
||||
const config& theme_cfg,
|
||||
|
@ -71,6 +63,7 @@ game_display::game_display(game_board& board, std::weak_ptr<wb::manager> wb,
|
|||
overlay_map_(),
|
||||
attack_indicator_src_(),
|
||||
attack_indicator_dst_(),
|
||||
hex_def_fl_labels_(),
|
||||
route_(),
|
||||
displayedUnitHex_(),
|
||||
sidebarScaling_(1.0),
|
||||
|
@ -176,7 +169,6 @@ void game_display::highlight_hex(map_location hex)
|
|||
invalidate_game_status();
|
||||
}
|
||||
|
||||
|
||||
void game_display::display_unit_hex(map_location hex)
|
||||
{
|
||||
if (!hex.valid())
|
||||
|
@ -228,11 +220,6 @@ void game_display::post_draw()
|
|||
}
|
||||
}
|
||||
|
||||
void game_display::post_commit()
|
||||
{
|
||||
halo_man_->render();
|
||||
}
|
||||
|
||||
void game_display::draw_hex_cursor(const map_location& loc)
|
||||
{
|
||||
if(!get_map().on_board(loc) || cursor::get() == cursor::WAIT) {
|
||||
|
@ -289,13 +276,24 @@ void game_display::draw_hex_cursor(const map_location& loc)
|
|||
}
|
||||
|
||||
//
|
||||
// Draw accompanying route markers, defence ratings, target status indicators
|
||||
// Draw accompanying defense ratings and turn reach numbers within the hex.
|
||||
//
|
||||
draw_movement_info(loc);
|
||||
|
||||
if(!game_config::images::selected.empty() && get_map().on_board(selectedHex_)) {
|
||||
static texture selected(image::get_texture(game_config::images::selected));
|
||||
|
||||
render_scaled_to_zoom(selected, selectedHex_); // SCALED_TO_HEX
|
||||
}
|
||||
}
|
||||
|
||||
void game_display::draw_hex_overlays()
|
||||
{
|
||||
//
|
||||
// Render halos.
|
||||
//
|
||||
halo_man_->render();
|
||||
|
||||
//
|
||||
// Mask on unreachable locations
|
||||
//
|
||||
|
@ -332,6 +330,17 @@ void game_display::draw_hex_overlays()
|
|||
render_scaled_to_zoom(indicator, attack_indicator_dst_);
|
||||
}
|
||||
|
||||
//
|
||||
// Draw route steps
|
||||
//
|
||||
if(std::shared_ptr<wb::manager> w = wb_.lock()) {
|
||||
//w->draw_hex(loc);
|
||||
|
||||
if(!w->is_active() && !w->has_temp_move()) {
|
||||
draw_footstep_images();
|
||||
}
|
||||
}
|
||||
|
||||
// Linger overlay unconditionally otherwise it might give glitches
|
||||
// so it's drawn over the shroud and fog.
|
||||
// FIXME: ^ split into seperate function so that happens.
|
||||
|
@ -343,126 +352,8 @@ void game_display::draw_hex_overlays()
|
|||
render_scaled_to_zoom(linger, loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void game_display::draw_hex(const map_location& loc)
|
||||
{
|
||||
return;
|
||||
|
||||
// Inherited.
|
||||
display::draw_hex(loc);
|
||||
|
||||
const bool on_map = get_map().on_board(loc);
|
||||
const bool is_shrouded = shrouded(loc);
|
||||
//const bool is_fogged = fogged(loc);
|
||||
|
||||
const int xpos = get_location_x(loc);
|
||||
const int ypos = get_location_y(loc);
|
||||
|
||||
//image::TYPE image_type = get_image_type(loc);
|
||||
|
||||
if(cursor::get() == cursor::WAIT) {
|
||||
// Interaction is disabled, so we don't need anything else
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(on_map && loc == mouseoverHex_) {
|
||||
drawing_queue::layer hex_top_layer = drawing_queue::LAYER_MOUSEOVER_BOTTOM;
|
||||
const unit *u = resources::gameboard->get_visible_unit(loc, dc_->teams()[viewing_team()] );
|
||||
if( u != nullptr ) {
|
||||
hex_top_layer = drawing_queue::LAYER_MOUSEOVER_TOP;
|
||||
}
|
||||
if(u == nullptr) {
|
||||
drawing_queue_add( hex_top_layer, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-top.png~RC(magenta>gold)", image::SCALED_TO_HEX));
|
||||
drawing_queue_add(drawing_queue::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-bottom.png~RC(magenta>gold)", image::SCALED_TO_HEX));
|
||||
} else if(dc_->teams()[currentTeam_].is_enemy(u->side())) {
|
||||
drawing_queue_add( hex_top_layer, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-enemy-top.png~RC(magenta>red)", image::SCALED_TO_HEX));
|
||||
drawing_queue_add(drawing_queue::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-enemy-bottom.png~RC(magenta>red)", image::SCALED_TO_HEX));
|
||||
} else if(dc_->teams()[currentTeam_].side() == u->side()) {
|
||||
drawing_queue_add( hex_top_layer, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-top.png~RC(magenta>green)", image::SCALED_TO_HEX));
|
||||
drawing_queue_add(drawing_queue::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-bottom.png~RC(magenta>green)", image::SCALED_TO_HEX));
|
||||
} else {
|
||||
drawing_queue_add( hex_top_layer, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-top.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
|
||||
drawing_queue_add(drawing_queue::LAYER_MOUSEOVER_BOTTOM, loc, xpos, ypos,
|
||||
image::get_image("misc/hover-hex-bottom.png~RC(magenta>lightblue)", image::SCALED_TO_HEX));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Draw reach_map information.
|
||||
// We remove the reachability mask of the unit that we want to attack.
|
||||
if(!is_shrouded && !reach_map_.empty()
|
||||
&& reach_map_.find(loc) == reach_map_.end() && loc != attack_indicator_dst_)
|
||||
{
|
||||
static texture unreachable = image::get_texture(game_config::images::unreachable);
|
||||
static texture::info info = unreachable.get_info();
|
||||
|
||||
SDL_Rect dst {xpos, ypos, info.w, info.h};
|
||||
video().render_copy(unreachable, nullptr, &dst); // SCALED_TO_HEX
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (std::shared_ptr<wb::manager> w = wb_.lock()) {
|
||||
w->draw_hex(loc);
|
||||
|
||||
if (!(w->is_active() && w->has_temp_move()))
|
||||
{
|
||||
std::vector<surface> footstepImages = footsteps_images(loc, route_, dc_);
|
||||
if (!footstepImages.empty()) {
|
||||
drawing_queue_add(drawing_queue::LAYER_FOOTSTEPS, loc, xpos, ypos, footsteps_images(loc, route_, dc_));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Draw the attack direction indicator
|
||||
// TODO: SCALED_TO_HEX
|
||||
if(on_map && loc == attack_indicator_src_) {
|
||||
texture indicator = image::get_texture("misc/attack-indicator-src-" + attack_indicator_direction() + ".png");
|
||||
texture::info info = indicator.get_info();
|
||||
|
||||
SDL_Rect dst {xpos, ypos, info.w, info.h};
|
||||
video().render_copy(indicator, nullptr, &dst);
|
||||
} else if(on_map && loc == attack_indicator_dst_) {
|
||||
texture indicator = image::get_texture("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png");
|
||||
texture::info info = indicator.get_info();
|
||||
|
||||
SDL_Rect dst {xpos, ypos, info.w, info.h};
|
||||
video().render_copy(indicator, nullptr, &dst);
|
||||
}
|
||||
|
||||
// Linger overlay unconditionally otherwise it might give glitches
|
||||
// so it's drawn over the shroud and fog.
|
||||
if(mode_ != RUNNING) {
|
||||
static texture linger = image::get_texture(game_config::images::linger);
|
||||
static texture::info info = linger.get_info();
|
||||
|
||||
SDL_Rect dst {xpos, ypos, info.w, info.h};
|
||||
video().render_copy(linger, nullptr, &dst); // TOD_COLORED
|
||||
}
|
||||
|
||||
if(on_map && loc == selectedHex_ && !game_config::images::selected.empty()) {
|
||||
static texture selected = image::get_texture(game_config::images::selected);
|
||||
static texture::info info = selected.get_info();
|
||||
|
||||
SDL_Rect dst {xpos, ypos, info.w, info.h};
|
||||
video().render_copy(selected, nullptr, &dst); // SCALED_TO_HEX
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Show def% and turn to reach info
|
||||
if(!is_shrouded && on_map) {
|
||||
draw_movement_info(loc);
|
||||
}
|
||||
|
||||
if(game_config::debug) {
|
||||
int debugH = debugHighlights_[loc];
|
||||
if (debugH) {
|
||||
|
@ -516,11 +407,40 @@ void game_display::set_game_mode(const game_mode mode)
|
|||
void game_display::draw_movement_info(const map_location& /*loc*/)
|
||||
{
|
||||
if(route_.steps.empty()) {
|
||||
hex_def_fl_labels_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<wb::manager> wb = wb_.lock();
|
||||
|
||||
//const unit_map::const_iterator selectedUnit =
|
||||
// resources::gameboard->find_visible_unit(selectedHex_,dc_->teams()[currentTeam_]);
|
||||
|
||||
//const unit_map::const_iterator mouseoveredUnit =
|
||||
// resources::gameboard->find_visible_unit(mouseoverHex_,dc_->teams()[currentTeam_]);
|
||||
|
||||
// First step of the route should be a unit.
|
||||
const unit_map::const_iterator un = (wb && wb->get_temp_move_unit().valid())
|
||||
? wb->get_temp_move_unit()
|
||||
: dc_->units().find(route_.steps.front());
|
||||
|
||||
const bool unit_at_start = (un != dc_->units().end());
|
||||
|
||||
if(!unit_at_start) {
|
||||
// Remove all the defense labels.
|
||||
hex_def_fl_labels_.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned int num_marks = route_.marks.size();
|
||||
|
||||
if(hex_def_fl_labels_.size() != num_marks) {
|
||||
hex_def_fl_labels_.resize(num_marks);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(const auto& mark : route_.marks) {
|
||||
const map_location& m_loc = mark.first;
|
||||
|
||||
|
@ -528,54 +448,58 @@ void game_display::draw_movement_info(const map_location& /*loc*/)
|
|||
continue;
|
||||
}
|
||||
|
||||
const unit_map::const_iterator un = (wb && wb->get_temp_move_unit().valid())
|
||||
? wb->get_temp_move_unit()
|
||||
: dc_->units().find(route_.steps.front());
|
||||
//
|
||||
// Display the unit's defence on this terrain
|
||||
//
|
||||
const int def = 100 - un->defense_modifier(get_map().get_terrain(m_loc));
|
||||
|
||||
if(un != dc_->units().end()) {
|
||||
#if 0
|
||||
// Display the def% of this terrain
|
||||
int def = 100 - un->defense_modifier(get_map().get_terrain(loc));
|
||||
std::stringstream def_text;
|
||||
def_text << def << "%";
|
||||
|
||||
std::stringstream def_text;
|
||||
def_text << def << "%";
|
||||
color_t color = game_config::red_to_green(def, false);
|
||||
|
||||
color_t color = game_config::red_to_green(def, false);
|
||||
// Simple mark (no turn point) uses smaller font.
|
||||
int def_font = mark.second.turns > 0 ? 18 : 16;
|
||||
|
||||
// simple mark (no turn point) use smaller font
|
||||
int def_font = w->second.turns > 0 ? 18 : 16;
|
||||
draw_text_in_hex(loc, drawing_queue::LAYER_MOVE_INFO, def_text.str(), def_font, color);
|
||||
#endif
|
||||
// TODO: do we want SCALED_TO_HEX?
|
||||
// LAYER_MOVE_INFO
|
||||
int& marker_id = hex_def_fl_labels_[i].id;
|
||||
marker_id = draw_text_in_hex(m_loc, def_text.str(), def_font, color, marker_id);
|
||||
|
||||
if(mark.second.invisible) {
|
||||
static texture hidden(image::get_texture("misc/hidden.png"));
|
||||
render_scaled_to_zoom(hidden, m_loc);
|
||||
}
|
||||
//
|
||||
// Draw special location markers
|
||||
//
|
||||
|
||||
if(mark.second.zoc) {
|
||||
static texture zoc(image::get_texture("misc/zoc.png"));
|
||||
render_scaled_to_zoom(zoc, m_loc);
|
||||
}
|
||||
// TODO: do we want SCALED_TO_HEX?
|
||||
// LAYER_MOVE_INFO
|
||||
|
||||
if(mark.second.capture) {
|
||||
static texture capture(image::get_texture("misc/capture.png"));
|
||||
render_scaled_to_zoom(capture, m_loc);
|
||||
}
|
||||
#if 0
|
||||
// We display turn info only if different from a simple last "1"
|
||||
if(w->second.turns > 1 || (w->second.turns == 1 && loc != route_.steps.back())) {
|
||||
std::stringstream turns_text;
|
||||
turns_text << w->second.turns;
|
||||
draw_text_in_hex(loc, drawing_queue::LAYER_MOVE_INFO, turns_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
|
||||
}
|
||||
#endif
|
||||
// The hex is full now, so skip the "show enemy moves"
|
||||
return;
|
||||
if(mark.second.invisible) {
|
||||
static texture hidden(image::get_texture("misc/hidden.png"));
|
||||
render_scaled_to_zoom(hidden, m_loc);
|
||||
}
|
||||
|
||||
if(mark.second.zoc) {
|
||||
static texture zoc(image::get_texture("misc/zoc.png"));
|
||||
render_scaled_to_zoom(zoc, m_loc);
|
||||
}
|
||||
|
||||
if(mark.second.capture) {
|
||||
static texture capture(image::get_texture("misc/capture.png"));
|
||||
render_scaled_to_zoom(capture, m_loc);
|
||||
}
|
||||
|
||||
// We display turn info only if different from a simple last "1"
|
||||
if(mark.second.turns > 1 || (mark.second.turns == 1 && m_loc != route_.steps.back())) {
|
||||
std::stringstream turns_text;
|
||||
turns_text << mark.second.turns;
|
||||
// draw_text_in_hex(m_loc, turns_text.str(), 17, font::NORMAL_COLOR, 0.5, 0.8);
|
||||
}
|
||||
|
||||
// The hex is full now, so skip the "show enemy moves"
|
||||
//return;
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// Search if there is a mark here
|
||||
pathfind::marked_route::mark_map::iterator w = route_.marks.find(loc);
|
||||
|
@ -583,7 +507,7 @@ void game_display::draw_movement_info(const map_location& /*loc*/)
|
|||
std::shared_ptr<wb::manager> wb = wb_.lock();
|
||||
|
||||
// Don't use empty route or the first step (the unit will be there)
|
||||
if(w != route_.marks.end() && !route_.steps.empty() && route_.steps.front() != loc) {
|
||||
if(w != route_.marks.end() && !route_.steps.empty() && ) {
|
||||
const unit_map::const_iterator un = (wb && wb->get_temp_move_unit().valid())
|
||||
? wb->get_temp_move_unit()
|
||||
: dc_->units().find(route_.steps.front());
|
||||
|
@ -663,76 +587,80 @@ void game_display::draw_movement_info(const map_location& /*loc*/)
|
|||
#endif
|
||||
}
|
||||
|
||||
std::vector<surface> footsteps_images(const map_location& loc, const pathfind::marked_route & route_, const display_context * dc_)
|
||||
void game_display::draw_footstep_images() const
|
||||
{
|
||||
std::vector<surface> res;
|
||||
|
||||
if (route_.steps.size() < 2) {
|
||||
return res; // no real "route"
|
||||
// No real route.
|
||||
if(route_.steps.size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<map_location>::const_iterator i =
|
||||
std::find(route_.steps.begin(),route_.steps.end(),loc);
|
||||
|
||||
if( i == route_.steps.end()) {
|
||||
return res; // not on the route
|
||||
}
|
||||
|
||||
// Check which footsteps images of game_config we will use
|
||||
int move_cost = 1;
|
||||
const unit_map::const_iterator u = dc_->units().find(route_.steps.front());
|
||||
if(u != dc_->units().end()) {
|
||||
move_cost = u->movement_cost(dc_->map().get_terrain(loc));
|
||||
}
|
||||
int image_number = std::min<int>(move_cost, game_config::foot_speed_prefix.size());
|
||||
if (image_number < 1) {
|
||||
return res; // Invalid movement cost or no images
|
||||
}
|
||||
const std::string foot_speed_prefix = game_config::foot_speed_prefix[image_number-1];
|
||||
const bool unit_at_start = u != dc_->units().end();
|
||||
|
||||
surface teleport = nullptr;
|
||||
for(auto iter = route_.steps.begin(); iter != route_.steps.end(); ++iter) {
|
||||
// Step location.
|
||||
const map_location& loc = *iter;
|
||||
|
||||
// We draw 2 half-hex (with possibly different directions),
|
||||
// but skip the first for the first step.
|
||||
const int first_half = (i == route_.steps.begin()) ? 1 : 0;
|
||||
// and the second for the last step
|
||||
const int second_half = (i+1 == route_.steps.end()) ? 0 : 1;
|
||||
|
||||
for (int h = first_half; h <= second_half; ++h) {
|
||||
const std::string sense( h==0 ? "-in" : "-out" );
|
||||
|
||||
if (!tiles_adjacent(*(i+(h-1)), *(i+h))) {
|
||||
std::string teleport_image =
|
||||
h==0 ? game_config::foot_teleport_enter : game_config::foot_teleport_exit;
|
||||
teleport = image::get_image(teleport_image, image::SCALED_TO_HEX);
|
||||
continue;
|
||||
// Check which footsteps image variant to use.
|
||||
int move_cost = 1;
|
||||
if(unit_at_start) {
|
||||
move_cost = u->movement_cost(dc_->map().get_terrain(loc));
|
||||
}
|
||||
|
||||
// In function of the half, use the incoming or outgoing direction
|
||||
map_location::DIRECTION dir = (i+(h-1))->get_relative_dir(*(i+h));
|
||||
|
||||
std::string rotate;
|
||||
if (dir > map_location::SOUTH_EAST) {
|
||||
// No image, take the opposite direction and do a 180 rotation
|
||||
dir = i->get_opposite_dir(dir);
|
||||
rotate = "~FL(horiz)~FL(vert)";
|
||||
const int image_number = std::min<int>(move_cost, game_config::foot_speed_prefix.size());
|
||||
if(image_number < 1) {
|
||||
continue; // Invalid movement cost or no images.
|
||||
}
|
||||
|
||||
const std::string image = foot_speed_prefix
|
||||
+ sense + "-" + i->write_direction(dir)
|
||||
+ ".png" + rotate;
|
||||
const std::string& foot_speed_prefix = game_config::foot_speed_prefix[image_number - 1];
|
||||
|
||||
res.push_back(image::get_image(image, image::SCALED_TO_HEX));
|
||||
std::string teleport_image = "";
|
||||
|
||||
// We draw 2 half-hex (with possibly different directions), but skip the first for the first step...
|
||||
const int first_half = (iter == route_.steps.begin()) ? 1 : 0;
|
||||
|
||||
// ...and the second for the last step
|
||||
const int second_half = (iter + 1 == route_.steps.end()) ? 0 : 1;
|
||||
|
||||
for(int h = first_half; h <= second_half; ++h) {
|
||||
const std::string sense(h == 0 ? "-in" : "-out");
|
||||
|
||||
const map_location& loc_a = *(iter + (h - 1));
|
||||
const map_location& loc_b = *(iter + h);
|
||||
|
||||
// If we have a teleport image, record it and preceed to next step.
|
||||
if(!tiles_adjacent(loc_a, loc_b)) {
|
||||
teleport_image = (h == 0)
|
||||
? game_config::foot_teleport_enter
|
||||
: game_config::foot_teleport_exit;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// In function of the half, use the incoming or outgoing direction
|
||||
map_location::DIRECTION dir = loc_a.get_relative_dir(loc_b);
|
||||
|
||||
bool rotate = false;
|
||||
if(dir > map_location::SOUTH_EAST) {
|
||||
// No image, take the opposite direction and flag a 180 rotation.
|
||||
dir = map_location::get_opposite_dir(dir);
|
||||
rotate = true;
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << foot_speed_prefix << sense << "-" << map_location::write_direction(dir) << ".png";
|
||||
|
||||
// Pass rotate flag twice so we get both a horizontal and vertical flip (180 rotation).
|
||||
render_scaled_to_zoom(image::get_texture(ss.str()), loc, rotate, rotate); // SCALED_TO_HEX
|
||||
}
|
||||
|
||||
// Render teleport image last, if any.
|
||||
if(!teleport_image.empty()) {
|
||||
render_scaled_to_zoom(image::get_texture(teleport_image), loc); // SCALED_TO_HEX
|
||||
}
|
||||
}
|
||||
|
||||
// we draw teleport image (if any) in last
|
||||
if (teleport != nullptr) res.push_back(teleport);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void game_display::highlight_reach(const pathfind::paths &paths_list)
|
||||
{
|
||||
unhighlight_reach();
|
||||
|
|
|
@ -26,11 +26,17 @@ class game_board;
|
|||
#include "pathfind/pathfind.hpp"
|
||||
|
||||
#include <deque>
|
||||
#include <memory>
|
||||
|
||||
// This needs to be separate from display.h because of the static
|
||||
// singleton member, which will otherwise trigger link failure
|
||||
// when building the editor.
|
||||
|
||||
namespace font
|
||||
{
|
||||
struct floating_label_scope_helper;
|
||||
}
|
||||
|
||||
class game_display : public display
|
||||
{
|
||||
public:
|
||||
|
@ -136,14 +142,11 @@ protected:
|
|||
*/
|
||||
virtual void post_draw() override;
|
||||
|
||||
virtual void post_commit() override;
|
||||
|
||||
virtual void draw_hex(const map_location& loc) override;
|
||||
|
||||
virtual void draw_hex_cursor(const map_location& loc) override;
|
||||
|
||||
virtual void draw_hex_overlays() override;
|
||||
public:
|
||||
|
||||
/** Set the attack direction indicator. */
|
||||
void set_attack_indicator(const map_location& src, const map_location& dst);
|
||||
void clear_attack_indicator();
|
||||
|
@ -207,12 +210,16 @@ private:
|
|||
|
||||
virtual void draw_sidebar() override;
|
||||
|
||||
void draw_footstep_images() const;
|
||||
|
||||
overlay_map overlay_map_;
|
||||
|
||||
// Locations of the attack direction indicator's parts
|
||||
map_location attack_indicator_src_;
|
||||
map_location attack_indicator_dst_;
|
||||
|
||||
std::vector<font::floating_label_scope_helper> hex_def_fl_labels_;
|
||||
|
||||
pathfind::marked_route route_;
|
||||
|
||||
map_location displayedUnitHex_;
|
||||
|
|
|
@ -469,8 +469,7 @@ static void draw_numbers(const map_location& hex, side_actions::numbers_t number
|
|||
color_t color = team::get_side_color(static_cast<int>(team_numbers[i]+1));
|
||||
const double x_in_hex = x_origin + x_offset;
|
||||
const double y_in_hex = y_origin + y_offset;
|
||||
display::get_singleton()->draw_text_in_hex(hex, drawing_queue::LAYER_ACTIONS_NUMBERING,
|
||||
number_text, font_size, color, x_in_hex, y_in_hex);
|
||||
display::get_singleton()->draw_text_in_hex(hex, number_text, font_size, color, 0, x_in_hex, y_in_hex);
|
||||
x_offset += x_offset_base;
|
||||
y_offset += y_offset_base;
|
||||
}
|
||||
|
|
|
@ -391,7 +391,7 @@ void move::draw_hex(const map_location& hex)
|
|||
{
|
||||
std::stringstream turn_text;
|
||||
turn_text << turn_number_;
|
||||
display::get_singleton()->draw_text_in_hex(hex, drawing_queue::LAYER_MOVE_INFO, turn_text.str(), 17, font::NORMAL_COLOR, 0.5,0.8);
|
||||
display::get_singleton()->draw_text_in_hex(hex, turn_text.str(), 17, font::NORMAL_COLOR, 0, 0.5,0.8);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -191,8 +191,7 @@ void recall::draw_hex(const map_location& hex)
|
|||
}
|
||||
size_t font_size = 16;
|
||||
color_t color {255, 0, 0}; //red
|
||||
display::get_singleton()->draw_text_in_hex(hex, drawing_queue::LAYER_ACTIONS_NUMBERING,
|
||||
number_text.str(), font_size, color, x_offset, y_offset);
|
||||
display::get_singleton()->draw_text_in_hex(hex, number_text.str(), font_size, color, 0, x_offset, y_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,8 +155,7 @@ void recruit::draw_hex(const map_location& hex)
|
|||
number_text << font::unicode_minus << cost_;
|
||||
size_t font_size = 16;
|
||||
color_t color {255, 0, 0}; //red
|
||||
display::get_singleton()->draw_text_in_hex(hex, drawing_queue::LAYER_ACTIONS_NUMBERING,
|
||||
number_text.str(), font_size, color, x_offset, y_offset);
|
||||
display::get_singleton()->draw_text_in_hex(hex, number_text.str(), font_size, color, x_offset, y_offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue