Help shows terrain types in the section for their default_base
Instead of the aliasing hack that the oasis terrain used to use, have the help topic generator reuse the editor_default_base as a hint that it should be included in that section. The terrain_type class gets a new boolean method, and more documentation. There's a couple of refactors to use the new method in old code too.
This commit is contained in:
parent
ebf93c02bb
commit
3fba8897d8
7 changed files with 65 additions and 25 deletions
|
@ -353,10 +353,7 @@ Most units receive 20 to 40% defense in sand."
|
|||
name= _ "Oasis"
|
||||
default_base=Dd
|
||||
string=^Do
|
||||
# Note: we must do the aliasing this way to allow the terrain to show up in the "Sand" terrain help group
|
||||
aliasof=Dt, Wst
|
||||
def_alias=_bas, Wst
|
||||
mvt_alias=_bas, Wst
|
||||
aliasof=_bas, Wst
|
||||
submerge=0.3
|
||||
heals=8
|
||||
editor_group=desert, water
|
||||
|
|
|
@ -170,11 +170,11 @@ void terrain_palette::setup_item(
|
|||
texture& overlay_image,
|
||||
std::stringstream& tooltip_text)
|
||||
{
|
||||
const t_translation::terrain_code base_terrain = map().get_terrain_info(terrain).default_base();
|
||||
const auto& info = map().get_terrain_info(terrain);
|
||||
|
||||
//Draw default base for overlay terrains
|
||||
if(base_terrain != t_translation::NONE_TERRAIN) {
|
||||
const std::string base_filename = map().get_terrain_info(base_terrain).editor_image();
|
||||
if(info.has_default_base()) {
|
||||
const std::string base_filename = info.editor_image();
|
||||
base_image = image::get_texture(base_filename);
|
||||
|
||||
if(!base_image) {
|
||||
|
@ -188,7 +188,7 @@ void terrain_palette::setup_item(
|
|||
}
|
||||
}
|
||||
|
||||
const std::string filename = map().get_terrain_info(terrain).editor_image();
|
||||
const std::string filename = info.editor_image();
|
||||
overlay_image = image::get_texture(filename);
|
||||
if(!overlay_image) {
|
||||
tooltip_text << "IMAGE NOT FOUND\n";
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "tod_manager.hpp" // for tod_manager
|
||||
#include "tstring.hpp" // for t_string, operator<<
|
||||
#include "units/types.hpp" // for unit_type, unit_type_data, etc
|
||||
#include "utils/general.hpp" // for contains
|
||||
#include "serialization/unicode.hpp" // for iterator
|
||||
#include "color.hpp"
|
||||
|
||||
|
@ -990,6 +991,13 @@ void generate_terrain_sections(section& sec, int /*level*/)
|
|||
terrain_topic.text = std::make_shared<terrain_topic_generator>(info);
|
||||
|
||||
t_translation::ter_list base_terrains = tdata->underlying_union_terrain(t);
|
||||
if (info.has_default_base()) {
|
||||
for (const auto base : tdata->underlying_union_terrain(info.default_base())) {
|
||||
if (!utils::contains(base_terrains, base)) {
|
||||
base_terrains.emplace_back(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const t_translation::terrain_code& base : base_terrains) {
|
||||
|
||||
const terrain_type& base_info = tdata->get_terrain_info(base);
|
||||
|
|
|
@ -89,9 +89,14 @@ static std::string print_behavior_description(ter_iter start, ter_iter end, cons
|
|||
if (!last_change_pos) {
|
||||
std::vector<std::string> names;
|
||||
for (ter_iter i = start; i != end; ++i) {
|
||||
const terrain_type tt = tdata->get_terrain_info(*i);
|
||||
if (!tt.editor_name().empty())
|
||||
names.push_back(tt.editor_name());
|
||||
if (*i == t_translation::BASE) {
|
||||
// TRANSLATORS: in a description of an overlay terrain, the terrain that it's placed on
|
||||
names.push_back(_("base terrain"));
|
||||
} else {
|
||||
const terrain_type tt = tdata->get_terrain_info(*i);
|
||||
if (!tt.editor_name().empty())
|
||||
names.push_back(tt.editor_name());
|
||||
}
|
||||
}
|
||||
|
||||
if (names.empty()) return "";
|
||||
|
@ -189,21 +194,31 @@ std::string terrain_topic_generator::operator()() const {
|
|||
// Almost all terrains will show the data in this conditional block. The ones that don't are the
|
||||
// archetypes used in [movetype]'s subtags such as [movement_costs].
|
||||
if (!type_.is_indivisible()) {
|
||||
ss << "\n" << _("Base Terrain: ");
|
||||
|
||||
bool first = true;
|
||||
std::vector<t_string> underlying;
|
||||
for (const auto& underlying_terrain : type_.union_type()) {
|
||||
const terrain_type& base = tdata->get_terrain_info(underlying_terrain);
|
||||
|
||||
if (base.editor_name().empty()) continue;
|
||||
|
||||
if (!first) {
|
||||
ss << ", ";
|
||||
} else {
|
||||
first = false;
|
||||
if (!base.editor_name().empty()) {
|
||||
underlying.push_back(make_link(base.editor_name(), ".." + terrain_prefix + base.id()));
|
||||
}
|
||||
}
|
||||
utils::string_map symbols;
|
||||
symbols["types"] = utils::format_conjunct_list("", underlying);
|
||||
// TRANSLATORS: $types is a conjunct list, typical values will be "Castle" or "Flat and Shallow Water".
|
||||
// The terrain names will be hypertext links to the help page of the corresponding terrain type.
|
||||
// There will always be at least 1 item in the list, but unlikely to be more than 3.
|
||||
ss << "\n" << VNGETTEXT("Basic terrain type: $types", "Basic terrain types: $types", underlying.size(), symbols);
|
||||
|
||||
ss << make_link(base.editor_name(), ".." + terrain_prefix + base.id());
|
||||
if (type_.has_default_base()) {
|
||||
const terrain_type& base = tdata->get_terrain_info(type_.default_base());
|
||||
|
||||
symbols.clear();
|
||||
if (base.is_indivisible()) {
|
||||
symbols["type"] = make_link(base.editor_name(), ".." + terrain_prefix + base.id());
|
||||
} else {
|
||||
symbols["type"] = make_link(base.editor_name(), terrain_prefix + base.id());
|
||||
}
|
||||
// TRANSLATORS: In the help for a terrain type, for example Dwarven Village is often placed on Cave Floor
|
||||
ss << "\n" << VGETTEXT("Typical base terrain: $type", symbols);
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
|
|
|
@ -293,7 +293,7 @@ terrain_type::terrain_type(const terrain_type& base, const terrain_type& overlay
|
|||
}
|
||||
|
||||
t_translation::terrain_code terrain_type::terrain_with_default_base() const {
|
||||
if(overlay_ && editor_default_base_ != t_translation::NONE_TERRAIN) {
|
||||
if(overlay_ && has_default_base()) {
|
||||
return t_translation::terrain_code(editor_default_base_.base, number_.overlay);
|
||||
}
|
||||
return number_;
|
||||
|
|
|
@ -166,11 +166,31 @@ public:
|
|||
*/
|
||||
bool is_combined() const { return combined_; }
|
||||
|
||||
/**
|
||||
* Overlay terrains defined by a [terrain_type] can declare a fallback base
|
||||
* terrain, for use when the overlay is selected in the editor, or when the
|
||||
* overlay is placed on the map using [terrain]replace_if_failed=true.
|
||||
*
|
||||
* If there's no default, returns a sentinel value; see has_default_base().
|
||||
*/
|
||||
t_translation::terrain_code default_base() const { return editor_default_base_; }
|
||||
bool has_default_base() const { return editor_default_base_ != t_translation::NONE_TERRAIN; }
|
||||
|
||||
/**
|
||||
* Return the overlay part of this terrain, on the default_base(). Might
|
||||
* return an unknown terrain, if there's a typo in the default base.
|
||||
*
|
||||
* If this terrain has no overlay, it returns the terrain itself, ignoring
|
||||
* the default_base() even if the terrain has a default_base().
|
||||
*
|
||||
* This is intended for the editor's single-layer placement, or for
|
||||
* replacing terrains via ActionWML, where the user or WML author intends
|
||||
* to only use one layer of the current terrain.
|
||||
*/
|
||||
t_translation::terrain_code terrain_with_default_base() const;
|
||||
|
||||
/**
|
||||
* Returns true if all most of the data matches. The ones that don't need to match:
|
||||
* Returns true if most of the data matches. The ones that don't need to match:
|
||||
* - editor_group_
|
||||
* - icon_image_
|
||||
* - description_
|
||||
|
|
|
@ -267,7 +267,7 @@ t_translation::terrain_code terrain_type_data::merge_terrains(const t_translatio
|
|||
if(new_t.base != t_translation::NO_LAYER) {
|
||||
result = new_t;
|
||||
}
|
||||
else if (get_terrain_info(new_t).default_base() != t_translation::NONE_TERRAIN) {
|
||||
else if (get_terrain_info(new_t).has_default_base()) {
|
||||
result = get_terrain_info(new_t).terrain_with_default_base();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue