00001 /* $Id: terrain_translation.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */ 00002 /* 00003 Copyright (C) 2006 - 2012 by Mark de Wever <koraq@xs4all.nl> 00004 Part of the Battle for Wesnoth Project http://www.wesnoth.org/ 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY. 00012 00013 See the COPYING file for more details. 00014 */ 00015 00016 /** @file */ 00017 00018 #ifndef TERRAIN_TRANSLATION_H_INCLUDED 00019 #define TERRAIN_TRANSLATION_H_INCLUDED 00020 00021 #include <SDL_types.h> //used for Uint32 definition 00022 #include <vector> 00023 #include <map> 00024 00025 #include "exceptions.hpp" 00026 00027 namespace t_translation { 00028 00029 /** 00030 * Return the maximum allowed map size (in either dimension), 00031 * the maximum map area is, therefore, this value squared. 00032 */ 00033 size_t max_map_size(); 00034 00035 typedef Uint32 t_layer; 00036 const t_layer WILDCARD = 0x2A000000; 00037 const t_layer NO_LAYER = 0xFFFFFFFF; 00038 00039 // The definitions for a terrain 00040 /** 00041 * A terrain string which is converted to a terrain is a string with 1 or 2 layers 00042 * the layers are separated by a caret and each group consists of 2 to 4 characters 00043 * if no second layer is defined it is stored as 0xFFFFFFFF, if the second layer 00044 * is empty (needed for matching) the layer has the value 0. 00045 */ 00046 struct t_terrain { 00047 t_terrain(const std::string& b, const std::string& o); 00048 t_terrain(const std::string& b, t_layer o = NO_LAYER); 00049 t_terrain(t_layer b, t_layer o) : base(b), overlay(o) {}; 00050 t_terrain() : base(0), overlay(NO_LAYER) {} 00051 00052 t_layer base; 00053 t_layer overlay; 00054 }; 00055 const t_terrain NONE_TERRAIN = t_terrain(); 00056 00057 inline bool operator<(const t_terrain& a, const t_terrain& b) 00058 { return a.base < b.base || (a.base == b.base && a.overlay < b.overlay); } 00059 00060 inline bool operator==(const t_terrain& a, const t_terrain& b) 00061 { return a.base == b.base && a.overlay == b.overlay; } 00062 00063 inline bool operator!=(const t_terrain& a, const t_terrain& b) 00064 { return a.base != b.base || a.overlay != b.overlay; } 00065 00066 inline t_terrain operator&(const t_terrain& a, const t_terrain& b) 00067 { return t_terrain(a.base & b.base, a.overlay & b.overlay); } 00068 00069 inline t_terrain operator|(const t_terrain& a, const t_terrain& b) 00070 { return t_terrain(a.base | b.base, a.overlay | b.overlay); } 00071 00072 // operator<< is defined later 00073 00074 typedef std::vector<t_terrain> t_list; 00075 typedef std::vector<std::vector<t_terrain> > t_map; 00076 00077 /** 00078 * This structure can be used for matching terrain strings. 00079 * It optimized for strings that need to be matched often, 00080 * and caches the wildcard info required for matching. 00081 */ 00082 struct t_match{ 00083 t_match(); 00084 t_match(const std::string& str, const t_layer filler = NO_LAYER); 00085 t_match(const t_terrain& tcode); 00086 00087 t_list terrain; 00088 t_list mask; 00089 t_list masked_terrain; 00090 bool has_wildcard; 00091 bool is_empty; 00092 }; 00093 00094 /** Contains an x and y coordinate used for starting positions in maps. */ 00095 struct coordinate { 00096 coordinate(); 00097 coordinate(const size_t x_, const size_t y_); 00098 size_t x; 00099 size_t y; 00100 }; 00101 00102 // Exception thrown if there's an error with the terrain. 00103 // Note: atm most thrown result in a crash, but I like 00104 // an uncatched exception better than an assert. 00105 struct error : public game::error { 00106 error(const std::string& message) : game::error(message) {} 00107 }; 00108 00109 // Some types of terrain which must be known, and can't just 00110 // be loaded in dynamically because they're special. 00111 // It's asserted that there will be corresponding entries for 00112 // these types of terrain in the terrain configuration file. 00113 extern const t_terrain VOID_TERRAIN; 00114 extern const t_terrain FOGGED; 00115 00116 // On the map the user can use this type to make odd shaped maps look good. 00117 extern const t_terrain OFF_MAP_USER; 00118 00119 extern const t_terrain HUMAN_CASTLE; 00120 extern const t_terrain HUMAN_KEEP; 00121 extern const t_terrain SHALLOW_WATER; 00122 extern const t_terrain DEEP_WATER; 00123 extern const t_terrain GRASS_LAND; 00124 extern const t_terrain FOREST; 00125 extern const t_terrain MOUNTAIN; 00126 extern const t_terrain HILL; 00127 00128 extern const t_terrain CAVE_WALL; 00129 extern const t_terrain CAVE; 00130 extern const t_terrain UNDERGROUND_VILLAGE; 00131 extern const t_terrain DWARVEN_CASTLE; 00132 extern const t_terrain DWARVEN_KEEP; 00133 00134 extern const t_terrain PLUS; // + 00135 extern const t_terrain MINUS; // - 00136 extern const t_terrain NOT; // ! 00137 extern const t_terrain STAR; // * 00138 extern const t_terrain BASE; // references the base terrain in movement/defense aliases 00139 00140 extern const t_match ALL_FORESTS; 00141 extern const t_match ALL_HILLS; 00142 extern const t_match ALL_MOUNTAINS; //excluding impassable mountains 00143 extern const t_match ALL_SWAMPS; 00144 00145 /** 00146 * Reads a single terrain from a string. 00147 * 00148 * @param str The string which should contain 1 terrain code; 00149 the new format of a terrain code 00150 * is 2 to 4 characters in the set 00151 *@verbatim 00152 * [a-Z][A-Z]/|\_ 00153 *@endverbatim 00154 * The underscore is intended for internal use. 00155 * Other letters and characters are not validated but 00156 * users of these letters can get nasty surprices. 00157 * The * is used as wildcard in some cases. 00158 * The terrain code can be two groups separated by a caret, 00159 * the first group is the base terrain, 00160 * the second the overlay terrain. 00161 * 00162 * @param filler if there's no layer this value will be used as the second layer 00163 * 00164 * @return A single terrain code 00165 */ 00166 t_terrain read_terrain_code(const std::string& str, const t_layer filler = NO_LAYER); 00167 00168 /** 00169 * Writes a single terrain code to a string. 00170 * The writers only support the new format. 00171 * 00172 * @param tcode The terrain code to convert to a string 00173 * 00174 * @return A string containing the terrain code 00175 */ 00176 std::string write_terrain_code(const t_terrain& tcode); 00177 inline std::ostream &operator<<(std::ostream &s, const t_terrain &a) 00178 { s << write_terrain_code(a); return s; } 00179 00180 /** 00181 * Reads a list of terrains from a string, when reading the 00182 * 00183 * @param str A string with one or more terrain codes (see read_terrain_code) 00184 * @param filler If there's no layer, this value will be used as the second layer 00185 * 00186 * @returns A vector which contains the terrain codes found in the string 00187 */ 00188 t_list read_list(const std::string& str, const t_layer filler = NO_LAYER); 00189 00190 /** 00191 * Writes a list of terrains to a string, only writes the new format. 00192 * 00193 * @param list A vector with one or more terrain codes 00194 * 00195 * @returns A string with the terrain codes, comma separated 00196 * and a space behind the commas. Not padded. 00197 */ 00198 std::string write_list(const t_list& list); 00199 00200 /** 00201 * Reads a gamemap string into a 2D vector 00202 * 00203 * @param str A string containing the gamemap, the following rules 00204 * are stated for a gamemap: 00205 * * The map is square 00206 * * The map can be prefixed with one or more empty lines, 00207 * these lines are ignored 00208 * * The map can be postfixed with one or more empty lines, 00209 * these lines are ignored 00210 * * Every end of line can be followed by one or more empty 00211 * lines, these lines are ignored. 00212 * @deprecated NOTE it's deprecated to use this feature. 00213 * * Terrain strings are separated by comma's or an end of line 00214 * symbol, for the last terrain string in the row. For 00215 * readability it's allowed to pad strings with either spaces 00216 * or tab, however the tab is deprecated. 00217 * * A terrain string contains either a terrain or a terrain and 00218 * starting loction. The following format is used 00219 * [S ]T 00220 * S = starting location a positive non-zero number 00221 * T = terrain code (see read_terrain_code) 00222 * @param starting_positions This parameter will be filled with the starting 00223 * locations found. Starting locations can only occur once 00224 * if multiple definitions occur of the same position only 00225 * the last is stored. The returned value is a map: 00226 * * first the starting locations 00227 * * second a coordinate structure where the location was found 00228 * 00229 * @returns A 2D vector with the terrains found the vector data is stored 00230 * like result[x][y] where x the column number is and y the row number. 00231 */ 00232 t_map read_game_map(const std::string& str, std::map<int, coordinate>& starting_positions); 00233 00234 /** 00235 * Write a gamemap in to a vector string. 00236 * 00237 * @param map A terrain vector, as returned from read_game_map 00238 * @param starting_positions A starting positions map, as returned from read_game_map 00239 * 00240 * @returns A terrain string which can be read with read_game_map. 00241 * For readability the map is padded to groups of 12 chars, 00242 * followed by a comma and space. 00243 */ 00244 std::string write_game_map(const t_map& map, std::map<int, coordinate> starting_positions = std::map<int, coordinate>()); 00245 00246 /** 00247 * Tests whether a specific terrain matches a list of expressions. 00248 * The list can use wildcard matching with *. 00249 * It also has an inversion function. 00250 * When a ! is found the result of the match is inverted. 00251 * The matching stops at the first match (regardless of the ! found) 00252 * the data is match from start to end. 00253 * 00254 * Example: 00255 * Ww, W* does match and returns true 00256 * Ww, {!, W*} does match and returns false (due to the !) 00257 * WW, Ww doesn't match and return false 00258 * 00259 * Multilayer rules: 00260 * If a terrain has multiple layers, each layer will be matched separately, 00261 * returning true only if both layers match. 00262 * 00263 * Example: 00264 * A*^* matches Abcd but also Abcd^Abcd 00265 * A*^ matches Abcd but *not* Abcd^Abcd 00266 * A*^Abcd does not match Abcd but matches Abcd^Abcd 00267 * 00268 * Note: If an expression doesn't specify a second layer (i.e. it contains 00269 * no caret) the second layer will be filled in with a default value 00270 * (See read_terrain_code and read_list). 00271 * 00272 * In the terrain building code, the second layer will default to the wildcard, 00273 * so both A* and A*^* will match Abcd^Abcd 00274 * 00275 * @param src the value to match (may not contain wildcards) 00276 * @param dest the list of expressions to match against 00277 * 00278 * @returns the result of the match (depending on the !'s) 00279 */ 00280 bool terrain_matches(const t_terrain& src, const t_list& dest); 00281 00282 /** 00283 * Tests whether a specific terrain matches an expression, 00284 * for matching rules see above. 00285 * 00286 * @param src the value to match (may not contain wildcards) 00287 * @param dest the expression to match against 00288 * 00289 * @returns the result of the match (depending on the !'s) 00290 */ 00291 bool terrain_matches(const t_terrain& src, const t_terrain& dest); 00292 00293 /** 00294 * Tests whether a certain terrain matches a list of expressions, for matching 00295 * rules see above. The matching requires some bit mask which impose a 00296 * certain overhead. This version uses a cache to cache the masks so if 00297 * a list needs to be matched often this version is preferred. 00298 * 00299 * @param src the value to match (may not contain wildcards) 00300 * @param dest the cached list of expressions to match against 00301 * 00302 * @returns the result of the match (depending on the !'s) 00303 */ 00304 bool terrain_matches(const t_terrain& src, const t_match& dest); 00305 00306 /** 00307 * Tests whether a terrain code contains a wildcard 00308 * 00309 * @param tcode the terrain code to test for a wildcard 00310 * 00311 * @returns true if wildcard found, else false 00312 */ 00313 bool has_wildcard(const t_terrain& tcode); 00314 00315 /** 00316 * Tests whether a terrain-code list contains at least 00317 * one item with a wildcard 00318 * 00319 * @param list the list to test for a wildcard 00320 * 00321 * @returns true if a wildcard found, else false 00322 */ 00323 bool has_wildcard(const t_list& list); 00324 00325 // These terrain letters are in the builder format, 00326 // and not usable in other parts of the engine 00327 const t_layer TB_STAR = '*' << 24; // It can be assumed this is the equivalent of STAR 00328 const t_layer TB_DOT = '.' << 24; 00329 00330 /** 00331 * Reads a builder map. 00332 * A builder map differs a great deal from a normal map, 00333 * hence the different functions. 00334 * 00335 * @param str The map data, a terrain letter is either a * or a . or a number as 00336 * anchor. The star or dot are stored in the base part of the terrain 00337 * and the anchor in the overlay part. If more letters are allowed as 00338 * special case they will be stored in the base part. 00339 * Anchor 0 is no anchor. 00340 * 00341 * @returns A 2D vector with the data found the vector data is stored 00342 * like result[y][x] where x the column number is and y the row number. 00343 */ 00344 t_map read_builder_map(const std::string& str); 00345 00346 } // end namespace t_translation 00347 00348 #endif
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:11 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |