1 ////////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2018 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See http://www.gnu.org/copyleft/gpl.html for details.
9 ////////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef __GLOBAL_ENEMY_HEADER__
12 #define __GLOBAL_ENEMY_HEADER__
13 
14 #include "global_actor.h"
15 #include "common/global/objects/global_object.h"
16 
17 #include <memory>
18 
19 namespace vt_script
20 {
21 class ReadScriptDescriptor;
22 }
23 
24 namespace vt_global
25 {
26 
27 //! \brief The Battle enemies harm levels
28 enum GLOBAL_ENEMY_HURT {
29     GLOBAL_ENEMY_HURT_NONE     = 0,
30     GLOBAL_ENEMY_HURT_SLIGHTLY = 1,
31     GLOBAL_ENEMY_HURT_MEDIUM   = 2,
32     GLOBAL_ENEMY_HURT_HEAVILY  = 3,
33     GLOBAL_ENEMY_HURT_TOTAL    = 4,
34 };
35 
36 /** ****************************************************************************
37 *** \brief Representation of enemies that fight in battles
38 ***
39 *** The game handles enemies a little different than most RPGs. Instead of an
40 *** enemy always having the same statistics for health, phys_atk, etc., enemy
41 *** stats are randomized so that the same type of enemy does not always have
42 *** the exact same stats. Guassian random values are applied to each enemy's
43 *** "base" stats before the player begins battle with that enemy, making
44 *** the enemy tougher or weaker than the base level depending on the outcome. Some
45 *** enemies (notably bosses) do not have this randomization applied to their stats
46 *** in order to make sure that bosses are challenging, but not overwhemlingly strong
47 *** or surprisingly weak.
48 ***
49 *** Enemies have one to several different skills that they may use in battle. An enemy
50 *** has to have at least one skill defined for it, otherwise they would not be able to
51 *** perform any action in battle. Enemy's may also carry a small chance of dropping an
52 *** item or other object after they are defeated.
53 *** ***************************************************************************/
54 class GlobalEnemy : public GlobalActor
55 {
56 public:
57     explicit GlobalEnemy(uint32_t id);
~GlobalEnemy()58     virtual ~GlobalEnemy() override
59     {
60     }
61 
62     /** \brief Enables the enemy to be able to use a specific skill
63     *** \param skill_id The integer ID of the skill to add to the enemy
64     *** \returns whether the skill was added successfully.
65     ***
66     *** This method should be called only <b>after</b> the Initialize() method has been invoked. The
67     *** purpose of this method is to allow non-standard skills to be used by enemies under certain
68     *** circumstances. For example, in scripted battle sequences where an enemy may become stronger
69     *** and gain access to new skills after certain criteria are met. Normally you would want to define
70     *** any skills that you wish an enemy to be able to use within their Lua definition file.
71     **/
72     bool AddSkill(uint32_t skill_id) override;
73 
74     /** \brief Uses random variables to calculate which objects, if any, the enemy dropped.
75     **/
76     std::vector<std::shared_ptr<GlobalObject>> DetermineDroppedObjects();
77 
78     //! \name Class member access functions
79     //@{
GetDrunesDropped()80     uint32_t GetDrunesDropped() const {
81         return _drunes_dropped;
82     }
83 
GetSpriteWidth()84     uint32_t GetSpriteWidth() const {
85         return _sprite_width;
86     }
87 
GetSpriteHeight()88     uint32_t GetSpriteHeight() const {
89         return _sprite_height;
90     }
91 
GetBattleAnimations()92     std::vector<vt_video::AnimatedImage>* GetBattleAnimations() {
93         return &_battle_animations;
94     }
95 
GetExperiencePoints()96     uint32_t GetExperiencePoints() const {
97         return _experience_points;
98     }
99     //@}
100 
101 protected:
102     //! \brief The Amount of XP the enemy holds
103     uint32_t _experience_points;
104 
105     //! \brief The dimensions of the enemy's battle sprite in pixels
106     uint32_t _sprite_width, _sprite_height;
107 
108     //! \brief The amount of drunes that the enemy will drop
109     uint32_t _drunes_dropped;
110 
111     /** \brief Dropped object containers
112     *** These two vectors are of the same size. _dropped_objects contains the IDs of the objects that the enemy
113     *** may drop. _dropped_chance contains a value from 0.0f to 1.0f that determines the probability of the
114     *** enemy dropping that object.
115     **/
116     //@{
117     std::vector<uint32_t> _dropped_objects;
118     std::vector<float> _dropped_chance;
119     //@}
120 
121     /** \brief Contains all of the possible skills that the enemy may possess
122     *** This container holds the IDs of all skills that the enemy may execute in battle.
123     *** The Initialize() function uses this data to populates the GlobalActor _skills container.
124     **/
125     std::vector<uint32_t> _skill_set;
126 
127     /** \brief The battle sprite animations for the enemy
128     *** Each enemy has four animations representing damage levels of 0%, 33%, 66%, and 100%. This vector thus
129     *** always has a size of four holding each of these image frames. The first element contains the 0%
130     *** damage frame, the second element contains the 33% damage frame, and so on.
131     **/
132     std::vector<vt_video::AnimatedImage> _battle_animations;
133 
134     /** \brief Initializes the enemy stats and skills
135     ***
136     *** This function sets the enemy's experience level, modifies its stats using Gaussian
137     *** random values, and constructs the skills that the enemy is capable of using.
138     ***
139     *** \note Certain enemies can skip the stat randomization step.
140     **/
141     void _Initialize();
142 }; // class GlobalEnemy : public GlobalActor
143 
144 } // namespace vt_global
145 
146 #endif // __GLOBAL_ENEMY_HEADER__
147