1 /*************************************************************************** 2 * Copyright (C) 2009 by Andrey Afletdinov <fheroes2@gmail.com> * 3 * * 4 * Part of the Free Heroes2 Engine: * 5 * http://sourceforge.net/projects/fheroes2 * 6 * * 7 * This program is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU General Public License as published by * 9 * the Free Software Foundation; either version 2 of the License, or * 10 * (at your option) any later version. * 11 * * 12 * This program is distributed in the hope that it will be useful, * 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 15 * GNU General Public License for more details. * 16 * * 17 * You should have received a copy of the GNU General Public License * 18 * along with this program; if not, write to the * 19 * Free Software Foundation, Inc., * 20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 21 ***************************************************************************/ 22 #ifndef H2TILES_H 23 #define H2TILES_H 24 25 #include <list> 26 27 #include "army_troop.h" 28 #include "artifact.h" 29 #include "color.h" 30 #include "direction.h" 31 #include "mp2.h" 32 #include "resource.h" 33 #include "skill.h" 34 35 class Heroes; 36 class Spell; 37 class Monster; 38 39 namespace MP2 40 { 41 struct mp2tile_t; 42 struct mp2addon_t; 43 } 44 45 namespace Interface 46 { 47 class GameArea; 48 bool SkipRedrawTileBottom4Hero( const uint8_t tileset, const uint8_t icnIndex, const int passable ); 49 } 50 51 namespace Maps 52 { 53 struct TilesAddon 54 { 55 enum level_t : uint8_t 56 { 57 GROUND = 0, 58 DOWN = 1, 59 SHADOW = 2, 60 UPPER = 3 61 }; 62 63 TilesAddon(); 64 TilesAddon( const uint8_t lv, const uint32_t uid, const uint8_t obj, const uint32_t index_ ); 65 TilesAddon( const TilesAddon & ta ); 66 67 ~TilesAddon() = default; 68 69 TilesAddon & operator=( const TilesAddon & ta ) = delete; 70 isUniqTilesAddon71 bool isUniq( const uint32_t id ) const 72 { 73 return uniq == id; 74 } 75 76 bool isRoad() const; 77 bool hasSpriteAnimation() const; 78 79 std::string String( int level ) const; 80 81 static bool isShadow( const TilesAddon & ); 82 83 static bool isResource( const TilesAddon & ); 84 static bool isArtifact( const TilesAddon & ); 85 static bool isFlag32( const TilesAddon & ); 86 87 static bool PredicateSortRules1( const TilesAddon &, const TilesAddon & ); 88 89 uint32_t uniq; 90 uint8_t level; 91 uint8_t object; 92 uint8_t index; 93 }; 94 95 struct Addons : public std::list<TilesAddon> 96 { 97 void Remove( u32 uniq ); 98 }; 99 100 class Tiles 101 { 102 public: 103 Tiles(); 104 105 void Init( s32, const MP2::mp2tile_t & ); 106 GetIndex()107 int32_t GetIndex() const 108 { 109 return _index; 110 } 111 112 fheroes2::Point GetCenter( void ) const; 113 MP2::MapObjectType GetObject( bool ignoreObjectUnderHero = true ) const; 114 uint8_t GetObjectTileset() const; 115 116 uint8_t GetObjectSpriteIndex() const; 117 118 u32 GetObjectUID() const; 119 120 // Get Tile metadata field #1 (used for things like monster count or resource amount) GetQuantity1()121 uint8_t GetQuantity1() const 122 { 123 return quantity1; 124 } 125 126 // Get Tile metadata field #2 (used for things like animations or resource type ) GetQuantity2()127 uint8_t GetQuantity2() const 128 { 129 return quantity2; 130 } 131 132 // Get third field containing Tile metadata (adventure spell ID) GetQuantity3()133 uint8_t GetQuantity3() const 134 { 135 return quantity3; 136 } 137 138 int GetPassable() const; 139 int GetGround() const; 140 bool isWater() const; 141 142 u32 TileSpriteIndex( void ) const; 143 u32 TileSpriteShape( void ) const; 144 145 const fheroes2::Image & GetTileSurface( void ) const; 146 147 bool isObject( const MP2::MapObjectType objectType ) const; 148 bool hasSpriteAnimation() const; 149 bool validateWaterRules( bool fromWater ) const; 150 bool isPassable( int direct, bool fromWater, bool skipfog, const int heroColor ) const; 151 bool isRoad() const; 152 bool isStream( void ) const; 153 bool isShadow() const; 154 bool GoodForUltimateArtifact() const; 155 156 TilesAddon * FindAddonLevel1( u32 uniq1 ); 157 TilesAddon * FindAddonLevel2( u32 uniq2 ); 158 159 void SetTile( u32 sprite_index, u32 shape /* 0: none, 1 : vert, 2: horz, 3: both */ ); 160 void SetObject( const MP2::MapObjectType objectType ); 161 SetIndex(const uint32_t index)162 void SetIndex( const uint32_t index ) 163 { 164 _index = index; 165 } 166 167 void setBoat( int direction ); 168 int getBoatDirection() const; 169 void resetObjectSprite(); 170 171 void FixObject( void ); 172 173 uint32_t GetRegion() const; 174 void UpdateRegion( uint32_t newRegionID ); 175 176 // Set initial passability based on information read from mp2 and addon structures. 177 void setInitialPassability(); 178 179 // Update passability based on neigbhours around. 180 void updatePassability(); 181 182 int getOriginalPassability() const; 183 184 bool isClearGround() const; 185 186 bool doesObjectExist( const uint32_t uid ) const; 187 188 // ICN::FLAGS32 version 189 void CaptureFlags32( const MP2::MapObjectType objectType, int col ); 190 191 // Removes all ICN::FLAGS32 objects from this tile. 192 void removeFlags(); 193 194 void RedrawTile( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 195 static void RedrawEmptyTile( fheroes2::Image & dst, const fheroes2::Point & mp, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ); 196 void RedrawBottom( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, bool isPuzzleDraw, const Interface::GameArea & area ) const; 197 void RedrawBottom4Hero( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 198 void RedrawTop( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const bool isPuzzleDraw, const Interface::GameArea & area ) const; 199 void RedrawTopFromBottom( fheroes2::Image & dst, const Interface::GameArea & area ) const; 200 void RedrawTop4Hero( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, bool skip_ground, const Interface::GameArea & area ) const; 201 void RedrawObjects( fheroes2::Image & dst, bool isPuzzleDraw, const Interface::GameArea & area ) const; 202 void RedrawBoat( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 203 void RedrawBoatShadow( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 204 void RedrawMonster( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 205 int GetFogDirections( int color ) const; 206 void RedrawFogs( fheroes2::Image & dst, int color, const Interface::GameArea & area ) const; 207 void RedrawAddon( fheroes2::Image & dst, const Addons & addon, const fheroes2::Rect & visibleTileROI, bool isPuzzleDraw, const Interface::GameArea & area ) const; 208 void RedrawPassable( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 209 210 void AddonsPushLevel1( const MP2::mp2tile_t & ); 211 void AddonsPushLevel1( const MP2::mp2addon_t & ); 212 void AddonsPushLevel1( const TilesAddon & ); 213 void AddonsPushLevel2( const MP2::mp2tile_t & ); 214 void AddonsPushLevel2( const MP2::mp2addon_t & ); 215 getLevel1Addons()216 const Addons & getLevel1Addons() const 217 { 218 return addons_level1; 219 } 220 getLevel2Addons()221 const Addons & getLevel2Addons() const 222 { 223 return addons_level2; 224 } 225 226 void AddonsSort( void ); 227 void Remove( u32 uniqID ); 228 void RemoveObjectSprite( void ); 229 void UpdateObjectSprite( uint32_t uniqID, uint8_t rawTileset, uint8_t newTileset, int indexChange ); 230 void ReplaceObjectSprite( uint32_t uniqID, uint8_t rawTileset, uint8_t newTileset, uint8_t indexToReplace, uint8_t newIndex ); 231 232 std::string String( void ) const; 233 isFog(const int colors)234 bool isFog( const int colors ) const 235 { 236 // colors may be the union friends 237 return ( fog_colors & colors ) == colors; 238 } 239 240 bool isFogAllAround( const int color ) const; 241 void ClearFog( int color ); 242 243 /* monster operation */ 244 bool MonsterJoinConditionSkip( void ) const; 245 bool MonsterJoinConditionFree( void ) const; 246 int MonsterJoinCondition( void ) const; 247 void MonsterSetJoinCondition( int ); 248 void MonsterSetFixedCount( void ); 249 bool MonsterFixedCount( void ) const; 250 void MonsterSetCount( u32 count ); 251 u32 MonsterCount( void ) const; 252 253 bool CaptureObjectIsProtection( void ) const; 254 255 /* object quantity operation */ 256 void QuantityUpdate( bool isFirstLoad = true ); 257 void QuantityReset( void ); 258 bool QuantityIsValid( void ) const; 259 void QuantitySetColor( int ); 260 int QuantityVariant( void ) const; 261 int QuantityExt( void ) const; 262 int QuantityColor( void ) const; 263 u32 QuantityGold( void ) const; 264 Spell QuantitySpell( void ) const; 265 Skill::Secondary QuantitySkill( void ) const; 266 Artifact QuantityArtifact( void ) const; 267 ResourceCount QuantityResourceCount( void ) const; 268 Funds QuantityFunds( void ) const; 269 Monster QuantityMonster( void ) const; 270 Troop QuantityTroop( void ) const; 271 272 void SetObjectPassable( bool ); 273 274 // Set Tile metadata field (used for things like adventure spell ID) SetQuantity3(const uint8_t value)275 void SetQuantity3( const uint8_t value ) 276 { 277 quantity3 = value; 278 } 279 280 Heroes * GetHeroes( void ) const; 281 void SetHeroes( Heroes * ); 282 283 // If tile is empty (MP2::OBJ_ZERO) then verify whether it is a coast and update the tile if needed. 284 void updateEmpty(); 285 286 // Set tile to coast MP2::OBJ_COAST) if it's near water or to empty (MP2::OBJ_ZERO) 287 void setAsEmpty(); 288 289 uint32_t getObjectIdByICNType( const int icnId ) const; 290 291 std::vector<uint8_t> getValidTileSets() const; 292 293 bool containsTileSet( const std::vector<uint8_t> & tileSets ) const; 294 295 static int ColorFromBarrierSprite( const uint8_t tileset, const uint8_t icnIndex ); 296 static int ColorFromTravellerTentSprite( const uint8_t tileset, const uint8_t icnIndex ); 297 static MP2::MapObjectType GetLoyaltyObject( const uint8_t tileset, const uint8_t icnIndex ); 298 static bool isShadowSprite( const uint8_t tileset, const uint8_t icnIndex ); 299 static bool isShadowSprite( const int tileset, const uint8_t icnIndex ); 300 static void UpdateAbandoneMineLeftSprite( uint8_t & tileset, uint8_t & index, const int resource ); 301 static void UpdateAbandoneMineRightSprite( uint8_t & tileset, uint8_t & index ); 302 static std::pair<int, int> ColorRaceFromHeroSprite( const uint32_t heroSpriteIndex ); 303 static std::pair<uint32_t, uint32_t> GetMonsterSpriteIndices( const Tiles & tile, const uint32_t monsterIndex ); 304 static void PlaceMonsterOnTile( Tiles & tile, const Monster & mons, const uint32_t count ); 305 static void UpdateAbandoneMineSprite( Tiles & tile ); 306 307 // Some tiles have incorrect object type. This is due to original Editor issues. 308 static void fixTileObjectType( Tiles & tile ); 309 310 static int32_t getIndexOfMainTile( const Maps::Tiles & tile ); 311 312 private: 313 TilesAddon * FindFlags( void ); 314 315 // correct flags, ICN::FLAGS32 vesion 316 void CorrectFlags32( const int col, const u32 index, const bool up ); 317 void RemoveJailSprite( void ); 318 319 void QuantitySetVariant( int ); 320 void QuantitySetExt( int ); 321 void QuantitySetSkill( int ); 322 void QuantitySetSpell( int ); 323 void QuantitySetArtifact( int ); 324 void QuantitySetResource( int, u32 ); 325 326 bool isTallObject() const; 327 328 bool isDetachedObject() const; 329 330 static void UpdateMonsterInfo( Tiles & ); 331 static void UpdateDwellingPopulation( Tiles & tile, bool isFirstLoad ); 332 static void UpdateMonsterPopulation( Tiles & ); 333 static void UpdateRNDArtifactSprite( Tiles & ); 334 static void UpdateRNDResourceSprite( Tiles & ); 335 336 static void updateTileById( Maps::Tiles & tile, const uint32_t uid, const uint8_t newIndex ); 337 338 friend StreamBase & operator<<( StreamBase &, const Tiles & ); 339 friend StreamBase & operator>>( StreamBase &, Tiles & ); 340 341 friend bool operator<( const Tiles & l, const Tiles & r ) 342 { 343 return l.GetIndex() < r.GetIndex(); 344 } 345 346 Addons addons_level1; 347 Addons addons_level2; // 16 348 349 int32_t _index = 0; 350 uint16_t pack_sprite_index = 0; 351 352 uint32_t uniq = 0; 353 uint8_t objectTileset = 0; 354 uint8_t objectIndex = 255; 355 uint8_t mp2_object = 0; 356 uint16_t tilePassable = DIRECTION_ALL; 357 uint8_t fog_colors = Color::ALL; 358 359 uint8_t heroID = 0; 360 uint8_t quantity1 = 0; 361 uint8_t quantity2 = 0; 362 uint8_t quantity3 = 0; 363 364 bool tileIsRoad = false; 365 366 // This field does not persist in savegame. 367 uint32_t _region = 0; 368 369 uint8_t _level = 0; 370 }; 371 372 StreamBase & operator<<( StreamBase &, const TilesAddon & ); 373 StreamBase & operator<<( StreamBase &, const Tiles & ); 374 StreamBase & operator>>( StreamBase &, TilesAddon & ); 375 StreamBase & operator>>( StreamBase &, Tiles & ); 376 } 377 378 #endif 379