1 /***************************************************************************
2  *   Copyright (C) 2010 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 H2BATTLE_TROOP_H
24 #define H2BATTLE_TROOP_H
25 
26 #include <utility>
27 #include <vector>
28 
29 #include "army_troop.h"
30 #include "battle_animation.h"
31 #include "battle_cell.h"
32 #include "bitmodes.h"
33 #include "players.h"
34 
35 class Spell;
36 class HeroBase;
37 
38 namespace Rand
39 {
40     class DeterministicRandomGenerator;
41 }
42 
43 namespace Battle
44 {
45     struct TargetInfo;
46 
47     struct ModeDuration : public std::pair<u32, u32>
48     {
49         ModeDuration( u32, u32 );
50 
51         bool isMode( u32 ) const;
52         bool isZeroDuration( void ) const;
53         void DecreaseDuration( void );
54     };
55 
56     struct ModesAffected : public std::vector<ModeDuration>
57     {
58         ModesAffected();
59 
60         u32 GetMode( u32 ) const;
61         void AddMode( u32, u32 );
62         void RemoveMode( u32 );
63         void DecreaseDuration( void );
64 
65         u32 FindZeroDuration( void ) const;
66     };
67 
68     enum
69     {
70         CONTOUR_MAIN = 0,
71         CONTOUR_REFLECT = 0x01
72     };
73 
74     // battle troop stats
75     class Unit : public ArmyTroop, public BitModes, public Control
76     {
77     public:
78         Unit( const Troop &, int32_t pos, bool reflect, const Rand::DeterministicRandomGenerator & randomGenerator, const uint32_t uid );
79         Unit( const Unit & ) = default;
80 
81         ~Unit() override;
82 
83         Unit & operator=( const Unit & ) = delete;
84 
85         bool isModes( u32 ) const override;
86         bool isBattle() const override;
87         std::string GetShotString() const override;
88         std::string GetSpeedString() const override;
89         u32 GetHitPointsLeft() const override;
90         virtual uint32_t GetMissingHitPoints() const;
91         u32 GetAffectedDuration( u32 ) const override;
92         u32 GetSpeed() const override;
93         int GetMorale() const override;
94 
95         Unit * GetMirror();
96         void SetMirror( Unit * );
97         void SetRandomMorale( void );
98         void SetRandomLuck( void );
99         void NewTurn( void );
100 
101         bool isValid() const override;
102         bool isArchers( void ) const;
103         bool isFlying( void ) const;
104         bool isTwiceAttack( void ) const;
105 
106         bool AllowResponse( void ) const;
107         bool isHandFighting( void ) const;
108         bool isReflect( void ) const;
109         bool isHaveDamage( void ) const;
110         bool isMagicResist( const Spell &, u32 ) const;
111         bool OutOfWalls( void ) const;
112         bool canReach( int index ) const;
113         bool canReach( const Unit & unit ) const;
114 
115         std::string String( bool more = false ) const;
116 
117         u32 GetUID( void ) const;
118         bool isUID( u32 ) const;
119 
120         s32 GetHeadIndex( void ) const;
121         s32 GetTailIndex( void ) const;
122         const Position & GetPosition( void ) const;
123         void SetPosition( s32 );
124         void SetPosition( const Position & );
125         void SetReflection( bool );
126 
127         u32 GetAttack() const override;
128         u32 GetDefense() const override;
129         int GetArmyColor( void ) const;
130         int GetColor() const override;
131         int GetCurrentColor() const; // the unit can be under spell what changes its affiliation
132         int GetCurrentOrArmyColor() const; // current unit color (if valid), color of the unit's army otherwise
133         int GetCurrentControl() const;
134         uint32_t GetMoveRange() const;
135         u32 GetSpeed( bool skipStandingCheck, bool skipMovedCheck ) const;
136         int GetControl() const override;
137         u32 GetDamage( const Unit & ) const;
138         s32 GetScoreQuality( const Unit & ) const;
139         uint32_t GetInitialCount() const;
140         u32 GetDead( void ) const;
141         u32 GetHitPoints( void ) const;
142         u32 GetShots( void ) const;
143         u32 ApplyDamage( Unit &, u32 );
144         u32 ApplyDamage( u32 );
145         uint32_t CalculateRetaliationDamage( uint32_t damageTaken ) const;
146         u32 CalculateMinDamage( const Unit & ) const;
147         u32 CalculateMaxDamage( const Unit & ) const;
148         u32 CalculateDamageUnit( const Unit & enemy, double dmg ) const;
149         bool ApplySpell( const Spell &, const HeroBase * hero, TargetInfo & );
150         bool AllowApplySpell( const Spell &, const HeroBase * hero, std::string * msg = nullptr, bool forceApplyToAlly = false ) const;
151         bool isUnderSpellEffect( const Spell & spell ) const;
152         std::vector<Spell> getCurrentSpellEffects() const;
153         void PostAttackAction();
154         void ResetBlind( void );
155         void SetBlindAnswer( bool value );
156         void SpellModesAction( const Spell &, u32, const HeroBase * );
157         void SpellApplyDamage( const Spell &, u32, const HeroBase *, TargetInfo & );
158         void SpellRestoreAction( const Spell &, u32, const HeroBase * );
159         u32 Resurrect( u32, bool, bool );
160 
161         bool SwitchAnimation( int rule, bool reverse = false );
162         bool SwitchAnimation( const std::vector<int> & animationList, bool reverse = false );
163         void IncreaseAnimFrame( bool loop = false );
164         bool isFinishAnimFrame( void ) const;
165         int GetFrame( void ) const;
166         uint32_t GetCustomAlpha() const;
167         void SetCustomAlpha( uint32_t alpha );
168 
169         fheroes2::Point GetStartMissileOffset( size_t ) const;
170 
171         int M82Attk( void ) const;
172         int M82Kill( void ) const;
173         int M82Move( void ) const;
174         int M82Wnce( void ) const;
175         int M82Expl( void ) const;
176 
177         fheroes2::Point GetBackPoint( void ) const;
178         fheroes2::Point GetCenterPoint() const;
179         fheroes2::Rect GetRectPosition( void ) const;
180 
181         u32 HowManyWillKilled( u32 ) const;
182 
183         void SetResponse( void );
184         void UpdateDirection( void );
185         bool UpdateDirection( const fheroes2::Rect & );
186         void PostKilledAction( void );
187 
188         u32 GetMagicResist( const Spell &, u32 ) const;
189         int GetSpellMagic() const;
190 
191         const HeroBase * GetCommander( void ) const;
192         const HeroBase * GetCurrentOrArmyCommander() const; // commander of the army with the current unit color (if valid), commander of the unit's army otherwise
193 
194         static bool isHandFighting( const Unit &, const Unit & );
195 
196         int GetAnimationState() const;
197         bool isIdling() const;
198         bool checkIdleDelay();
199 
200         // Find a better way to expose it without a million getters/setters
201         AnimationState animation;
202 
203     private:
204         const uint32_t _uid;
205         u32 hp;
206         u32 count0;
207         u32 dead;
208         u32 shots;
209         u32 disruptingray;
210         bool reflect;
211 
212         Position position;
213         ModesAffected affected;
214         Unit * mirror;
215         RandomizedDelay idleTimer;
216 
217         bool blindanswer;
218         uint32_t customAlphaMask;
219 
220         const Rand::DeterministicRandomGenerator & _randomGenerator;
221     };
222 }
223 
224 #endif
225