Skip to content

Commit

Permalink
Create a named struct for terrain name and movement pair
Browse files Browse the repository at this point in the history
This allows the sorting logic top be shared between the sidebar and the
unit preview pane. It also means that we no longer need to create a lambda
to sort them.

I also refactored the generation of movement cost data in help. In
particular, we're no longer extracting the struct to named local variables.

(cherry-picked from commit d8e2498)
  • Loading branch information
jyrkive committed Oct 7, 2018
1 parent a380ba8 commit f245cd6
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 88 deletions.
1 change: 1 addition & 0 deletions projectfiles/VC14/wesnoth.vcxproj
Expand Up @@ -3996,6 +3996,7 @@
<ClInclude Include="..\..\src\teambuilder.hpp" />
<ClInclude Include="..\..\src\terrain\builder.hpp" />
<ClInclude Include="..\..\src\terrain\filter.hpp" />
<ClInclude Include="..\..\src\terrain\movement.hpp" />
<ClInclude Include="..\..\src\terrain\terrain.hpp" />
<ClInclude Include="..\..\src\terrain\translation.hpp" />
<ClInclude Include="..\..\src\terrain\type_data.hpp" />
Expand Down
4 changes: 4 additions & 0 deletions projectfiles/VC14/wesnoth.vcxproj.filters
Expand Up @@ -3048,6 +3048,10 @@
<ClInclude Include="..\..\src\utils\scope_exit.hpp">
<Filter>utils</Filter>
</ClInclude>
<ClInclude Include="..\..\src\chat_log.hpp" />
<ClInclude Include="..\..\src\terrain\movement.hpp">
<Filter>Terrain</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\src\tests\test_sdl_utils.hpp">
Expand Down
24 changes: 8 additions & 16 deletions src/gui/widgets/unit_preview_pane.cpp
Expand Up @@ -37,6 +37,7 @@
#include "play_controller.hpp"
#include "resources.hpp"
#include "team.hpp"
#include "terrain/movement.hpp"
#include "units/attack_type.hpp"
#include "units/types.hpp"
#include "units/helper.hpp"
Expand Down Expand Up @@ -145,13 +146,7 @@ static inline std::string get_hp_tooltip(const utils::string_map& res, const std

static inline std::string get_mp_tooltip(int total_movement, std::function<int (t_translation::terrain_code)> get)
{
auto movement_compare = [](std::pair<t_string, int> a, std::pair<t_string, int> b)
{
return translation::icompare(a.first, b.first) < 0;
};

// terrain_moves pair: first: name, second: movement_cost
std::set<std::pair<t_string, int>, decltype(movement_compare)> terrain_moves(movement_compare);
std::set<terrain_movement> terrain_moves;
std::ostringstream tooltip;
tooltip << "<big>" << _("Movement Costs:") << "</big>";

Expand All @@ -172,21 +167,18 @@ static inline std::string get_mp_tooltip(int total_movement, std::function<int (
}
}

for(const std::pair<t_string, int> tm: terrain_moves)
for(const terrain_movement& tm: terrain_moves)
{
const std::string name = tm.first;
const int moves = tm.second;

tooltip << '\n' << font::unicode_bullet << " " << name << ": ";
tooltip << '\n' << font::unicode_bullet << " " << tm.name << ": ";

// movement - range: 1 .. 5, movetype::UNREACHABLE=impassable
const bool cannot_move = moves > total_movement;
const bool cannot_move = tm.moves > total_movement;

std::string color;
if(cannot_move) {
// cannot move in this terrain
color = "red";
} else if(moves > 1) {
} else if(tm.moves > 1) {
color = "yellow";
} else {
color = "white";
Expand All @@ -195,10 +187,10 @@ static inline std::string get_mp_tooltip(int total_movement, std::function<int (
tooltip << "<span color='" << color << "'>";

// A 5 MP margin; if the movement costs go above the unit's max moves + 5, we replace it with dashes.
if(cannot_move && (moves > total_movement + 5)) {
if(cannot_move && (tm.moves > total_movement + 5)) {
tooltip << font::unicode_figure_dash;
} else {
tooltip << moves;
tooltip << tm.moves;
}

tooltip << "</span>";
Expand Down
87 changes: 37 additions & 50 deletions src/help/help_topic_generators.cpp
Expand Up @@ -51,6 +51,11 @@ struct terrain_movement_info
const int vision_cost;
const int jamming_cost;
const bool defense_cap;

bool operator<(const terrain_movement_info& other) const
{
return translation::icompare(name, other.name) < 0;
}
};

static std::string best_str(bool best) {
Expand Down Expand Up @@ -242,12 +247,6 @@ static void print_trait_list(std::stringstream & ss, const std::vector<trait_dat
}

std::string unit_topic_generator::operator()() const {
// Used for sorting terrain_movement_info terrain_moves. Needs to be declared before terrain_moves.
auto movement_compare = [](terrain_movement_info a, terrain_movement_info b)
{
return translation::icompare(a.name, b.name) < 0;
};

// Force the lazy loading to build this unit.
unit_types.build_unit_type(type_, unit_type::FULL);

Expand Down Expand Up @@ -658,14 +657,10 @@ std::string unit_topic_generator::operator()() const {
}

table.push_back(first_row);
std::set<t_translation::terrain_code>::const_iterator terrain_it =
preferences::encountered_terrains().begin();

std::set<terrain_movement_info, decltype(movement_compare)> terrain_moves(movement_compare);
std::set<terrain_movement_info> terrain_moves;

for (; terrain_it != preferences::encountered_terrains().end();
++terrain_it) {
const t_translation::terrain_code terrain = *terrain_it;
for (t_translation::terrain_code terrain : preferences::encountered_terrains()) {
if (terrain == t_translation::FOGGED || terrain == t_translation::VOID_TERRAIN || t_translation::terrain_matches(terrain, t_translation::ALL_OFF_MAP)) {
continue;
}
Expand All @@ -692,84 +687,76 @@ std::string unit_topic_generator::operator()() const {
}
}

for(const terrain_movement_info &terr_move : terrain_moves)
for(const terrain_movement_info &m : terrain_moves)
{
std::vector<item> row;
const std::string& name = terr_move.name;
const std::string& id = terr_move.id;
const int defense = terr_move.defense;
const int moves = terr_move.movement_cost;
const int views = terr_move.vision_cost;
const int jams = terr_move.jamming_cost;
const bool has_cap = terr_move.defense_cap;
const bool cannot_move = moves > type_.movement();


bool high_res = false;
const std::string tc_base = high_res ? "images/buttons/icon-base-32.png" : "images/buttons/icon-base-16.png";
const std::string terrain_image = "icons/terrain/terrain_type_" + id + (high_res ? "_30.png" : ".png");
const std::string terrain_image = "icons/terrain/terrain_type_" + m.id + (high_res ? "_30.png" : ".png");

const std::string final_image = tc_base + "~RC(magenta>" + id + ")~BLIT(" + terrain_image + ")";
const std::string final_image = tc_base + "~RC(magenta>" + m.id + ")~BLIT(" + terrain_image + ")";

row.emplace_back("<img>src='" + final_image + "'</img> " +
make_link(name, "..terrain_" + id),
font::line_width(name, normal_font_size) + (high_res ? 32 : 16) );
make_link(m.name, "..terrain_" + m.id),
font::line_width(m.name, normal_font_size) + (high_res ? 32 : 16) );

//defense - range: +10 % .. +70 %
std::string color;
if (defense <= 10) {
if (m.defense <= 10) {
color = "red";
} else if (defense <= 30) {
} else if (m.defense <= 30) {
color = "yellow";
} else if (defense <= 50) {
} else if (m.defense <= 50) {
color = "white";
} else {
color = "green";
}

std::stringstream str;
str << "<format>color=" << color << " text='"<< defense << "%'</format>";
str << "<format>color=" << color << " text='"<< m.defense << "%'</format>";
std::string markup = str.str();
str.str(clear_stringstream);
str << defense << "%";
str << m.defense << "%";
row.emplace_back(markup, font::line_width(str.str(), normal_font_size));

//movement - range: 1 .. 5, movetype::UNREACHABLE=impassable
str.str(clear_stringstream);
bool cannot_move = m.movement_cost > type_.movement();
if (cannot_move) { // cannot move in this terrain
color = "red";
} else if (moves > 1) {
} else if (m.movement_cost > 1) {
color = "yellow";
} else {
color = "white";
}
str << "<format>color=" << color << " text='";
// A 5 MP margin; if the movement costs go above
// the unit's max moves + 5, we replace it with dashes.
if(cannot_move && (moves > type_.movement() + 5)) {
if(cannot_move && (m.movement_cost > type_.movement() + 5)) {
str << font::unicode_figure_dash;
} else {
str << moves;
str << m.movement_cost;
}
str << "'</format>";
markup = str.str();
str.str(clear_stringstream);
str << moves;
str << m.movement_cost;
row.emplace_back(markup, font::line_width(str.str(), normal_font_size));

//defense cap
if (has_terrain_defense_caps) {
str.str(clear_stringstream);
if (has_cap) {
str << "<format>color='"<< color <<"' text='" << defense << "%'</format>";
if (m.defense_cap) {
str << "<format>color='"<< color <<"' text='" << m.defense << "%'</format>";
} else {
str << "<format>color=white text='" << font::unicode_figure_dash << "'</format>";
}

markup = str.str();
str.str(clear_stringstream);
if (has_cap) {
str << defense << '%';
if (m.defense_cap) {
str << m.defense << '%';
} else {
str << font::unicode_figure_dash;
}
Expand All @@ -779,51 +766,51 @@ std::string unit_topic_generator::operator()() const {
//vision
if (has_vision) {
str.str(clear_stringstream);
const bool cannot_view = views > type_.vision();
const bool cannot_view = m.vision_cost > type_.vision();
if (cannot_view) { // cannot view in this terrain
color = "red";
} else if (views > moves) {
} else if (m.vision_cost > m.movement_cost) {
color = "yellow";
} else if (views == moves) {
} else if (m.vision_cost == m.movement_cost) {
color = "white";
} else {
color = "green";
}
str << "<format>color=" << color << " text='";
// A 5 MP margin; if the vision costs go above
// the unit's vision + 5, we replace it with dashes.
if(cannot_view && (views > type_.vision() + 5)) {
if(cannot_view && (m.vision_cost > type_.vision() + 5)) {
str << font::unicode_figure_dash;
} else {
str << views;
str << m.vision_cost;
}
str << "'</format>";
markup = str.str();
str.str(clear_stringstream);
str << views;
str << m.vision_cost;
row.emplace_back(markup, font::line_width(str.str(), normal_font_size));
}

//jamming
if (has_jamming) {
str.str(clear_stringstream);
const bool cannot_jam = jams > type_.jamming();
const bool cannot_jam = m.jamming_cost > type_.jamming();
if (cannot_jam) { // cannot jamm in this terrain
color = "red";
} else if (jams > views) {
} else if (m.jamming_cost > m.vision_cost) {
color = "yellow";
} else if (jams == views) {
} else if (m.jamming_cost == m.vision_cost) {
color = "white";
} else {
color = "green";
}
str << "<format>color=" << color << " text='";
// A 5 MP margin; if the jamming costs go above
// the unit's jamming + 5, we replace it with dashes.
if ( cannot_jam && jams > type_.jamming() + 5 ) {
if (cannot_jam && m.jamming_cost > type_.jamming() + 5) {
str << font::unicode_figure_dash;
} else {
str << jams;
str << m.jamming_cost;
}
str << "'</format>";

Expand Down
31 changes: 9 additions & 22 deletions src/reports.cpp
Expand Up @@ -25,6 +25,7 @@
#include "reports.hpp"
#include "color.hpp"
#include "team.hpp"
#include "terrain/movement.hpp"
#include "tod_manager.hpp"
#include "units/unit.hpp"
#include "units/helper.hpp"
Expand Down Expand Up @@ -582,27 +583,16 @@ static config unit_moves(reports::context & rc, const unit* u)
std::ostringstream str, tooltip;
double movement_frac = 1.0;

auto movement_compare = [](std::pair<t_string, int> a, std::pair<t_string, int> b)
{
return translation::icompare(a.first, b.first) < 0;
};

// terrain_moves pair: first: name, second: movement_cost
std::set<std::pair<t_string, int>, decltype(movement_compare)> terrain_moves(movement_compare);
std::set<terrain_movement> terrain_moves;

if (u->side() == rc.screen().playing_side()) {
movement_frac = static_cast<double>(u->movement_left()) / std::max<int>(1, u->total_movement());
if (movement_frac > 1.0)
movement_frac = 1.0;
}

std::set<t_translation::terrain_code>::const_iterator terrain_it =
preferences::encountered_terrains().begin();

tooltip << _("Movement Costs:") << "\n";
for (; terrain_it != preferences::encountered_terrains().end();
++terrain_it) {
const t_translation::terrain_code terrain = *terrain_it;
for (t_translation::terrain_code terrain : preferences::encountered_terrains()) {
if (terrain == t_translation::FOGGED || terrain == t_translation::VOID_TERRAIN || t_translation::terrain_matches(terrain, t_translation::ALL_OFF_MAP))
continue;

Expand All @@ -613,28 +603,25 @@ static config unit_moves(reports::context & rc, const unit* u)
}
}

for(const std::pair<t_string, int> tm : terrain_moves)
{
const std::string name = tm.first;
const int moves = tm.second;
tooltip << name << ": ";
for (const terrain_movement& tm : terrain_moves) {
tooltip << tm.name << ": ";

std::string color;
//movement - range: 1 .. 5, movetype::UNREACHABLE=impassable
const bool cannot_move = moves > u->total_movement();
const bool cannot_move = tm.moves > u->total_movement();
if (cannot_move) // cannot move in this terrain
color = "red";
else if (moves > 1)
else if (tm.moves > 1)
color = "yellow";
else
color = "white";
tooltip << "<span foreground=\"" << color << "\">";
// A 5 MP margin; if the movement costs go above
// the unit's max moves + 5, we replace it with dashes.
if(cannot_move && (moves > u->total_movement() + 5)) {
if (cannot_move && (tm.moves > u->total_movement() + 5)) {
tooltip << font::unicode_figure_dash;
} else {
tooltip << moves;
tooltip << tm.moves;
}
tooltip << naps << '\n';
}
Expand Down
32 changes: 32 additions & 0 deletions src/terrain/movement.hpp
@@ -0,0 +1,32 @@
/*
Copyright (C) 2018 by Jyrki Vesterinen <sandgtx@gmail.com>
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
or at your option any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/

#pragma once

#include "gettext.hpp"
#include "tstring.hpp"

struct terrain_movement
{
const t_string& name;
int moves;

terrain_movement(const t_string& name_, int moves_)
: name(name_), moves(moves_)
{}

bool operator<(const terrain_movement& other) const
{
return translation::icompare(name, other.name) < 0;
}
};

0 comments on commit f245cd6

Please sign in to comment.