Horizon Official Technical Documentation
Horizon::Zone::Combat Class Reference

#include <Combat.hpp>

Public Member Functions

 Combat (std::shared_ptr< Unit > unit, std::shared_ptr< Unit > target)
 
 ~Combat ()
 
std::shared_ptr< Unitunit () const
 
std::shared_ptr< Unittarget () const
 
combat_retaliate_type weapon_attack ()
 
int64_t calculate_weapon_defense (int64_t damage)
 
int64_t calculate_magic_defense (int64_t damage)
 
combat_damage calculate_weapon_attack ()
 
combat_damage calculate_magic_attack ()
 
combat_damage calculate_misc_attack ()
 
int64_t deduce_weapon_element_attack (int64_t damage, element_type def_ele, item_equip_location_index loc)
 
int64_t deduce_damage_size_modifier (int64_t damage, item_equip_location_index loc)
 

Private Attributes

time_t _start_time {0}
 
std::weak_ptr< Unit_unit
 
std::weak_ptr< Unit_target
 

Constructor & Destructor Documentation

◆ Combat()

Combat::Combat ( std::shared_ptr< Unit unit,
std::shared_ptr< Unit target 
)
explicit
57: _unit(unit), _target(target), _start_time(std::time(nullptr))
58{
59}
std::shared_ptr< Unit > target() const
Definition: Combat.hpp:658
std::shared_ptr< Unit > unit() const
Definition: Combat.hpp:657
time_t _start_time
Definition: Combat.hpp:670
std::weak_ptr< Unit > _target
Definition: Combat.hpp:671
std::weak_ptr< Unit > _unit
Definition: Combat.hpp:671

◆ ~Combat()

Combat::~Combat ( )
62{
63}

Member Function Documentation

◆ calculate_magic_attack()

combat_damage Combat::calculate_magic_attack ( )
226{
227 combat_damage dmg;
228 if (unit()->type() == UNIT_PLAYER) {
229 EquipmentListType const& equipments = unit()->downcast<Horizon::Zone::Units::Player>()->inventory()->equipments();
230 std::shared_ptr<const item_entry_data> weapon_right = nullptr;
231 }
232
233 int magic_atk = unit()->status()->equip_matk()->get_min() + std::rand() % (unit()->status()->equip_matk()->get_max() - unit()->status()->equip_matk()->get_min());
234
235 dmg.right_damage = magic_atk;
236
238
239 return dmg;
240}
std::array< std::pair< item_equip_location_mask, std::weak_ptr< item_entry_data > >, IT_EQPI_MAX > EquipmentListType
Definition: ItemDefinitions.hpp:577
@ UNIT_PLAYER
Definition: UnitDefinitions.hpp:45
int64_t calculate_magic_defense(int64_t damage)
Definition: Combat.cpp:220
Definition: Player.hpp:62
Definition: CombatDefinitions.hpp:106
int64_t right_damage
Definition: CombatDefinitions.hpp:107

References calculate_magic_defense(), combat_damage::right_damage, unit(), and UNIT_PLAYER.

+ Here is the call graph for this function:

◆ calculate_magic_defense()

int64_t Combat::calculate_magic_defense ( int64_t  damage)
221{
222 return (int)((100.0f - target()->status()->hard_mdef()->total() / (target()->status()->hard_mdef()->total() + 100.0f) * 90.0f) / 100.0f * damage - target()->status()->soft_mdef()->total());
223}

References target().

Referenced by calculate_magic_attack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculate_misc_attack()

combat_damage Combat::calculate_misc_attack ( )
243{
244 combat_damage dmg;
245 return dmg;
246}

◆ calculate_weapon_attack()

