37 #define ERR_CF LOG_STREAM(err, log_config)
38 #define LOG_G LOG_STREAM(info, lg::general())
39 #define DBG_G LOG_STREAM(debug, lg::general())
76 {
return tdata_->underlying_mvt_terrain(terrain); }
78 {
return tdata_->underlying_def_terrain(terrain); }
80 {
return tdata_->underlying_union_terrain(terrain); }
82 {
return tdata_->get_terrain_string(terrain); }
84 {
return tdata_->get_terrain_editor_string(terrain); }
86 {
return tdata_->get_underlying_terrain_string(terrain); }
88 {
return tdata_->get_terrain_info(terrain).is_village(); }
90 {
return tdata_->get_terrain_info(terrain).gives_healing(); }
92 {
return tdata_->get_terrain_info(terrain).is_castle(); }
94 {
return tdata_->get_terrain_info(terrain).is_keep(); }
97 {
return tdata_->get_terrain_info(terrain); }
109 DBG_G <<
"loading map: '" <<
data <<
"'";
115 , starting_positions_()
131 if(allow_invalid)
return;
152 if(
tdata_->map().count(
t) == 0) {
154 std::stringstream ss;
156 <<
") '" <<
t <<
"'";
174 std::size_t header_offset =
data.find(
"\n\n");
175 if(header_offset == std::string::npos) {
180 header_offset =
data.find(
"\r\n\r\n");
182 const std::size_t comma_offset =
data.find(
",");
186 if(header_offset == std::string::npos || comma_offset < header_offset) {
190 return data.substr(header_offset + 2);
203 const int xstart = std::max<int>(0, -xpos);
205 const int xoffset = xpos;
207 const int ystart_even = std::max<int>(0, -ypos);
209 const int yoffset_even = ypos;
211 const int ystart_odd = std::max<int>(0, -ypos +(xpos & 1) -(m_is_odd ? 1 : 0));
213 const int yoffset_odd = ypos -(xpos & 1) + (m_is_odd ? 1 : 0);
215 for(
int x1 = xstart; x1 != xend; ++x1) {
216 int ystart, yend, yoffset;
220 yoffset = yoffset_odd;
223 ystart = ystart_even;
225 yoffset = yoffset_even;
227 for(
int y1 = ystart; y1 != yend; ++y1) {
228 const int x2 = x1 + xoffset;
229 const int y2 = y1 + yoffset;
248 rule = ¤t_rule;
261 if (!ignore_special_locations) {
264 int x = pair.second.wml_x();
265 int y = pair.second.wml_y();
267 if(x < xstart || x >= xend || y < ystart_odd || y >= yend_odd) {
272 if(x < xstart || x >= xend || y < ystart_even || y >= yend_even) {
276 int x_new = x + xoffset;
277 int y_new = y + ((x & 1 ) ? yoffset_odd : yoffset_even);
313 bool is_number(
const std::string&
id) {
314 return std::find_if(
id.begin(),
id.end(), [](
char c) {
return !std::isdigit(
c); }) ==
id.
end();
322 const std::string&
id = pair.left;
333 if(is_number(*locName)) {
383 bool replace_if_failed)
390 DBG_G <<
"set_terrain: " <<
loc <<
" is not on the map.";
402 const bool new_village =
tdata_->is_village(new_terrain);
404 if(old_village && !new_village) {
407 }
else if(!old_village && new_village) {
413 (*this)[
loc] = new_terrain;
418 bool with_border)
const
420 std::vector<map_location> res;
423 int xmin = 1, xmax =
w(), ymin = 1, ymax =
h();
432 for (
unsigned i = 0;
i < xvals.size() ||
i < yvals.size(); ++
i)
434 std::pair<int,int> xrange, yrange;
436 if (
i < xvals.size()) {
438 if (xrange.first < xmin) xrange.first = xmin;
439 if (xrange.second > xmax) xrange.second = xmax;
442 xrange.second = xmax;
445 if (
i < yvals.size()) {
447 if (yrange.first < ymin) yrange.first = ymin;
448 if (yrange.second > ymax) yrange.second = ymax;
451 yrange.second = ymax;
454 for(
int x2 = xrange.first; x2 <= xrange.second; ++x2) {
455 for(
int y2 = yrange.first; y2 <= yrange.second; ++y2) {
456 res.emplace_back(x2-1,y2-1);
470 std::vector<map_location> res;
471 for(
int i = 1;
i <=
n;
i++) {
A config object defines a single node in a WML file, with access to child nodes.
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
int w() const
Effective map width.
void set_starting_position(int side, const map_location &loc)
Manipulate starting positions of the different sides.
void set_special_location(const std::string &id, const map_location &loc)
int h() const
Effective map height.
void overlay(const gamemap_base &m, map_location loc, const std::vector< overlay_rule > &rules=std::vector< overlay_rule >(), bool is_odd=false, bool ignore_special_locations=false)
Overlays another map onto this one at the given position.
map_location special_location(const std::string &id) const
std::vector< map_location > parse_location_range(const std::string &xvals, const std::string &yvals, bool with_border=false) const
Parses ranges of locations into a vector of locations, using this map's dimensions as bounds.
map_location starting_position(int side) const
int total_width() const
Real width of the map, including borders.
std::string to_string() const
int num_valid_starting_positions() const
Counts the number of sides that have valid starting positions on this map.
bool on_board_with_border(const map_location &loc) const
int total_height() const
Real height of the map, including borders.
int is_starting_position(const map_location &loc) const
returns the side number of the side starting at position loc, 0 if no such side exists.
virtual set_terrain_result set_terrain(const map_location &loc, const terrain_code &terrain, const terrain_type_data::merge_mode mode=terrain_type_data::BOTH, bool replace_if_failed=false)=0
Clobbers over the terrain at location 'loc', with the given terrain.
location_map starting_positions_
village_state
What happens to a village hex when its terrain is changed.
const std::string * is_special_location(const map_location &loc) const
returns the name of the special location at position loc, null if no such location exists.
int border_size() const
Size of the map border.
const std::vector< map_location > starting_positions() const
bool on_board(const map_location &loc) const
Tell if a location is on the map.
location_map & special_locations()
const t_translation::ter_list & underlying_union_terrain(const map_location &loc) const
bool is_village(const map_location &loc) const
std::string get_underlying_terrain_string(const t_translation::terrain_code &terrain) const
bool is_castle(const map_location &loc) const
void read(const std::string &data, const bool allow_invalid=true)
const t_translation::ter_list & underlying_mvt_terrain(const map_location &loc) const
const t_translation::ter_list & underlying_def_terrain(const map_location &loc) const
const t_translation::ter_list & get_terrain_list() const
Gets the list of terrains.
std::string write() const
std::vector< map_location > villages_
std::string get_terrain_editor_string(const map_location &loc) const
void write_terrain(const map_location &loc, config &cfg) const
Writes the terrain at loc to cfg.
std::string_view strip_legacy_header(std::string_view data) const
Returns a subview of data which excludes any legacy headers.
gamemap(const std::string &data)
Loads a map.
bool is_keep(const map_location &loc) const
std::string get_terrain_string(const map_location &loc) const
std::shared_ptr< terrain_type_data > tdata_
gamemap_base::set_terrain_result set_terrain(const map_location &loc, const terrain_code &terrain, const terrain_type_data::merge_mode mode=terrain_type_data::BOTH, bool replace_if_failed=false) override
Clobbers over the terrain at location 'loc', with the given terrain.
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
int gives_healing(const map_location &loc) const
Contains the database of all known terrain types, both those defined explicitly by WML [terrain_type]...
Definitions for the interface to Wesnoth Markup Language (WML).
T end(const std::pair< T, T > &p)
Standard logging facilities (interface).
static lg::log_domain log_config("config")
ter_map read_game_map(std::string_view str, starting_positions &starting_positions, coordinate border_offset)
Reads a gamemap string into a 2D vector.
std::string write_game_map(const ter_map &map, const starting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
const terrain_code VOID_TERRAIN
VOID_TERRAIN is used for shrouded hexes.
bool terrain_matches(const terrain_code &src, const terrain_code &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
std::vector< terrain_code > ter_list
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
std::string write_terrain_code(const terrain_code &tcode)
Writes a single terrain code to a string.
const terrain_code FOGGED
const terrain_code NONE_TERRAIN
std::size_t erase(Container &container, const Value &value)
Convenience wrapper for using std::remove on a container.
int stoi(std::string_view str)
Same interface as std::stoi and meant as a drop in replacement, except:
std::pair< int, int > parse_range(std::string_view str)
Recognises the following patterns, and returns a {min, max} pair.
std::vector< std::string > split(const config_attribute_value &val)
terrain_type_data::merge_mode mode_
utils::optional< t_translation::terrain_code > terrain_
Encapsulates the map of the game.
static const map_location & null_location()
terrain_code & get(int x, int y)
std::vector< terrain_code > data
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
static map_location::direction n
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE(cond, message)
The macro to use for the validation of WML.