convert help_topic_generator to new markup (partial)
This commit is contained in:
parent
78ca6f50a9
commit
fe9de2f638
1 changed files with 347 additions and 44 deletions
|
@ -20,11 +20,11 @@
|
|||
#include "font/sdl_ttf_compat.hpp"
|
||||
#include "formula/string_utils.hpp" // for VNGETTEXT
|
||||
#include "game_config.hpp" // for debug, menu_contract, etc
|
||||
#include "preferences/preferences.hpp" // for encountered_terrains, etc
|
||||
#include "gettext.hpp" // for _, gettext, N_
|
||||
#include "language.hpp" // for string_table, symbol_table
|
||||
#include "log.hpp" // for LOG_STREAM, logger, etc
|
||||
#include "movetype.hpp" // for movetype, movetype::effects, etc
|
||||
#include "preferences/preferences.hpp" // for encountered_terrains, etc
|
||||
#include "units/race.hpp" // for unit_race, etc
|
||||
#include "terrain/terrain.hpp" // for terrain_type
|
||||
#include "terrain/translation.hpp" // for operator==, ter_list, etc
|
||||
|
@ -140,13 +140,13 @@ std::string terrain_topic_generator::operator()() const {
|
|||
|
||||
if (!type_.icon_image().empty())
|
||||
ss << "<img>src='images/buttons/icon-base-32.png~RC(magenta>" << type_.id()
|
||||
<< ")~BLIT("<< "terrain/" << type_.icon_image() << "_30.png)" << "'</img> ";
|
||||
<< ")~BLIT("<< "terrain/" << type_.icon_image() << "_30.png)" << "'</img>";
|
||||
|
||||
if (!type_.editor_image().empty())
|
||||
ss << "<img>src='" << type_.editor_image() << "'</img> ";
|
||||
ss << "<img>src='" << type_.editor_image() << "'</img>";
|
||||
|
||||
if (!type_.help_topic_text().empty())
|
||||
ss << "\n\n" << type_.help_topic_text().str() << "\n";
|
||||
ss << "\n" << type_.help_topic_text().str() << "\n";
|
||||
else
|
||||
ss << "\n";
|
||||
|
||||
|
@ -185,7 +185,7 @@ std::string terrain_topic_generator::operator()() const {
|
|||
}
|
||||
|
||||
if(!special_notes.empty()) {
|
||||
ss << "\n" << _("Special Notes:") << '\n';
|
||||
ss << "\n\n" << _("<header>Special Notes</header>") << "\n";
|
||||
for(const auto& note : special_notes) {
|
||||
ss << font::unicode_bullet << " " << note << '\n';
|
||||
}
|
||||
|
@ -309,20 +309,8 @@ std::string unit_topic_generator::operator()() const {
|
|||
const int screen_width = video::game_canvas_size().x;
|
||||
|
||||
ss << _("Level") << " " << type_.level();
|
||||
ss << "\n\n";
|
||||
|
||||
ss << "<img>src='" << male_type.image();
|
||||
ss << "~RC(" << male_type.flag_rgb() << ">red)";
|
||||
if (screen_width >= 1200) ss << "~SCALE_SHARP(200%,200%)";
|
||||
ss << "' box='no'</img> ";
|
||||
|
||||
if (female_type.image() != male_type.image()) {
|
||||
ss << "<img>src='" << female_type.image();
|
||||
ss << "~RC(" << female_type.flag_rgb() << ">red)";
|
||||
if (screen_width >= 1200) ss << "~SCALE_SHARP(200%,200%)";
|
||||
ss << "' box='no'</img> ";
|
||||
}
|
||||
|
||||
// Portraits
|
||||
const std::string &male_portrait = male_type.small_profile().empty() ?
|
||||
male_type.big_profile() : male_type.small_profile();
|
||||
const std::string &female_portrait = female_type.small_profile().empty() ?
|
||||
|
@ -344,15 +332,29 @@ std::string unit_topic_generator::operator()() const {
|
|||
|
||||
// TODO: figure out why the second checks don't match but the last does
|
||||
if (has_male_portrait) {
|
||||
ss << "<img>src='" << male_portrait << "~FL(horiz)~SCALE_INTO(" << sz << ',' << sz << ")' box='no' align='right' float='yes'</img> ";
|
||||
ss << "<img>src='" << male_portrait << "~FL(horiz)~SCALE_INTO(" << sz << ',' << sz << ")' box='no' align='right' float='yes'</img>";
|
||||
}
|
||||
|
||||
|
||||
if (has_female_portrait) {
|
||||
ss << "<img>src='" << female_portrait << "~FL(horiz)~SCALE_INTO(" << sz << ',' << sz << ")' box='no' align='right' float='yes'</img> ";
|
||||
ss << "<img>src='" << female_portrait << "~FL(horiz)~SCALE_INTO(" << sz << ',' << sz << ")' box='no' align='right' float='yes'</img>";
|
||||
}
|
||||
|
||||
ss << "\n\n\n";
|
||||
// Unit Images
|
||||
ss << "<img>src='" << male_type.image();
|
||||
ss << "~RC(" << male_type.flag_rgb() << ">red)";
|
||||
if (screen_width >= 1200) ss << "~SCALE_SHARP(200%,200%)";
|
||||
ss << "' box='no'</img>";
|
||||
|
||||
if (female_type.image() != male_type.image()) {
|
||||
ss << "<img>src='" << female_type.image();
|
||||
ss << "~RC(" << female_type.flag_rgb() << ">red)";
|
||||
if (screen_width >= 1200) ss << "~SCALE_SHARP(200%,200%)";
|
||||
ss << "' box='no'</img>";
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
|
||||
// #endif
|
||||
|
||||
// Print cross-references to units that this unit advances from/to.
|
||||
// Cross reference to the topics containing information about those units.
|
||||
|
@ -444,7 +446,6 @@ std::string unit_topic_generator::operator()() const {
|
|||
|
||||
ss << make_link(var_name, ref_id);
|
||||
}
|
||||
ss << "\n"; //added even if empty, to avoid shifting
|
||||
|
||||
// Print the race of the unit, cross-reference it to the respective topic.
|
||||
const std::string race_id = type_.race_id();
|
||||
|
@ -454,7 +455,7 @@ std::string unit_topic_generator::operator()() const {
|
|||
}
|
||||
ss << _("Race: ");
|
||||
ss << make_link(race_name, "..race_" + race_id);
|
||||
ss << "\n\n";
|
||||
ss << "\n";
|
||||
|
||||
// Print the possible traits of the unit, cross-reference them
|
||||
// to their respective topics.
|
||||
|
@ -493,28 +494,29 @@ std::string unit_topic_generator::operator()() const {
|
|||
ss << traits_label;
|
||||
if (line2) {
|
||||
std::stringstream must_have_count;
|
||||
must_have_count << " (" << must_have_traits.size() << ") : ";
|
||||
must_have_count << "\n (" << must_have_traits.size() << ") : ";
|
||||
std::stringstream random_count;
|
||||
random_count << " (" << (type_.num_traits() - must_have_traits.size() - must_have_nameless_traits) << ") : ";
|
||||
|
||||
int second_line_whitespace = font::pango_line_width(traits_label+must_have_count.str(), normal_font_size)
|
||||
- font::pango_line_width(random_count.str(), normal_font_size);
|
||||
// int second_line_whitespace = font::pango_line_width(traits_label+must_have_count.str(), normal_font_size)
|
||||
// - font::pango_line_width(random_count.str(), normal_font_size);
|
||||
// This ensures that the second line is justified so that the ':' characters are aligned.
|
||||
|
||||
ss << must_have_count.str();
|
||||
print_trait_list(ss, must_have_traits);
|
||||
ss << "\n" << jump(second_line_whitespace) << random_count.str();
|
||||
// ss << "\n" << jump(second_line_whitespace) << random_count.str();
|
||||
ss << "\n" << random_count.str();
|
||||
print_trait_list(ss, random_traits);
|
||||
} else {
|
||||
ss << ": ";
|
||||
print_trait_list(ss, must_have_traits);
|
||||
}
|
||||
ss << "\n\n";
|
||||
ss << "\n";
|
||||
} else {
|
||||
if (line2) {
|
||||
ss << _("Traits") << " (" << (type_.num_traits() - must_have_nameless_traits) << ") : ";
|
||||
print_trait_list(ss, random_traits);
|
||||
ss << "\n\n";
|
||||
ss << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -578,33 +580,33 @@ std::string unit_topic_generator::operator()() const {
|
|||
// TRANSLATORS: This string is used in the help page of a single unit. If the translation
|
||||
// uses spaces, use non-breaking spaces as appropriate for the target language to prevent
|
||||
// unpleasant line breaks (issue #3256).
|
||||
ss << _("HP:") << font::nbsp << type_.hitpoints() << jump(30)
|
||||
ss << _("HP:") << font::nbsp << type_.hitpoints() << " "
|
||||
// TRANSLATORS: This string is used in the help page of a single unit. If the translation
|
||||
// uses spaces, use non-breaking spaces as appropriate for the target language to prevent
|
||||
// unpleasant line breaks (issue #3256).
|
||||
<< _("Moves:") << font::nbsp << type_.movement() << jump(30);
|
||||
<< _("Moves:") << font::nbsp << type_.movement() << " ";
|
||||
if (type_.vision() != type_.movement()) {
|
||||
// TRANSLATORS: This string is used in the help page of a single unit. If the translation
|
||||
// uses spaces, use non-breaking spaces as appropriate for the target language to prevent
|
||||
// unpleasant line breaks (issue #3256).
|
||||
ss << _("Vision:") << font::nbsp << type_.vision() << jump(30);
|
||||
ss << _("Vision:") << font::nbsp << type_.vision() << " ";
|
||||
}
|
||||
if (type_.jamming() > 0) {
|
||||
// TRANSLATORS: This string is used in the help page of a single unit. If the translation
|
||||
// uses spaces, use non-breaking spaces as appropriate for the target language to prevent
|
||||
// unpleasant line breaks (issue #3256).
|
||||
ss << _("Jamming:") << font::nbsp << type_.jamming() << jump(30);
|
||||
ss << _("Jamming:") << font::nbsp << type_.jamming() << " ";
|
||||
}
|
||||
// TRANSLATORS: This string is used in the help page of a single unit. If the translation
|
||||
// uses spaces, use non-breaking spaces as appropriate for the target language to prevent
|
||||
// unpleasant line breaks (issue #3256).
|
||||
ss << _("Cost:") << font::nbsp << type_.cost() << jump(30)
|
||||
ss << _("Cost:") << font::nbsp << type_.cost() << " "
|
||||
// TRANSLATORS: This string is used in the help page of a single unit. If the translation
|
||||
// uses spaces, use non-breaking spaces as appropriate for the target language to prevent
|
||||
// unpleasant line breaks (issue #3256).
|
||||
<< _("Alignment:") << font::nbsp
|
||||
<< make_link(type_.alignment_description(type_.alignment(), type_.genders().front()), "time_of_day")
|
||||
<< jump(30);
|
||||
<< " ";
|
||||
if (type_.can_advance() || type_.modification_advancements()) {
|
||||
// TRANSLATORS: This string is used in the help page of a single unit. It uses
|
||||
// non-breaking spaces to prevent unpleasant line breaks (issue #3256). In the
|
||||
|
@ -614,21 +616,317 @@ std::string unit_topic_generator::operator()() const {
|
|||
|
||||
// Print the detailed description about the unit.
|
||||
ss << "\n\n" << detailed_description;
|
||||
|
||||
if(const auto notes = type_.special_notes(); !notes.empty()) {
|
||||
ss << "\n\n" << _("Special Notes:") << '\n';
|
||||
ss << "\n\n" << _("<header>Special Notes</header>") << "\n";
|
||||
for(const auto& note : notes) {
|
||||
ss << font::unicode_bullet << " " << note << '\n';
|
||||
ss << font::unicode_bullet << " <i>" << note << "</i>" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
// Print the attacks table
|
||||
ss << "\n<header>Attacks</header>";
|
||||
|
||||
if (!type_.attacks().empty()) {
|
||||
// Start table
|
||||
ss << "<table col=6/>";
|
||||
|
||||
// Print headers for the table.
|
||||
ss
|
||||
<< " " << "<jump/>"
|
||||
<< _("<b>Name</b>") << "<jump/>"
|
||||
<< _("<b>Strikes</b>") << "<jump/>"
|
||||
<< _("<b>Range</b>") << "<jump/>"
|
||||
<< _("<b>Type</b>") << "<jump/>"
|
||||
<< _("<b>Special</b>") << "<br/>";
|
||||
|
||||
std::stringstream attack_ss;
|
||||
|
||||
// Print information about every attack.
|
||||
for(const attack_type& attack : type_.attacks()) {
|
||||
std::string lang_weapon = attack.name();
|
||||
std::string lang_type = string_table["type_" + attack.type()];
|
||||
|
||||
// Attack icon
|
||||
attack_ss << "<img>src='" << attack.icon() << "'</img> <jump/>";
|
||||
|
||||
// attack name
|
||||
attack_ss << lang_weapon << "<jump/>";
|
||||
|
||||
// damage x strikes
|
||||
attack_ss << attack.damage() << font::weapon_numbers_sep << attack.num_attacks()
|
||||
<< " " << attack.accuracy_parry_description() << "<jump/>";
|
||||
|
||||
// range
|
||||
const std::string range_icon = "icons/profiles/" + attack.range() + "_attack.png~SCALE_INTO(16,16)";
|
||||
attack_ss << "<img src='" << range_icon << "'/>";
|
||||
if (attack.min_range() > 1 || attack.max_range() > 1) {
|
||||
attack_ss << attack.min_range() << "-" << attack.max_range() << ' ';
|
||||
}
|
||||
attack_ss << string_table["range_" + attack.range()] << "<jump/>";
|
||||
|
||||
// type
|
||||
const std::string type_icon = "icons/profiles/" + attack.type() + ".png~SCALE_INTO(16,16)";
|
||||
attack_ss << "<img src='" << type_icon << "'/>";
|
||||
attack_ss << lang_type << "<jump/>";
|
||||
|
||||
// special
|
||||
std::vector<std::pair<t_string, t_string>> specials = attack.special_tooltips();
|
||||
if (!specials.empty()) {
|
||||
std::string lang_special = "";
|
||||
const std::size_t specials_size = specials.size();
|
||||
for (std::size_t i = 0; i != specials_size; ++i) {
|
||||
const std::string ref_id = std::string("weaponspecial_")
|
||||
+ specials[i].first.base_str();
|
||||
lang_special = (specials[i].first);
|
||||
attack_ss << make_link(lang_special, ref_id);
|
||||
if (i+1 != specials_size) {
|
||||
attack_ss << ", "; //comma placed before next special
|
||||
}
|
||||
}
|
||||
} else {
|
||||
attack_ss << "none";
|
||||
}
|
||||
attack_ss << "<br/>";
|
||||
}
|
||||
|
||||
ss << attack_ss.str();
|
||||
ss << "<endtable/>";
|
||||
}
|
||||
|
||||
// Generate the movement type of the unit, with resistance, defense, movement, jamming and vision data updated according to any 'musthave' traits which always apply
|
||||
movetype movement_type = type_.movement_type();
|
||||
config::const_child_itors traits = type_.possible_traits();
|
||||
if (!traits.empty() && type_.num_traits() > 0) {
|
||||
for (const config & t : traits) {
|
||||
if (t["availability"].str() == "musthave") {
|
||||
for (const config & effect : t.child_range("effect")) {
|
||||
if (!effect.has_child("filter") // If this is musthave but has a unit filter, it might not always apply, so don't apply it in the help.
|
||||
&& movetype::effects.find(effect["apply_to"].str()) != movetype::effects.end()) {
|
||||
movement_type.merge(effect, effect["replace"].to_bool());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print the resistance table of the unit.
|
||||
ss << "\n<header>Resistances</header>";
|
||||
|
||||
// Start table
|
||||
ss << "<table col=2/>";
|
||||
ss << _("<b>Attack Type</b>") << "<jump/>";
|
||||
ss << _("<b>Resistance</b>") << "<br/>";
|
||||
|
||||
utils::string_map_res dam_tab = movement_type.damage_table();
|
||||
for(std::pair<std::string, std::string> dam_it : dam_tab) {
|
||||
int resistance = 100;
|
||||
try {
|
||||
resistance -= std::stoi(dam_it.second);
|
||||
} catch(std::invalid_argument&) {}
|
||||
std::string resist = std::to_string(resistance) + '%';
|
||||
const std::size_t pos = resist.find('-');
|
||||
if (pos != std::string::npos) {
|
||||
resist.replace(pos, 1, font::unicode_minus);
|
||||
}
|
||||
std::string color = unit_helper::resistance_color(resistance);
|
||||
const std::string lang_type = string_table["type_" + dam_it.first];
|
||||
const std::string type_icon = "icons/profiles/" + dam_it.first + ".png~SCALE_INTO(16,16)";
|
||||
ss << "<img src='" << type_icon << "'/>";
|
||||
ss << lang_type << "<jump/>";
|
||||
std::stringstream str;
|
||||
str << "<format>color=\"" << color << "\" text='"<< resist << "'</format>";
|
||||
ss << str.str() << "<br/>";
|
||||
}
|
||||
|
||||
ss << "<endtable/>";
|
||||
|
||||
if (std::shared_ptr<terrain_type_data> tdata = load_terrain_types_data()) {
|
||||
// Print the terrain modifier table of the unit.
|
||||
ss << "\n<header>Terrain Modifiers</header>";
|
||||
ss << "<table col=3/>";
|
||||
ss << _("<b>Terrain</b>") << "<jump/>";
|
||||
ss << _("<b>Defense</b>") << "<jump/>";
|
||||
ss << _("<b>Movement Cost</b>") << "<br/>";
|
||||
// ss << _("<b>Defense Cap</b>") << "<jump/>";
|
||||
// ss << _("<b>Vision Cost</b>") << "<jump/>";
|
||||
// ss << _("<b>Jamming Cost</b>") << "<br/>";
|
||||
|
||||
std::set<terrain_movement_info> terrain_moves;
|
||||
|
||||
for (t_translation::terrain_code terrain : prefs::get().encountered_terrains()) {
|
||||
if (terrain == t_translation::FOGGED || terrain == t_translation::VOID_TERRAIN || t_translation::terrain_matches(terrain, t_translation::ALL_OFF_MAP)) {
|
||||
continue;
|
||||
}
|
||||
const terrain_type& info = tdata->get_terrain_info(terrain);
|
||||
const int moves = movement_type.movement_cost(terrain);
|
||||
const bool cannot_move = moves > type_.movement();
|
||||
if (cannot_move && info.hide_if_impassable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info.is_indivisible() && info.is_nonnull()) {
|
||||
terrain_movement_info movement_info =
|
||||
{
|
||||
info.name(),
|
||||
info.id(),
|
||||
100 - movement_type.defense_modifier(terrain),
|
||||
moves,
|
||||
movement_type.vision_cost(terrain),
|
||||
movement_type.jamming_cost(terrain),
|
||||
movement_type.get_defense().capped(terrain)
|
||||
};
|
||||
|
||||
terrain_moves.insert(movement_info);
|
||||
}
|
||||
}
|
||||
|
||||
for(const terrain_movement_info &m : terrain_moves)
|
||||
{
|
||||
// std::vector<item> row;
|
||||
|
||||
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_" + m.id + (high_res ? "_30.png" : ".png");
|
||||
|
||||
const std::string final_image = tc_base + "~RC(magenta>" + m.id + ")~BLIT(" + terrain_image + ")";
|
||||
|
||||
// row.emplace_back("<img>src='" + final_image + "'</img> " +
|
||||
// make_link(m.name, "..terrain_" + m.id),
|
||||
// font::pango_line_width(m.name, normal_font_size) + (high_res ? 32 : 16) );
|
||||
ss << "<img>src='" + final_image + "'</img> " + make_link(m.name, "..terrain_" + m.id) << "<jump/>";
|
||||
|
||||
//defense - range: +10 % .. +70 %
|
||||
// passing false to select the more saturated red-to-green scale
|
||||
std::string color = game_config::red_to_green(m.defense, false).to_hex_string();
|
||||
|
||||
std::stringstream str;
|
||||
std::stringstream str_unformatted;
|
||||
str << "<format>color='" << color << "' text='"<< m.defense << "%'</format>";
|
||||
str_unformatted << m.defense << "%";
|
||||
// row.emplace_back(str.str(), font::pango_line_width(str_unformatted.str(), normal_font_size));
|
||||
ss << str.str() << "<jump/>";
|
||||
|
||||
//movement - range: 1 .. 5, movetype::UNREACHABLE=impassable
|
||||
str.str(clear_stringstream);
|
||||
str_unformatted.str(clear_stringstream);
|
||||
const bool cannot_move = m.movement_cost > type_.movement(); // cannot move in this terrain
|
||||
double movement_red_to_green = 100.0 - 25.0 * m.movement_cost;
|
||||
|
||||
// passing true to select the less saturated red-to-green scale
|
||||
std::string movement_color = game_config::red_to_green(movement_red_to_green, true).to_hex_string();
|
||||
str << "<format>color='" << movement_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 && (m.movement_cost > type_.movement() + 5)) {
|
||||
str_unformatted << font::unicode_figure_dash;
|
||||
} else if(cannot_move) {
|
||||
str_unformatted << "(" << m.movement_cost << ")";
|
||||
} else {
|
||||
str_unformatted << m.movement_cost;
|
||||
}
|
||||
if(m.movement_cost != 0) {
|
||||
const int movement_hexes_per_turn = type_.movement() / m.movement_cost;
|
||||
str_unformatted << " ";
|
||||
for(int i = 0; i < movement_hexes_per_turn; ++i) {
|
||||
// Unicode horizontal black hexagon and Unicode zero width space (to allow a line break)
|
||||
str_unformatted << "\u2b23\u200b";
|
||||
}
|
||||
}
|
||||
str << str_unformatted.str() << "'</format>";
|
||||
// row.emplace_back(str.str(), font::pango_line_width(str_unformatted.str(), normal_font_size));
|
||||
ss << str.str() << "<br/>";
|
||||
|
||||
//defense cap
|
||||
// if (has_terrain_defense_caps) {
|
||||
// str.str(clear_stringstream);
|
||||
// str_unformatted.str(clear_stringstream);
|
||||
// if (m.defense_cap) {
|
||||
// str << "<format>color='"<< color <<"' text='" << m.defense << "%'</format>";
|
||||
// str_unformatted << m.defense << "%";
|
||||
// } else {
|
||||
// str << "<format>color=white text='" << font::unicode_figure_dash << "'</format>";
|
||||
// str_unformatted << font::unicode_figure_dash;
|
||||
// }
|
||||
// row.emplace_back(str.str(), font::pango_line_width(str_unformatted.str(), normal_font_size));
|
||||
// }
|
||||
|
||||
//vision
|
||||
// if (has_vision) {
|
||||
// str.str(clear_stringstream);
|
||||
// str_unformatted.str(clear_stringstream);
|
||||
// const bool cannot_view = m.vision_cost > type_.vision(); // cannot view in this terrain
|
||||
// double vision_red_to_green = 100.0 - 25.0 * m.vision_cost;
|
||||
|
||||
// // passing true to select the less saturated red-to-green scale
|
||||
// std::string vision_color = game_config::red_to_green(vision_red_to_green, true).to_hex_string();
|
||||
// str << "<format>color='" << vision_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 && (m.vision_cost > type_.vision() + 5)) {
|
||||
// str_unformatted << font::unicode_figure_dash;
|
||||
// } else if(cannot_view) {
|
||||
// str_unformatted << "(" << m.vision_cost << ")";
|
||||
// } else {
|
||||
// str_unformatted << m.vision_cost;
|
||||
// }
|
||||
// if(m.vision_cost != 0) {
|
||||
// const int vision_hexes_per_turn = type_.vision() / m.vision_cost;
|
||||
// str_unformatted << " ";
|
||||
// for(int i = 0; i < vision_hexes_per_turn; ++i) {
|
||||
// // Unicode horizontal black hexagon and Unicode zero width space (to allow a line break)
|
||||
// str_unformatted << "\u2b23\u200b";
|
||||
// }
|
||||
// }
|
||||
// str << str_unformatted.str() << "'</format>";
|
||||
// row.emplace_back(str.str(), font::pango_line_width(str_unformatted.str(), normal_font_size));
|
||||
// }
|
||||
|
||||
// //jamming
|
||||
// if (has_jamming) {
|
||||
// str.str(clear_stringstream);
|
||||
// str_unformatted.str(clear_stringstream);
|
||||
// const bool cannot_jam = m.jamming_cost > type_.jamming(); // cannot jam in this terrain
|
||||
// double jamming_red_to_green = 100.0 - 25.0 * m.jamming_cost;
|
||||
|
||||
// // passing true to select the less saturated red-to-green scale
|
||||
// std::string jamming_color = game_config::red_to_green(jamming_red_to_green, true).to_hex_string();
|
||||
// str << "<format>color='" << jamming_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 && m.jamming_cost > type_.jamming() + 5) {
|
||||
// str_unformatted << font::unicode_figure_dash;
|
||||
// } else if(cannot_jam) {
|
||||
// str_unformatted << "(" << m.jamming_cost << ")";
|
||||
// } else {
|
||||
// str_unformatted << m.jamming_cost;
|
||||
// }
|
||||
// if(m.jamming_cost != 0) {
|
||||
// const int jamming_hexes_per_turn = type_.jamming() / m.jamming_cost;
|
||||
// str_unformatted << " ";
|
||||
// for(int i = 0; i < jamming_hexes_per_turn; ++i) {
|
||||
// // Unicode horizontal black hexagon and Unicode zero width space (to allow a line break)
|
||||
// str_unformatted << "\u2b23\u200b";
|
||||
// }
|
||||
// }
|
||||
// str << str_unformatted.str() << "'</format>";
|
||||
// row.emplace_back(str.str(), font::pango_line_width(str_unformatted.str(), normal_font_size));
|
||||
// }
|
||||
}
|
||||
|
||||
ss << "<endtable/>";
|
||||
}
|
||||
|
||||
/*
|
||||
// Padding for range and damage type icons
|
||||
const auto padding = 4; // matches the alignment of the terrain rows
|
||||
|
||||
// Print the different attacks a unit has, if it has any.
|
||||
if (!type_.attacks().empty()) {
|
||||
// Print headers for the table.
|
||||
ss << "\n\n<header>text='" << escape(_("unit help^Attacks"))
|
||||
<< "'</header>\n\n";
|
||||
ss << "\n<header>text='" << escape(_("unit help^Attacks"))
|
||||
<< "'</header>\n";
|
||||
|
||||
table_spec table;
|
||||
|
||||
std::vector<item> first_row;
|
||||
|
@ -932,11 +1230,16 @@ std::string unit_topic_generator::operator()() const {
|
|||
|
||||
table.push_back(row);
|
||||
}
|
||||
*/
|
||||
|
||||
// ss << generate_table(table);
|
||||
|
||||
// } else {
|
||||
// WRN_HP << "When building unit help topics, the display object was null and we couldn't get the terrain info we need.";
|
||||
// }
|
||||
|
||||
// PLAIN_LOG << ss.str();
|
||||
|
||||
ss << generate_table(table);
|
||||
} else {
|
||||
WRN_HP << "When building unit help topics, the display object was null and we couldn't get the terrain info we need.";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue