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  static void overlay_impl(
113  // const but changed via set_terrain
114  const t_translation::ter_map& m1,
116  const t_translation::ter_map& m2,
118  std::function<void (const map_location&, const t_translation::terrain_code&, terrain_type_data::merge_mode, bool)> set_terrain,
119  map_location loc,
120  const std::vector<overlay_rule>& rules,
121  bool is_odd,
122  bool ignore_special_locations);
123 
124  /** Effective map width. */
125  int w() const { return w_; }
126 
127  /** Effective map height. */
128  int h() const { return h_; }
129 
130  /** Size of the map border. */
131  int border_size() const { return default_border; }
132 
133  /** Real width of the map, including borders. */
134  int total_width() const { return tiles_.w; }
135 
136  /** Real height of the map, including borders */
137  int total_height() const { return tiles_.h; }
138 
140  {
141  return tiles_.get(loc.x + border_size(), loc.y + border_size());
142  }
143 private:
144  //private method, use set_terrain instead which also updates villages_.
146  {
147  return tiles_.get(loc.x + border_size(), loc.y + border_size());
148  }
149 public:
150 
151  /**
152  * Looks up terrain at a particular location.
153  *
154  * Hexes off the map may be looked up, and their 'emulated' terrain will
155  * also be returned. This allows proper drawing of the edges of the map.
156  */
158 
159  /** Writes the terrain at loc to cfg. */
160  void write_terrain(const map_location &loc, config& cfg) const;
161 
162 
163  /** Manipulate starting positions of the different sides. */
164  void set_starting_position(int side, const map_location& loc);
165  map_location starting_position(int side) const;
166 
167  void set_special_location(const std::string& id, const map_location& loc);
168  map_location special_location(const std::string& id) const;
169 
170 
171  /// returns the side number of the side starting at position loc, 0 if no such side exists.
172  const std::string* is_starting_position(const map_location& loc) const;
173  int num_valid_starting_positions() const;
174 
175 
176  /**
177  * Tell if a location is on the map.
178  *
179  * Should be called before indexing using [].
180  * @todo inline for performance? -- Ilor
181  */
182  bool on_board(const map_location& loc) const;
183  bool on_board_with_border(const map_location& loc) const;
184 
185  /** Tell if the map is of 0 size. */
186  bool empty() const
187  {
188  return w_ == 0 || h_ == 0;
189  }
190 
191  /** Return a list of the locations of villages on the map. */
192  const std::vector<map_location>& villages() const { return villages_; }
193 
194  /** Shortcut to get_terrain_info(get_terrain(loc)). */
195  const terrain_type& get_terrain_info(const map_location &loc) const;
196 
197  /** Gets the list of terrains. */
199 
200  /**
201  * Clobbers over the terrain at location 'loc', with the given terrain.
202  * Uses mode and replace_if_failed like merge_terrains().
203  */
204  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);
205 
206  /**
207  * Maximum number of players supported.
208  *
209  * Warning: when you increase this, you need to add
210  * more definitions to the team_colors.cfg file.
211  */
212  enum { MAX_PLAYERS = 9 };
213 
214  /** The default border style for a map. */
215  static const int default_border = 1;
216 
217  /** Parses ranges of locations into a vector of locations, using this map's dimensions as bounds. */
218  std::vector<map_location> parse_location_range(const std::string& xvals,
219  const std::string &yvals, bool with_border = false) const;
220 
223 
224  template<typename F>
225  void for_each_loc(const F& f) const
226  {
227  for (int x = -border_size(); x < w() + border_size(); ++x) {
228  for (int y = -border_size(); y < h() + border_size(); ++y) {
229  f({ x, y });
230  }
231  }
232  }
233  //Doesn't include border.
234  template<typename F>
235  void for_each_walkable_loc(const F& f) const
236  {
237  for (int x = 0; x < w(); ++x) {
238  for (int y = 0; y < h(); ++y) {
239  f({ x, y });
240  }
241  }
242  }
243 
244 protected:
246 
248 
249 private:
250 
251  /**
252  * Reads the header of a map which is saved in the deprecated map_data format.
253  *
254  * @param data The mapdata to load.
255  */
256  int read_header(const std::string& data);
257 
259 
260 protected:
261  std::vector<map_location> villages_;
262 
263  /** Sizes of the map area. */
264  int w_;
265  int h_;
266 };
bool is_keep(const map_location &loc) const
Definition: map.cpp:71
void for_each_loc(const F &f) const
Definition: map.hpp:225
const t_translation::ter_list & underlying_union_terrain(const map_location &loc) const
Definition: map.cpp:58
bool is_odd(T num)
Definition: math.hpp:34
int h() const
Effective map height.
Definition: map.hpp:128
const t_translation::ter_list & underlying_def_terrain(const map_location &loc) const
Definition: map.cpp:56
std::vector< map_location > villages_
Definition: map.hpp:261
void write_terrain(const map_location &loc, config &cfg) const
Writes the terrain at loc to cfg.
Definition: map.cpp:100
bool is_castle(const map_location &loc) const
Definition: map.cpp:69
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:86
const t_translation::terrain_code operator[](const map_location &loc) const
Definition: map.hpp:139
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:349
const t_translation::ter_list & get_terrain_list() const
Gets the list of terrains.
Definition: map.cpp:43
int border_size() const
Size of the map border.
Definition: map.hpp:131
static const int default_border
The default border style for a map.
Definition: map.hpp:215
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:97
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:377
t_translation::starting_positions starting_positions
Definition: map.hpp:221
std::string get_terrain_string(const map_location &loc) const
Definition: map.cpp:60
t_translation::terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:309
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:389
int total_width() const
Real width of the map, including borders.
Definition: map.hpp:134
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:416
std::string write() const
Definition: map.cpp:205
int gives_healing(const map_location &loc) const
Definition: map.cpp:67
const starting_positions & special_locations() const
Definition: map.hpp:222
bool empty() const
Tell if the map is of 0 size.
Definition: map.hpp:186
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:382
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:355
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:210
static void overlay_impl(const t_translation::ter_map &m1, t_translation::starting_positions &m1_st, const t_translation::ter_map &m2, const t_translation::starting_positions &m2_st, std::function< void(const map_location &, const t_translation::terrain_code &, terrain_type_data::merge_mode, bool)> set_terrain, map_location loc, const std::vector< overlay_rule > &rules, bool is_odd, bool ignore_special_locations)
Definition: map.cpp:216
int num_valid_starting_positions() const
Definition: map.cpp:336
void for_each_walkable_loc(const F &f) const
Definition: map.hpp:235
int w_
Sizes of the map area.
Definition: map.hpp:264
void read(const std::string &data, const bool allow_invalid=true)
Definition: map.cpp:121
t_translation::terrain_code & operator[](const map_location &loc)
Definition: map.hpp:145
static const ::config * terrain
The terrain used to create the cache.
Definition: minimap.cpp:130
const t_translation::ter_list & underlying_mvt_terrain(const map_location &loc) const
Definition: map.cpp:54
ter_data_cache tdata_
Definition: map.hpp:258
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:125
t_translation::ter_map tiles_
Definition: map.hpp:245
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:105
std::string get_terrain_editor_string(const map_location &loc) const
Definition: map.cpp:62
map_location starting_position(int side) const
Definition: map.cpp:331
int total_height() const
Real height of the map, including borders.
Definition: map.hpp:137
terrain_code & get(int x, int y)
Definition: translation.hpp:90
starting_positions starting_positions_
Definition: map.hpp:247
bool is_village(const map_location &loc) const
Definition: map.cpp:65
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:178
#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:192
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:372
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:92
int h_
Definition: map.hpp:265
virtual ~gamemap()
Definition: map.cpp:117
map_location special_location(const std::string &id) const
Definition: map.cpp:319
std::shared_ptr< terrain_type_data > ter_data_cache