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