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