32 #include <boost/optional.hpp>
33 #include <boost/shared_ptr.hpp>
40 #define WRN_HP LOG_STREAM(warn, log_help)
41 #define DBG_HP LOG_STREAM(debug, log_help)
46 std::string lang_policy = (best ?
_(
"Best of") :
_(
"Worst of"));
49 return "<format>color='" + color_policy +
"' text='" + lang_policy +
"'</format>";
52 typedef t_translation::t_list::const_iterator
t_it;
57 if (start == end)
return "";
60 boost::optional<t_it> last_change_pos;
62 bool best = begin_best;
63 for (t_it
i = start;
i !=
end; ++
i) {
72 if (!last_change_pos) {
73 std::vector<std::string>
names;
74 for (t_it
i = start;
i !=
end; ++
i) {
80 if (names.size() == 0)
return "";
81 if (names.size() == 1)
return names.at(0);
84 if (!first_level) ss <<
"( ";
87 for (
size_t i = 1;
i < names.size();
i++) {
88 ss <<
", " << names.at(
i);
91 if (!first_level) ss <<
" )";
93 std::vector<std::string>
names;
94 for (t_it
i = *last_change_pos+1;
i !=
end; ++
i) {
105 if (!first_level) ss <<
"( ";
111 if (!first_level) ss <<
" )";
117 std::stringstream ss;
120 ss <<
"<img>src='images/buttons/icon-base-32.png~RC(magenta>" <<
type_.
id()
121 <<
")~BLIT("<<
"terrain/" <<
type_.
icon_image() <<
"_30.png)" <<
"'</img> ";
134 WRN_HP <<
"When building terrain help topics, we couldn't acquire any terrain types data\n";
142 ss <<
"\n" <<
_(
"Base Terrain: ");
146 const terrain_type& mvt_base = tdata->get_terrain_info(underlying_terrain);
161 ss <<
"\n" <<
_(
"Movement properties: ");
165 ss <<
"\n" <<
_(
"Defense properties: ");
172 ss <<
"ID: " <<
type_.
id() <<
"\n";
177 ss <<
"Keep: " << (
type_.
is_keep() ?
"Yes" :
"No") <<
"\n";
187 ss <<
"Hide Help: " << (
type_.
hide_help() ?
"Yes" :
"No") <<
"\n";
195 ss <<
"\nEditor Image: Empty\n";
201 ss <<
"\nDebug Mvt Description String:";
207 ss <<
"\nDebug Def Description String:";
227 for(i++; i < l.size(); i++) {
228 ss <<
", " <<
make_link(l[i].first,l[i].second);
236 std::stringstream ss;
247 ss <<
"<img>src='" << male_type.
image() <<
"~XBRZ(2)' box='no'</img> ";
249 ss <<
"<img>src='" << male_type.
image() <<
"~RC(" << male_type.
flag_rgb() <<
">red)~XBRZ(2)' box='no'</img> ";
252 if (&female_type != &male_type) {
254 ss <<
"<img>src='" << female_type.
image() <<
"~XBRZ(2)' box='no'</img> ";
256 ss <<
"<img>src='" << female_type.
image() <<
"~RC(" << female_type.
flag_rgb() <<
">red)~XBRZ(2)' box='no'</img> ";
267 if (screen_width <= 800) {
269 }
else if(screen_width <= 1024) {
274 if (!male_portrait.empty() && male_portrait != male_type.
image() && male_portrait !=
"unit_image") {
275 ss <<
"<img>src='" << male_portrait <<
"~FL(horiz)~SCALE_INTO(" << sz <<
',' << sz <<
")' box='no' align='right' float='yes'</img> ";
280 if (!female_portrait.empty() && female_portrait != male_portrait && female_portrait != female_type.
image() && female_portrait !=
"unit_image") {
281 ss <<
"<img>src='" << female_portrait <<
"~FL(horiz)~SCALE_INTO(" << sz <<
',' << sz <<
")' box='no' align='right' float='yes'</img> ";
288 const bool first_reverse_value =
true;
289 bool reverse = first_reverse_value;
292 std::vector<std::string> adv_units =
304 ss <<
_(
"Advances from: ");
306 ss <<
_(
"Advances to: ");
329 }
while(reverse != first_reverse_value);
340 ss <<
_(
"Base units: ");
358 ss <<
_(
"Variations: ");
381 if (race_name.empty()) {
382 race_name =
_ (
"race^Miscellaneous");
385 ss <<
make_link(race_name,
"..race_" + race_id);
392 std::vector<trait_data> must_have_traits;
393 std::vector<trait_data> random_traits;
395 for (
const config & trait : traits) {
398 const std::string ref_id =
"traits_"+trait[
"id"].str();
399 ((trait[
"availability"].str() ==
"musthave") ? must_have_traits : random_traits).push_back(std::make_pair(lang_trait_name, ref_id));
402 bool line1 = !must_have_traits.empty();
403 bool line2 = !random_traits.empty() &&
type_.
num_traits() - must_have_traits.size() > 0;
409 std::stringstream must_have_count;
410 must_have_count <<
" (" << must_have_traits.size() <<
") : ";
411 std::stringstream random_count;
412 random_count <<
" (" << (
type_.
num_traits() - must_have_traits.size()) <<
") : ";
418 ss << must_have_count.str();
420 ss <<
"\n" <<
jump(second_line_whitespace) << random_count.str();
439 ss <<
_(
"Abilities: ");
440 for(std::vector<t_string>::const_iterator ability_it =
type_.
abilities().begin(),
442 ability_it != ability_end; ++ability_it) {
443 const std::string ref_id =
"ability_" + ability_it->base_str();
446 if (ability_it + 1 != ability_end) {
455 ss <<
_(
"Ability Upgrades: ");
458 ability_it != ability_end; ++ability_it) {
459 const std::string ref_id =
"ability_" + ability_it->base_str();
462 if (ability_it + 1 != ability_end) {
488 ss <<
"\n\n" << detailed_description;
492 if (!attacks.empty()) {
494 ss <<
"\n\n<header>text='" <<
escape(
_(
"unit help^Attacks"))
498 std::vector<item> first_row;
500 first_row.push_back(
item(
"", 0));
506 table.push_back(first_row);
508 for(std::vector<attack_type>::const_iterator attack_it = attacks.begin(),
509 attack_end = attacks.end();
510 attack_it != attack_end; ++attack_it) {
513 std::vector<item>
row;
514 std::stringstream attack_ss;
515 attack_ss <<
"<img>src='" << (*attack_it).icon() <<
"'</img>";
516 row.push_back(std::make_pair(attack_ss.str(),
image_width(attack_it->icon())));
519 attack_ss.str(clear_stringstream);
521 <<
" " << attack_it->accuracy_parry_description();
523 attack_ss.str(clear_stringstream);
524 if ((*attack_it).min_range() > 1 || (*attack_it).max_range() > 1) {
525 attack_ss << (*attack_it).min_range() <<
"-" << (*attack_it).max_range() <<
' ';
527 attack_ss <<
string_table[
"range_" + (*attack_it).range()];
529 attack_ss.str(clear_stringstream);
532 std::vector<std::pair<t_string, t_string> > specials = attack_it->special_tooltips();
533 if (!specials.empty()) {
535 const size_t specials_size = specials.size();
536 for (
size_t i = 0;
i != specials_size; ++
i) {
538 + specials[
i].first.base_str();
539 lang_special = (specials[
i].first);
540 attack_ss <<
make_link(lang_special, ref_id);
541 if (
i+1 != specials_size) {
545 row.push_back(std::make_pair(attack_ss.str(),
548 table.push_back(row);
557 for (
const config &
t : traits) {
558 if (
t[
"availability"].str() ==
"musthave") {
560 if (!effect.child(
"filter")
562 movement_type.
merge(effect, effect[
"replace"].to_bool());
570 ss <<
"\n\n<header>text='" <<
escape(
_(
"Resistances"))
573 std::vector<item> first_res_row;
576 resistance_table.push_back(first_res_row);
578 for (utils::string_map::const_iterator dam_it = dam_tab.begin(), dam_end = dam_tab.end();
579 dam_it != dam_end; ++dam_it) {
580 std::vector<item>
row;
581 int resistance = 100 - std::stoi((*dam_it).second);
583 snprintf(resi,
sizeof(resi),
"% 4d%%",resistance);
585 const size_t pos = resist.find(
'-');
586 if (pos != std::string::npos) {
592 std::stringstream str;
593 str <<
"<format>color=\"" << color <<
"\" text='"<< resist <<
"'</format>";
595 str.str(clear_stringstream);
597 row.push_back(std::make_pair(markup,
599 resistance_table.push_back(row);
605 ss <<
"\n\n<header>text='" <<
escape(
_(
"Terrain Modifiers"))
607 std::vector<item> first_row;
614 if (has_terrain_defense_caps) {
627 table.push_back(first_row);
628 std::set<t_translation::t_terrain>::const_iterator terrain_it =
640 std::vector<item>
row;
644 const int views = movement_type.
vision_cost(terrain);
647 bool high_res =
false;
648 const std::string tc_base = high_res ?
"images/buttons/icon-base-32.png" :
"images/buttons/icon-base-16.png";
649 const std::string terrain_image =
"icons/terrain/terrain_type_" +
id + (high_res ?
"_30.png" :
".png");
651 const std::string final_image = tc_base +
"~RC(magenta>" +
id +
")~BLIT(" + terrain_image +
")";
653 row.push_back(std::make_pair(
"<img>src='" + final_image +
"'</img> " +
662 }
else if (defense <= 30) {
664 }
else if (defense <= 50) {
670 std::stringstream str;
671 str <<
"<format>color=" << color <<
" text='"<< defense <<
"%'</format>";
673 str.str(clear_stringstream);
674 str << defense <<
"%";
675 row.push_back(std::make_pair(markup,
679 str.str(clear_stringstream);
683 }
else if (moves > 1) {
688 str <<
"<format>color=" << color <<
" text='";
698 str.str(clear_stringstream);
700 row.push_back(std::make_pair(markup,
704 if (has_terrain_defense_caps) {
705 str.str(clear_stringstream);
708 str <<
"<format>color='"<< color <<
"' text='" << defense <<
"%'</format>";
713 str.str(clear_stringstream);
715 str << defense <<
'%';
719 row.push_back(std::make_pair(markup,
725 str.str(clear_stringstream);
729 }
else if (views > moves) {
731 }
else if (views == moves) {
736 str <<
"<format>color=" << color <<
" text='";
746 str.str(clear_stringstream);
748 row.push_back(std::make_pair(markup,
754 str.str(clear_stringstream);
758 }
else if (jams > views) {
760 }
else if (jams == views) {
765 str <<
"<format>color=" << color <<
" text='";
778 table.push_back(row);
784 WRN_HP <<
"When building unit help topics, the display object was null and we couldn't get the terrain info we need.\n";
child_itors child_range(const std::string &key)
const t_string & help_topic_text() const
const std::string unit_prefix
static lg::log_domain log_help("help")
const unit_type & get_gender_unit_type(std::string gender) const
const t_string & type_name() const
The name of the unit in the current language setting.
const std::vector< t_string > & abilities() const
void push_tab_pair(std::vector< std::pair< std::string, unsigned int > > &v, const std::string &s)
const std::vector< std::string > advances_from() const
int vision_cost(const t_translation::t_terrain &terrain, bool slowed=false) const
Returns the cost to see through the indicated terrain.
virtual std::string operator()() const
const std::string unknown_unit_topic
GLuint GLuint GLsizei GLenum type
t_translation::t_list::const_iterator t_it
const movetype & movement_type() const
const std::string & variation_name() const
bool hide_in_editor() const
const t_string & name() const
unit_type_data unit_types
const std::string & id() const
const unit_race * race() const
Never returns nullptr, but may point to the null race.
const std::string & image() const
static CVideo & get_singleton()
const std::string variation_
void push_header(std::vector< item > &row, const std::string &name) const
const t_translation::t_list & union_type() const
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus...
const int normal_font_size
void merge(const config &new_cfg, bool overwrite=true)
Merges the given config over the existing data.
The basic "size" of the unit - flying, small land, large land, etc.
unsigned image_width(const std::string &filename)
const std::string & editor_group() const
const std::string terrain_prefix
const t_terrain OFF_MAP_USER
bool capped(const t_translation::t_terrain &terrain) const
Returns whether there is a defense cap associated to this terrain.
const t_string & editor_name() const
int movement_cost(const t_translation::t_terrain &terrain, bool slowed=false) const
Returns the cost to move through the indicated terrain.
std::pair< const_child_iterator, const_child_iterator > const_child_itors
const std::string unicode_minus
static std::string best_str(bool best)
bool has_vision_data() const
Returns whether or not there are any vision-specific costs.
static UNUSEDNOWARN std::string _(const char *str)
const std::string & flag_rgb() const
std::string generate_table(const table_spec &tab, const unsigned int spacing)
std::map< std::string, t_string > string_map
int gives_healing() const
const std::string unicode_en_dash
const std::string & big_profile() const
const std::string & editor_image() const
t_translation::t_terrain number() const
terrain_defense & get_defense()
std::vector< std::vector< std::pair< std::string, unsigned int > > > table_spec
static const std::set< std::string > effects
The set of applicable effects for movement types.
static std::string print_behavior_description(t_it start, t_it end, const tdata_cache &tdata, bool first_level=true, bool begin_best=true)
std::set< t_translation::t_terrain > & encountered_terrains()
const std::vector< unit_race::GENDER > & genders() const
The returned vector will not be empty, provided this has been built to the HELP_INDEXED status...
bool show_variations_in_help() const
Whether the unit type has at least one help-visible variation.
const terrain_type & type_
void build_unit_type(const unit_type &ut, unit_type::BUILD_STATUS status) const
Makes sure the provided unit_type is built to the specified level.
tdata_cache load_terrain_types_data()
Load the appropriate terrain types data to use.
const t_string & plural_name() const
static UNUSEDNOWARN std::string gettext(const char *str)
static const ::config * terrain
The terrain used to create the cache.
const std::string & small_profile() const
GLuint const GLuint * names
utils::string_map damage_table() const
Returns a map from attack types to resistances.
std::string race_id() const
Returns the ID of this type's race without the need to build the type.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
const std::vector< std::string > & advances_to() const
static void print_trait_list(std::stringstream &ss, const std::vector< trait_data > &l)
const std::string unicode_figure_dash
const std::string variation_prefix
std::pair< std::string, unsigned > item
std::string resistance_color(const int resistance)
const unit_type & get_variation(const std::string &id) const
config::const_child_itors possible_traits() const
std::string make_link(const std::string &text, const std::string &dst)
std::vector< std::string > variations() const
unsigned screen_width
The screen resolution should be available for all widgets since their drawing method will depend on i...
virtual std::string operator()() const
const config & get_cfg() const
std::string escape(const std::string &s)
Prepend all chars with meaning inside attributes with a backslash.
GLuint const GLchar * name
int experience_needed(bool with_acceleration=true) const
const t_terrain VOID_TERRAIN
GLenum GLenum GLvoid * row
std::string jump(const unsigned amount)
const std::vector< t_string > & adv_abilities() const
bool has_terrain_defense_caps(const std::set< t_translation::t_terrain > &ts) const
Returns whether or not there are any terrain caps with respect to a set of terrains.
symbol_table string_table
bool has_jamming_data() const
Returns whether or not there are any jamming-specific costs.
std::vector< attack_type > attacks() const
Standard logging facilities (interface).
unsigned int num_traits() const
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
const std::string & str() const
A config object defines a single node in a WML file, with access to child nodes.
static std::string alignment_description(ALIGNMENT align, unit_race::GENDER gender=unit_race::MALE)
UNIT_DESCRIPTION_TYPE description_type(const unit_type &type)
Return the type of description that should be shown for a unit of the given kind. ...
const t_string & income_description() const
GLenum GLsizei GLenum GLenum const GLvoid * table
GLsizei const GLcharARB ** string
int jamming_cost(const t_translation::t_terrain &terrain, bool slowed=false) const
Returns the cost to "jam" through the indicated terrain.
int line_width(const std::string &line, int font_size, int style)
Determine the width of a line of text given a certain font size.
const std::string & icon_image() const
std::pair< std::string, std::string > trait_data
const std::string & id() const
The id for this unit_type.
int defense_modifier(const t_translation::t_terrain &terrain) const
Returns the defensive value of the indicated terrain.
t_string unit_description() const
std::vector< t_terrain > t_list