terrain_translation.hpp

Go to the documentation of this file.
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