combat_damage Combat::calculate_weapon_attack ( )
94{
95 combat_damage dmg;
96
97 if (unit()->type() == UNIT_PLAYER) {
98 EquipmentListType const& equipments = unit()->downcast<Horizon::Zone::Units::Player>()->inventory()->equipments();
99
100 // Calculate element damage ratio and damage.
101 int64_t batk = unit()->status()->base_attack()->total();
102
103 if (unit()->type() == UNIT_PLAYER) {
104 std::shared_ptr<const item_entry_data> weapon_right = nullptr, weapon_left = nullptr;
105
106 std::function<bool(item_weapon_type)> is_ranged_weapon = [](item_weapon_type weapon_type) -> bool {
107 switch (weapon_type) {
108 case IT_WT_BOW:
109 case IT_WT_MUSICAL:
110 case IT_WT_WHIP:
111 case IT_WT_REVOLVER:
112 case IT_WT_RIFLE:
113 case IT_WT_GATLING:
114 case IT_WT_SHOTGUN:
115 case IT_WT_GRENADE:
116 return true;
117 default:
118 break;
119 }
120
121 return false;
122 };
123
124 if (equipments[IT_EQPI_HAND_R].second.expired() == false) {
125 int64_t status_atk_min = 0, status_atk_max = 0;
126 float bonus = 0.00f, variance = 0.00f;
129 dmg.right_damage = (batk << 1);
130 weapon_right = equipments[IT_EQPI_HAND_R].second.lock();
131 if (is_ranged_weapon(weapon_right->config->sub_type.weapon_t)) {
132 bonus = unit()->status()->weapon_attack_right()->total() * unit()->status()->dexterity()->total() / 100.00f;
133 } else {
134 bonus = unit()->status()->weapon_attack_right()->total() * unit()->status()->strength()->total() / 100.00f;
135 }
136 variance = 5.0f * unit()->status()->weapon_attack_right()->total() * weapon_right->config->level.weapon / 100.00f;
137 status_atk_min = unit()->status()->weapon_attack_right()->total() - variance + bonus;
138 status_atk_max = unit()->status()->weapon_attack_right()->total() + variance + bonus;
139 dmg.right_damage += (status_atk_max > status_atk_min) ? status_atk_min + std::rand() % (status_atk_max - status_atk_min + 1) : status_atk_min;
140 }
141
142 if (equipments[IT_EQPI_HAND_L].second.expired() == false) {
143 int64_t status_atk_min = 0, status_atk_max = 0;
144 float bonus = 0.00f, variance = 0.00f;
147 dmg.left_damage = batk;
148 weapon_left = equipments[IT_EQPI_HAND_L].second.lock();
149 if (is_ranged_weapon(weapon_left->config->sub_type.weapon_t)) {
150 bonus = unit()->status()->weapon_attack_left()->total() * unit()->status()->dexterity()->total() / 100.00f;
151 } else {
152 bonus = unit()->status()->weapon_attack_left()->total() * unit()->status()->strength()->total() / 100.00f;
153 }
154 variance = 5.0f * unit()->status()->weapon_attack_left()->total() * weapon_left->config->level.weapon / 100.00f;
155 status_atk_min = unit()->status()->weapon_attack_left()->total() - variance + bonus;
156 status_atk_max = unit()->status()->weapon_attack_left()->total() + variance + bonus;
157 dmg.left_damage += (status_atk_max > status_atk_min) ? status_atk_min + std::rand() % (status_atk_max - status_atk_min + 1) : status_atk_min;
158 }
159 }
160 } else {
161 dmg.right_damage = (std::rand() % unit()->status()->creature_attack_damage()->get_min()) + (unit()->status()->creature_attack_damage()->get_max() - unit()->status()->creature_attack_damage()->get_min());
162 int64_t status_atk_min = 0, status_atk_max = 0;
163 status_atk_min = dmg.right_damage * 80 / 100;
164 status_atk_max = dmg.right_damage * 120 / 100;
165 dmg.right_damage += (status_atk_max > status_atk_min) ? status_atk_min + std::rand() % (status_atk_max - status_atk_min + 1) : status_atk_min;
166 }
167
168 int target_flee = target()->status()->flee()->total();
169 bool hit = (std::rand() % 100) < (unit()->status()->hit()->total() - target_flee);
170
171 if (dmg.left_damage)
173
175
176 int damage_total = dmg.left_damage + dmg.right_damage;
177
178 if (dmg.left_damage < 0)
179 dmg.left_damage = 0;
180 if (dmg.right_damage < 0)
181 dmg.right_damage = 0;
182
183 if (damage_total < 0) {
184 damage_total = 0;
185 }
186
187 int cri = unit()->status()->crit()->total();
188
189 cri -= target()->status()->base_level()->total() / 15 + 2 * target()->status()->luck()->total();
190
191 dmg.is_critical = (std::rand() % 1000 < cri) ? true : false;
192
193 if (dmg.is_critical) {
194 hit = true;
195 dmg.left_damage += dmg.left_damage * 40 / 100;
196 dmg.right_damage += dmg.right_damage * 40 / 100;
197 }
198
199 if (hit) {
201 } else {
203 dmg.left_damage = 0;
204 dmg.right_damage = 0;
205 damage_total = 0;
206 }
207
208 if (!hit) {
209 dmg.number_of_hits *= -1;
210 } else {
211 if (dmg.left_damage > 0)
212 dmg.number_of_hits = 2;
213 else
214 dmg.number_of_hits = 1;
215 }
216
217 return dmg;
218}
@ CBT_RET_FLEE
Definition: CombatDefinitions.hpp:54
@ CBT_RET_DEF
Definition: CombatDefinitions.hpp:57
@ IT_EQPI_HAND_L
Definition: ItemDefinitions.hpp:213
@ IT_EQPI_HAND_R
Definition: ItemDefinitions.hpp:214
item_weapon_type
Definition: ItemDefinitions.hpp:99
@ IT_WT_GATLING
Definition: ItemDefinitions.hpp:119
@ IT_WT_GRENADE
Definition: ItemDefinitions.hpp:121
@ IT_WT_RIFLE
Definition: ItemDefinitions.hpp:118
@ IT_WT_BOW
Definition: ItemDefinitions.hpp:111
@ IT_WT_SHOTGUN
Definition: ItemDefinitions.hpp:120
@ IT_WT_WHIP
Definition: ItemDefinitions.hpp:114
@ IT_WT_MUSICAL
Definition: ItemDefinitions.hpp:113
@ IT_WT_REVOLVER
Definition: ItemDefinitions.hpp:117
@ ELE_NEUTRAL
Definition: UnitDefinitions.hpp:971
int64_t calculate_weapon_defense(int64_t damage)
Definition: Combat.cpp:65
int64_t deduce_weapon_element_attack(int64_t damage, element_type def_ele, item_equip_location_index loc)
Definition: Combat.cpp:248
int64_t deduce_damage_size_modifier(int64_t damage, item_equip_location_index loc)
Definition: Combat.cpp:277
int number_of_hits
Definition: CombatDefinitions.hpp:109
bool is_critical
Definition: CombatDefinitions.hpp:116
combat_retaliate_type result
Definition: CombatDefinitions.hpp:113
int64_t left_damage
Definition: CombatDefinitions.hpp:107

