The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
map.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Routines related to game-maps, terrain, locations, directions. etc.
18  */
19 
20 #include "map/map.hpp"
21 
22 #include "global.hpp"
23 
24 #include "config.hpp"
25 #include "formula/string_utils.hpp"
26 #include "log.hpp"
27 #include "map/exception.hpp"
28 #include "serialization/parser.hpp"
30 #include "terrain/terrain.hpp"
31 #include "terrain/type_data.hpp"
32 #include "wml_exception.hpp"
33 
34 #include <algorithm>
35 #include <sstream>
36 #include <utility>
37 
38 #include <boost/optional.hpp>
39 
40 static lg::log_domain log_config("config");
41 #define ERR_CF LOG_STREAM(err, log_config)
42 #define LOG_G LOG_STREAM(info, lg::general())
43 #define DBG_G LOG_STREAM(debug, lg::general())
44 
45 /** Gets the list of terrains. */
47 {
48  return tdata_->list();
49 }
50 
51 /** Shortcut to get_terrain_info(get_terrain(loc)). */
53 {
54  return tdata_->get_terrain_info(get_terrain(loc));
55 }
56 
58  { return underlying_mvt_terrain(get_terrain(loc)); }
60  { return underlying_def_terrain(get_terrain(loc)); }
62  { return underlying_union_terrain(get_terrain(loc)); }
64  { return get_terrain_string(get_terrain(loc)); }
66  { return get_terrain_editor_string(get_terrain(loc)); }
67 
68 bool gamemap::is_village(const map_location& loc) const
69  { return on_board(loc) && is_village(get_terrain(loc)); }
70 int gamemap::gives_healing(const map_location& loc) const
71  { return on_board(loc) ? gives_healing(get_terrain(loc)) : 0; }
72 bool gamemap::is_castle(const map_location& loc) const
73  { return on_board(loc) && is_castle(get_terrain(loc)); }
74 bool gamemap::is_keep(const map_location& loc) const
75  { return on_board(loc) && is_keep(get_terrain(loc)); }
76 
77 
78 /* Forwarded methods of tdata_ */
80  { return tdata_->underlying_mvt_terrain(terrain); }
82  { return tdata_->underlying_def_terrain(terrain); }
84  { return tdata_->underlying_union_terrain(terrain); }
86  { return tdata_->get_terrain_string(terrain); }
88  { return tdata_->get_terrain_editor_string(terrain); }
90  { return tdata_->get_underlying_terrain_string(terrain); }
92  { return tdata_->get_terrain_info(terrain).is_village(); }
94  { return tdata_->get_terrain_info(terrain).gives_healing(); }
96  { return tdata_->get_terrain_info(terrain).is_castle(); }
98  { return tdata_->get_terrain_info(terrain).is_keep(); }
99 
101  { return tdata_->get_terrain_info(terrain); }
102 
103 void gamemap::write_terrain(const map_location &loc, config& cfg) const
104 {
105  cfg["terrain"] = t_translation::write_terrain_code(get_terrain(loc));
106 }
107 
109  tiles_(1),
110  tdata_(tdata),
111  villages_(),
112  borderCache_(),
113  terrainFrequencyCache_(),
114  w_(-1),
115  h_(-1),
116  total_width_(0),
117  total_height_(0),
118  border_size_(default_border)
119 {
120  DBG_G << "loading map: '" << data << "'\n";
121 
122  read(data);
123 }
124 
125 gamemap::gamemap(const tdata_cache& tdata, const config& level):
126  tiles_(1),
127  tdata_(tdata),
128  villages_(),
129  borderCache_(),
130  terrainFrequencyCache_(),
131  w_(-1),
132  h_(-1),
133  total_width_(0),
134  total_height_(0),
135  border_size_(default_border)
136 {
137  DBG_G << "loading map: '" << level.debug() << "'\n";
138 
139  const std::string& map_data = level["map_data"];
140  if (!map_data.empty()) {
141  read(map_data);
142  } else {
143  w_ = 0;
144  h_ = 0;
145  total_width_ = 0;
146  total_height_ = 0;
147  }
148 }
149 
151 {
152 }
153 
154 void gamemap::read(const std::string& data, const bool allow_invalid, int border_size) {
155 
156  // Initial stuff
158  tiles_.clear();
159  villages_.clear();
160  starting_positions_.clear();
161 
162  if(data.empty()) {
163  w_ = 0;
164  h_ = 0;
165  total_width_ = 0;
166  total_height_ = 0;
167  if(allow_invalid) return;
168  }
169 
170  int offset = read_header(data);
171 
172  const std::string& data_only = std::string(data, offset);
173 
174  try {
176 
177  } catch(t_translation::error& e) {
178  // We re-throw the error but as map error.
179  // Since all codepaths test for this, it's the least work.
181  }
182 
183  // Post processing on the map
184  total_width_ = tiles_.size();
185  total_height_ = total_width_ > 0 ? tiles_[0].size() : 0;
186  w_ = total_width_ - 2 * border_size_;
187  h_ = total_height_ - 2 * border_size_;
188  //Disabled since there are callcases which pass along a valid map header but empty
189  //map data. Still, loading (and actually applying) an empty map causes problems later on.
190  //Other callcases which need to load a dummy map use completely empty data :(.
191  //VALIDATE((w_ >= 1 && h_ >= 1), "A map needs at least 1 tile, the map cannot be loaded.");
192 
193  for(int x = 0; x < total_width_; ++x) {
194  for(int y = 0; y < total_height_; ++y) {
195 
196  // Is the terrain valid?
197  if(tdata_->map().count(tiles_[x][y]) == 0) {
198  if(!tdata_->try_merge_terrains(tiles_[x][y])) {
199  std::stringstream ss;
200  ss << "Illegal tile in map: (" << t_translation::write_terrain_code(tiles_[x][y])
201  << ") '" << tiles_[x][y] << "'\n";
202  ERR_CF << ss.str();
203  ss << "The map cannot be loaded.";
204  throw incorrect_map_format_error(ss.str().c_str());
205  }
206  }
207 
208  // Is it a village?
209  if(x >= border_size_ && y >= border_size_
210  && x < total_width_-border_size_ && y < total_height_-border_size_
211  && tdata_->is_village(tiles_[x][y])) {
212  villages_.push_back(map_location(x-border_size_, y-border_size_));
213  }
214  }
215  }
216 }
217 
219 {
220  // Test whether there is a header section
221  size_t header_offset = data.find("\n\n");
222  if(header_offset == std::string::npos) {
223  // For some reason Windows will fail to load a file with \r\n
224  // lineending properly no problems on Linux with those files.
225  // This workaround fixes the problem the copy later will copy
226  // the second \r\n to the map, but that's no problem.
227  header_offset = data.find("\r\n\r\n");
228  }
229  const size_t comma_offset = data.find(",");
230  // The header shouldn't contain commas, so if the comma is found
231  // before the header, we hit a \n\n inside or after a map.
232  // This is no header, so don't parse it as it would be.
233 
234  if (!(!(header_offset == std::string::npos || comma_offset < header_offset)))
235  return 0;
236 
237  std::string header_str(std::string(data, 0, header_offset + 1));
238  config header;
239  ::read(header, header_str);
240 
241  border_size_ = header["border_size"];
242 
243  return header_offset + 2;
244 }
245 
246 
248 {
250 }
251 namespace
252 {
253  struct overlay_rule
254  {
258  boost::optional<t_translation::t_terrain> terrain_;
259  bool use_old_;
260  bool replace_if_failed_;
261 
262  overlay_rule()
263  : old_()
264  , new_()
265  , mode_(terrain_type_data::BOTH)
266  , terrain_()
267  , use_old_(false)
268  , replace_if_failed_(false)
269  {
270 
271  }
272  };
273 }
274 void gamemap::overlay(const gamemap& m, const config& rules_cfg, int xpos, int ypos, bool border)
275 {
276  //const config::const_child_itors &rules = rules_cfg.child_range("rule");
277  std::vector<overlay_rule> rules(rules_cfg.child_count("rule"));
278  for(size_t i = 0; i <rules.size(); ++i)
279  {
280  const config& cfg = rules_cfg.child("rule", i);
281  rules[i].old_ = t_translation::read_list(cfg["old"]);
282  rules[i].new_ = t_translation::read_list(cfg["new"]);
283  rules[i].mode_ = cfg["layer"] == "base" ? terrain_type_data::BASE : cfg["layer"] == "overlay" ? terrain_type_data::OVERLAY : terrain_type_data::BOTH;
284  const t_translation::t_list& terrain = t_translation::read_list(cfg["terrain"]);
285  if(!terrain.empty()) {
286  rules[i].terrain_ = terrain[0];
287  }
288  rules[i].use_old_ = cfg["use_old"].to_bool();
289  rules[i].replace_if_failed_ = cfg["replace_if_failed"].to_bool();
290  }
291 
292  int actual_border = (m.border_size() == border_size()) && border ? border_size() : 0;
293 
294  const int xstart = std::max<int>(-actual_border, -xpos - actual_border);
295  const int ystart = std::max<int>(-actual_border, -ypos - actual_border - ((xpos & 1) ? 1 : 0));
296  const int xend = std::min<int>(m.w() + actual_border, w() + actual_border - xpos);
297  const int yend = std::min<int>(m.h() + actual_border, h() + actual_border - ypos);
298 
299  for(int x1 = xstart; x1 < xend; ++x1) {
300  for(int y1 = ystart; y1 < yend; ++y1) {
301  const int x2 = x1 + xpos;
302  const int y2 = y1 + ypos + ((xpos & 1) && (x1 & 1) ? 1 : 0);
303 
304  const t_translation::t_terrain t = m.tiles_[x1 + m.border_size_][y1 + m.border_size_];
305  const t_translation::t_terrain current = tiles_[x2 + border_size_][y2 + border_size_];
306 
308  continue;
309  }
310 
311  // See if there is a matching rule
312  const overlay_rule* rule = nullptr;
313  for(const overlay_rule& current_rule : rules)
314  {
315  if(!current_rule.old_.empty() && !t_translation::terrain_matches(current, current_rule.old_)) {
316  continue;
317  }
318  if(!current_rule.new_.empty() && !t_translation::terrain_matches(t, current_rule.new_)) {
319  continue;
320  }
321  rule = &current_rule;
322  break;
323  }
324 
325  if (rule && !rule->use_old_) {
326  set_terrain(map_location(x2, y2), rule->terrain_ ? *rule->terrain_ : t , rule->mode_, rule->replace_if_failed_);
327  }
328  else {
329  set_terrain(map_location(x2,y2), t);
330  if (false /*TODO: add overwrite special locs paramter*/) {
331  starting_positions_.right.erase(t_translation::coordinate(x2, y2));
332  for (auto& pair : m.starting_positions_.right.equal_range(t_translation::coordinate(x1, y1))) {
333  starting_positions_.insert(tstarting_positions::value_type(pair.second, t_translation::coordinate(x2, y2)));
334  }
335  }
336  }
337  }
338  }
339 }
340 
342 {
343 
344  if(on_board_with_border(loc)) {
345  return tiles_[loc.x + border_size_][loc.y + border_size_];
346  }
347 
348  if ( loc == map_location::null_location() ) {
350  }
351 
352  const std::map<map_location, t_translation::t_terrain>::const_iterator itor = borderCache_.find(loc);
353  if(itor != borderCache_.end())
354  return itor->second;
355 
356  // If not on the board, decide based on what surrounding terrain is
358  int number_of_items = 0;
359 
360  map_location adj[6];
361  get_adjacent_tiles(loc,adj);
362  for(int n = 0; n != 6; ++n) {
363  if(on_board(adj[n])) {
364  items[number_of_items] = tiles_[adj[n].x][adj[n].y];
365  ++number_of_items;
366  } else {
367  // If the terrain is off map but already in the border cache,
368  // this will be used to determine the terrain.
369  // This avoids glitches
370  // * on map with an even width in the top right corner
371  // * on map with an odd height in the bottom left corner.
372  // It might also change the result on other map and become random,
373  // but the border tiles will be determined in the future, so then
374  // this will no longer be used in the game
375  // (The editor will use this feature to expand maps in a better way).
376  std::map<map_location, t_translation::t_terrain>::const_iterator itor =
377  borderCache_.find(adj[n]);
378 
379  // Only add if it is in the cache and a valid terrain
380  if(itor != borderCache_.end() &&
381  itor->second != t_translation::NONE_TERRAIN) {
382 
383  items[number_of_items] = itor->second;
384  ++number_of_items;
385  }
386  }
387 
388  }
389 
390  // Count all the terrain types found,
391  // and see which one is the most common, and use it.
392  t_translation::t_terrain used_terrain;
393  int terrain_count = 0;
394  for(int i = 0; i != number_of_items; ++i) {
395  if(items[i] != used_terrain && !tdata_->is_village(items[i]) && !tdata_->is_keep(items[i])) {
396  const int c = std::count(items+i+1,items+number_of_items,items[i]) + 1;
397  if(c > terrain_count) {
398  used_terrain = items[i];
399  terrain_count = c;
400  }
401  }
402  }
403 
404  borderCache_.insert(std::pair<map_location, t_translation::t_terrain>(loc,used_terrain));
405  return used_terrain;
406 
407 }
408 
410 {
411  auto it = starting_positions_.left.find(id);
412  if (it != starting_positions_.left.end()) {
413  auto& coordinate = it->second;
414  return map_location(coordinate.x, coordinate.y);
415  }
416  else {
417  return map_location();
418  }
419 }
420 
422 {
423  return special_location(std::to_string(n));
424 }
425 
427 {
428  int res = 0;
429  for (auto pair : starting_positions_) {
430  const std::string& id = pair.left;
431  bool is_number = std::find_if(id.begin(), id.end(), [](char c) { return !std::isdigit(c); }) == id.end();
432  if (is_number) {
433  res = std::max(res, std::stoi(id));
434  }
435  }
436  return res;
437 }
438 
440 {
441  auto it = starting_positions_.right.find(t_translation::coordinate(loc.x, loc.y));
442  return it == starting_positions_.right.end() ? nullptr : &it->second;
443 }
444 
446 {
447  bool valid = loc.valid();
448  auto it_left = starting_positions_.left.find(id);
449  if (it_left != starting_positions_.left.end()) {
450  if (valid) {
451  starting_positions_.left.replace_data(it_left, t_translation::coordinate(loc.x, loc.y));
452  }
453  else {
454  starting_positions_.left.erase(it_left);
455  }
456  }
457  else {
458  starting_positions_.left.insert(it_left, std::make_pair(id, t_translation::coordinate(loc.x, loc.y)));
459  }
460 }
461 
463 {
464  set_special_location(std::to_string(side), loc);
465 }
466 
467 bool gamemap::on_board(const map_location& loc) const
468 {
469  return loc.valid() && loc.x < w_ && loc.y < h_;
470 }
471 
473 {
474  return !(tiles_.empty() || tiles_[0].empty()) && // tiles_ is not empty when initialized.
475  loc.x >= -border_size_ && loc.x < w_ + border_size_ &&
476  loc.y >= -border_size_ && loc.y < h_ + border_size_;
477 }
478 
480  if(!on_board_with_border(loc)) {
481  // off the map: ignore request
482  return;
483  }
484 
485  t_translation::t_terrain new_terrain = tdata_->merge_terrains(get_terrain(loc), terrain, mode, replace_if_failed);
486 
487  if(new_terrain == t_translation::NONE_TERRAIN) {
488  return;
489  }
490 
491  if(on_board(loc)) {
492  const bool old_village = is_village(loc);
493  const bool new_village = tdata_->is_village(new_terrain);
494 
495  if(old_village && !new_village) {
496  villages_.erase(std::remove(villages_.begin(),villages_.end(),loc),villages_.end());
497  } else if(!old_village && new_village) {
498  villages_.push_back(loc);
499  }
500  }
501 
502  tiles_[loc.x + border_size_][loc.y + border_size_] = new_terrain;
503 
504  // Update the off-map autogenerated tiles
505  map_location adj[6];
506  get_adjacent_tiles(loc,adj);
507 
508  for(int n = 0; n < 6; ++n) {
510  }
511 }
512 
513 const std::map<t_translation::t_terrain, size_t>& gamemap::get_weighted_terrain_frequencies() const
514 {
515  if(terrainFrequencyCache_.empty() == false) {
516  return terrainFrequencyCache_;
517  }
518 
519  const map_location center(w()/2,h()/2);
520 
521  const size_t furthest_distance = distance_between(map_location::ZERO(),center);
522 
523  const size_t weight_at_edge = 100;
524  const size_t additional_weight_at_center = 200;
525 
526  for(size_t i = 0; i != size_t(w()); ++i) {
527  for(size_t j = 0; j != size_t(h()); ++j) {
528  const size_t distance = distance_between(map_location(i,j),center);
529  terrainFrequencyCache_[tiles_[i + border_size_][j]] += weight_at_edge +
530  (furthest_distance-distance)*additional_weight_at_center;
531  }
532  }
533 
534  return terrainFrequencyCache_;
535 }
536 
537 std::vector<map_location> gamemap::parse_location_range(const std::string &x, const std::string &y,
538  bool with_border) const
539 {
540  std::vector<map_location> res;
541  const std::vector<std::string> xvals = utils::split(x);
542  const std::vector<std::string> yvals = utils::split(y);
543  int xmin = 1, xmax = w(), ymin = 1, ymax = h();
544  if (with_border) {
545  int bs = border_size();
546  xmin -= bs;
547  xmax += bs;
548  ymin -= bs;
549  ymax += bs;
550  }
551 
552  for (unsigned i = 0; i < xvals.size() || i < yvals.size(); ++i)
553  {
554  std::pair<int,int> xrange, yrange;
555 
556  if (i < xvals.size()) {
557  xrange = utils::parse_range(xvals[i]);
558  if (xrange.first < xmin) xrange.first = xmin;
559  if (xrange.second > xmax) xrange.second = xmax;
560  } else {
561  xrange.first = xmin;
562  xrange.second = xmax;
563  }
564 
565  if (i < yvals.size()) {
566  yrange = utils::parse_range(yvals[i]);
567  if (yrange.first < ymin) yrange.first = ymin;
568  if (yrange.second > ymax) yrange.second = ymax;
569  } else {
570  yrange.first = ymin;
571  yrange.second = ymax;
572  }
573 
574  for(int x = xrange.first; x <= xrange.second; ++x) {
575  for(int y = yrange.first; y <= yrange.second; ++y) {
576  res.push_back(map_location(x-1,y-1));
577  }
578  }
579  }
580  return res;
581 }
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:472
Contains an x and y coordinate used for starting positions in maps.
Definition: translation.hpp:97
int w_
Definition: font.cpp:607
std::vector< map_location > villages_
Definition: map.hpp:238
t_list read_list(const std::string &str, const t_layer filler)
Reads a list of terrains from a string, when reading the.
GLint level
Definition: glew.h:1220
std::string get_underlying_terrain_string(const t_translation::t_terrain &terrain) const
Definition: map.cpp:89
std::string get_terrain_editor_string(const map_location &loc) const
Definition: map.cpp:65
std::string write_game_map(const t_map &map, const tstarting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
const GLfloat * c
Definition: glew.h:12741
const t_translation::t_list & get_terrain_list() const
Gets the list of terrains.
Definition: map.cpp:46
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
const t_terrain NONE_TERRAIN
Definition: translation.hpp:56
int border_size_
The size of the border around the map.
Definition: map.hpp:254
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
Definition: location.hpp:274
bool is_village(const map_location &loc) const
Definition: map.cpp:68
tdata_cache tdata_
Allows lookup of terrain at a particular location.
Definition: map.hpp:237
static lg::log_domain log_config("config")
#define DBG_G
Definition: map.cpp:43
static const map_location & ZERO()
Old implementation:
Definition: location.hpp:190
t_map read_game_map(const std::string &str, tstarting_positions &starting_positions, coordinate border_offset)
Reads a gamemap string into a 2D vector.
std::map< map_location, t_translation::t_terrain > borderCache_
Definition: map.hpp:240
const t_terrain FOGGED
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
const std::vector< std::string > items
std::string debug() const
Definition: config.cpp:1438
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
std::map< t_translation::t_terrain, size_t > terrainFrequencyCache_
Definition: map.hpp:241
GLenum mode
Definition: glew.h:2390
const t_translation::t_list & underlying_union_terrain(const map_location &loc) const
Definition: map.cpp:61
GLdouble GLdouble t
Definition: glew.h:1366
Definitions for the interface to Wesnoth Markup Language (WML).
std::string get_terrain_string(const map_location &loc) const
Definition: map.cpp:63
GLintptr offset
Definition: glew.h:1650
int h_
Definition: font.cpp:607
GLuint GLuint end
Definition: glew.h:1221
gamemap(const tdata_cache &tdata, const std::string &data)
Loads a map, with the given terrain configuration.
Definition: map.cpp:108
map_location starting_position(int side) const
Definition: map.cpp:421
bool valid() const
Definition: location.hpp:69
size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
Definition: location.hpp:357
int w() const
Effective map width.
Definition: map.hpp:105
Encapsulates the map of the game.
Definition: map.hpp:37
void set_special_location(const std::string &id, const map_location &loc)
Definition: map.cpp:445
int border_size() const
Size of the map border.
Definition: map.hpp:111
int w_
Sizes of the map area.
Definition: map.hpp:245
static const map_location & null_location()
Definition: location.hpp:195
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:135
void read(const std::string &data, const bool allow_invalid=true, const int border_size=1)
Definition: map.cpp:154
GLuint GLuint GLsizei count
Definition: glew.h:1221
const std::map< t_translation::t_terrain, size_t > & get_weighted_terrain_frequencies() const
Returns a list of the frequencies of different terrain types on the map, with terrain nearer the cent...
Definition: map.cpp:513
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:47
Encapsulates the map of the game.
Definition: location.hpp:38
const terrain_type & get_terrain_info(const t_translation::t_terrain &terrain) const
Definition: map.cpp:100
std::pair< int, int > parse_range(std::string const &str)
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...
Definition: map.cpp:537
std::string write() const
Definition: map.cpp:247
GLuint res
Definition: glew.h:9258
map_location special_location(const std::string &id) const
Definition: map.cpp:409
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
int h() const
Effective map height.
Definition: map.hpp:108
size_t i
Definition: function.cpp:1057
bool terrain_matches(const t_terrain &src, const t_terrain &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
GLint GLint GLint GLint GLint x
Definition: glew.h:1220
bool is_castle(const map_location &loc) const
Definition: map.cpp:72
void set_terrain(const map_location &loc, const t_translation::t_terrain &terrain, const terrain_type_data::tmerge_mode mode=terrain_type_data::BOTH, bool replace_if_failed=false)
Clobbers over the terrain at location 'loc', with the given terrain.
Definition: map.cpp:479
void write_terrain(const map_location &loc, config &cfg) const
Writes the terrain at loc to cfg.
Definition: map.cpp:103
std::string write_terrain_code(const t_terrain &tcode)
Writes a single terrain code to a string.
unsigned child_count(const std::string &key) const
Definition: config.cpp:635
t_translation::t_terrain get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:341
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: glew.h:1222
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:467
const t_terrain VOID_TERRAIN
tstarting_positions starting_positions_
The size of the starting positions array is MAX_PLAYERS + 1, because the positions themselves are num...
Definition: map.hpp:216
GLclampd n
Definition: glew.h:5903
const GLdouble * m
Definition: glew.h:6968
int read_header(const std::string &data)
Reads the header of a map which is saved in the deprecated map_data format.
Definition: map.cpp:218
void remove_from_border_cache(const map_location &loc)
Remove the cached border terrain at loc.
Definition: map.hpp:189
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
int num_valid_starting_positions() const
Definition: map.cpp:426
int total_width_
Sizes of the map including the borders.
Definition: map.hpp:249
Standard logging facilities (interface).
void set_starting_position(int side, const map_location &loc)
Manipulate starting positions of the different sides.
Definition: map.cpp:462
std::string message
Definition: exceptions.hpp:29
const std::string * 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.
Definition: map.cpp:439
#define c
Definition: glew.h:12743
const t_translation::t_list & underlying_def_terrain(const map_location &loc) const
Definition: map.cpp:59
void overlay(const gamemap &m, const config &rules, int x=0, int y=0, bool border=false)
Overlays another map onto this one at the given position.
Definition: map.cpp:274
const std::string remove
remove directive
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.
#define e
t_translation::t_map tiles_
Definition: map.hpp:210
#define ERR_CF
Definition: map.cpp:41
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
const t_translation::t_list & underlying_mvt_terrain(const map_location &loc) const
Definition: map.cpp:57
int h_
Definition: map.hpp:246
virtual ~gamemap()
Definition: map.cpp:150
GLsizei const GLcharARB ** string
Definition: glew.h:4503
int total_height_
Definition: map.hpp:250
bool is_keep(const map_location &loc) const
Definition: map.cpp:74
std::vector< t_terrain > t_list
Definition: translation.hpp:75
int gives_healing(const map_location &loc) const
Definition: map.cpp:70
const std::string valid
Little parts of regex templates used to parse Wml annoations.