tron@3636: /* $Id$ */ tron@3636: truelight@7309: /** @file slope.h Definitions of a slope. truelight@7309: * This file defines the enumeration and helper functions for handling truelight@7309: * the slope info of a tile. truelight@7309: */ belugas@6420: tron@3636: #ifndef SLOPE_H tron@3636: #define SLOPE_H tron@3636: truelight@7309: /** truelight@7309: * Enumeration for the slope-type. truelight@7309: * truelight@7309: * This enumeration use the chars N,E,S,W corresponding the truelight@7309: * direction north, east, south and west. The top corner of a tile truelight@7309: * is the north-part of the tile. The whole slope is encoded with truelight@7309: * 5 bits, 4 bits for each corner and 1 bit for a steep-flag. truelight@7309: */ rubidium@6248: enum Slope { truelight@7309: SLOPE_FLAT = 0x00, ///< a flat tile truelight@7309: SLOPE_W = 0x01, ///< the west corner of the tile is raised truelight@7309: SLOPE_S = 0x02, ///< the south corner of the tile is raised truelight@7309: SLOPE_E = 0x04, ///< the east corner of the tile is raised truelight@7309: SLOPE_N = 0x08, ///< the north corner of the tile is raised truelight@7309: SLOPE_STEEP = 0x10, ///< indicates the slope is steep truelight@7309: SLOPE_NW = SLOPE_N | SLOPE_W, ///< north and west corner are raised truelight@7309: SLOPE_SW = SLOPE_S | SLOPE_W, ///< south and west corner are raised truelight@7309: SLOPE_SE = SLOPE_S | SLOPE_E, ///< south and east corner are raised truelight@7309: SLOPE_NE = SLOPE_N | SLOPE_E, ///< north and east corner are raised truelight@7309: SLOPE_EW = SLOPE_E | SLOPE_W, ///< east and west corner are raised truelight@7309: SLOPE_NS = SLOPE_N | SLOPE_S, ///< north and south corner are raised truelight@7309: SLOPE_ELEVATED = SLOPE_N | SLOPE_E | SLOPE_S | SLOPE_W, ///< all corner are raised, similar to SLOPE_FLAT truelight@7309: SLOPE_NWS = SLOPE_N | SLOPE_W | SLOPE_S, ///< north, west and south corner are raised truelight@7309: SLOPE_WSE = SLOPE_W | SLOPE_S | SLOPE_E, ///< west, south and east corner are raised truelight@7309: SLOPE_SEN = SLOPE_S | SLOPE_E | SLOPE_N, ///< south, east and north corner are raised truelight@7309: SLOPE_ENW = SLOPE_E | SLOPE_N | SLOPE_W, ///< east, north and west corner are raised truelight@7309: SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS, ///< a steep slope falling to east (from west) truelight@7309: SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE, ///< a steep slope falling to north (from south) truelight@7309: SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN, ///< a steep slope falling to west (from east) truelight@7309: SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW ///< a steep slope falling to south (from north) rubidium@6248: }; tron@3636: truelight@7309: /** truelight@7309: * Checks if a slope is steep. truelight@7309: * truelight@7309: * @param s The given #Slope. truelight@7309: * @return True if the slope is steep, else false. truelight@7309: */ tron@3636: static inline bool IsSteepSlope(Slope s) tron@3636: { tron@3636: return (s & SLOPE_STEEP) != 0; tron@3636: } tron@3636: truelight@7309: /** truelight@7309: * Return the complement of a slope. truelight@7309: * truelight@7309: * This method returns the complement of a slope. The complement of a truelight@7309: * slope is a slope with raised corner which aren't raised in the given truelight@7309: * slope. truelight@7309: * truelight@7309: * @pre The slope must not be steep. truelight@7309: * @param s The #Slope to get the complement. truelight@7309: * @return a complement Slope of the given slope. truelight@7309: */ tron@3636: static inline Slope ComplementSlope(Slope s) tron@3636: { tron@3636: assert(!IsSteepSlope(s)); tron@3636: return (Slope)(0xF ^ s); tron@3636: } tron@3636: rubidium@7335: /** rubidium@7335: * Returns the highest corner of a slope (one corner raised or a steep slope). rubidium@7335: * rubidium@7335: * @pre The slope must be a slope with one corner raised or a steep slope. rubidium@7335: * @param s The #Slope. rubidium@7335: * @return Number of the highest corner. (0 west, 1 south, 2 east, 3 north) rubidium@7335: */ rubidium@7335: static inline byte GetHighestSlopeCorner(Slope s) rubidium@7335: { rubidium@7335: switch (s) { rubidium@7335: case SLOPE_W: rubidium@7335: case SLOPE_STEEP_W: return 0; rubidium@7335: case SLOPE_S: rubidium@7335: case SLOPE_STEEP_S: return 1; rubidium@7335: case SLOPE_E: rubidium@7335: case SLOPE_STEEP_E: return 2; rubidium@7335: case SLOPE_N: rubidium@7335: case SLOPE_STEEP_N: return 3; rubidium@7335: default: NOT_REACHED(); rubidium@7335: } rubidium@7335: } rubidium@7335: rubidium@7582: /** rubidium@7582: * Returns the height of the highest corner of a slope relative to TileZ (= minimal height) rubidium@7582: * rubidium@7582: * @param s The #Slope. rubidium@7582: * @return Relative height of highest corner. rubidium@7582: */ rubidium@7582: static inline uint GetSlopeMaxZ(Slope s) rubidium@7582: { rubidium@7582: if (s == SLOPE_FLAT) return 0; rubidium@7582: if (IsSteepSlope(s)) return 2 * TILE_HEIGHT; rubidium@7582: return TILE_HEIGHT; rubidium@7582: } rubidium@7582: rubidium@7335: rubidium@7335: /** rubidium@7335: * Enumeration for Foundations. rubidium@7335: */ rubidium@7335: enum Foundation { rubidium@7335: FOUNDATION_NONE, ///< The tile has no foundation, the slope remains unchanged. rubidium@7335: FOUNDATION_LEVELED, ///< The tile is leveled up to a flat slope. rubidium@7335: FOUNDATION_INCLINED_X, ///< The tile has an along X-axis inclined foundation. rubidium@7335: FOUNDATION_INCLINED_Y, ///< The tile has an along Y-axis inclined foundation. rubidium@7335: FOUNDATION_STEEP_LOWER, ///< The tile has a steep slope. The lowerst corner is raised by a foundation to allow building railroad on the lower halftile. rubidium@7335: FOUNDATION_STEEP_HIGHER, ///< The tile has a steep slope. Three corners are raised by a foundation to allow building railroad on the higher halftile. rubidium@7335: }; rubidium@7335: rubidium@7335: /** rubidium@7335: * Tests for FOUNDATION_NONE. rubidium@7335: * rubidium@7335: * @param f Maybe a #Foundation. rubidium@7335: * @return true iff f is a foundation. rubidium@7335: */ rubidium@7335: static inline bool IsFoundation(Foundation f) rubidium@7335: { rubidium@7335: return f != FOUNDATION_NONE; rubidium@7335: } rubidium@7335: rubidium@7335: /** rubidium@7335: * Tests if the foundation is a leveled foundation. rubidium@7335: * rubidium@7335: * @param f The #Foundation. rubidium@7335: * @return true iff f is a leveled foundation. rubidium@7335: */ rubidium@7335: static inline bool IsLeveledFoundation(Foundation f) rubidium@7335: { rubidium@7335: return f == FOUNDATION_LEVELED; rubidium@7335: } rubidium@7335: rubidium@7335: /** rubidium@7335: * Tests if the foundation is an inclined foundation. rubidium@7335: * rubidium@7335: * @param f The #Foundation. rubidium@7335: * @return true iff f is an inclined foundation. rubidium@7335: */ rubidium@7335: static inline bool IsInclinedFoundation(Foundation f) rubidium@7335: { rubidium@7335: return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y); rubidium@7335: } rubidium@7335: rubidium@7335: /** rubidium@7335: * Returns the foundation needed to flatten a slope. rubidium@7335: * The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED. rubidium@7335: * rubidium@7335: * @pre The slope must not be steep. rubidium@7335: * @param s The current #Slope. rubidium@7335: * @return The needed #Foundation. rubidium@7335: */ rubidium@7335: static inline Foundation FlatteningFoundation(Slope s) rubidium@7335: { rubidium@7335: assert(!IsSteepSlope(s)); rubidium@7335: return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED); rubidium@7335: } rubidium@7335: rubidium@7335: /** rubidium@7335: * Returns the along a specific axis inclined foundation. rubidium@7335: * rubidium@7335: * @param axis The #Axis. rubidium@7335: * @return The needed #Foundation. rubidium@7335: */ rubidium@7335: static inline Foundation InclinedFoundation(Axis axis) rubidium@7335: { rubidium@7335: return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y); rubidium@7335: } rubidium@7335: peter1138@4666: #endif /* SLOPE_H */