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 H2CASTLE_H 23 #define H2CASTLE_H 24 25 #include <algorithm> 26 #include <map> 27 #include <string> 28 #include <vector> 29 30 #include "army.h" 31 #include "bitmodes.h" 32 #include "captain.h" 33 #include "castle_heroes.h" 34 #include "mageguild.h" 35 #include "position.h" 36 #include "ui_button.h" 37 38 namespace fheroes2 39 { 40 class RandomMonsterAnimation; 41 } 42 43 class Heroes; 44 45 enum building_t : uint32_t 46 { 47 BUILD_NOTHING = 0x00000000, 48 BUILD_THIEVESGUILD = 0x00000001, 49 BUILD_TAVERN = 0x00000002, 50 BUILD_SHIPYARD = 0x00000004, 51 BUILD_WELL = 0x00000008, 52 BUILD_STATUE = 0x00000010, 53 BUILD_LEFTTURRET = 0x00000020, 54 BUILD_RIGHTTURRET = 0x00000040, 55 BUILD_MARKETPLACE = 0x00000080, 56 BUILD_WEL2 = 0x00000100, // Farm, Garbage He, Crystal Gar, Waterfall, Orchard, Skull Pile 57 BUILD_MOAT = 0x00000200, 58 BUILD_SPEC = 0x00000400, // Fortification, Coliseum, Rainbow, Dungeon, Library, Storm 59 BUILD_CASTLE = 0x00000800, 60 BUILD_CAPTAIN = 0x00001000, 61 BUILD_SHRINE = 0x00002000, 62 BUILD_MAGEGUILD1 = 0x00004000, 63 BUILD_MAGEGUILD2 = 0x00008000, 64 BUILD_MAGEGUILD3 = 0x00010000, 65 BUILD_MAGEGUILD4 = 0x00020000, 66 BUILD_MAGEGUILD5 = 0x00040000, 67 BUILD_MAGEGUILD = BUILD_MAGEGUILD1 | BUILD_MAGEGUILD2 | BUILD_MAGEGUILD3 | BUILD_MAGEGUILD4 | BUILD_MAGEGUILD5, 68 BUILD_TENT = 0x00080000, // deprecated 69 DWELLING_MONSTER1 = 0x00100000, 70 DWELLING_MONSTER2 = 0x00200000, 71 DWELLING_MONSTER3 = 0x00400000, 72 DWELLING_MONSTER4 = 0x00800000, 73 DWELLING_MONSTER5 = 0x01000000, 74 DWELLING_MONSTER6 = 0x02000000, 75 DWELLING_MONSTERS = DWELLING_MONSTER1 | DWELLING_MONSTER2 | DWELLING_MONSTER3 | DWELLING_MONSTER4 | DWELLING_MONSTER5 | DWELLING_MONSTER6, 76 DWELLING_UPGRADE2 = 0x04000000, 77 DWELLING_UPGRADE3 = 0x08000000, 78 DWELLING_UPGRADE4 = 0x10000000, 79 DWELLING_UPGRADE5 = 0x20000000, 80 DWELLING_UPGRADE6 = 0x40000000, 81 DWELLING_UPGRADE7 = 0x80000000, // black dragon 82 DWELLING_UPGRADES = DWELLING_UPGRADE2 | DWELLING_UPGRADE3 | DWELLING_UPGRADE4 | DWELLING_UPGRADE5 | DWELLING_UPGRADE6 | DWELLING_UPGRADE7 83 }; 84 85 enum buildcond_t 86 { 87 NOT_TODAY = -1, 88 ALREADY_BUILT = -2, 89 NEED_CASTLE = -3, 90 BUILD_DISABLE = -4, 91 UNKNOWN_UPGRADE = -5, 92 REQUIRES_BUILD = -6, 93 LACK_RESOURCES = -7, 94 UNKNOWN_COND = 0, 95 ALLOW_BUILD = 1 96 }; 97 98 class Castle : public MapPosition, public BitModes, public ColorBase, public Control 99 { 100 public: 101 enum flags_t 102 { 103 ALLOWCASTLE = 0x0002, 104 CUSTOMARMY = 0x0004, 105 ALLOWBUILD = 0x0008, 106 // UNUSED = 0x0010, 107 CAPITAL = 0x0020 108 }; 109 110 enum class CastleDialogReturnValue : int 111 { 112 DoNothing, 113 Close, // Close the dialog. 114 NextCastle, // Open main dialog of the next castle. 115 PreviousCastle, // Open main dialog of the previous castle. 116 NextCostructionWindow, // Open construction dialog of the next castle. 117 PreviousCostructionWindow // Open construction dialog of the previous castle. 118 }; 119 120 Castle(); 121 Castle( s32, s32, int rs ); 122 ~Castle() override = default; 123 124 void LoadFromMP2( std::vector<uint8_t> & data ); 125 126 Captain & GetCaptain( void ); 127 const Captain & GetCaptain( void ) const; 128 129 bool isCastle( void ) const; 130 bool isCapital( void ) const; 131 bool HaveNearlySea( void ) const; 132 bool PresentBoat( void ) const; 133 bool AllowBuyHero( const Heroes &, std::string * = nullptr ) const; 134 bool isPosition( const fheroes2::Point & ) const; 135 bool isNecromancyShrineBuild( void ) const; 136 137 u32 CountBuildings( void ) const; 138 139 Heroes * RecruitHero( Heroes * ); 140 CastleHeroes GetHeroes( void ) const; 141 142 int GetRace( void ) const; 143 144 const std::string & GetName() const; 145 146 // This method must be called only at the time of map loading and only for castles with empty names. 147 void setName( const std::set<std::string> & usedNames ); 148 149 int GetControl( void ) const override; 150 151 int GetLevelMageGuild( void ) const; 152 const MageGuild & GetMageGuild( void ) const; 153 bool HaveLibraryCapability( void ) const; 154 bool isLibraryBuild( void ) const; 155 void MageGuildEducateHero( HeroBase & ) const; 156 157 bool isFortificationBuild() const; 158 159 const Army & GetArmy( void ) const; 160 Army & GetArmy( void ); 161 const Army & GetActualArmy( void ) const; 162 Army & GetActualArmy( void ); 163 double GetGarrisonStrength( const Heroes * attackingHero ) const; 164 u32 getMonstersInDwelling( u32 ) const; 165 u32 GetActualDwelling( u32 ) const; 166 167 bool RecruitMonsterFromDwelling( uint32_t dw, uint32_t count, bool force = false ); 168 bool RecruitMonster( const Troop & troop, bool showDialog = true ); 169 void recruitBestAvailable( Funds budget ); 170 uint32_t getRecruitLimit( const Monster & monster, const Funds & budget ) const; 171 172 int getBuildingValue() const; 173 174 // Used only for AI. 175 double getVisitValue( const Heroes & hero ) const; 176 177 void ChangeColor( int ); 178 179 void ActionNewDay( void ); 180 void ActionNewWeek( void ); 181 void ActionNewMonth( void ); 182 void ActionPreBattle( void ); 183 void ActionAfterBattle( bool attacker_wins ); 184 185 void DrawImageCastle( const fheroes2::Point & pt ) const; 186 187 CastleDialogReturnValue OpenDialog( const bool readOnly, const bool openConstructionWindow ); 188 189 int GetAttackModificator( const std::string * ) const; 190 int GetDefenseModificator( const std::string * ) const; 191 int GetPowerModificator( std::string * ) const; 192 int GetKnowledgeModificator( const std::string * ) const; 193 int GetMoraleModificator( std::string * ) const; 194 int GetLuckModificator( std::string * ) const; 195 196 bool AllowBuyBuilding( u32 ) const; 197 bool isBuild( u32 bd ) const; 198 bool BuyBuilding( u32 ); 199 bool AllowBuyBoat( void ) const; 200 bool BuyBoat( void ) const; 201 u32 GetBuildingRequirement( u32 ) const; 202 203 int CheckBuyBuilding( u32 ) const; 204 static int GetAllBuildingStatus( const Castle & ); 205 206 void Scoute( void ) const; 207 208 std::string GetStringBuilding( u32 ) const; 209 std::string GetDescriptionBuilding( u32 ) const; 210 211 static const char * GetStringBuilding( u32, int race ); 212 static const char * GetDescriptionBuilding( u32, int race ); 213 214 static int GetICNBuilding( u32, int race ); 215 static int GetICNBoat( int race ); 216 u32 GetUpgradeBuilding( u32 ) const; 217 218 static bool PredicateIsCastle( const Castle * ); 219 static bool PredicateIsTown( const Castle * ); 220 static bool PredicateIsBuildBuilding( const Castle * castle, const uint32_t building ); 221 222 static u32 GetGrownWell( void ); 223 static u32 GetGrownWel2( void ); 224 static u32 GetGrownWeekOf(); 225 static u32 GetGrownMonthOf( void ); 226 227 std::string String( void ) const; 228 229 int DialogBuyHero( const Heroes * ) const; 230 int DialogBuyCastle( bool fixed = true ) const; 231 232 void SwapCastleHeroes( CastleHeroes & ); 233 234 private: 235 enum class ConstructionDialogResult : int 236 { 237 DoNothing, 238 NextConstructionWindow, // Open construction dialog for the next castle. 239 PrevConstructionWindow, // Open construction dialog for the previous castle. 240 Build, // Build something. 241 RecruitHero // Recruit a hero. 242 }; 243 244 u32 * GetDwelling( u32 dw ); 245 void EducateHeroes( void ); 246 247 ConstructionDialogResult openConstructionDialog( uint32_t & dwellingTobuild ); 248 249 void OpenTavern( void ) const; 250 void OpenWell( void ); 251 void OpenMageGuild( const CastleHeroes & heroes ) const; 252 void WellRedrawInfoArea( const fheroes2::Point & cur_pt, const std::vector<fheroes2::RandomMonsterAnimation> & monsterAnimInfo ) const; 253 void JoinRNDArmy( void ); 254 void PostLoad( void ); 255 256 friend StreamBase & operator<<( StreamBase &, const Castle & ); 257 friend StreamBase & operator>>( StreamBase &, Castle & ); 258 259 int race; 260 u32 building; 261 Captain captain; 262 263 std::string name; 264 265 MageGuild mageguild; 266 u32 dwelling[CASTLEMAXMONSTER]; 267 Army army; 268 }; 269 270 namespace CastleDialog 271 { 272 // Class used for fading animation 273 class FadeBuilding 274 { 275 public: FadeBuilding()276 FadeBuilding() 277 : _alpha( 255 ) 278 , _build( BUILD_NOTHING ) 279 {} 280 281 void StartFadeBuilding( const uint32_t build ); 282 283 bool UpdateFadeBuilding(); 284 IsFadeDone()285 bool IsFadeDone() const 286 { 287 return _alpha == 255; 288 } 289 290 void StopFadeBuilding(); 291 GetAlpha()292 uint8_t GetAlpha() const 293 { 294 return _alpha; 295 } 296 GetBuild()297 uint32_t GetBuild() const 298 { 299 return _build; 300 } 301 302 private: 303 uint8_t _alpha; 304 uint32_t _build; 305 }; 306 307 struct builds_t 308 { builds_tbuilds_t309 builds_t( building_t b, const fheroes2::Rect & r ) 310 : id( b ) 311 , coord( r ) 312 {} 313 314 bool operator==( u32 b ) const 315 { 316 return b == static_cast<uint32_t>( id ); 317 } 318 319 building_t id; 320 fheroes2::Rect coord; 321 }; 322 323 struct CacheBuildings : std::vector<builds_t> 324 { 325 CacheBuildings( const Castle &, const fheroes2::Point & ); 326 }; 327 328 void RedrawAllBuilding( const Castle & castle, const fheroes2::Point & dst_pt, const CacheBuildings & orders, const CastleDialog::FadeBuilding & alphaBuilding, 329 const uint32_t animationIndex ); 330 void RedrawBuildingSpriteToArea( const fheroes2::Sprite &, s32, s32, const fheroes2::Rect &, uint8_t alpha = 255 ); 331 332 void CastleRedrawBuilding( const Castle &, const fheroes2::Point &, u32 build, u32 frame, uint8_t alpha = 255 ); 333 void CastleRedrawBuildingExtended( const Castle &, const fheroes2::Point &, u32 build, u32 frame, uint8_t alpha = 255 ); 334 } 335 336 struct VecCastles : public std::vector<Castle *> 337 { 338 Castle * GetFirstCastle( void ) const; 339 340 void ChangeColors( int, int ); 341 void SortByBuildingValue(); 342 }; 343 344 class AllCastles 345 { 346 public: 347 AllCastles(); 348 AllCastles( AllCastles & ) = delete; 349 350 ~AllCastles(); 351 352 AllCastles & operator=( const AllCastles & ) = delete; 353 354 void Init( void ); 355 void Clear( void ); 356 357 void AddCastle( Castle * castle ); 358 359 Castle * Get( const fheroes2::Point & position ) const; 360 361 void Scoute( int ) const; 362 NewDay()363 void NewDay() 364 { 365 std::for_each( _castles.begin(), _castles.end(), []( Castle * castle ) { castle->ActionNewDay(); } ); 366 } 367 NewWeek()368 void NewWeek() 369 { 370 std::for_each( _castles.begin(), _castles.end(), []( Castle * castle ) { castle->ActionNewWeek(); } ); 371 } 372 NewMonth()373 void NewMonth() 374 { 375 std::for_each( _castles.begin(), _castles.end(), []( Castle * castle ) { castle->ActionNewMonth(); } ); 376 } 377 378 // begin/end methods so we can iterate through the elements begin()379 std::vector<Castle *>::const_iterator begin() const 380 { 381 return _castles.begin(); 382 } 383 end()384 std::vector<Castle *>::const_iterator end() const 385 { 386 return _castles.end(); 387 } 388 Size()389 size_t Size() const 390 { 391 return _castles.size(); 392 } 393 394 private: 395 std::vector<Castle *> _castles; 396 std::map<fheroes2::Point, size_t> _castleTiles; 397 }; 398 399 StreamBase & operator<<( StreamBase &, const VecCastles & ); 400 StreamBase & operator>>( StreamBase &, VecCastles & ); 401 402 StreamBase & operator<<( StreamBase &, const AllCastles & ); 403 StreamBase & operator>>( StreamBase &, AllCastles & ); 404 405 StreamBase & operator<<( StreamBase &, const Castle & ); 406 StreamBase & operator>>( StreamBase &, Castle & ); 407 408 #endif 409