References calculate_weapon_defense(), CBT_RET_DEF, CBT_RET_FLEE, deduce_damage_size_modifier(), deduce_weapon_element_attack(), ELE_NEUTRAL, combat_damage::is_critical, IT_EQPI_HAND_L, IT_EQPI_HAND_R, IT_WT_BOW, IT_WT_GATLING, IT_WT_GRENADE, IT_WT_MUSICAL, IT_WT_REVOLVER, IT_WT_RIFLE, IT_WT_SHOTGUN, IT_WT_WHIP, combat_damage::left_damage, combat_damage::number_of_hits, combat_damage::result, combat_damage::right_damage, target(), unit(), and UNIT_PLAYER.

Referenced by weapon_attack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculate_weapon_defense()

int64_t Combat::calculate_weapon_defense ( int64_t  damage)
66{
67 return (int)((100.0f - target()->status()->soft_def()->total() / (target()->status()->soft_def()->total() + 400.0f) * 90.0f) / 100.0f * damage - target()->status()->hard_def()->total());
68}

References target().

Referenced by calculate_weapon_attack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deduce_damage_size_modifier()

int64_t Combat::deduce_damage_size_modifier ( int64_t  damage,
item_equip_location_index  loc 
)
278{
279 if (unit()->type() == UNIT_PLAYER) {
280 EquipmentListType const &equipments = unit()->downcast<Horizon::Zone::Units::Player>()->inventory()->equipments();
281 std::shared_ptr<const item_entry_data> weapon = nullptr;
282
283 if (equipments[loc].second.expired())
284 return damage;
285
286 weapon = equipments[loc].second.lock();
287
288 if (loc == IT_EQPI_HAND_R || loc == IT_EQPI_HAND_L)
289 return damage; // not a weapon.
290
291 std::shared_ptr<const item_config_data> weapond = ItemDB->get_item_by_id(weapon->item_id);
292
293 if (weapond == nullptr) {
294 HLog(warning) << "Combat::deduce_weapon_element_attack: could not find item config of right hand weapon ID: " << weapon->item_id << ". ignoring..." ;
295 return damage;
296 }
297
298 int32_t size_damage_ratio = ItemDB->get_weapon_target_size_modifier(weapond->sub_type.weapon_t, (unit_size_type) unit()->status()->size()->get_base());
299
300 damage += (size_damage_ratio < 100 ? -(damage * (size_damage_ratio - 100) / 100) : (damage * (size_damage_ratio - 100) / 100));
301 }
302
303 return damage;
304}
#define ItemDB
Definition: ItemDB.hpp:119
#define HLog(type)
Definition: Logger.hpp:122
unit_size_type
Definition: UnitDefinitions.hpp:36

