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_ATTACK_POINT_HEADER__ 12 #define __GLOBAL_ATTACK_POINT_HEADER__ 13 14 #include "common/global/status_effects/status_effect_enums.h" 15 16 #include "engine/video/image.h" 17 18 #include "utils/ustring.h" 19 20 #include <memory> 21 22 namespace vt_script 23 { 24 class ReadScriptDescriptor; 25 } 26 27 namespace vt_global 28 { 29 30 class GlobalArmor; 31 class GlobalActor; 32 33 /** \name Character Attack Point Positions 34 *** \brief They represent the index location of the attack points and armor types for characters 35 **/ 36 enum GLOBAL_POSITION { 37 GLOBAL_POSITION_HEAD = 0, 38 GLOBAL_POSITION_TORSO = 1, 39 GLOBAL_POSITION_ARMS = 2, 40 GLOBAL_POSITION_LEGS = 3, 41 GLOBAL_POSITION_INVALID = 4 42 }; 43 44 /** **************************************************************************** 45 *** \brief Represents the points of attack present on an actor 46 *** 47 *** An attack point is a location where an actor may be attacked. It is <b>not</b> a numerical 48 *** quantity. Actors typically have multiple attack points, each with their own resistances and 49 *** weaknesses. For example, the number of attack points on all characters is four and they 50 *** are located on the head, torso, arms, and legs. Each attack points may have certain weaknesses 51 *** or resistances. 52 *** ***************************************************************************/ 53 class GlobalAttackPoint 54 { 55 public: 56 //! \param actor_owner A pointer to the GlobalActor owner of this attack point 57 explicit GlobalAttackPoint(GlobalActor* owner); ~GlobalAttackPoint()58 ~GlobalAttackPoint() { 59 _actor_owner = nullptr; 60 } 61 62 /** \brief Reads in the attack point's data from a script file 63 *** \param script A reference to the open script file where to retrieve the data from 64 *** \return True upon success, false upon failure. 65 *** 66 *** There are two requirements for using this function. First, the script file must already 67 *** be opened for reading permissions. Second, the table which contains the attack point data 68 *** must be opened <b>prior</b> to making this function call. This function will not close the 69 *** table containing the attack point when it finishes loading the data, so the calling routine 70 *** must remember to close the table after this call is made. 71 **/ 72 bool LoadData(vt_script::ReadScriptDescriptor& script); 73 74 /** \brief Determines the total physical and magical defense of the attack point 75 *** \param equipped_armor A pointer to the armor equipped on the attack point, or nullptr if no armor is equipped 76 *** 77 *** This method uses the owning GlobalActor's base defense stats, the attack point's defense modifiers stats, 78 *** and the properties of the equipped armor to calculate the attack point's total physical and magical defense. 79 *** This method should be called whenever the actor's base defense stats or equipped armor on this point changes. 80 **/ 81 void CalculateTotalDefense(const std::shared_ptr<GlobalArmor>& equipped_armor); 82 83 /** \brief Determines the total evade rating of the attack point 84 *** 85 *** This method uses the owning GlobalActor's base evade rating and the attack point's evade modifiers stats to 86 *** calculate the attack point's total evade rating. This method should be called whenever the actor's base defense 87 *** rating changes. 88 **/ 89 void CalculateTotalEvade(); 90 91 //! \name Class Member Access Functions 92 //@{ GetName()93 vt_utils::ustring& GetName() { 94 return _name; 95 } 96 GetActorOwner()97 GlobalActor* GetActorOwner() const { 98 return _actor_owner; 99 } 100 GetXPosition()101 int16_t GetXPosition() const { 102 return _x_position; 103 } 104 GetYPosition()105 int16_t GetYPosition() const { 106 return _y_position; 107 } 108 GetPhysDefModifier()109 float GetPhysDefModifier() const { 110 return _phys_def_modifier; 111 } 112 GetMagDefModifier()113 float GetMagDefModifier() const { 114 return _mag_def_modifier; 115 } 116 GetEvadeModifier()117 float GetEvadeModifier() const { 118 return _evade_modifier; 119 } 120 GetTotalPhysicalDefense()121 uint16_t GetTotalPhysicalDefense() const { 122 return _total_physical_defense; 123 } 124 GetTotalMagicalDefense(GLOBAL_ELEMENTAL element)125 uint16_t GetTotalMagicalDefense(GLOBAL_ELEMENTAL element) const { 126 if (element <= GLOBAL_ELEMENTAL_INVALID || element >= GLOBAL_ELEMENTAL_TOTAL) 127 element = GLOBAL_ELEMENTAL_NEUTRAL; 128 129 return _total_magical_defense[element]; 130 } 131 GetTotalEvadeRating()132 float GetTotalEvadeRating() const { 133 return _total_evade_rating; 134 } 135 GetStatusEffects()136 const std::vector<std::pair<GLOBAL_STATUS, float> >& GetStatusEffects() const { 137 return _status_effects; 138 } 139 140 //! \note Use this method with extreme caution. It does not update defense/evade totals or any other members SetActorOwner(GlobalActor * new_owner)141 void SetActorOwner(GlobalActor* new_owner) { 142 _actor_owner = new_owner; 143 } 144 //@} 145 146 private: 147 /** \brief The name of the attack point as is displayed on the screen 148 *** Usually, this is simply the name of a body part such as "head" or "tail". More elaborate names 149 *** may be chosen for special foes and bosses, however. 150 **/ 151 vt_utils::ustring _name; 152 153 //! \brief A pointer to the actor which "owns" this attack point (i.e., the attack point is a location on the actor) 154 GlobalActor* _actor_owner; 155 156 /** \brief The position of the physical attack point relative to the actor's battle sprite 157 *** These members treat the bottom center of the sprite as the origin (0, 0) and increase in the 158 *** right and upwards directions. The combination of these two members point to the center pinpoint 159 *** location of the attack point. The units of these two members are in number of pixels. The _y_position 160 *** member should always be positive, by _x_position may be either positive or negative. 161 **/ 162 int16_t _x_position; 163 int16_t _y_position; 164 165 /** \brief The defense and evasion percentage modifiers for this attack point 166 *** 167 *** These are called "modifiers" because they modify the value of phys_def, mag_def, and evade ratings of the 168 *** actor. They represent percentage change from the base stat. So for example, a phys_def modifer that is 0.25f 169 *** increases the phys_def of the attack point by 25%. If the base mag_def rating was 10 and the mag_def 170 *** modifier was -0.30f, the resulting mag_def for the attack point would be: 10 + (10 * -0.30f) = 7. 171 *** 172 *** The lower bound for each modifier is -1.0f (-100%), which will result in a value of zero for that stat. No 173 *** actor stats can be negative so even if the modifier drops below -1.0f, the resulting value will still be zero. 174 *** There is no theoretical upper bound, but it is usually advised to keep it under 1.0f (100%). 175 **/ 176 //@{ 177 float _phys_def_modifier; 178 float _mag_def_modifier; 179 float _evade_modifier; 180 //@} 181 182 /** \brief The cumulative defense and evade stats for this attack point 183 *** These totals include the actor's base stat, the percentage modifier for the attack point, and the stats of any 184 *** armor that is equipped on the attack point. 185 **/ 186 //@{ 187 uint32_t _total_physical_defense; 188 //! \brief The magical defense is computed against each elements. 189 uint32_t _total_magical_defense[GLOBAL_ELEMENTAL_TOTAL]; 190 float _total_evade_rating; 191 //@} 192 193 /** \brief A vector containing all status effects that may be triggered by attacking the point 194 *** This vector contains only the status effects that have a non-zero chance of affecting their target. Therefore, 195 *** it is very possible that this vector may be empty, and usually it will contain only a single entry. The first 196 *** element of the pair is an identifier for the type of status. The second element is a floating point value from 197 *** 0.0 to 100.0, representing a 0-100% probability range for this effect to be triggered upon being hit. 198 **/ 199 std::vector<std::pair<GLOBAL_STATUS, float> > _status_effects; 200 }; // class GlobalAttackPoint 201 202 } // namespace vt_global 203 204 #endif // __GLOBAL_ATTACK_POINT_HEADER__ 205