The Battle for Wesnoth  1.15.0-dev
map.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3  Part of the Battle for Wesnoth Project https://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 /** @file */
16 
17 #pragma once
18 
19 class config;
20 
21 #include "map/location.hpp"
22 #include "terrain/translation.hpp"
23 #include "terrain/type_data.hpp"
24 
25 #include <boost/optional.hpp>
26 
27 //class terrain_type_data; Can't forward declare because of enum
28 
29 /**
30  * Encapsulates the map of the game.
31  *
32  * Although the game is hexagonal, the map is stored as a grid.
33  * Each type of terrain is represented by a multiletter terrain code.
34  * @todo Update for new map-format.
35  */
36 class gamemap
37 {
38 public:
39 
40  /* Get info from the terrain_type_data object about the terrain at a location */
44  std::string get_terrain_string(const map_location& loc) const;
45  std::string get_terrain_editor_string(const map_location& loc) const;
46 
47  bool is_village(const map_location& loc) const;
48  int gives_healing(const map_location& loc) const;
49  bool is_castle(const map_location& loc) const;
50  bool is_keep(const map_location& loc) const;
51 
52  /* The above wrappers, but which takes a terrain. This is the old syntax, preserved for brevity in certain cases. */
56  std::string get_terrain_string(const t_translation::terrain_code& terrain) const;
57  std::string get_terrain_editor_string(const t_translation::terrain_code& terrain) const;
58  std::string get_underlying_terrain_string(const t_translation::terrain_code& terrain) const;
59 
60  bool is_village(const t_translation::terrain_code & terrain) const;
61  int gives_healing(const t_translation::terrain_code & terrain) const;
62  bool is_castle(const t_translation::terrain_code & terrain) const;
63  bool is_keep(const t_translation::terrain_code & terrain) const;
64 
65  // Also expose this for the same reason:
66  const terrain_type& get_terrain_info(const t_translation::terrain_code & terrain) const;
67 
68  /* Get the underlying terrain_type_data object. */
69  const ter_data_cache & tdata() const { return tdata_; }
70 
71  /**
72  * Loads a map, with the given terrain configuration.
73  *
74  * Data should be a series of lines, with each character representing one
75  * hex on the map. Starting locations are represented by numbers.
76  *
77  * @param tdata the terrain data
78  * @param data the map data to load.
79  */
80  gamemap(const ter_data_cache &tdata, const std::string &data); //throw(incorrect_map_format_error)
81 
82  virtual ~gamemap();
83 
84  void read(const std::string& data, const bool allow_invalid = true);
85 
86  std::string write() const;
87 
88  struct overlay_rule
89  {
93  boost::optional<t_translation::terrain_code> terrain_;
94  bool use_old_;
96 
98  : old_()
99  , new_()
100  , mode_(terrain_type_data::BOTH)
101  , terrain_()
102  , use_old_(false)
103  , replace_if_failed_(false)
104  {
105 
106  }
107  };
108 
109  /** Overlays another map onto this one at the given position. */
110  void overlay(const gamemap& m, map_location loc, const std::vector<overlay_rule>& rules = std::vector<overlay_rule>(), bool is_odd = false, bool ignore_special_locations = false);
111 
112  /** Effective map width. */
113  int w() const { return w_; }
114 
115  /** Effective map height. */
116  int h() const { return h_; }
117 
118  /** Size of the map border. */
119  int border_size() const { return default_border; }
120 
121  /** Real width of the map, including borders. */
122  int total_width() const { return tiles_.w; }
123 
124  /** Real height of the map, including borders */
125  int total_height() const { return tiles_.h; }
126 
128  {
129  return tiles_.get(loc.x + border_size(), loc.y + border_size());
130  }
131 private:
132  //private method, use set_terrain instead which also updates villages_.
134  {
135  return tiles_.get(loc.x + border_size(), loc.y + border_size());
136  }
137 public:
138 
139  /**
140  * Looks up terrain at a particular location.
141  *
142  * Hexes off the map may be looked up, and their 'emulated' terrain will
143  * also be returned. This allows proper drawing of the edges of the map.
144  */
146 
147  /** Writes the terrain at loc to cfg. */
148  void write_terrain(const map_location &loc, config& cfg) const;
149 
150 
151  /** Manipulate starting positions of the different sides. */
152  void set_starting_position(int side, const map_location& loc);
153  map_location starting_position(int side) const;
154 
155  void set_special_location(const std::string& id, const map_location& loc);
156  map_location special_location(const std::string& id) const;
157 
158 
159  /// returns the side number of the side starting at position loc, 0 if no such side exists.
160  const std::string* is_starting_position(const map_location& loc) const;
161  int num_valid_starting_positions() const;
162 
163 
164  /**
165  * Tell if a location is on the map.
166  *
167  * Should be called before indexing using [].
168  * @todo inline for performance? -- Ilor
169  */
170  bool on_board(const map_location& loc) const;
171  bool on_board_with_border(const map_location& loc) const;
172 
173  /** Tell if the map is of 0 size. */
174  bool empty() const
175  {
176  return w_ == 0 || h_ == 0;
177  }
178 
179  /** Return a list of the locations of villages on the map. */
180  const std::vector<map_location>& villages() const { return villages_; }
181 
182  /** Shortcut to get_terrain_info(get_terrain(loc)). */
183  const terrain_type& get_terrain_info(const map_location &loc) const;
184 
185  /** Gets the list of terrains. */
187 
188  /**
189  * Clobbers over the terrain at location 'loc', with the given terrain.
190  * Uses mode and replace_if_failed like merge_terrains().
191  */
192  void set_terrain(const map_location& loc, const t_translation::terrain_code & terrain, const terrain_type_data::merge_mode mode=terrain_type_data::BOTH, bool replace_if_failed = false);
193 
194  /**
195  * Maximum number of players supported.
196  *
197  * Warning: when you increase this, you need to add
198  * more definitions to the team_colors.cfg file.
199  */
200  enum { MAX_PLAYERS = 9 };
201 
202  /** The default border style for a map. */
203  static const int default_border = 1;
204 
205  /** Parses ranges of locations into a vector of locations, using this map's dimensions as bounds. */
206  std::vector<map_location> parse_location_range(const std::string& xvals,
207  const std::string &yvals, bool with_border = false) const;
208 
211 
212  template<typename F>
213  void for_each_loc(const F& f) const
214  {
215  for (int x = -border_size(); x < w() + border_size(); ++x) {
216  for (int y = -border_size(); y < h() + border_size(); ++y) {
217  f({ x, y });
218  }
219  }
220  }
221  //Doesn't include border.
222  template<typename F>
223  void for_each_walkable_loc(const F& f) const
224  {
225  for (int x = 0; x < w(); ++x) {
226  for (int y = 0; y < h(); ++y) {
227  f({ x, y });
228  }
229  }
230  }
231 
232 protected:
234 
236 
237 private:
238 
239  /**
240  * Reads the header of a map which is saved in the deprecated map_data format.
241  *
242  * @param data The mapdata to load.
243  */
244  int read_header(const std::string& data);
245 
247 
248 protected:
249  std::vector<map_location> villages_;
250 
251  /** Sizes of the map area. */
252  int w_;
253  int h_;
254 };
bool is_keep(const map_location &loc) const
Definition: map.cpp:70
void for_each_loc(const F &f) const
Definition: map.hpp:213
const t_translation::ter_list & underlying_union_terrain(const map_location &loc) const
Definition: map.cpp:57
bool is_odd(T num)
Definition: math.hpp:34
int h() const
Effective map height.
Definition: map.hpp:116
const t_translation::ter_list & underlying_def_terrain(const map_location &loc) const
Definition: map.cpp:55
std::vector< map_location > villages_
Definition: map.hpp:249
void write_terrain(const map_location &loc, config &cfg) const
Writes the terrain at loc to cfg.
Definition: map.cpp:99
bool is_castle(const map_location &loc) const
Definition: map.cpp:68
boost::bimaps::bimap< boost::bimaps::set_of< std::string >, boost::bimaps::multiset_of< coordinate > > starting_positions
t_translation::ter_list new_
Definition: map.hpp:91
std::string get_underlying_terrain_string(const t_translation::terrain_code &terrain) const
Definition: map.cpp:85
const t_translation::terrain_code operator[](const map_location &loc) const
Definition: map.hpp:127
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:332
const t_translation::ter_list & get_terrain_list() const
Gets the list of terrains.
Definition: map.cpp:42
int border_size() const
Size of the map border.
Definition: map.hpp:119
static const int default_border
The default border style for a map.
Definition: map.hpp:203
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Definition: translation.hpp:50
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:96
boost::optional< t_translation::terrain_code > terrain_
Definition: map.hpp:93
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:360
t_translation::starting_positions starting_positions
Definition: map.hpp:209
std::string get_terrain_string(const map_location &loc) const
Definition: map.cpp:59
t_translation::terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:292
void set_terrain(const map_location &loc, const t_translation::terrain_code &terrain, const terrain_type_data::merge_mode mode=terrain_type_data::BOTH, bool replace_if_failed=false)
Clobbers over the terrain at location &#39;loc&#39;, with the given terrain.
Definition: map.cpp:372
int total_width() const
Real width of the map, including borders.
Definition: map.hpp:122
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&#39;s dimensions as bounds...
Definition: map.cpp:399
std::string write() const
Definition: map.cpp:204
int gives_healing(const map_location &loc) const
Definition: map.cpp:66
const starting_positions & special_locations() const
Definition: map.hpp:210
bool empty() const
Tell if the map is of 0 size.
Definition: map.hpp:174
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:365
Encapsulates the map of the game.
Definition: map.hpp:36
void set_special_location(const std::string &id, const map_location &loc)
Definition: map.cpp:338
void overlay(const gamemap &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.
Definition: map.cpp:209
int num_valid_starting_positions() const
Definition: map.cpp:319
void for_each_walkable_loc(const F &f) const
Definition: map.hpp:223
int w_
Sizes of the map area.
Definition: map.hpp:252
void read(const std::string &data, const bool allow_invalid=true)
Definition: map.cpp:120
t_translation::terrain_code & operator[](const map_location &loc)
Definition: map.hpp:133
const t_translation::ter_list & underlying_mvt_terrain(const map_location &loc) const
Definition: map.cpp:53
ter_data_cache tdata_
Definition: map.hpp:246
t_translation::ter_list old_
Definition: map.hpp:90
Encapsulates the map of the game.
Definition: location.hpp:42
int w() const
Effective map width.
Definition: map.hpp:113
t_translation::ter_map tiles_
Definition: map.hpp:233
const ter_data_cache & tdata() const
Definition: map.hpp:69
gamemap(const ter_data_cache &tdata, const std::string &data)
Loads a map, with the given terrain configuration.
Definition: map.cpp:104
std::string get_terrain_editor_string(const map_location &loc) const
Definition: map.cpp:61
map_location starting_position(int side) const
Definition: map.cpp:314
int total_height() const
Real height of the map, including borders.
Definition: map.hpp:125
terrain_code & get(int x, int y)
Definition: translation.hpp:90
starting_positions starting_positions_
Definition: map.hpp:235
bool is_village(const map_location &loc) const
Definition: map.cpp:64
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:177
#define f
bool replace_if_failed_
Definition: map.hpp:95
const std::vector< map_location > & villages() const
Return a list of the locations of villages on the map.
Definition: map.hpp:180
std::vector< terrain_code > ter_list
Definition: translation.hpp:78
void set_starting_position(int side, const map_location &loc)
Manipulate starting positions of the different sides.
Definition: map.cpp:355
terrain_type_data::merge_mode mode_
Definition: map.hpp:92
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
int h_
Definition: map.hpp:253
virtual ~gamemap()
Definition: map.cpp:116
map_location special_location(const std::string &id) const
Definition: map.cpp:302
std::shared_ptr< terrain_type_data > ter_data_cache