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