TrinityCore
Loading...
Searching...
No Matches
StatSystem.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "Unit.h"
19#include "DB2Stores.h"
20#include "Item.h"
21#include "Player.h"
22#include "Pet.h"
23#include "GameTables.h"
24#include "ObjectMgr.h"
25#include "SharedDefines.h"
26#include "SpellAuras.h"
27#include "SpellAuraEffects.h"
28#include "World.h"
29#include <G3D/g3dmath.h>
30#include <numeric>
31
32inline bool _ModifyUInt32(bool apply, uint32& baseValue, int32& amount)
33{
34 // If amount is negative, change sign and value of apply.
35 if (amount < 0)
36 {
37 apply = !apply;
38 amount = -amount;
39 }
40 if (apply)
41 baseValue += amount;
42 else
43 {
44 // Make sure we do not get uint32 overflow.
45 if (amount > int32(baseValue))
46 amount = baseValue;
47 baseValue -= amount;
48 }
49 return apply;
50}
51
52/*#######################################
53######## ########
54######## UNIT STAT SYSTEM ########
55######## ########
56#######################################*/
57
63
65{
66 float minDamage = 0.0f;
67 float maxDamage = 0.0f;
68
69 CalculateMinMaxDamage(attType, false, true, minDamage, maxDamage);
70
71 switch (attType)
72 {
73 case BASE_ATTACK:
74 default:
77 break;
78 case OFF_ATTACK:
81 break;
82 case RANGED_ATTACK:
85 break;
86 }
87}
88
90{
91 if (power == POWER_MANA)
92 return GetCreateMana();
93
94 if (PowerTypeEntry const* powerType = sDB2Manager.GetPowerTypeEntry(power))
95 return powerType->MaxBasePower;
96
97 return 0;
98}
99
100/*#######################################
101######## ########
102######## PLAYERS STAT SYSTEM ########
103######## ########
104#######################################*/
105
107{
108 // value = ((base_value * base_pct) + total_value) * total_pct
109 float value = GetTotalStatValue(stat);
110
111 SetStat(stat, int32(value));
112
113 if (stat == STAT_STAMINA || stat == STAT_INTELLECT || stat == STAT_STRENGTH)
114 {
115 Pet* pet = GetPet();
116 if (pet)
117 pet->UpdateStats(stat);
118 }
119
120 switch (stat)
121 {
122 case STAT_AGILITY:
125 break;
126 case STAT_STAMINA:
128 break;
129 case STAT_INTELLECT:
131 break;
132 default:
133 break;
134 }
135
136 if (stat == STAT_STRENGTH)
138 else if (stat == STAT_AGILITY)
139 {
142 }
143
144 UpdateArmor();
147 return true;
148}
149
150void Player::ApplySpellPowerBonus(int32 amount, bool apply)
151{
153 return;
154
155 apply = _ModifyUInt32(apply, m_baseSpellPower, amount);
156
157 // For speed just update for client
159 for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
160 ApplyModDamageDonePos(SpellSchools(i), amount, apply);
161
163 {
166 }
167}
168
170{
171 // Magic damage modifiers implemented in Unit::SpellDamageBonusDone
172 // This information for client side use only
173 // Get healing bonus for all schools
175 // Get damage bonus for all schools
177 for (uint16 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
178 {
180 std::accumulate(modDamageAuras.begin(), modDamageAuras.end(), 0, [i](SpellEffectValue negativeMod, AuraEffect const* aurEff)
181 {
182 if (aurEff->GetAmount() < 0 && aurEff->GetMiscValue() & (1 << i))
183 negativeMod += aurEff->GetAmount();
184 return negativeMod;
185 }));
187 SpellBaseDamageBonusDone(SpellSchoolMask(1 << i)) - m_activePlayerData->ModDamageDoneNeg[i]);
188 }
189
191 {
194 }
195}
196
198{
199 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
200 {
201 float value = GetTotalStatValue(Stats(i));
202 SetStat(Stats(i), int32(value));
203 }
204
205 UpdateArmor();
206 // calls UpdateAttackPowerAndDamage() in UpdateArmor for SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR
209
210 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
212
225
226 return true;
227}
228
230{
231 ApplyModTargetResistance(-amount, apply);
232 m_spellPenetrationItemMod += apply ? amount : -amount;
233}
234
236{
237 if (school > SPELL_SCHOOL_NORMAL)
238 {
240
241 Pet* pet = GetPet();
242 if (pet)
243 pet->UpdateResistances(school);
244 }
245 else
246 UpdateArmor();
247}
248
250{
251 UnitMods unitMod = UNIT_MOD_ARMOR;
252
253 float value = GetFlatModifierValue(unitMod, BASE_VALUE); // base armor
254 value *= GetPctModifierValue(unitMod, BASE_PCT); // armor percent
255
256 // SPELL_AURA_MOD_ARMOR_PCT_FROM_STAT counts as base armor
258 int32 miscValue = aurEff->GetMiscValue();
259 Stats stat = (miscValue != -2) ? Stats(miscValue) : GetPrimaryStat();
260 value += CalculatePct(float(GetStat(stat)), aurEff->GetAmount());
261 return true;
262 });
263
264 float baseValue = value;
265
266 value += GetFlatModifierValue(unitMod, TOTAL_VALUE); // bonus armor from auras and items
267 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
269
270 SetArmor(int32(value), int32(value - baseValue));
271
272 Pet* pet = GetPet();
273 if (pet)
274 pet->UpdateArmor();
275
276 UpdateAttackPowerAndDamage(); // armor dependent auras update for SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR
277}
278
280{
281 // Taken from PaperDollFrame.lua - 6.0.3.19085
282 float ratio = 10.0f;
283 if (GtHpPerStaEntry const* hpBase = sHpPerStaGameTable.GetRow(GetLevel()))
284 ratio = hpBase->Health;
285
286 float stamina = GetStat(STAT_STAMINA);
287
288 return stamina * ratio;
289}
290
292{
293 uint8 primaryStatPriority = [&]() -> uint8
294 {
295 if (ChrSpecializationEntry const* specialization = GetPrimarySpecializationEntry())
296 return specialization->PrimaryStatPriority;
297
298 return sChrClassesStore.AssertEntry(GetClass())->PrimaryStatPriority;
299 }();
300
301 if (primaryStatPriority >= 4)
302 return STAT_STRENGTH;
303
304 if (primaryStatPriority >= 2)
305 return STAT_AGILITY;
306
307 return STAT_INTELLECT;
308}
309
311{
312 UnitMods unitMod = UNIT_MOD_HEALTH;
313
314 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
315 value *= GetPctModifierValue(unitMod, BASE_PCT);
317 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
318
319 SetMaxHealth((uint32)value);
320}
321
323{
324 return sDB2Manager.GetPowerIndexByClass(power, GetClass());
325}
326
328{
329 uint32 powerIndex = GetPowerIndex(power);
330 if (powerIndex == MAX_POWERS || powerIndex >= MAX_POWERS_PER_CLASS)
331 return;
332
334
335 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
336 value *= GetPctModifierValue(unitMod, BASE_PCT);
337 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
338 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
339
340 SetMaxPower(power, (int32)std::lroundf(value));
341}
342
344{
345 float val2 = 0.0f;
346 float level = float(GetLevel());
347
348 ChrClassesEntry const* entry = sChrClassesStore.AssertEntry(GetClass());
350
352 {
353 if (!ranged)
354 {
355 float strengthValue = std::max(GetStat(STAT_STRENGTH) * entry->AttackPowerPerStrength, 0.0f);
356 float agilityValue = std::max(GetStat(STAT_AGILITY) * entry->AttackPowerPerAgility, 0.0f);
357
359 // Directly taken from client, SHAPESHIFT_FLAG_AP_FROM_STRENGTH ?
360 if (form && form->Flags & 0x20)
361 agilityValue += std::max(GetStat(STAT_AGILITY) * entry->AttackPowerPerStrength, 0.0f);
362
363 val2 = strengthValue + agilityValue;
364 }
365 else
366 val2 = (level + std::max(GetStat(STAT_AGILITY), 0.0f)) * entry->RangedAttackPowerPerAgility;
367 }
368 else
369 {
370 int32 minSpellPower = m_activePlayerData->ModHealingDonePos;
371 for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
372 minSpellPower = std::min(minSpellPower, m_activePlayerData->ModDamageDonePos[i]);
373
374 val2 = CalculatePct(float(minSpellPower), *m_activePlayerData->OverrideAPBySpellPowerPercent);
375 }
376
377 SetStatFlatModifier(unitMod, BASE_VALUE, val2);
378
379 float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
380 float attPowerMod = GetFlatModifierValue(unitMod, TOTAL_VALUE);
381 float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
382
383 if (ranged)
384 {
385 SetRangedAttackPower(int32(base_attPower));
386 SetRangedAttackPowerModPos(int32(attPowerMod));
387 SetRangedAttackPowerMultiplier(attPowerMultiplier);
388 }
389 else
390 {
391 SetAttackPower(int32(base_attPower));
392 SetAttackPowerModPos(int32(attPowerMod));
393 SetAttackPowerMultiplier(attPowerMultiplier);
394 }
395
396 Pet* pet = GetPet(); //update pet's AP
397 Guardian* guardian = GetGuardianPet();
398 //automatically update weapon damage after attack power modification
399 if (ranged)
400 {
402 if (pet && pet->IsHunterPet()) // At ranged attack change for hunter pet
404 }
405 else
406 {
408 if (Item* offhand = GetWeaponForAttack(OFF_ATTACK, true))
409 if (CanDualWield() || offhand->GetTemplate()->HasFlag(ITEM_FLAG3_ALWAYS_ALLOW_DUAL_WIELD))
411
414
415 if (pet && pet->IsPetGhoul()) // At melee attack power change for DK pet
417
418 if (guardian && guardian->IsSpiritWolf()) // At melee attack power change for Shaman feral spirit
419 guardian->UpdateAttackPowerAndDamage();
420 }
421}
422
423void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const
424{
425 UnitMods unitMod;
426
427 switch (attType)
428 {
429 case BASE_ATTACK:
430 default:
431 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
432 break;
433 case OFF_ATTACK:
434 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
435 break;
436 case RANGED_ATTACK:
437 unitMod = UNIT_MOD_DAMAGE_RANGED;
438 break;
439 }
440
441 float attackPowerMod = std::max(GetAPMultiplier(attType, normalized), 0.25f);
442
443 float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType, false) / 3.5f * attackPowerMod;
444 float basePct = GetPctModifierValue(unitMod, BASE_PCT);
445 float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
446 float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
447
448 float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
449 float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
450
451 float versaDmgMod = 1.0f;
452
454
456 if (shapeshift && shapeshift->CombatRoundTime)
457 {
458 weaponMinDamage = weaponMinDamage * shapeshift->CombatRoundTime / 1000.0f / attackPowerMod;
459 weaponMaxDamage = weaponMaxDamage * shapeshift->CombatRoundTime / 1000.0f / attackPowerMod;
460 }
461 else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case)
462 {
463 // cannot use ranged/off attack, set values to 0
464 if (attType != BASE_ATTACK)
465 {
466 minDamage = 0;
467 maxDamage = 0;
468 return;
469 }
470 weaponMinDamage = BASE_MINDAMAGE;
471 weaponMaxDamage = BASE_MAXDAMAGE;
472 }
473
474 minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct * versaDmgMod;
475 maxDamage = ((weaponMaxDamage + baseValue) * basePct + totalValue) * totalPct * versaDmgMod;
476}
477
479{
480 // No block
481 float value = 0.0f;
482 if (CanBlock())
483 {
484 // Base value
485 value = 5.0f;
486 // Increase from SPELL_AURA_MOD_BLOCK_PERCENT aura
488 // Increase from rating
490
491 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
492 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_BLOCK) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_BLOCK) : value;
493 }
495}
496
523
536
538{
539 if (!CanUseMastery())
540 {
542 return;
543 }
544
548
550 if (!chrSpec)
551 return;
552
553 for (auto const& [_, aura] : GetOwnedAuras())
554 if (aura->GetCasterGUID() == GetGUID() && aura->GetSpellInfo()->HasAttribute(SPELL_ATTR8_MASTERY_AFFECTS_POINTS))
555 for (AuraEffect* auraEff : aura->GetAuraEffects())
556 if (G3D::fuzzyNe(auraEff->GetSpellEffectInfo().BonusCoefficient, 0.0f))
557 auraEff->RecalculateAmount(this);
558}
559
561{
562 // No proof that CR_VERSATILITY_DAMAGE_DONE is allways = ActivePlayerData::Versatility
564
565 if (GetClass() == CLASS_HUNTER)
567 else
569}
570
583
585{
586 0.9560f, // Warrior
587 0.9560f, // Paladin
588 0.9880f, // Hunter
589 0.9880f, // Rogue
590 0.9830f, // Priest
591 0.9560f, // DK
592 0.9880f, // Shaman
593 0.9830f, // Mage
594 0.9830f, // Warlock
595 0.9830f, // Monk
596 0.9720f, // Druid
597 0.9830f, // Demon Hunter
598 0.9880f, // Evoker
599 1.0f, // Adventurer
600 1.0f, // Traveler
601};
602
603// helper function
604float CalculateDiminishingReturns(float const (&capArray)[MAX_CLASSES], uint8 playerClass, float nonDiminishValue, float diminishValue)
605{
606 // 1 1 k cx
607 // --- = --- + --- <=> x' = --------
608 // x' c x x + ck
609
610 // where:
611 // k is m_diminishing_k for that class
612 // c is capArray for that class
613 // x is chance before DR (diminishValue)
614 // x' is chance after DR (our result)
615
616 uint32 const classIdx = playerClass - 1;
617
618 float const k = m_diminishing_k[classIdx];
619 float const c = capArray[classIdx];
620
621 float result = c * diminishValue / (diminishValue + c * k);
622 result += nonDiminishValue;
623 return result;
624}
625
626constexpr float parry_cap[MAX_CLASSES] =
627{
628 65.631440f, // Warrior
629 65.631440f, // Paladin
630 145.560408f, // Hunter
631 145.560408f, // Rogue
632 0.0f, // Priest
633 65.631440f, // DK
634 145.560408f, // Shaman
635 0.0f, // Mage
636 0.0f, // Warlock
637 90.6425f, // Monk
638 0.0f, // Druid
639 65.631440f, // Demon Hunter
640 0.0f, // Evoker
641 0.0f, // Adventurer
642 0.0f, // Traveler
643};
644
646{
647 // No parry
648 float value = 0.0f;
649 uint32 pclass = GetClass() - 1;
650 if (CanParry() && parry_cap[pclass] > 0.0f)
651 {
652 float nondiminishing = 5.0f;
653 // Parry from rating
654 float diminishing = GetRatingBonusValue(CR_PARRY);
655 // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura
657
658 // apply diminishing formula to diminishing parry chance
659 value = CalculateDiminishingReturns(parry_cap, GetClass(), nondiminishing, diminishing);
660
661 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
662 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) : value;
663
664 }
666}
667
668constexpr float dodge_cap[MAX_CLASSES] =
669{
670 65.631440f, // Warrior
671 65.631440f, // Paladin
672 145.560408f, // Hunter
673 145.560408f, // Rogue
674 150.375940f, // Priest
675 65.631440f, // DK
676 145.560408f, // Shaman
677 150.375940f, // Mage
678 150.375940f, // Warlock
679 145.560408f, // Monk
680 116.890707f, // Druid
681 145.560408f, // Demon Hunter
682 145.560408f, // Evoker
683 0.0f, // Adventurer
684 0.0f, // Traveler
685};
686
688{
689 float diminishing = 0.0f, nondiminishing = 0.0f;
690 GetDodgeFromAgility(diminishing, nondiminishing);
691 // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura
693 // Dodge from rating
694 diminishing += GetRatingBonusValue(CR_DODGE);
695
696 // apply diminishing formula to diminishing dodge chance
697 float value = CalculateDiminishingReturns(dodge_cap, GetClass(), nondiminishing, diminishing);
698
699 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
700 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) : value;
701
703}
704
706{
707 float crit = 5.0f;
708 // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
710 // Increase crit from SPELL_AURA_MOD_CRIT_PCT
712 // Increase crit from spell crit ratings
714
715 // Store crit value
717}
718
720{
722 for (CorruptionEffectsEntry const* corruptionEffect : sCorruptionEffectsStore)
723 {
725 continue;
726
727 if (effectiveCorruption < corruptionEffect->MinCorruption)
728 {
729 RemoveAura(corruptionEffect->Aura);
730 continue;
731 }
732
733 if (!ConditionMgr::IsPlayerMeetingCondition(this, corruptionEffect->PlayerConditionID))
734 {
735 RemoveAura(corruptionEffect->Aura);
736 continue;
737 }
738
739 CastSpell(this, corruptionEffect->Aura, true);
740 }
741}
742
748
753
758
764
766{
767 if (attack == RANGED_ATTACK)
768 return;
769
771
772 Item const* weapon = GetWeaponForAttack(attack, true);
773 expertise += GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE, [weapon](AuraEffect const* aurEff) -> bool
774 {
775 return aurEff->GetSpellInfo()->IsItemFitToSpellRequirements(weapon);
776 });
777
778 if (expertise < 0)
779 expertise = 0;
780
781 switch (attack)
782 {
783 case BASE_ATTACK:
785 break;
786 case OFF_ATTACK:
788 break;
789 default:
790 break;
791 }
792}
793
794void Player::ApplyManaRegenBonus(int32 amount, bool apply)
795{
796 _ModifyUInt32(apply, m_baseManaRegen, amount);
798}
799
800void Player::ApplyHealthRegenBonus(int32 amount, bool apply)
801{
802 _ModifyUInt32(apply, m_baseHealthRegen, amount);
803}
804
806{
807 uint32 manaIndex = GetPowerIndex(POWER_MANA);
808 if (manaIndex == MAX_POWERS)
809 return;
810
811 // Get base of Mana Pool in sBaseMPGameTable
812 uint32 basemana = 0;
813 sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), basemana);
814 float base_regen = basemana / 100.f;
815
817
818 // Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT
820
821 // Apply PCT bonus from SPELL_AURA_MOD_MANA_REGEN_PCT
823
826}
827
829{
831 return;
832
833 uint32 runeIndex = GetPowerIndex(POWER_RUNES);
834 if (runeIndex == MAX_POWERS)
835 return;
836
837 PowerTypeEntry const* runeEntry = sDB2Manager.GetPowerTypeEntry(POWER_RUNES);
838
839 uint32 cooldown = GetRuneBaseCooldown();
840 SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenFlatModifier, runeIndex), float(1 * IN_MILLISECONDS) / float(cooldown) - runeEntry->RegenPeace);
842}
843
856
869
870/*#######################################
871######## ########
872######## MOBS STAT SYSTEM ########
873######## ########
874#######################################*/
875
877{
878 if (PowerTypeEntry const* powerType = sDB2Manager.GetPowerTypeEntry(power))
879 if (!powerType->GetFlags().HasFlag(PowerTypeFlags::IsUsedByNPCs))
880 return 0;
881
882 return Unit::GetCreatePowerValue(power);
883}
884
886{
887 return true;
888}
889
891{
895
896 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
898
900
901 return true;
902}
903
905{
908 SetArmor(int32(baseValue), int32(value - baseValue));
909}
910
912{
914 SetMaxHealth(uint32(value));
915}
916
918{
919 if (power == GetPowerType())
920 return 0;
921 switch (power)
922 {
924 return 2;
926 return 1;
928 return 3;
930 return 4;
932 return 5;
933 default:
934 break;
935 }
936 return MAX_POWERS;
937}
938
940{
941 if (GetPowerIndex(power) == MAX_POWERS)
942 return;
943
945
946 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
947 value *= GetPctModifierValue(unitMod, BASE_PCT);
948 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
949 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
950
951 SetMaxPower(power, (int32)std::lroundf(value));
952}
953
955{
957
958 float baseAttackPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
959 float attackPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
960
961 if (ranged)
962 {
963 SetRangedAttackPower(int32(baseAttackPower));
964 SetRangedAttackPowerMultiplier(attackPowerMultiplier);
965 }
966 else
967 {
968 SetAttackPower(int32(baseAttackPower));
969 SetAttackPowerMultiplier(attackPowerMultiplier);
970 }
971
972 // automatically update weapon damage after attack power modification
973 if (ranged)
975 else
976 {
979 }
980}
981
982void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const
983{
984 float variance = 1.0f;
985 UnitMods unitMod;
986 switch (attType)
987 {
988 case BASE_ATTACK:
989 default:
990 variance = GetCreatureTemplate()->BaseVariance;
991 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
992 break;
993 case OFF_ATTACK:
994 variance = GetCreatureTemplate()->BaseVariance;
995 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
996 break;
997 case RANGED_ATTACK:
999 unitMod = UNIT_MOD_DAMAGE_RANGED;
1000 break;
1001 }
1002
1003 if (attType == OFF_ATTACK && !haveOffhandWeapon())
1004 {
1005 minDamage = 0.0f;
1006 maxDamage = 0.0f;
1007 return;
1008 }
1009
1010 float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
1011 float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
1012
1013 if (!CanUseAttackType(attType)) // disarm case
1014 {
1015 weaponMinDamage = 0.0f;
1016 weaponMaxDamage = 0.0f;
1017 }
1018
1019 float attackPower = GetTotalAttackPowerValue(attType, false);
1020 float attackSpeedMulti = GetAPMultiplier(attType, normalized);
1021 float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + (attackPower / 3.5f) * variance;
1022 float basePct = GetPctModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
1023 float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
1024 float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
1025 float dmgMultiplier = GetCreatureDifficulty()->DamageModifier; // = DamageModifier * GetDamageMod(rank);
1026
1027 minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
1028 maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
1029}
1030
1031/*#######################################
1032######## ########
1033######## PETS STAT SYSTEM ########
1034######## ########
1035#######################################*/
1036
1037#define ENTRY_IMP 416
1038#define ENTRY_VOIDWALKER 1860
1039#define ENTRY_SUCCUBUS 1863
1040#define ENTRY_FELHUNTER 417
1041#define ENTRY_FELGUARD 17252
1042#define ENTRY_WATER_ELEMENTAL 510
1043#define ENTRY_TREANT 1964
1044#define ENTRY_FIRE_ELEMENTAL 15438
1045#define ENTRY_GHOUL 26125
1046#define ENTRY_BLOODWORM 28017
1047
1049{
1050 // value = ((base_value * base_pct) + total_value) * total_pct
1051 float value = GetTotalStatValue(stat);
1052 UpdateStatBuffMod(stat);
1053 float ownersBonus = 0.0f;
1054
1055 Unit* owner = GetOwner();
1056 // Handle Death Knight Glyphs and Talents
1057 float mod = 0.75f;
1058 if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
1059 {
1060 if (stat == STAT_STAMINA)
1061 mod = 0.3f; // Default Owner's Stamina scale
1062 else
1063 mod = 0.7f; // Default Owner's Strength scale
1064
1065 ownersBonus = float(owner->GetStat(stat)) * mod;
1066 value += ownersBonus;
1067 }
1068 else if (stat == STAT_STAMINA)
1069 {
1070 ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 30);
1071 value += ownersBonus;
1072 }
1073 //warlock's and mage's pets gain 30% of owner's intellect
1074 else if (stat == STAT_INTELLECT)
1075 {
1076 if (owner->GetClass() == CLASS_WARLOCK || owner->GetClass() == CLASS_MAGE)
1077 {
1078 ownersBonus = CalculatePct(owner->GetStat(stat), 30);
1079 value += ownersBonus;
1080 }
1081 }
1082/*
1083 else if (stat == STAT_STRENGTH)
1084 {
1085 if (IsPetGhoul())
1086 value += float(owner->GetStat(stat)) * 0.3f;
1087 }
1088*/
1089
1090 SetStat(stat, int32(value));
1091 m_statFromOwner[stat] = ownersBonus;
1092 UpdateStatBuffMod(stat);
1093
1094 switch (stat)
1095 {
1097 case STAT_AGILITY: UpdateArmor(); break;
1098 case STAT_STAMINA: UpdateMaxHealth(); break;
1100 default:
1101 break;
1102 }
1103
1104 return true;
1105}
1106
1108{
1110
1111 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
1112 UpdateStats(Stats(i));
1113
1114 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
1116
1118
1119 return true;
1120}
1121
1123{
1124 if (school > SPELL_SCHOOL_NORMAL)
1125 {
1127 float bonusValue = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)) - baseValue;
1128
1129 // hunter and warlock pets gain 40% of owner's resistance
1130 if (IsPet())
1131 {
1132 baseValue += float(CalculatePct(m_owner->GetResistance(SpellSchools(school)), 40));
1133 bonusValue += float(CalculatePct(m_owner->GetBonusResistanceMod(SpellSchools(school)), 40));
1134 }
1135
1136 SetResistance(SpellSchools(school), int32(baseValue));
1137 SetBonusResistanceMod(SpellSchools(school), int32(bonusValue));
1138 }
1139 else
1140 UpdateArmor();
1141}
1142
1144{
1145 float baseValue = 0.0f;
1146 float value = 0.0f;
1147 float bonus_armor = 0.0f;
1148 UnitMods unitMod = UNIT_MOD_ARMOR;
1149
1150 // hunter pets gain 35% of owner's armor value, warlock pets gain 100% of owner's armor
1151 if (IsHunterPet())
1152 bonus_armor = float(CalculatePct(m_owner->GetArmor(), 70));
1153 else if (IsPet())
1154 bonus_armor = m_owner->GetArmor();
1155
1156 value = GetFlatModifierValue(unitMod, BASE_VALUE);
1157 baseValue = value;
1158 value *= GetPctModifierValue(unitMod, BASE_PCT);
1159 value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
1160 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1161
1162 SetArmor(int32(baseValue), int32(value - baseValue));
1163}
1164
1166{
1167 UnitMods unitMod = UNIT_MOD_HEALTH;
1168 float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA);
1169
1170 float multiplicator;
1171 switch (GetEntry())
1172 {
1173 case ENTRY_IMP: multiplicator = 8.4f; break;
1174 case ENTRY_VOIDWALKER: multiplicator = 11.0f; break;
1175 case ENTRY_SUCCUBUS: multiplicator = 9.1f; break;
1176 case ENTRY_FELHUNTER: multiplicator = 9.5f; break;
1177 case ENTRY_FELGUARD: multiplicator = 11.0f; break;
1178 case ENTRY_BLOODWORM: multiplicator = 1.0f; break;
1179 default: multiplicator = 10.0f; break;
1180 }
1181
1182 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
1183 value *= GetPctModifierValue(unitMod, BASE_PCT);
1184 value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
1185 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1186
1187 SetMaxHealth((uint32)value);
1188}
1189
1191{
1192 if (GetPowerIndex(power) == MAX_POWERS)
1193 return;
1194
1196
1197 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
1198 value *= GetPctModifierValue(unitMod, BASE_PCT);
1199 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
1200 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1201
1202 SetMaxPower(power, int32(value));
1203}
1204
1206{
1207 if (ranged)
1208 return;
1209
1210 float val = 0.0f;
1211 float bonusAP = 0.0f;
1213
1214 if (GetEntry() == ENTRY_IMP) // imp's attack power
1215 val = GetStat(STAT_STRENGTH) - 10.0f;
1216 else
1217 val = 2 * GetStat(STAT_STRENGTH) - 20.0f;
1218
1219 Player* owner = GetOwner() ? GetOwner()->ToPlayer() : nullptr;
1220 if (owner)
1221 {
1222 if (IsHunterPet()) //hunter pets benefit from owner's attack power
1223 {
1224 float mod = 1.0f; //Hunter contribution modifier
1225 bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
1227 }
1228 else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
1229 {
1230 bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
1232 }
1233 else if (IsSpiritWolf()) //wolf benefit from shaman's attack power
1234 {
1235 float dmg_multiplier = 0.31f;
1236 bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier;
1237 SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier));
1238 }
1239 //demons benefit from warlocks shadow or fire damage
1240 else if (IsPet())
1241 {
1242 int32 fire = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FIRE];
1243 int32 shadow = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_SHADOW] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_SHADOW];
1244 int32 maximum = (fire > shadow) ? fire : shadow;
1245 if (maximum < 0)
1246 maximum = 0;
1247 SetBonusDamage(int32(maximum * 0.15f));
1248 bonusAP = maximum * 0.57f;
1249 }
1250 //water elementals benefit from mage's frost damage
1251 else if (GetEntry() == ENTRY_WATER_ELEMENTAL)
1252 {
1253 int32 frost = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FROST] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FROST];
1254 if (frost < 0)
1255 frost = 0;
1256 SetBonusDamage(int32(frost * 0.4f));
1257 }
1258 }
1259
1261
1262 //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
1263 float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
1264 float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
1265
1266 SetAttackPower(int32(base_attPower));
1267 SetAttackPowerMultiplier(attPowerMultiplier);
1268
1269 //automatically update weapon damage after attack power modification
1271}
1272
1274{
1275 if (attType > BASE_ATTACK)
1276 return;
1277
1278 float bonusDamage = 0.0f;
1279 if (Player* playerOwner = m_owner->ToPlayer())
1280 {
1281 //force of nature
1282 if (GetEntry() == ENTRY_TREANT)
1283 {
1284 int32 spellDmg = playerOwner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_NATURE] - playerOwner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_NATURE];
1285 if (spellDmg > 0)
1286 bonusDamage = spellDmg * 0.09f;
1287 }
1288 //greater fire elemental
1289 else if (GetEntry() == ENTRY_FIRE_ELEMENTAL)
1290 {
1291 int32 spellDmg = playerOwner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE] - playerOwner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FIRE];
1292 if (spellDmg > 0)
1293 bonusDamage = spellDmg * 0.4f;
1294 }
1295 }
1296
1298
1299 float att_speed = float(GetBaseAttackTime(BASE_ATTACK))/1000.0f;
1300
1301 float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType, false) / 3.5f * att_speed + bonusDamage;
1302 float base_pct = GetPctModifierValue(unitMod, BASE_PCT);
1303 float total_value = GetFlatModifierValue(unitMod, TOTAL_VALUE);
1304 float total_pct = GetPctModifierValue(unitMod, TOTAL_PCT);
1305
1306 float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
1307 float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
1308
1309 float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
1310 float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
1311
1314}
1315
1317{
1318 m_bonusSpellDamage = damage;
1319 if (Player* playerOwner = GetOwner()->ToPlayer())
1320 playerOwner->SetPetSpellPower(damage);
1321}
@ IN_MILLISECONDS
Definition Common.h:38
DB2Storage< ChrClassesEntry > sChrClassesStore("ChrClasses.db2", &ChrClassesLoadInfo::Instance)
DB2Storage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore("SpellShapeshiftForm.db2", &SpellShapeshiftFormLoadInfo::Instance)
DB2Storage< CorruptionEffectsEntry > sCorruptionEffectsStore("CorruptionEffects.db2", &CorruptionEffectsLoadInfo::Instance)
#define sDB2Manager
Definition DB2Stores.h:569
CorruptionEffectsFlag
Definition DBCEnums.h:460
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
GameTable< GtHpPerStaEntry > sHpPerStaGameTable
@ ITEM_FLAG3_ALWAYS_ALLOW_DUAL_WIELD
#define sObjectMgr
Definition ObjectMgr.h:1885
#define MAX_STATS
#define MAX_POWERS_PER_CLASS
@ CLASS_HUNTER
@ CLASS_WARLOCK
@ CLASS_MAGE
@ CLASS_DEATH_KNIGHT
SpellSchoolMask
@ SPELL_SCHOOL_MASK_ALL
WeaponAttackType
@ OFF_ATTACK
@ BASE_ATTACK
@ RANGED_ATTACK
Powers
@ MAX_POWERS
@ POWER_ALTERNATE_POWER
@ POWER_ALTERNATE_QUEST
@ POWER_RUNES
@ POWER_COMBO_POINTS
@ POWER_MANA
@ POWER_ALTERNATE_MOUNT
@ POWER_ALTERNATE_ENCOUNTER
#define MAX_CLASSES
Stats
@ STAT_INTELLECT
@ STAT_AGILITY
@ STAT_STRENGTH
@ STAT_STAMINA
SpellSchools
@ SPELL_SCHOOL_SHADOW
@ SPELL_SCHOOL_NORMAL
@ SPELL_SCHOOL_NATURE
@ SPELL_SCHOOL_FROST
@ SPELL_SCHOOL_FIRE
@ SPELL_SCHOOL_HOLY
@ MAX_SPELL_SCHOOL
@ SPELL_ATTR8_MASTERY_AFFECTS_POINTS
@ SPELL_AURA_OVERRIDE_ATTACK_POWER_BY_SP_PCT
@ SPELL_AURA_MOD_PARRY_PERCENT
@ SPELL_AURA_MOD_SPELL_HIT_CHANCE
@ SPELL_AURA_MOD_EXPERTISE
@ SPELL_AURA_MOD_POWER_REGEN
@ SPELL_AURA_MOD_HEALING_DONE_PERCENT
@ SPELL_AURA_MOD_ARMOR_PCT_FROM_STAT
@ SPELL_AURA_MOD_BONUS_ARMOR_PCT
@ SPELL_AURA_MOD_SPELL_CRIT_CHANCE
@ SPELL_AURA_MOD_MANA_REGEN_PCT
@ SPELL_AURA_MOD_DODGE_PERCENT
@ SPELL_AURA_MASTERY
@ SPELL_AURA_MOD_CRIT_PCT
@ SPELL_AURA_MOD_VERSATILITY
@ SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT
@ SPELL_AURA_MOD_POWER_REGEN_PERCENT
@ SPELL_AURA_MOD_DAMAGE_DONE
@ SPELL_AURA_MOD_BLOCK_PERCENT
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
#define ENTRY_FELGUARD
#define ENTRY_FIRE_ELEMENTAL
#define ENTRY_BLOODWORM
#define ENTRY_VOIDWALKER
#define ENTRY_FELHUNTER
constexpr float dodge_cap[MAX_CLASSES]
float CalculateDiminishingReturns(float const (&capArray)[MAX_CLASSES], uint8 playerClass, float nonDiminishValue, float diminishValue)
constexpr float parry_cap[MAX_CLASSES]
#define ENTRY_TREANT
bool _ModifyUInt32(bool apply, uint32 &baseValue, int32 &amount)
#define ENTRY_WATER_ELEMENTAL
#define ENTRY_SUCCUBUS
float const m_diminishing_k[MAX_CLASSES]
#define ENTRY_IMP
#define BASE_MAXDAMAGE
Definition UnitDefines.h:34
#define BASE_MINDAMAGE
Definition UnitDefines.h:33
@ BASE_VALUE
Definition Unit.h:156
@ TOTAL_VALUE
Definition Unit.h:158
@ FLAT_MOD
Definition Unit.h:245
@ PCT_MOD
Definition Unit.h:246
@ MINDAMAGE
Definition Unit.h:171
@ MAXDAMAGE
Definition Unit.h:172
UnitMods
Definition Unit.h:176
@ UNIT_MOD_DAMAGE_OFFHAND
Definition Unit.h:219
@ UNIT_MOD_ARMOR
Definition Unit.h:209
@ UNIT_MOD_ATTACK_POWER
Definition Unit.h:216
@ UNIT_MOD_RESISTANCE_START
Definition Unit.h:225
@ UNIT_MOD_HEALTH
Definition Unit.h:182
@ UNIT_MOD_DAMAGE_RANGED
Definition Unit.h:220
@ UNIT_MOD_POWER_START
Definition Unit.h:227
@ UNIT_MOD_DAMAGE_MAINHAND
Definition Unit.h:218
@ UNIT_MOD_ATTACK_POWER_RANGED
Definition Unit.h:217
@ OFFHAND_CRIT_PERCENTAGE
Definition Unit.h:238
@ CRIT_PERCENTAGE
Definition Unit.h:236
@ RANGED_CRIT_PERCENTAGE
Definition Unit.h:237
@ CR_EXPERTISE
Definition Unit.h:340
@ CR_CORRUPTION
Definition Unit.h:328
@ CR_HIT_MELEE
Definition Unit.h:322
@ CR_ARMOR_PENETRATION
Definition Unit.h:341
@ CR_CRIT_MELEE
Definition Unit.h:325
@ CR_CRIT_RANGED
Definition Unit.h:326
@ CR_VERSATILITY_HEALING_DONE
Definition Unit.h:346
@ CR_PARRY
Definition Unit.h:320
@ CR_DODGE
Definition Unit.h:319
@ CR_CORRUPTION_RESISTANCE
Definition Unit.h:329
@ CR_BLOCK
Definition Unit.h:321
@ CR_VERSATILITY_DAMAGE_DONE
Definition Unit.h:345
@ CR_HIT_SPELL
Definition Unit.h:324
@ CR_MASTERY
Definition Unit.h:342
@ CR_CRIT_SPELL
Definition Unit.h:327
@ CR_HIT_RANGED
Definition Unit.h:323
@ TOTAL_PCT
Definition Unit.h:165
@ BASE_PCT
Definition Unit.h:164
T AddPct(T &base, U pct)
Definition Util.h:85
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:565
T CalculatePct(T base, U pct)
Definition Util.h:72
SpellInfo const * GetSpellInfo() const
int32 GetMiscValue() const
SpellEffectValue GetAmount() const
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
void SetUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
Definition BaseEntity.h:221
void SetUpdateFieldStatValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type value)
Definition BaseEntity.h:299
UF::UpdateFieldHolder m_values
Definition BaseEntity.h:205
void ApplyModUpdateFieldValue(UF::UpdateFieldPrivateSetter< T > setter, typename UF::UpdateFieldPrivateSetter< T >::value_type mod, bool apply)
Definition BaseEntity.h:306
static bool IsPlayerMeetingCondition(Player const *player, uint32 conditionId)
bool UpdateAllStats() override
CreatureDifficulty const * GetCreatureDifficulty() const
Definition Creature.h:268
bool UpdateStats(Stats stat) override
uint32 GetPowerIndex(Powers power) const override
int32 GetCreatePowerValue(Powers power) const override
void UpdateAttackPowerAndDamage(bool ranged=false) override
void UpdateArmor() override
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:266
void UpdateMaxPower(Powers power) override
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const override
void UpdateMaxHealth() override
void UpdateResistances(uint32 school) override
void UpdateMaxPower(Powers power) override
void UpdateMaxHealth() override
bool UpdateStats(Stats stat) override
void SetBonusDamage(int32 damage)
int32 m_bonusSpellDamage
float m_statFromOwner[MAX_STATS]
void UpdateDamagePhysical(WeaponAttackType attType) override
void UpdateArmor() override
bool UpdateAllStats() override
void UpdateAttackPowerAndDamage(bool ranged=false) override
Definition Item.h:179
Unit * GetOwner() const
bool IsSpiritWolf() const
Unit *const m_owner
bool IsPetGhoul() const
Player * ToPlayer()
Definition Object.h:126
uint32 GetEntry() const
Definition Object.h:89
Definition Pet.h:40
void UpdateParryPercentage()
void UpdateMastery()
void UpdateArmorPenetration(int32 amount)
void UpdateDodgePercentage()
void ApplyModTargetResistance(int32 mod, bool apply)
Definition Player.h:2205
void UpdateMaxPower(Powers power) override
bool CanUseMastery() const
Definition Player.cpp:30610
bool CanParry() const
Definition Player.h:2489
void UpdateCritPercentage(WeaponAttackType attType)
UF::UpdateField< UF::ActivePlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition Player.h:3062
uint32 GetPowerIndex(Powers power) const override
float GetRatingBonusValue(CombatRating cr) const
Definition Player.cpp:5240
uint32 GetRuneBaseCooldown() const
Definition Player.cpp:27097
bool CanBlock() const
Definition Player.h:2491
void UpdateVersatilityDamageDone()
void UpdateCorruption()
void UpdateBlockPercentage()
void ApplyModDamageDonePos(SpellSchools school, int32 mod, bool apply)
Definition Player.h:2215
void ApplySpellPenetrationBonus(int32 amount, bool apply)
void UpdateArmor() override
void UpdateManaRegen()
void RecalculateRating(CombatRating cr)
Definition Player.h:2229
Pet * GetPet() const
Definition Player.cpp:22060
bool UpdateStats(Stats stat) override
void _RemoveAllItemMods()
Definition Player.cpp:8945
void _ApplyAllItemMods()
Definition Player.cpp:8985
void UpdateSpellHitChances()
void UpdateExpertise(WeaponAttackType attType)
void _ApplyAllStatBonuses()
float GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
Definition Player.cpp:5075
void ApplyAllAzeriteItemMods(bool apply)
Definition Player.cpp:9052
void UpdateHealingDonePercentMod()
void ApplyManaRegenBonus(int32 amount, bool apply)
void GetDodgeFromAgility(float &diminishing, float &nondiminishing) const
Definition Player.cpp:5099
void SetBaseModPctValue(BaseModGroup modGroup, float val)
Definition Player.cpp:4997
void UpdateResistances(uint32 school) override
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const override
void UpdateSpellDamageAndHealingBonus()
uint32 m_baseSpellPower
Definition Player.h:3257
void UpdateMaxHealth() override
void UpdateMeleeHitChances()
void UpdateAllRunesRegen()
uint32 m_baseHealthRegen
Definition Player.h:3259
void UpdateRangedHitChances()
uint32 m_baseManaRegen
Definition Player.h:3258
void UpdateAllRatings()
Definition Player.cpp:5466
void ApplySpellPowerBonus(int32 amount, bool apply)
void UpdateAllCritPercentages()
bool UpdateAllStats() override
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition Player.cpp:9669
void _RemoveAllStatBonuses()
int32 m_spellPenetrationItemMod
Definition Player.h:3260
Stats GetPrimaryStat() const
void ApplyHealthRegenBonus(int32 amount, bool apply)
void UpdateSpellCritChance()
ChrSpecializationEntry const * GetPrimarySpecializationEntry() const
Definition Player.cpp:30819
float GetHealthBonusFromStamina() const
void UpdateAttackPowerAndDamage(bool ranged=false) override
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition Unit.h:635
float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
Definition Unit.cpp:9664
virtual void UpdateResistances(uint32 school)
Definition Unit.cpp:9891
bool IsHunterPet() const
Definition Unit.h:752
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1342
void SetStat(Stats stat, int32 val)
Definition Unit.h:773
float GetTotalAuraModValue(UnitMods unitMod) const
Definition Unit.cpp:9837
float GetTotalStatValue(Stats stat) const
Definition Unit.cpp:9821
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3828
virtual int32 GetCreatePowerValue(Powers power) const
uint8 GetClass() const
Definition Unit.h:764
void SetArmor(int32 val, int32 bonusVal)
Definition Unit.h:775
bool CanUseAttackType(uint8 attacktype) const
Definition Unit.cpp:2607
virtual void UpdateAllResistances()
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1504
std::forward_list< AuraEffect * > AuraEffectList
Definition Unit.h:652
bool haveOffhandWeapon() const
Definition Unit.cpp:525
bool IsPet() const
Definition Unit.h:751
Powers GetPowerType() const
Definition Unit.h:811
bool CanDualWield() const
Definition Unit.h:703
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition Unit.cpp:10934
float m_modRangedHitChance
Definition Unit.h:1515
void SetBonusResistanceMod(SpellSchools school, int32 val)
Definition Unit.h:785
void SetRangedAttackPowerModPos(int32 attackPowerMod)
Definition Unit.h:1564
float GetTotalAuraMultiplier(AuraType auraType) const
Definition Unit.cpp:5074
virtual void UpdateDamagePhysical(WeaponAttackType attType)
void _ApplyAllAuraStatMods()
Definition Unit.cpp:4598
void SetRangedAttackPowerMultiplier(float attackPowerMult)
Definition Unit.h:1566
void SetResistance(SpellSchools school, int32 val)
Definition Unit.h:784
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
Definition Unit.cpp:5139
float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const
Definition Unit.cpp:9942
uint32 GetCreateHealth() const
Definition Unit.h:1415
float GetTotalAuraModifier(AuraType auraType) const
Definition Unit.cpp:5069
bool HasAuraType(AuraType auraType) const
Definition Unit.cpp:4814
uint32 GetArmor() const
Definition Unit.h:774
float m_modMeleeHitChance
Definition Unit.h:1514
void _RemoveAllAuraStatMods()
Definition Unit.cpp:4592
float GetAPMultiplier(WeaponAttackType attType, bool normalized) const
Definition Unit.cpp:11034
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const =0
void SetAttackPower(int32 attackPower)
Definition Unit.h:1559
void SetMaxHealth(uint64 val)
Definition Unit.cpp:10004
float GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
Definition Unit.cpp:5129
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition Unit.h:1881
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:7583
float GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon=true) const
Definition Unit.cpp:9912
float GetCreateStat(Stats stat) const
Definition Unit.h:1421
int32 GetBonusResistanceMod(SpellSchools school) const
Definition Unit.h:782
void SetCanModifyStats(bool modifyStats)
Definition Unit.h:1549
float GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType) const
Definition Unit.cpp:9653
float GetStat(Stats stat) const
Definition Unit.h:772
void SetMaxPower(Powers power, int32 val)
Definition Unit.cpp:10083
uint32 GetCreateMana() const
Definition Unit.h:1417
void SetRangedAttackPower(int32 attackPower)
Definition Unit.h:1563
int32 GetResistance(SpellSchools school) const
Definition Unit.h:781
float m_modSpellHitChance
Definition Unit.h:1516
Guardian * GetGuardianPet() const
Definition Unit.cpp:6231
void SetAttackPowerMultiplier(float attackPowerMult)
Definition Unit.h:1562
AuraMap & GetOwnedAuras()
Definition Unit.h:1285
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:7084
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
Definition Unit.cpp:9635
void SetAttackPowerModPos(int32 attackPowerMod)
Definition Unit.h:1560
uint8 GetLevel() const
Definition Unit.h:757
void UpdateStatBuffMod(Stats stat)
Definition Unit.cpp:5219
#define sWorld
Definition World.h:916
@ CONFIG_STATS_LIMITS_DODGE
Definition World.h:215
@ CONFIG_STATS_LIMITS_PARRY
Definition World.h:216
@ CONFIG_STATS_LIMITS_CRIT
Definition World.h:218
@ CONFIG_STATS_LIMITS_BLOCK
Definition World.h:217
@ CONFIG_STATS_LIMITS_ENABLE
Definition World.h:172
uint8 AttackPowerPerAgility
uint8 RangedAttackPowerPerAgility
uint8 AttackPowerPerStrength
UpdateField< float, 70, 80 > SpellCritPercentage
UpdateFieldArray< int32, 32, 332, 333 > CombatRatings
UpdateField< float, 70, 72 > BlockPercentage
UpdateField< int32, 70, 87 > Versatility
UpdateField< float, 32, 68 > OffhandExpertise
UpdateFieldArray< int32, 7, 271, 279 > ModDamageDoneNeg
UpdateFieldArray< int32, 7, 271, 272 > ModDamageDonePos
UpdateField< float, 70, 77 > CritPercentage
UpdateField< int32, 70, 92 > ModHealingDonePos
UpdateField< float, 70, 83 > Mastery
UpdateField< float, 70, 73 > DodgePercentage
UpdateField< float, 70, 78 > RangedCritPercentage
UpdateField< float, 70, 79 > OffhandCritPercentage
UpdateFieldArray< float, 7, 271, 293 > ModHealingDonePercent
UpdateField< float, 70, 75 > ParryPercentage
UpdateField< float, 32, 67 > MainhandExpertise
UpdateField< float, 32, 62 > MaxDamage
UpdateField< float, 32, 63 > MinOffHandDamage
UpdateField< float, 32, 61 > MinDamage
UpdateField< float, 96, 105 > MinRangedDamage
UpdateField< float, 64, 65 > MaxOffHandDamage
UpdateFieldArray< float, 10, 137, 158 > PowerRegenFlatModifier
UpdateField< float, 96, 106 > MaxRangedDamage
UpdateFieldArray< float, 10, 137, 168 > PowerRegenInterruptedFlatModifier