References HLog, IT_EQPI_HAND_L, IT_EQPI_HAND_R, ItemDB, unit(), and UNIT_PLAYER.

Referenced by calculate_weapon_attack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ deduce_weapon_element_attack()

int64_t Combat::deduce_weapon_element_attack ( int64_t  damage,
element_type  def_ele,
item_equip_location_index  loc 
)
249{
250 if (unit()->type() == UNIT_PLAYER) {
251 EquipmentListType const &equipments = unit()->downcast<Horizon::Zone::Units::Player>()->inventory()->equipments();
252 std::shared_ptr<const item_entry_data> weapon = nullptr;
253
254 if (equipments[loc].second.expired())
255 return damage;
256
257 weapon = equipments[loc].second.lock();
258
259 if (loc != IT_EQPI_HAND_R || loc != IT_EQPI_HAND_L)
260 return damage; // not a weapon.
261
262 std::shared_ptr<const item_config_data> weapond = ItemDB->get_item_by_id(weapon->item_id);
263
264 if (weapond == nullptr) {
265 HLog(warning) << "Combat::deduce_weapon_element_attack: could not find item config of right hand weapon ID: " << weapon->item_id << ". ignoring..." ;
266 return damage;
267 }
268
269 int32_t attribute_damage_ratio = ItemDB->get_weapon_attribute_modifier(weapond->level.weapon, ELE_NEUTRAL, def_ele);
270
271 damage += (attribute_damage_ratio < 100 ? -(damage * (attribute_damage_ratio - 100) / 100) : (damage * (attribute_damage_ratio - 100) / 100));
272 }
273
274 return damage;
275}

References ELE_NEUTRAL, HLog, IT_EQPI_HAND_L, IT_EQPI_HAND_R, ItemDB, unit(), and UNIT_PLAYER.

Referenced by calculate_weapon_attack().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ target()

std::shared_ptr< Unit > Horizon::Zone::Combat::target ( ) const
inline
658{ return _target.lock(); }

References _target.

Referenced by calculate_magic_defense(), calculate_weapon_attack(), calculate_weapon_defense(), Horizon::Zone::UnitComponent::sync_data_types(), and weapon_attack().

+ Here is the caller graph for this function:

◆ unit()

std::shared_ptr< Unit > Horizon::Zone::Combat::unit ( ) const
inline

◆ weapon_attack()

combat_retaliate_type Combat::weapon_attack ( )
71{
73
74 int64_t damage_total = dmg.left_damage + dmg.right_damage;
75
78 CombatRegistry::MeleeResultOperation *melee_operation = new CombatRegistry::MeleeResultOperation(melee_operand, CombatRegistry::MeleeResultOperation::melee_result_operation_type::MELEE_RESULT_OPERATION_DAMAGE, melee_value);
79
82 CombatRegistry::AttributeOperation *attr_operation = new CombatRegistry::AttributeOperation(attr_operand, CombatRegistry::AttributeOperation::attribute_operation_type::ATTRIBUTE_OPERATION_SUBTRACT_FROM_BASE, attr_value);
83
84 int time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
86 stage->add_operation(melee_operation);
87 stage->add_operation(attr_operation);
88 unit()->combat_registry()->queue_combat_stage(stage);
89
90 return dmg.result;
91}
void add_operation(CombatOperation *operation)
Definition: Combat.hpp:604
combat_damage calculate_weapon_attack()
Definition: Combat.cpp:93

References Horizon::Zone::CombatRegistry::CombatStage::add_operation(), calculate_weapon_attack(), combat_damage::left_damage, combat_damage::result, combat_damage::right_damage, target(), and unit().

+ Here is the call graph for this function:

Member Data Documentation

◆ _start_time

time_t Horizon::Zone::Combat::_start_time {0}
private

◆ _target

std::weak_ptr<Unit> Horizon::Zone::Combat::_target
private

Referenced by target().

◆ _unit

std::weak_ptr<Unit> Horizon::Zone::Combat::_unit
private

Referenced by unit().


The documentation for this class was generated from the following files: