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 23 #ifndef H2HEROES_H 24 #define H2HEROES_H 25 26 #include <algorithm> 27 #include <list> 28 #include <string> 29 #include <vector> 30 31 #include "army.h" 32 #include "heroes_base.h" 33 #include "pairs.h" 34 #include "route.h" 35 #include "visit.h" 36 37 namespace Battle 38 { 39 class Only; 40 } 41 42 namespace Interface 43 { 44 class GameArea; 45 } 46 47 class StreamBuf; 48 49 struct HeroSeedsForLevelUp 50 { 51 uint32_t seedPrimarySkill = 0; 52 uint32_t seedSecondaySkill1 = 0; 53 uint32_t seedSecondaySkill2 = 0; 54 uint32_t seedSecondaySkillRandomChoose = 0; 55 }; 56 57 class Heroes : public HeroBase, public ColorBase 58 { 59 public: 60 enum 61 { 62 // knight 63 LORDKILBURN, 64 SIRGALLANTH, 65 ECTOR, 66 GVENNETH, 67 TYRO, 68 AMBROSE, 69 RUBY, 70 MAXIMUS, 71 DIMITRY, 72 // barbarian 73 THUNDAX, 74 FINEOUS, 75 JOJOSH, 76 CRAGHACK, 77 JEZEBEL, 78 JACLYN, 79 ERGON, 80 TSABU, 81 ATLAS, 82 // sorceress 83 ASTRA, 84 NATASHA, 85 TROYAN, 86 VATAWNA, 87 REBECCA, 88 GEM, 89 ARIEL, 90 CARLAWN, 91 LUNA, 92 // warlock 93 ARIE, 94 ALAMAR, 95 VESPER, 96 CRODO, 97 BAROK, 98 KASTORE, 99 AGAR, 100 FALAGAR, 101 WRATHMONT, 102 // wizard 103 MYRA, 104 FLINT, 105 DAWN, 106 HALON, 107 MYRINI, 108 WILFREY, 109 SARAKIN, 110 KALINDRA, 111 MANDIGAL, 112 // necromancer 113 ZOM, 114 DARLANA, 115 ZAM, 116 RANLOO, 117 CHARITY, 118 RIALDO, 119 ROXANA, 120 SANDRO, 121 CELIA, 122 // From The Succession Wars campaign. 123 ROLAND, 124 CORLAGON, 125 ELIZA, 126 ARCHIBALD, 127 HALTON, 128 BAX, 129 // From The Price of Loyalty expansion. 130 SOLMYR, 131 DAINWIN, 132 MOG, 133 UNCLEIVAN, 134 JOSEPH, 135 GALLAVANT, 136 ELDERIAN, 137 CEALLACH, 138 DRAKONIA, 139 MARTINE, 140 JARKONAS, 141 // debugger 142 DEBUG_HERO, 143 UNKNOWN 144 }; 145 146 static const fheroes2::Sprite & GetPortrait( int heroid, int type ); 147 static const char * GetName( int heroid ); 148 149 enum flags_t 150 { 151 SHIPMASTER = 0x00000001, 152 // UNUSED = 0x00000002, 153 SPELLCASTED = 0x00000004, 154 ENABLEMOVE = 0x00000008, 155 // UNUSED = 0x00000010, 156 // UNUSED = 0x00000020, 157 // UNUSED = 0x00000040, 158 JAIL = 0x00000080, 159 ACTION = 0x00000100, 160 SAVE_MP_POINTS = 0x00000200, 161 SLEEPER = 0x00000400, 162 GUARDIAN = 0x00000800, 163 NOTDEFAULTS = 0x00001000, 164 NOTDISMISS = 0x00002000, 165 VISIONS = 0x00004000, 166 PATROL = 0x00008000, 167 CUSTOMARMY = 0x00010000, 168 CUSTOMSKILLS = 0x00020000, 169 SKIPPED_TURN = 0x00040000, 170 WAITING = 0x00080000, 171 MOVED = 0x00100000 172 }; 173 174 // Types of heroes. Used only for AI as humans are smart enough to manage heroes by themselves. 175 enum class Role : int 176 { 177 // The most ordinary hero's role with no any specialization. This type does eveything what a hero can do: 178 // collecting resources, fighting (mostly weak) monsters, claiming towns and mines and expanding the visible territory. 179 HUNTER, 180 181 // The type of hero with a skew towards fights. His main priority is to kill monsters and enemies, capture castles and guarded mines. 182 // This type still can capture valuable mines or dwellings if they're on the way to something better. 183 FIGHTER, 184 185 // The main goal for Scout is to discover new areas so he should run towards the fog of war to expand the visible territory. 186 // These heroes usually appear when either no tasks exist on the map or when AI has too many heroes. 187 SCOUT, 188 189 // Courier's life is to deliver things from one place to another. Usually they bring an army for Fighters or Champions from 190 // dwellings, castles or from one hero to another. 191 COURIER, 192 193 // The mightiest hero among others. The main purpose of this type is to run over the enemy's territory and defeat all heroes there while 194 // capturing all castles and towns. This type of hero is set when one (or few) heroes are too strong in comparison to others. 195 CHAMPION 196 }; 197 198 struct RedrawIndex 199 { 200 int32_t topOnBottom = -1; 201 int32_t topOnDirectionBottom = -1; 202 int32_t topOnDirection = -1; 203 int32_t objectsOnBottom = -1; 204 int32_t objectsOnDirectionBottom = -1; 205 }; 206 207 Heroes(); 208 Heroes( int heroid, int rc ); 209 Heroes( int heroID, int race, int initialLevel ); 210 211 bool isValid() const override; 212 bool isFreeman( void ) const; 213 void SetFreeman( int reason ); 214 215 const Castle * inCastle() const override; 216 Castle * inCastleMutable() const; 217 218 void LoadFromMP2( s32 map_index, int cl, int rc, StreamBuf ); 219 void PostLoad( void ); 220 221 int GetRace() const override; 222 const std::string & GetName() const override; 223 int GetColor() const override; 224 int GetType() const override; 225 int GetControl() const override; 226 227 int GetKillerColor( void ) const; 228 void SetKillerColor( int ); 229 230 const Army & GetArmy() const override; 231 Army & GetArmy() override; 232 233 int GetID( void ) const; 234 235 double getMeetingValue( const Heroes & otherHero ) const; 236 double getRecruitValue() const; 237 int getStatsValue() const; 238 239 int GetAttack() const override; 240 int GetDefense() const override; 241 int GetPower() const override; 242 int GetKnowledge() const override; 243 244 int GetAttack( std::string * ) const; 245 int GetDefense( std::string * ) const; 246 int GetPower( std::string * ) const; 247 int GetKnowledge( std::string * ) const; 248 249 void IncreasePrimarySkill( int skill ); 250 251 int GetMorale() const override; 252 int GetLuck() const override; 253 int GetMoraleWithModificators( std::string * str = nullptr ) const; 254 int GetLuckWithModificators( std::string * str = nullptr ) const; 255 int GetLevel( void ) const; 256 257 MP2::MapObjectType GetMapsObject() const; 258 void SetMapsObject( const MP2::MapObjectType objectType ); 259 260 const fheroes2::Point & GetCenterPatrol( void ) const; 261 void SetCenterPatrol( const fheroes2::Point & ); 262 int GetSquarePatrol( void ) const; 263 264 u32 GetMaxSpellPoints() const override; 265 u32 GetMaxMovePoints() const; 266 267 u32 GetMovePoints( void ) const; 268 void IncreaseMovePoints( u32 ); 269 bool MayStillMove( const bool ignorePath, const bool ignoreSleeper ) const; 270 void ResetMovePoints( void ); 271 void MovePointsScaleFixed( void ); 272 273 bool HasSecondarySkill( int ) const; 274 bool HasMaxSecondarySkill( void ) const; 275 int GetLevelSkill( int ) const override; 276 u32 GetSecondaryValues( int ) const override; 277 void LearnSkill( const Skill::Secondary & ); 278 Skill::SecSkills & GetSecondarySkills( void ); 279 280 bool PickupArtifact( const Artifact & ); 281 bool HasUltimateArtifact( void ) const; 282 u32 GetCountArtifacts( void ) const; 283 bool IsFullBagArtifacts( void ) const; 284 285 int GetMobilityIndexSprite( void ) const; 286 287 // Returns the relative height of mana column near hero's portrait in heroes panel. Returned value will be in range [0; 25]. 288 int GetManaIndexSprite( void ) const; 289 290 int OpenDialog( bool readonly = false, bool fade = false, bool disableDismiss = false, bool disableSwitch = false ); 291 void MeetingDialog( Heroes & ); 292 293 bool Recruit( int col, const fheroes2::Point & pt ); 294 bool Recruit( const Castle & castle ); 295 296 void ActionNewDay( void ); 297 void ActionNewWeek( void ); 298 void ActionNewMonth( void ); 299 void ActionAfterBattle() override; 300 void ActionPreBattle() override; 301 302 bool BuySpellBook( const Castle *, int shrine = 0 ); 303 304 const Route::Path & GetPath() const; 305 Route::Path & GetPath(); 306 int GetRangeRouteDays( s32 ) const; 307 void ShowPath( bool ); 308 void RescanPath(); 309 void RescanPathPassable(); 310 311 int GetDirection() const; 312 void setDirection( int directionToSet ); 313 314 // set visited cell 315 void SetVisited( s32, Visit::type_t = Visit::LOCAL ); 316 317 // Set global visited state for itself and for allies. 318 void setVisitedForAllies( const int32_t tileIndex ) const; 319 320 void SetVisitedWideTile( s32, const MP2::MapObjectType objectType, Visit::type_t = Visit::LOCAL ); 321 bool isObjectTypeVisited( const MP2::MapObjectType object, Visit::type_t = Visit::LOCAL ) const; 322 bool isVisited( const Maps::Tiles &, Visit::type_t = Visit::LOCAL ) const; 323 324 // These methods are used only for AI. 325 bool hasMetWithHero( int heroID ) const; 326 void markHeroMeeting( int heroID ); 327 void unmarkHeroMeeting(); 328 329 bool Move( bool fast = false ); 330 void Move2Dest( const int32_t destination ); 331 bool isMoveEnabled( void ) const; 332 bool CanMove( void ) const; 333 void SetMove( bool ); 334 bool isAction( void ) const; 335 void ResetAction( void ); 336 void Action( int tileIndex, bool isDestination ); 337 void ActionNewPosition( const bool allowMonsterAttack ); 338 void ApplyPenaltyMovement( uint32_t penalty ); 339 bool ActionSpellCast( const Spell & ); 340 341 bool MayCastAdventureSpells() const; 342 343 const RedrawIndex & GetRedrawIndex() const; 344 void SetRedrawIndexes(); 345 void UpdateRedrawTop( const Maps::Tiles & tile ); 346 void UpdateRedrawBottom( const Maps::Tiles & tile ); 347 void RedrawTop( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 348 void RedrawBottom( fheroes2::Image & dst, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area, bool isPuzzleDraw ) const; 349 void Redraw( fheroes2::Image & dst, const int32_t dx, int32_t dy, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 350 void RedrawShadow( fheroes2::Image & dst, const int32_t dx, int32_t dy, const fheroes2::Rect & visibleTileROI, const Interface::GameArea & area ) const; 351 352 void PortraitRedraw( const int32_t px, const int32_t py, const PortraitType type, fheroes2::Image & dstsf ) const override; 353 int GetSpriteIndex( void ) const; 354 355 // These 2 methods must be used only for hero's animation. Please never use them anywhere else! 356 void SetSpriteIndex( int index ); 357 void SetOffset( const fheroes2::Point & offset ); 358 359 void FadeOut( const fheroes2::Point & offset = fheroes2::Point() ) const; 360 void FadeIn( const fheroes2::Point & offset = fheroes2::Point() ) const; 361 void Scoute( const int tileIndex ) const; 362 int GetScoute( void ) const; 363 u32 GetVisionsDistance( void ) const; 364 365 bool isShipMaster( void ) const; 366 void SetShipMaster( bool ); 367 uint32_t lastGroundRegion() const; 368 void setLastGroundRegion( uint32_t regionID ); 369 370 u32 GetExperience( void ) const; 371 void IncreaseExperience( const uint32_t amount, const bool autoselect = false ); 372 373 std::string String( void ) const; 374 const fheroes2::Sprite & GetPortrait( int type ) const; 375 376 static int GetLevelFromExperience( u32 ); 377 static u32 GetExperienceFromLevel( int ); 378 379 static void ScholarAction( Heroes &, Heroes & ); 380 381 fheroes2::Point MovementDirection() const; 382 383 int GetAttackedMonsterTileIndex() const; 384 void SetAttackedMonsterTileIndex( int idx ); 385 setAIRole(const Role role)386 void setAIRole( const Role role ) 387 { 388 _aiRole = role; 389 } 390 getAIRole()391 Role getAIRole() const 392 { 393 return _aiRole; 394 } 395 396 private: 397 friend StreamBase & operator<<( StreamBase &, const Heroes & ); 398 friend StreamBase & operator>>( StreamBase &, Heroes & ); 399 400 friend class Recruits; 401 friend class Battle::Only; 402 403 HeroSeedsForLevelUp GetSeedsForLevelUp() const; 404 void LevelUp( bool skipsecondary, bool autoselect = false ); 405 void LevelUpSecondarySkill( const HeroSeedsForLevelUp & seeds, int primary, bool autoselect = false ); 406 void AngleStep( int ); 407 bool MoveStep( bool fast = false ); 408 static void MoveStep( Heroes &, s32 to, bool newpos ); 409 static uint32_t GetStartingXp(); 410 bool isInVisibleMapArea() const; 411 412 // This function is useful only in a situation when AI hero moves out of the fog 413 // we don't update his direction during movement under the fog so there is a situation 414 // when initial hero's sprite is set incorrectly. This function fixes it 415 void SetValidDirectionSprite(); 416 417 uint32_t UpdateMovementPoints( const uint32_t movePoints, const int skill ) const; 418 419 // Daily replenishment of spell points 420 void ReplenishSpellPoints(); 421 422 bool isInDeepOcean() const; 423 424 enum 425 { 426 SKILL_VALUE = 100 427 }; 428 429 std::string name; 430 ColorBase killer_color; 431 u32 experience; 432 s32 move_point_scale; 433 434 Skill::SecSkills secondary_skills; 435 436 Army army; 437 438 int hid; /* hero id */ 439 int portrait; /* hero id */ 440 int _race; 441 int save_maps_object; 442 443 Route::Path path; 444 445 int direction; 446 int sprite_index; 447 fheroes2::Point _offset; // used only during hero's movement 448 449 fheroes2::Point patrol_center; 450 int patrol_square; 451 452 std::list<IndexObject> visit_object; 453 uint32_t _lastGroundRegion = 0; 454 455 RedrawIndex _redrawIndex; 456 457 mutable int _alphaValue; 458 459 int _attackedMonsterTileIndex; // used only when hero attacks a group of wandering monsters 460 461 // This value should NOT be saved in save file as it's dynamically set during AI turn. 462 Role _aiRole; 463 464 enum 465 { 466 HERO_MOVE_STEP = 4 // in pixels 467 }; 468 }; 469 470 struct VecHeroes : public std::vector<Heroes *> 471 { 472 Heroes * Get( int /* hero id */ ) const; 473 Heroes * Get( const fheroes2::Point & ) const; 474 }; 475 476 struct AllHeroes : public VecHeroes 477 { 478 AllHeroes(); 479 AllHeroes( const AllHeroes & ) = delete; 480 481 ~AllHeroes(); 482 483 AllHeroes & operator=( const AllHeroes & ) = delete; 484 485 void Init( void ); 486 void clear( void ); 487 488 void Scoute( int ) const; 489 NewDayAllHeroes490 void NewDay() 491 { 492 std::for_each( begin(), end(), []( Heroes * hero ) { hero->ActionNewDay(); } ); 493 } 494 NewWeekAllHeroes495 void NewWeek() 496 { 497 std::for_each( begin(), end(), []( Heroes * hero ) { hero->ActionNewWeek(); } ); 498 } 499 NewMonthAllHeroes500 void NewMonth() 501 { 502 std::for_each( begin(), end(), []( Heroes * hero ) { hero->ActionNewMonth(); } ); 503 } 504 505 Heroes * GetGuest( const Castle & ) const; 506 Heroes * GetGuard( const Castle & ) const; 507 Heroes * GetFreeman( int race ) const; 508 Heroes * FromJail( s32 ) const; 509 Heroes * GetFreemanSpecial( int heroID ) const; 510 511 bool HaveTwoFreemans( void ) const; 512 }; 513 514 StreamBase & operator<<( StreamBase &, const VecHeroes & ); 515 StreamBase & operator>>( StreamBase &, VecHeroes & ); 516 517 StreamBase & operator<<( StreamBase &, const Heroes & ); 518 StreamBase & operator>>( StreamBase &, Heroes & ); 519 520 StreamBase & operator<<( StreamBase &, const AllHeroes & ); 521 StreamBase & operator>>( StreamBase &, AllHeroes & ); 522 523 #endif 524