Got a bunch more components drawing

Reachmaps, attack indicators, shroud/fog (incomplete).
This commit is contained in:
Charles Dang 2017-06-14 14:20:30 +11:00
parent 66f2d3f49c
commit 643ebe221f
4 changed files with 210 additions and 237 deletions

View file

@ -956,7 +956,7 @@ static const std::string& get_direction(size_t n)
return dirs[n >= dirs.size() ? 0 : n];
}
std::vector<surface> display::get_fog_shroud_images(const map_location& loc, image::TYPE image_type)
std::vector<texture> display::get_fog_shroud_images(const map_location& loc, image::TYPE image_type)
{
std::vector<std::string> names;
@ -1034,12 +1034,14 @@ std::vector<surface> display::get_fog_shroud_images(const map_location& loc, ima
}
// now get the surfaces
std::vector<surface> res;
std::vector<texture> res;
res.reserve(names.size());
for (std::string& name : names) {
surface surf(image::get_image(name, image_type));
if (surf)
res.push_back(std::move(surf));
for(std::string& name : names) {
texture tex(image::get_texture(name)); // TODO: image_type
if(tex) {
res.push_back(std::move(tex));
}
}
return res;
@ -1388,6 +1390,7 @@ void display::draw_text_in_hex(const map_location& loc,
}
}
}
drawing_buffer_add(layer, loc, x, y, text_surf);
}
@ -1555,6 +1558,7 @@ void display::announce(const std::string& message, const color_t& color, const a
if(options.discard_previous) {
font::remove_floating_label(prevLabel);
}
font::floating_label flabel(message);
flabel.set_font_size(font::SIZE_XLARGE);
flabel.set_color(color);
@ -2888,50 +2892,135 @@ void display::draw_invalidated() {
}
}
void display::draw_hex(const map_location& /*loc*/)
//
// NEW RENDERING CODE =========================================================================
//
void display::draw_hex(const map_location& loc)
{
return;
const int xpos = get_location_x(loc);
const int ypos = get_location_y(loc);
//int xpos = get_location_x(loc);
//int ypos = get_location_y(loc);
image::TYPE image_type = get_image_type(loc);
//image::TYPE image_type = get_image_type(loc);
const bool on_map = get_map().on_board(loc);
const time_of_day& tod = get_time_of_day(loc);
//const bool on_map = get_map().on_board(loc);
//const time_of_day& tod = get_time_of_day(loc);
const bool is_shrouded = shrouded(loc);
const bool is_fogged = fogged(loc);
//int num_images_fg = 0;
//int num_images_bg = 0;
// FIXME
if(dc_->teams().empty()) {
//return;
}
// TODO: why is this created every time?
unit_drawer drawer = unit_drawer(*this);
std::vector<texture> images_fg = get_terrain_images(loc, tod.id, image_type, FOREGROUND);
std::vector<texture> images_bg = get_terrain_images(loc, tod.id, image_type, BACKGROUND);
// Some debug output
const int num_images_fg = images_fg.size();
const int num_images_bg = images_bg.size();
if(!is_shrouded) {
//
// Background terrains
//
for(const texture& t : images_bg) {
render_scaled_to_zoom(t, xpos, ypos);
}
//
// Village flags
//
const texture& flag = get_flag(loc);
if(flag) {
render_scaled_to_zoom(flag, xpos, ypos);
}
}
//
// Units
//
auto u_it = dc_->units().find(loc);
auto request = exclusive_unit_draw_requests_.find(loc);
// Real units
if(u_it != dc_->units().end() && (request == exclusive_unit_draw_requests_.end() || request->second == u_it->id())) {
drawer.redraw_unit(*u_it);
}
// Fake (moving) units
for(const unit* temp_unit : *fake_unit_man_) {
if(request == exclusive_unit_draw_requests_.end() || request->second == temp_unit->id()) {
drawer.redraw_unit(*temp_unit);
}
}
//
// Foreground terrains
//
if(!is_shrouded) {
for(const texture& t : images_fg) {
render_scaled_to_zoom(t, xpos, ypos);
}
}
//
// Shroud and fog
//
if(is_shrouded || is_fogged) {
// If is_shrouded is false, is_fogged is true
const std::string& weather_image = is_shrouded
? get_variant(shroud_images_, loc)
: get_variant(fog_images_, loc);
// TODO: image type
render_scaled_to_zoom(image::get_texture(weather_image), xpos, ypos);
}
if(!is_shrouded) {
// TODO:
// std::vector<texture> fog_shroud_images = get_fog_shroud_images(loc, image_type);
}
//
// Mouseover overlays (TODO: delegate to editor)
//
#if 0
if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc)))
&& mouseover_hex_overlay_ != nullptr)
{
render_scaled_to_zoom(mouseover_hex_overlay_, xpos, ypos);
}
#endif
//
// Arrows
//
auto arrows_in_hex = arrows_map_.find(loc);
if(arrows_in_hex != arrows_map_.end()) {
for(arrow* const a : arrows_in_hex->second) {
a->draw_hex(loc);
}
}
//
// Hex cursor (TODO: split into layers)
//
if(on_map && loc == mouseoverHex_) {
draw_hex_cursor(loc);
}
//
// TODO
//
//if(!shrouded(loc)) {
#if 0
std::vector<texture> images_fg = get_terrain_images(loc,tod.id, image_type, FOREGROUND);
std::vector<texture> images_bg = get_terrain_images(loc,tod.id, image_type, BACKGROUND);
if(images_fg.empty() && images_bg.empty()) {
return;
}
num_images_fg = images_fg.size();
num_images_bg = images_bg.size();
for(auto& t : images_bg) {
//assert(t);
}
for(auto& t : images_fg) {
//assert(t);
}
// unshrouded terrain (the normal case)
if(!images_bg.empty()) {
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, images_bg);
} else {
//std::cerr << "bg images empty" << std::endl;
}
if(!images_fg.empty()) {
drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_FG, loc, xpos, ypos, images_fg);
} else {
//std::cerr << "fg images empty" << std::endl;
}
// Draw the grid, if that's been enabled
if(grid_) {
@ -2945,9 +3034,7 @@ void display::draw_hex(const map_location& /*loc*/)
// village-control flags.
//drawing_buffer_add(drawing_buffer::LAYER_TERRAIN_BG, loc, xpos, ypos, get_flag(loc));
//}
#endif
#if 0
if(!shrouded(loc)) {
typedef overlay_map::const_iterator Itor;
std::pair<Itor,Itor> overlays = overlays_->equal_range(loc);
@ -2990,38 +3077,8 @@ void display::draw_hex(const map_location& /*loc*/)
image::get_image(tod_hex_mask,image::SCALED_TO_HEX));
}
// Paint mouseover overlays
if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc)))
&& mouseover_hex_overlay_ != nullptr) {
drawing_buffer_add(drawing_buffer::LAYER_MOUSEOVER_OVERLAY, loc, xpos, ypos, mouseover_hex_overlay_);
}
// Paint arrows
arrows_map_t::const_iterator arrows_in_hex = arrows_map_.find(loc);
if(arrows_in_hex != arrows_map_.end()) {
for (arrow* const a : arrows_in_hex->second) {
a->draw_hex(loc);
}
}
// Apply shroud, fog and linger overlay
if(shrouded(loc)) {
// We apply void also on off-map tiles
// to shroud the half-hexes too
const std::string& shroud_image = get_variant(shroud_images_, loc);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image(shroud_image, image_type));
} else if(fogged(loc)) {
const std::string& fog_image = get_variant(fog_images_, loc);
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos,
image::get_image(fog_image, image_type));
}
if(!shrouded(loc)) {
drawing_buffer_add(drawing_buffer::LAYER_FOG_SHROUD, loc, xpos, ypos, get_fog_shroud_images(loc, image_type));
}
if (on_map) {
if (draw_coordinates_) {
int off_x = xpos + hex_size()/2;
@ -3085,138 +3142,31 @@ void display::draw_hex(const map_location& /*loc*/)
#endif
}
//
// NEW RENDERING CODE =========================================================================
//
//template<typename... T>
////void display::render_scaled_to_zoom(const texture& tex, const int x_pos, const int y_pos, T&&... extra_args)
void display::draw_gamemap()
{
SDL_Rect area = map_area();
render_clip_rect_setter setter(&area);
// TODO: ToD coloring of terrains.
// The unit drawer can't function without teams.
// FIXME
if(dc_->teams().empty()) {
//return;
}
// TODO: why is this created every time?
unit_drawer drawer = unit_drawer(*this);
for(const map_location& loc : get_visible_hexes()) {
const int xpos = get_location_x(loc);
const int ypos = get_location_y(loc);
image::TYPE image_type = get_image_type(loc);
const bool on_map = get_map().on_board(loc);
const time_of_day& tod = get_time_of_day(loc);
// TODO:
//if(shrouded(loc))) {
// return;
//}
//
// Background terrains
//
get_terrain_images(loc, tod.id, image_type, FOREGROUND);
for(const texture& t : terrain_image_vector_) {
render_scaled_to_zoom(t, xpos, ypos);
}
//
// Village flags
//
texture flag = get_flag(loc);
if(flag) {
render_scaled_to_zoom(flag, xpos, ypos);
}
//
// Units
//
auto u_it = dc_->units().find(loc);
auto request = exclusive_unit_draw_requests_.find(loc);
// Real units
if(u_it != dc_->units().end() && (request == exclusive_unit_draw_requests_.end() || request->second == u_it->id())) {
drawer.redraw_unit(*u_it);
}
// Fake (moving) units
for(const unit* temp_unit : *fake_unit_man_) {
if(request == exclusive_unit_draw_requests_.end() || request->second == temp_unit->id()) {
drawer.redraw_unit(*temp_unit);
}
}
//
// Foreground terrains
//
get_terrain_images(loc, tod.id, image_type, BACKGROUND);
for(const texture& t : terrain_image_vector_) {
render_scaled_to_zoom(t, xpos, ypos);
}
//
// Mouseover overlays
//
#if 0
if(loc == mouseoverHex_ && (on_map || (in_editor() && get_map().on_board_with_border(loc)))
&& mouseover_hex_overlay_ != nullptr)
{
render_scaled_to_zoom(mouseover_hex_overlay_, xpos, ypos);
}
#endif
//
// Arrows
//
auto arrows_in_hex = arrows_map_.find(loc);
if(arrows_in_hex != arrows_map_.end()) {
for(arrow* const a : arrows_in_hex->second) {
a->draw_hex(loc);
}
}
//
// Hex cursor (TODO: split into layers)
//
if(on_map && loc == mouseoverHex_) {
draw_hex_cursor(loc);
}
}
}
void display::draw_new()
{
// Execute any pre-draw actions from derived classes.
pre_draw();
// Draw theme background.
const SDL_Rect area = map_outside_area();
draw_background(area, theme_.border().background_image);
const SDL_Rect outside_area = map_outside_area();
draw_background(outside_area, theme_.border().background_image);
// Progress animations.
invalidate_animations();
// Draw the gamemap and its contents (units, etc);
draw_gamemap();
post_commit();
draw_all_panels();
draw_minimap();
SDL_Rect map_area_rect = map_area();
render_clip_rect_setter setter(&map_area_rect);
// Draw the gamemap and its contents (units, etc);
for(const map_location& loc : get_visible_hexes()) {
draw_hex(loc);
}
post_commit();
// Draw map labels.
font::draw_floating_labels();
@ -3228,8 +3178,9 @@ void display::draw_new()
draw_debugging_aids();
// Call any redraw observers.
// FIXME: makes the editor slow.
for(std::function<void(display&)> f : redraw_observers_) {
f(*this);
// f(*this);
}
// Execute any post-draw actions from derived classes.

View file

@ -745,8 +745,6 @@ protected:
*/
virtual void draw_sidebar() {}
void draw_gamemap();
void draw_minimap();
enum TERRAIN_TYPE { BACKGROUND, FOREGROUND};
@ -755,7 +753,7 @@ protected:
const std::string& timeid,
TERRAIN_TYPE terrain_type);
std::vector<surface> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);
std::vector<texture> get_fog_shroud_images(const map_location& loc, image::TYPE image_type);
void draw_image_for_report(surface& img, SDL_Rect& rect);

