The Battle for Wesnoth  1.19.18+dev
map.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2025
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 class config;
19 
20 #include "map/location.hpp"
21 #include "terrain/translation.hpp"
22 #include "terrain/type_data.hpp"
23 #include "utils/optional_fwd.hpp"
24 
25 //class terrain_type_data; Can't forward declare because of enum
26 
27 // This could be moved to a separate file pair...
29 {
30 public:
34  virtual ~gamemap_base();
35 
36  /** The default border style for a map. */
37  static const int default_border = 1;
38 
39  /**
40  * Maximum number of players supported.
41  *
42  * Warning: when you increase this, you need to add
43  * more definitions to the team_colors.cfg file.
44  */
45  static const int MAX_PLAYERS = 9;
46 
47  std::string to_string() const;
48 
49  /** Effective map width. */
50  int w() const { return total_width() - 2 * border_size(); }
51 
52  /** Effective map height. */
53  int h() const { return total_height() - 2 * border_size(); }
54 
55  /** Size of the map border. */
56  int border_size() const { return default_border; }
57 
58  /** Real width of the map, including borders. */
59  int total_width() const { return tiles_.w; }
60 
61  /** Real height of the map, including borders */
62  int total_height() const { return tiles_.h; }
63 
64  /** Total square area of the map, including borders. */
65  int total_area() const { return total_width() * total_height(); }
66 
67  /** Tell if the map is of 0 size. */
68  bool empty() const
69  {
70  return w() <= 0 || h() <= 0;
71  }
72 
73  /**
74  * Tell if a location is on the map.
75  */
76  bool on_board(const map_location& loc) const;
77  bool on_board_with_border(const map_location& loc) const;
78 
79  /** What happens to a village hex when its terrain is changed. */
81 
83  {
86  };
87 
88  /**
89  * Clobbers over the terrain at location 'loc', with the given terrain.
90  * Uses mode and replace_if_failed like merge_terrains().
91  */
93  const terrain_code& terrain,
95  bool replace_if_failed = false) = 0;
96 
97  /**
98  * Looks up terrain at a particular location.
99  *
100  * Hexes off the map may be looked up, and their 'emulated' terrain will
101  * also be returned. This allows proper drawing of the edges of the map.
102  */
104 
107  const std::vector<map_location> starting_positions() const;
108 
109  void set_special_location(const std::string& id, const map_location& loc);
110  map_location special_location(const std::string& id) const;
111 
112  /** Manipulate starting positions of the different sides. */
113  void set_starting_position(int side, const map_location& loc);
114  map_location starting_position(int side) const;
115 
116  /** Counts the number of sides that have valid starting positions on this map */
117  int num_valid_starting_positions() const;
118  /** returns the side number of the side starting at position loc, 0 if no such side exists. */
119  int is_starting_position(const map_location& loc) const;
120  /** returns the name of the special location at position loc, null if no such location exists. */
121  const std::string* is_special_location(const map_location& loc) const;
122 
123  /** Parses ranges of locations into a vector of locations, using this map's dimensions as bounds. */
124  std::vector<map_location> parse_location_range(const std::string& xvals, const std::string &yvals, bool with_border = false) const;
125 
127  {
131  utils::optional<t_translation::terrain_code> terrain_;
132  bool use_old_{false};
133  bool replace_if_failed_{false};
134  };
135 
136  /** Overlays another map onto this one at the given position. */
137  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);
138 
139  template<typename F>
140  void for_each_loc(const F& f) const
141  {
142  for(int x = 0; x < total_width(); ++x) {
143  for(int y = 0; y < total_height(); ++y) {
144  f(map_location{x, y , wml_loc()});
145  }
146  }
147  }
148  //Doesn't include border.
149  template<typename F>
150  void for_each_walkable_loc(const F& f) const
151  {
152  for(int x = 0; x < w(); ++x) {
153  for(int y = 0; y < h(); ++y) {
154  f(map_location{x, y});
155  }
156  }
157  }
158 protected:
159  gamemap_base() = default;
160  gamemap_base(int w, int h, const terrain_code& default_ter);
161  terrain_map& tiles() {return tiles_;}
162  const terrain_map& tiles() const {return tiles_;}
163 private:
166 };
167 
168 /**
169  * Encapsulates the map of the game.
170  *
171  * Although the game is hexagonal, the map is stored as a grid.
172  * Each type of terrain is represented by a multiletter terrain code.
173  * @todo Update for new map-format.
174  */
175 class gamemap : public gamemap_base
176 {
177 public:
178 
179  /* Get info from the terrain_type_data object about the terrain at a location */
180  std::string get_terrain_string(const map_location& loc) const;
181  std::string get_terrain_editor_string(const map_location& loc) const;
182  std::string get_underlying_terrain_string(const map_location& loc) const;
183 
184  bool is_village(const map_location& loc) const;
185  int gives_healing(const map_location& loc) const;
186  bool is_castle(const map_location& loc) const;
187  bool is_keep(const map_location& loc) const;
188 
189  /* The above wrappers, but which takes a terrain. This is the old syntax, preserved for brevity in certain cases. */
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  // Also expose this for the same reason:
195  const terrain_type& get_terrain_info(const t_translation::terrain_code & terrain) const;
196 
197  /**
198  * Loads a map.
199  *
200  * Data should be a series of lines, with each character representing one
201  * hex on the map. Starting locations are represented by numbers.
202  *
203  * @param data the map data to load.
204  */
205  gamemap(std::string_view data); // throw(incorrect_map_format_error)
206  gamemap(int w, int h, const terrain_code& default_ter);
207 
208  void read(std::string_view data, const bool allow_invalid = true);
209 
210  std::string write() const;
211 
213  {
214  return tiles().get(loc.x + border_size(), loc.y + border_size());
215  }
216 private:
217  //private method, use set_terrain instead which also updates villages_.
219  {
220  return tiles().get(loc.x + border_size(), loc.y + border_size());
221  }
222 public:
224  const terrain_code& terrain,
226  bool replace_if_failed = false) override;
227 
228  /** Writes the terrain at loc to cfg. */
229  void write_terrain(const map_location &loc, config& cfg) const;
230 
231  /** Return a list of the locations of villages on the map. */
232  const std::vector<map_location>& villages() const { return villages_; }
233 
234  /** Shortcut to get_terrain_info(get_terrain(loc)). */
235  const terrain_type& get_terrain_info(const map_location &loc) const;
236 
237  /** Gets the list of terrains. */
239 
240 private:
241 
242  /**
243  * Returns a subview of @a data which excludes any legacy headers.
244  *
245  * @param data The mapdata to load.
246  */
247  std::string_view strip_legacy_header(std::string_view data) const;
248 
250 
251 protected:
252  std::vector<map_location> villages_;
253 };
map_location loc
Definition: move.cpp:172
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:157
int total_area() const
Total square area of the map, including borders.
Definition: map.hpp:65
void for_each_walkable_loc(const F &f) const
Definition: map.hpp:150
virtual ~gamemap_base()
Definition: map.cpp:106
terrain_code get_terrain(const map_location &loc) const
Looks up terrain at a particular location.
Definition: map.cpp:265
int w() const
Effective map width.
Definition: map.hpp:50
void set_starting_position(int side, const map_location &loc)
Manipulate starting positions of the different sides.
Definition: map.cpp:342
t_translation::starting_positions location_map
Definition: map.hpp:33
terrain_map & tiles()
Definition: map.hpp:161
void set_special_location(const std::string &id, const map_location &loc)
Definition: map.cpp:325
int h() const
Effective map height.
Definition: map.hpp:53
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:177
static const int MAX_PLAYERS
Maximum number of players supported.
Definition: map.hpp:45
map_location special_location(const std::string &id) const
Definition: map.cpp:274
gamemap_base()=default
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:396
map_location starting_position(int side) const
Definition: map.cpp:286
t_translation::terrain_code terrain_code
Definition: map.hpp:31
void for_each_loc(const F &f) const
Definition: map.hpp:140
int total_width() const
Real width of the map, including borders.
Definition: map.hpp:59
const location_map & special_locations() const
Definition: map.hpp:106
const terrain_map & tiles() const
Definition: map.hpp:162
std::string to_string() const
Definition: map.cpp:442
int num_valid_starting_positions() const
Counts the number of sides that have valid starting positions on this map.
Definition: map.cpp:297
bool on_board_with_border(const map_location &loc) const
Definition: map.cpp:352
static const int default_border
The default border style for a map.
Definition: map.hpp:37
int total_height() const
Real height of the map, including borders.
Definition: map.hpp:62
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:309
bool empty() const
Tell if the map is of 0 size.
Definition: map.hpp:68
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_
Definition: map.hpp:165
village_state
What happens to a village hex when its terrain is changed.
Definition: map.hpp:80
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:319
int border_size() const
Size of the map border.
Definition: map.hpp:56
const std::vector< map_location > starting_positions() const
Definition: map.cpp:447
bool on_board(const map_location &loc) const
Tell if a location is on the map.
Definition: map.cpp:347
location_map & special_locations()
Definition: map.hpp:105
terrain_map tiles_
Definition: map.hpp:164
Encapsulates the map of the game.
Definition: map.hpp:176
bool is_village(const map_location &loc) const
Definition: map.cpp:60
t_translation::terrain_code & operator[](const map_location &loc)
Definition: map.hpp:218
bool is_castle(const map_location &loc) const
Definition: map.cpp:64
std::string get_underlying_terrain_string(const map_location &loc) const
Definition: map.cpp:57
const t_translation::ter_list & get_terrain_list() const
Gets the list of terrains.
Definition: map.cpp:42
std::string write() const
Definition: map.cpp:172
const t_translation::terrain_code & operator[](const map_location &loc) const
Definition: map.hpp:212
std::vector< map_location > villages_
Definition: map.hpp:252
std::string get_terrain_editor_string(const map_location &loc) const
Definition: map.cpp:55
void write_terrain(const map_location &loc, config &cfg) const
Writes the terrain at loc to cfg.
Definition: map.cpp:81
std::string_view strip_legacy_header(std::string_view data) const
Returns a subview of data which excludes any legacy headers.
Definition: map.cpp:150
const std::vector< map_location > & villages() const
Return a list of the locations of villages on the map.
Definition: map.hpp:232
bool is_keep(const map_location &loc) const
Definition: map.cpp:66
std::string get_terrain_string(const map_location &loc) const
Definition: map.cpp:53
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.
Definition: map.cpp:359
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
Definition: map.cpp:78
gamemap(std::string_view data)
Loads a map.
Definition: map.cpp:86
void read(std::string_view data, const bool allow_invalid=true)
Definition: map.cpp:110
terrain_type_data * tdata_
Definition: map.hpp:249
int gives_healing(const map_location &loc) const
Definition: map.cpp:62
Contains the database of all known terrain types, both those defined explicitly by WML [terrain_type]...
Definition: type_data.hpp:41
const config * cfg
constexpr bool is_odd(T num)
Definition: math.hpp:34
constexpr terrain_code NONE_TERRAIN
Definition: translation.hpp:58
std::vector< terrain_code > ter_list
Definition: translation.hpp:77
boost::bimaps::bimap< boost::bimaps::set_of< std::string >, boost::bimaps::multiset_of< coordinate > > starting_positions
std::string_view data
Definition: picture.cpp:188
terrain_type_data::merge_mode mode_
Definition: map.hpp:130
t_translation::ter_list new_
Definition: map.hpp:129
utils::optional< t_translation::terrain_code > terrain_
Definition: map.hpp:131
t_translation::ter_list old_
Definition: map.hpp:128
village_state village_change
Definition: map.hpp:85
Encapsulates the map of the game.
Definition: location.hpp:46
terrain_code & get(int x, int y)
Definition: translation.hpp:83
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
#define f