00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef MAP_H_INCLUDED
00019 #define MAP_H_INCLUDED
00020
00021 class config;
00022 class gamestatus;
00023 class unit;
00024 class vconfig;
00025 class unit_map;
00026
00027 #include "terrain.hpp"
00028
00029 #include "serialization/string_utils.hpp"
00030
00031 #include <iostream>
00032 #include <map>
00033 #include <string>
00034 #include <vector>
00035 #include <set>
00036
00037 #define MAX_MAP_AREA 65536
00038
00039
00040
00041
00042
00043 class gamemap
00044 {
00045 public:
00046
00047
00048
00049
00050
00051 const t_translation::t_list& underlying_mvt_terrain(t_translation::t_terrain terrain) const;
00052 const t_translation::t_list& underlying_def_terrain(t_translation::t_terrain terrain) const;
00053 const t_translation::t_list& underlying_union_terrain(t_translation::t_terrain terrain) const;
00054
00055
00056 struct incorrect_format_exception {
00057 incorrect_format_exception(const char* msg) : msg_(msg) {}
00058 const char* const msg_;
00059 };
00060
00061
00062 struct location {
00063
00064 enum DIRECTION { NORTH, NORTH_EAST, SOUTH_EAST, SOUTH,
00065 SOUTH_WEST, NORTH_WEST, NDIRECTIONS };
00066
00067 static DIRECTION parse_direction(const std::string& str);
00068
00069
00070 static std::vector<DIRECTION> parse_directions(const std::string& str);
00071 static std::string write_direction(DIRECTION dir);
00072
00073 location() : x(-1000), y(-1000) {}
00074 location(int x, int y) : x(x), y(y) {}
00075 location(const config& cfg, const variable_set *variables);
00076
00077 void write(config& cfg) const;
00078
00079 inline bool valid() const { return x >= 0 && y >= 0; }
00080
00081 inline bool valid(const int parWidth, const int parHeight) const
00082 {
00083 return ((x >= 0) && (y >= 0) && (x < parWidth) && (y < parHeight));
00084 }
00085
00086 int x, y;
00087 bool matches_range(const std::string& xloc, const std::string& yloc) const;
00088
00089
00090 bool operator<(const location& a) const { return x < a.x || (x == a.x && y < a.y); }
00091 bool operator==(const location& a) const { return x == a.x && y == a.y; }
00092 bool operator!=(const location& a) const { return !operator==(a); }
00093
00094
00095 location operator-() const;
00096 location operator+(const location &a) const;
00097 location &operator+=(const location &a);
00098 location operator-(const location &a) const;
00099 location &operator-=(const location &a);
00100
00101
00102 location get_direction(DIRECTION d, int n = 1) const;
00103 DIRECTION get_relative_dir(location loc) const;
00104 static DIRECTION get_opposite_dir(DIRECTION d);
00105
00106 static const location null_location;
00107 };
00108
00109
00110
00111
00112
00113 static int get_drawing_order (const gamemap::location& loc )
00114 { return (loc.y * 2 + loc.x % 2) * 1024+loc.x; }
00115
00116 const t_translation::t_list& underlying_mvt_terrain(const location& loc) const
00117 { return underlying_mvt_terrain(get_terrain(loc)); }
00118 const t_translation::t_list& underlying_def_terrain(const location& loc) const
00119 { return underlying_def_terrain(get_terrain(loc)); }
00120 const t_translation::t_list& underlying_union_terrain(const location& loc) const
00121 { return underlying_union_terrain(get_terrain(loc)); }
00122
00123 bool is_village(t_translation::t_terrain terrain) const
00124 { return get_terrain_info(terrain).is_village(); }
00125 int gives_healing(t_translation::t_terrain terrain) const
00126 { return get_terrain_info(terrain).gives_healing(); }
00127 bool is_castle(t_translation::t_terrain terrain) const
00128 { return get_terrain_info(terrain).is_castle(); }
00129 bool is_keep(t_translation::t_terrain terrain) const
00130 { return get_terrain_info(terrain).is_keep(); }
00131
00132 bool is_village(const location& loc) const
00133 { return on_board(loc) && is_village(get_terrain(loc)); }
00134 int gives_healing(const location& loc) const
00135 { return on_board(loc) ? gives_healing(get_terrain(loc)) : 0; }
00136 bool is_castle(const location& loc) const
00137 { return on_board(loc) && is_castle(get_terrain(loc)); }
00138 bool is_keep(const location& loc) const
00139 { return on_board(loc) && is_keep(get_terrain(loc)); }
00140
00141 enum tborder {
00142 NO_BORDER = 0,
00143 SINGLE_TILE_BORDER
00144 };
00145
00146 enum tusage {
00147 IS_MAP,
00148 IS_MASK
00149 };
00150
00151 enum tmerge_mode {
00152 BASE,
00153 OVERLAY,
00154 BOTH
00155 };
00156
00157
00158
00159
00160
00161
00162 gamemap(const config& terrain_cfg, const std::string& data);
00163 void read(const std::string& data);
00164
00165 std::string write() const;
00166
00167
00168 void overlay(const gamemap& m, const config& rules, const int x=0, const int y=0);
00169
00170
00171 int w() const { return w_; }
00172 int h() const { return h_; }
00173
00174
00175 int total_width() const { return total_width_; }
00176 int total_height() const { return total_height_; }
00177
00178 const t_translation::t_terrain operator[](const gamemap::location& loc) const
00179 { return tiles_[loc.x + border_size_][loc.y + border_size_]; }
00180
00181
00182
00183
00184
00185 t_translation::t_terrain get_terrain(const location& loc) const;
00186
00187
00188 void write_terrain(const gamemap::location &loc, config& cfg) const;
00189
00190
00191
00192 const location& starting_position(int side) const;
00193 int is_starting_position(const location& loc) const;
00194 int num_valid_starting_positions() const;
00195
00196 void set_starting_position(int side, const location& loc);
00197
00198
00199
00200 bool on_board(const location& loc, const bool include_border = false) const;
00201
00202
00203 bool empty() const
00204 {
00205 return w_ == 0 || h_ == 0;
00206 }
00207
00208
00209 const std::vector<location>& villages() const { return villages_; }
00210
00211
00212
00213 const terrain_type& get_terrain_info(const t_translation::t_terrain terrain) const;
00214
00215
00216 const terrain_type& get_terrain_info(const location &loc) const
00217 { return get_terrain_info(get_terrain(loc)); }
00218
00219
00220 const t_translation::t_list& get_terrain_list() const
00221 { return terrainList_; }
00222
00223
00224
00225 void set_terrain(const location& loc, const t_translation::t_terrain terrain, const tmerge_mode mode=BOTH, bool replace_if_failed = false);
00226
00227
00228
00229 const std::map<t_translation::t_terrain, size_t>& get_weighted_terrain_frequencies() const;
00230
00231
00232
00233 void remove_from_border_cache(const location &loc)
00234 { borderCache_.erase(loc); }
00235
00236
00237
00238
00239 enum { MAX_PLAYERS = 9 };
00240
00241
00242 tusage get_usage() const { return usage_; }
00243
00244
00245
00246 static const std::string default_map_header;
00247
00248 static const tborder default_border;
00249
00250
00251
00252
00253
00254
00255
00256 t_translation::t_terrain merge_terrains(const t_translation::t_terrain old_t, const t_translation::t_terrain new_t, const tmerge_mode mode, bool replace_if_failed = false);
00257
00258 protected:
00259 t_translation::t_map tiles_;
00260
00261
00262 location startingPositions_[MAX_PLAYERS+1];
00263
00264
00265
00266
00267 void clear_border_cache() { borderCache_.clear(); }
00268
00269 private:
00270 int num_starting_positions() const
00271 { return sizeof(startingPositions_)/sizeof(*startingPositions_); }
00272
00273
00274 const t_translation::t_list operator[](int index) const
00275 { return tiles_[index + border_size_]; }
00276
00277
00278
00279 bool try_merge_terrains(const t_translation::t_terrain terrain);
00280
00281 t_translation::t_list terrainList_;
00282 std::map<t_translation::t_terrain, terrain_type> tcodeToTerrain_;
00283 std::vector<location> villages_;
00284
00285 mutable std::map<location, t_translation::t_terrain> borderCache_;
00286 mutable std::map<t_translation::t_terrain, size_t> terrainFrequencyCache_;
00287
00288
00289 int w_;
00290 int h_;
00291
00292
00293 int total_width_;
00294 int total_height_;
00295
00296
00297 int border_size_;
00298
00299 tusage usage_;
00300 };
00301
00302 class viewpoint
00303 {
00304 public:
00305 virtual bool shrouded(const gamemap::location& loc) const = 0;
00306 virtual bool fogged(const gamemap::location& loc) const = 0;
00307 virtual ~viewpoint() {};
00308 };
00309
00310
00311 std::vector<gamemap::location> parse_location_range(const std::string& xvals,
00312 const std::string& yvals, const gamemap *const map=NULL);
00313
00314
00315 std::ostream &operator<<(std::ostream &s, gamemap::location const &l);
00316
00317 #endif