View file

@ -205,11 +205,14 @@ void game_display::scroll_to_leader(int side, SCROLL_TYPE scroll_type,bool force
}
}
void game_display::pre_draw() {
if (std::shared_ptr<wb::manager> w = wb_.lock()) {
void game_display::pre_draw()
{
if(std::shared_ptr<wb::manager> w = wb_.lock()) {
w->pre_draw();
}
process_reachmap_changes();
/**
* @todo FIXME: must modify changed, but best to do it at the
* floating_label level
@ -217,8 +220,8 @@ void game_display::pre_draw() {
chat_man_->prune_chat_messages();
}
void game_display::post_draw() {
void game_display::post_draw()
{
if (std::shared_ptr<wb::manager> w = wb_.lock()) {
w->post_draw();
}
@ -226,6 +229,8 @@ void game_display::post_draw() {
void game_display::draw_invalidated()
{
return; // DONE
halo_man_->unrender(invalidated_);
display::draw_invalidated();
if (fake_unit_man_->empty()) {
@ -275,12 +280,12 @@ void game_display::draw_hex_cursor(const map_location& loc)
fg_path = "misc/hover-hex-bottom.png~RC(magenta>lightblue)";
}
texture cursor_bg = image::get_texture(image::locator(bg_path));
texture cursor_bg = image::get_texture(bg_path);
if(cursor_bg) {
render_scaled_to_zoom(cursor_bg, xpos, ypos);
}
texture cursor_fg = image::get_texture(image::locator(fg_path));
texture cursor_fg = image::get_texture(fg_path);
if(cursor_fg) {
render_scaled_to_zoom(cursor_fg, xpos, ypos);
}
@ -288,16 +293,17 @@ void game_display::draw_hex_cursor(const map_location& 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 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);
display::draw_hex(loc);
//image::TYPE image_type = get_image_type(loc);
if(cursor::get() == cursor::WAIT) {
// Interaction is disabled, so we don't need anything else
@ -335,17 +341,19 @@ void game_display::draw_hex(const map_location& loc)
}
#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 const image::locator unreachable(game_config::images::unreachable);
drawing_buffer_add(drawing_buffer::LAYER_REACHMAP, loc, xpos, ypos,
image::get_image(unreachable,image::SCALED_TO_HEX));
// 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);
@ -357,29 +365,43 @@ void game_display::draw_hex(const map_location& loc)
}
}
}
#endif
// Draw the attack direction indicator
// TODO: SCALED_TO_HEX
if(on_map && loc == attack_indicator_src_) {
drawing_buffer_add(drawing_buffer::LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_image("misc/attack-indicator-src-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
} else if (on_map && loc == attack_indicator_dst_) {
drawing_buffer_add(drawing_buffer::LAYER_ATTACK_INDICATOR, loc, xpos, ypos,
image::get_image("misc/attack-indicator-dst-" + attack_indicator_direction() + ".png", image::SCALED_TO_HEX));
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 const image::locator linger(game_config::images::linger);
drawing_buffer_add(drawing_buffer::LAYER_LINGER_OVERLAY, loc, xpos, ypos,
image::get_image(linger, image::TOD_COLORED));
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 const image::locator selected(game_config::images::selected);
drawing_buffer_add(drawing_buffer::LAYER_SELECTED_HEX, loc, xpos, ypos,
image::get_image(selected, image::SCALED_TO_HEX));
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);
@ -392,7 +414,9 @@ void game_display::draw_hex(const map_location& loc)
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, txt, 18, font::BAD_COLOR);
}
}
//simulate_delay += 1;
#endif
}
const time_of_day& game_display::get_time_of_day(const map_location& loc) const
@ -426,7 +450,6 @@ void game_display::draw_sidebar()
}
}
void game_display::set_game_mode(const game_mode mode)
{
if(mode != mode_) {
@ -443,11 +466,11 @@ 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) {
const unit_map::const_iterator un =
(wb && wb->get_temp_move_unit().valid()) ?
wb->get_temp_move_unit() : dc_->units().find(route_.steps.front());
if(w != route_.marks.end() && !route_.steps.empty() && route_.steps.front() != loc) {
const unit_map::const_iterator un = (wb && wb->get_temp_move_unit().valid())
? wb->get_temp_move_unit()
: dc_->units().find(route_.steps.front());
if(un != dc_->units().end()) {
// Display the def% of this terrain
int move_cost = un->movement_cost(get_map().get_terrain(loc));
@ -490,6 +513,7 @@ void game_display::draw_movement_info(const map_location& loc)
return;
}
}
// When out-of-turn, it's still interesting to check out the terrain defs of the selected unit
else if (selectedHex_.valid() && loc == mouseoverHex_)
{
@ -511,9 +535,9 @@ void game_display::draw_movement_info(const map_location& loc)
}
}
if (!reach_map_.empty()) {
if(!reach_map_.empty()) {
reach_map::iterator reach = reach_map_.find(loc);
if (reach != reach_map_.end() && reach->second > 1) {
if(reach != reach_map_.end() && reach->second > 1) {
const std::string num = std::to_string(reach->second);
draw_text_in_hex(loc, drawing_buffer::LAYER_MOVE_INFO, num, 16, font::YELLOW_COLOR);
}

View file

@ -226,8 +226,8 @@ void unit_drawer::redraw_unit(const unit & u) const
ellipse << "-" << leader << nozoc << selected << "bottom.png~RC(ellipse_red>" << tc << ")";
// Load the ellipse parts recolored to match team color
ellipse_back = image::get_texture(image::locator(ellipse_top) /*, image::SCALED_TO_ZOOM)*/);
ellipse_front = image::get_texture(image::locator(ellipse_bot) /*, image::SCALED_TO_ZOOM)*/);
ellipse_back = image::get_texture(ellipse_top /*, image::SCALED_TO_ZOOM)*/);
ellipse_front = image::get_texture(ellipse_bot /*, image::SCALED_TO_ZOOM)*/);
}
}