TrinityCore
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
59{
62}
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
151{
153 return;
154
156
157 // For speed just update for client
159 for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
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](int32 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{
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
498{
499 auto applyCritLimit = [](float value)
500 {
501 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
502 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_CRIT) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_CRIT) : value;
503 return value;
504 };
505
506 switch (attType)
507 {
508 case OFF_ATTACK:
511 break;
512 case RANGED_ATTACK:
515 break;
516 case BASE_ATTACK:
517 default:
520 break;
521 }
522}
523
525{
526 float value = 5.0f;
527
531
535}
536
538{
539 if (!CanUseMastery())
540 {
542 return;
543 }
544
548
550 if (!chrSpec)
551 return;
552
553 for (int32 masterySpellId : chrSpec->MasterySpellID)
554 {
555 if (Aura* aura = GetAura(masterySpellId))
556 {
557 for (AuraEffect* auraEff : aura->GetAuraEffects())
558 {
559 if (!auraEff)
560 continue;
561
562 float mult = auraEff->GetSpellEffectInfo().BonusCoefficient;
563 if (G3D::fuzzyEq(mult, 0.0f))
564 continue;
565
566 auraEff->ChangeAmount(int32(value * mult));
567 }
568 }
569 }
570}
571
573{
574 // No proof that CR_VERSATILITY_DAMAGE_DONE is allways = ActivePlayerData::Versatility
576
577 if (GetClass() == CLASS_HUNTER)
579 else
581}
582
584{
585 float value = 1.0f;
586
588
590 AddPct(value, auraEffect->GetAmount());
591
592 for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
594}
595
597{
598 0.9560f, // Warrior
599 0.9560f, // Paladin
600 0.9880f, // Hunter
601 0.9880f, // Rogue
602 0.9830f, // Priest
603 0.9560f, // DK
604 0.9880f, // Shaman
605 0.9830f, // Mage
606 0.9830f, // Warlock
607 0.9830f, // Monk
608 0.9720f, // Druid
609 0.9830f, // Demon Hunter
610 0.9880f, // Evoker
611 1.0f, // Adventurer
612};
613
614// helper function
615float CalculateDiminishingReturns(float const (&capArray)[MAX_CLASSES], uint8 playerClass, float nonDiminishValue, float diminishValue)
616{
617 // 1 1 k cx
618 // --- = --- + --- <=> x' = --------
619 // x' c x x + ck
620
621 // where:
622 // k is m_diminishing_k for that class
623 // c is capArray for that class
624 // x is chance before DR (diminishValue)
625 // x' is chance after DR (our result)
626
627 uint32 const classIdx = playerClass - 1;
628
629 float const k = m_diminishing_k[classIdx];
630 float const c = capArray[classIdx];
631
632 float result = c * diminishValue / (diminishValue + c * k);
633 result += nonDiminishValue;
634 return result;
635}
636
637float const parry_cap[MAX_CLASSES] =
638{
639 65.631440f, // Warrior
640 65.631440f, // Paladin
641 145.560408f, // Hunter
642 145.560408f, // Rogue
643 0.0f, // Priest
644 65.631440f, // DK
645 145.560408f, // Shaman
646 0.0f, // Mage
647 0.0f, // Warlock
648 90.6425f, // Monk
649 0.0f, // Druid
650 65.631440f, // Demon Hunter
651 0.0f, // Evoker
652 0.0f, // Adventurer
653};
654
656{
657 // No parry
658 float value = 0.0f;
659 uint32 pclass = GetClass() - 1;
660 if (CanParry() && parry_cap[pclass] > 0.0f)
661 {
662 float nondiminishing = 5.0f;
663 // Parry from rating
664 float diminishing = GetRatingBonusValue(CR_PARRY);
665 // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura
667
668 // apply diminishing formula to diminishing parry chance
669 value = CalculateDiminishingReturns(parry_cap, GetClass(), nondiminishing, diminishing);
670
671 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
672 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) : value;
673
674 }
676}
677
678float const dodge_cap[MAX_CLASSES] =
679{
680 65.631440f, // Warrior
681 65.631440f, // Paladin
682 145.560408f, // Hunter
683 145.560408f, // Rogue
684 150.375940f, // Priest
685 65.631440f, // DK
686 145.560408f, // Shaman
687 150.375940f, // Mage
688 150.375940f, // Warlock
689 145.560408f, // Monk
690 116.890707f, // Druid
691 145.560408f, // Demon Hunter
692 145.560408f, // Evoker
693 0.0f, // Adventurer
694};
695
697{
698 float diminishing = 0.0f, nondiminishing = 0.0f;
699 GetDodgeFromAgility(diminishing, nondiminishing);
700 // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura
702 // Dodge from rating
703 diminishing += GetRatingBonusValue(CR_DODGE);
704
705 // apply diminishing formula to diminishing dodge chance
706 float value = CalculateDiminishingReturns(dodge_cap, GetClass(), nondiminishing, diminishing);
707
708 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
709 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) : value;
710
712}
713
715{
716 float crit = 5.0f;
717 // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
719 // Increase crit from SPELL_AURA_MOD_CRIT_PCT
721 // Increase crit from spell crit ratings
723
724 // Store crit value
726}
727
729{
731 for (CorruptionEffectsEntry const* corruptionEffect : sCorruptionEffectsStore)
732 {
734 continue;
735
736 if (effectiveCorruption < corruptionEffect->MinCorruption)
737 {
738 RemoveAura(corruptionEffect->Aura);
739 continue;
740 }
741
742 if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(corruptionEffect->PlayerConditionID))
743 {
744 if (!ConditionMgr::IsPlayerMeetingCondition(this, playerCondition))
745 {
746 RemoveAura(corruptionEffect->Aura);
747 continue;
748 }
749 }
750
751 CastSpell(this, corruptionEffect->Aura, true);
752 }
753}
754
756{
757 // Store Rating Value
759}
760
762{
764}
765
767{
769}
770
772{
775}
776
778{
779 if (attack == RANGED_ATTACK)
780 return;
781
783
784 Item const* weapon = GetWeaponForAttack(attack, true);
785 expertise += GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE, [weapon](AuraEffect const* aurEff) -> bool
786 {
787 return aurEff->GetSpellInfo()->IsItemFitToSpellRequirements(weapon);
788 });
789
790 if (expertise < 0)
791 expertise = 0;
792
793 switch (attack)
794 {
795 case BASE_ATTACK:
797 break;
798 case OFF_ATTACK:
800 break;
801 default:
802 break;
803 }
804}
805
807{
810}
811
813{
815}
816
818{
819 uint32 manaIndex = GetPowerIndex(POWER_MANA);
820 if (manaIndex == MAX_POWERS)
821 return;
822
823 // Get base of Mana Pool in sBaseMPGameTable
824 uint32 basemana = 0;
825 sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), basemana);
826 float base_regen = basemana / 100.f;
827
829
830 // Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT
832
833 // Apply PCT bonus from SPELL_AURA_MOD_MANA_REGEN_PCT
835
838}
839
841{
843 return;
844
845 uint32 runeIndex = GetPowerIndex(POWER_RUNES);
846 if (runeIndex == MAX_POWERS)
847 return;
848
849 PowerTypeEntry const* runeEntry = sDB2Manager.GetPowerTypeEntry(POWER_RUNES);
850
851 uint32 cooldown = GetRuneBaseCooldown();
852 SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenFlatModifier, runeIndex), float(1 * IN_MILLISECONDS) / float(cooldown) - runeEntry->RegenPeace);
854}
855
857{
858 SetCanModifyStats(false);
859
863
864 SetCanModifyStats(true);
865
867}
868
870{
871 SetCanModifyStats(false);
872
876
877 SetCanModifyStats(true);
878
880}
881
882/*#######################################
883######## ########
884######## MOBS STAT SYSTEM ########
885######## ########
886#######################################*/
887
889{
890 if (PowerTypeEntry const* powerType = sDB2Manager.GetPowerTypeEntry(power))
891 if (!powerType->GetFlags().HasFlag(PowerTypeFlags::IsUsedByNPCs))
892 return 0;
893
894 return Unit::GetCreatePowerValue(power);
895}
896
898{
899 return true;
900}
901
903{
907
908 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
910
912
913 return true;
914}
915
917{
920 SetArmor(int32(baseValue), int32(value - baseValue));
921}
922
924{
926 SetMaxHealth(uint32(value));
927}
928
930{
931 if (power == GetPowerType())
932 return 0;
933 switch (power)
934 {
936 return 2;
938 return 1;
940 return 3;
942 return 4;
944 return 5;
945 default:
946 break;
947 }
948 return MAX_POWERS;
949}
950
952{
953 if (GetPowerIndex(power) == MAX_POWERS)
954 return;
955
957
958 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
959 value *= GetPctModifierValue(unitMod, BASE_PCT);
960 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
961 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
962
963 SetMaxPower(power, (int32)std::lroundf(value));
964}
965
967{
969
970 float baseAttackPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
971 float attackPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
972
973 if (ranged)
974 {
975 SetRangedAttackPower(int32(baseAttackPower));
976 SetRangedAttackPowerMultiplier(attackPowerMultiplier);
977 }
978 else
979 {
980 SetAttackPower(int32(baseAttackPower));
981 SetAttackPowerMultiplier(attackPowerMultiplier);
982 }
983
984 // automatically update weapon damage after attack power modification
985 if (ranged)
987 else
988 {
991 }
992}
993
994void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const
995{
996 float variance = 1.0f;
997 UnitMods unitMod;
998 switch (attType)
999 {
1000 case BASE_ATTACK:
1001 default:
1002 variance = GetCreatureTemplate()->BaseVariance;
1003 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
1004 break;
1005 case OFF_ATTACK:
1006 variance = GetCreatureTemplate()->BaseVariance;
1007 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
1008 break;
1009 case RANGED_ATTACK:
1010 variance = GetCreatureTemplate()->RangeVariance;
1011 unitMod = UNIT_MOD_DAMAGE_RANGED;
1012 break;
1013 }
1014
1015 if (attType == OFF_ATTACK && !haveOffhandWeapon())
1016 {
1017 minDamage = 0.0f;
1018 maxDamage = 0.0f;
1019 return;
1020 }
1021
1022 float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
1023 float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
1024
1025 if (!CanUseAttackType(attType)) // disarm case
1026 {
1027 weaponMinDamage = 0.0f;
1028 weaponMaxDamage = 0.0f;
1029 }
1030
1031 float attackPower = GetTotalAttackPowerValue(attType, false);
1032 float attackSpeedMulti = GetAPMultiplier(attType, normalized);
1033 float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + (attackPower / 3.5f) * variance;
1034 float basePct = GetPctModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
1035 float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
1036 float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
1037 float dmgMultiplier = GetCreatureDifficulty()->DamageModifier; // = DamageModifier * GetDamageMod(rank);
1038
1039 minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
1040 maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
1041}
1042
1043/*#######################################
1044######## ########
1045######## PETS STAT SYSTEM ########
1046######## ########
1047#######################################*/
1048
1049#define ENTRY_IMP 416
1050#define ENTRY_VOIDWALKER 1860
1051#define ENTRY_SUCCUBUS 1863
1052#define ENTRY_FELHUNTER 417
1053#define ENTRY_FELGUARD 17252
1054#define ENTRY_WATER_ELEMENTAL 510
1055#define ENTRY_TREANT 1964
1056#define ENTRY_FIRE_ELEMENTAL 15438
1057#define ENTRY_GHOUL 26125
1058#define ENTRY_BLOODWORM 28017
1059
1061{
1062 // value = ((base_value * base_pct) + total_value) * total_pct
1063 float value = GetTotalStatValue(stat);
1064 UpdateStatBuffMod(stat);
1065 float ownersBonus = 0.0f;
1066
1067 Unit* owner = GetOwner();
1068 // Handle Death Knight Glyphs and Talents
1069 float mod = 0.75f;
1070 if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
1071 {
1072 if (stat == STAT_STAMINA)
1073 mod = 0.3f; // Default Owner's Stamina scale
1074 else
1075 mod = 0.7f; // Default Owner's Strength scale
1076
1077 ownersBonus = float(owner->GetStat(stat)) * mod;
1078 value += ownersBonus;
1079 }
1080 else if (stat == STAT_STAMINA)
1081 {
1082 ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 30);
1083 value += ownersBonus;
1084 }
1085 //warlock's and mage's pets gain 30% of owner's intellect
1086 else if (stat == STAT_INTELLECT)
1087 {
1088 if (owner->GetClass() == CLASS_WARLOCK || owner->GetClass() == CLASS_MAGE)
1089 {
1090 ownersBonus = CalculatePct(owner->GetStat(stat), 30);
1091 value += ownersBonus;
1092 }
1093 }
1094/*
1095 else if (stat == STAT_STRENGTH)
1096 {
1097 if (IsPetGhoul())
1098 value += float(owner->GetStat(stat)) * 0.3f;
1099 }
1100*/
1101
1102 SetStat(stat, int32(value));
1103 m_statFromOwner[stat] = ownersBonus;
1104 UpdateStatBuffMod(stat);
1105
1106 switch (stat)
1107 {
1109 case STAT_AGILITY: UpdateArmor(); break;
1110 case STAT_STAMINA: UpdateMaxHealth(); break;
1112 default:
1113 break;
1114 }
1115
1116 return true;
1117}
1118
1120{
1122
1123 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
1124 UpdateStats(Stats(i));
1125
1126 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
1128
1130
1131 return true;
1132}
1133
1135{
1136 if (school > SPELL_SCHOOL_NORMAL)
1137 {
1139 float bonusValue = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)) - baseValue;
1140
1141 // hunter and warlock pets gain 40% of owner's resistance
1142 if (IsPet())
1143 {
1144 baseValue += float(CalculatePct(m_owner->GetResistance(SpellSchools(school)), 40));
1145 bonusValue += float(CalculatePct(m_owner->GetBonusResistanceMod(SpellSchools(school)), 40));
1146 }
1147
1148 SetResistance(SpellSchools(school), int32(baseValue));
1149 SetBonusResistanceMod(SpellSchools(school), int32(bonusValue));
1150 }
1151 else
1152 UpdateArmor();
1153}
1154
1156{
1157 float baseValue = 0.0f;
1158 float value = 0.0f;
1159 float bonus_armor = 0.0f;
1160 UnitMods unitMod = UNIT_MOD_ARMOR;
1161
1162 // hunter pets gain 35% of owner's armor value, warlock pets gain 100% of owner's armor
1163 if (IsHunterPet())
1164 bonus_armor = float(CalculatePct(m_owner->GetArmor(), 70));
1165 else if (IsPet())
1166 bonus_armor = m_owner->GetArmor();
1167
1168 value = GetFlatModifierValue(unitMod, BASE_VALUE);
1169 baseValue = value;
1170 value *= GetPctModifierValue(unitMod, BASE_PCT);
1171 value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
1172 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1173
1174 SetArmor(int32(baseValue), int32(value - baseValue));
1175}
1176
1178{
1179 UnitMods unitMod = UNIT_MOD_HEALTH;
1180 float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA);
1181
1182 float multiplicator;
1183 switch (GetEntry())
1184 {
1185 case ENTRY_IMP: multiplicator = 8.4f; break;
1186 case ENTRY_VOIDWALKER: multiplicator = 11.0f; break;
1187 case ENTRY_SUCCUBUS: multiplicator = 9.1f; break;
1188 case ENTRY_FELHUNTER: multiplicator = 9.5f; break;
1189 case ENTRY_FELGUARD: multiplicator = 11.0f; break;
1190 case ENTRY_BLOODWORM: multiplicator = 1.0f; break;
1191 default: multiplicator = 10.0f; break;
1192 }
1193
1194 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
1195 value *= GetPctModifierValue(unitMod, BASE_PCT);
1196 value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
1197 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1198
1199 SetMaxHealth((uint32)value);
1200}
1201
1203{
1204 if (GetPowerIndex(power) == MAX_POWERS)
1205 return;
1206
1208
1209 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
1210 value *= GetPctModifierValue(unitMod, BASE_PCT);
1211 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
1212 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1213
1214 SetMaxPower(power, int32(value));
1215}
1216
1218{
1219 if (ranged)
1220 return;
1221
1222 float val = 0.0f;
1223 float bonusAP = 0.0f;
1225
1226 if (GetEntry() == ENTRY_IMP) // imp's attack power
1227 val = GetStat(STAT_STRENGTH) - 10.0f;
1228 else
1229 val = 2 * GetStat(STAT_STRENGTH) - 20.0f;
1230
1231 Player* owner = GetOwner() ? GetOwner()->ToPlayer() : nullptr;
1232 if (owner)
1233 {
1234 if (IsHunterPet()) //hunter pets benefit from owner's attack power
1235 {
1236 float mod = 1.0f; //Hunter contribution modifier
1237 bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
1239 }
1240 else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
1241 {
1242 bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
1244 }
1245 else if (IsSpiritWolf()) //wolf benefit from shaman's attack power
1246 {
1247 float dmg_multiplier = 0.31f;
1248 bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier;
1249 SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier));
1250 }
1251 //demons benefit from warlocks shadow or fire damage
1252 else if (IsPet())
1253 {
1254 int32 fire = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FIRE];
1255 int32 shadow = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_SHADOW] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_SHADOW];
1256 int32 maximum = (fire > shadow) ? fire : shadow;
1257 if (maximum < 0)
1258 maximum = 0;
1259 SetBonusDamage(int32(maximum * 0.15f));
1260 bonusAP = maximum * 0.57f;
1261 }
1262 //water elementals benefit from mage's frost damage
1263 else if (GetEntry() == ENTRY_WATER_ELEMENTAL)
1264 {
1265 int32 frost = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FROST] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FROST];
1266 if (frost < 0)
1267 frost = 0;
1268 SetBonusDamage(int32(frost * 0.4f));
1269 }
1270 }
1271
1273
1274 //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
1275 float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
1276 float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
1277
1278 SetAttackPower(int32(base_attPower));
1279 SetAttackPowerMultiplier(attPowerMultiplier);
1280
1281 //automatically update weapon damage after attack power modification
1283}
1284
1286{
1287 if (attType > BASE_ATTACK)
1288 return;
1289
1290 float bonusDamage = 0.0f;
1291 if (Player* playerOwner = m_owner->ToPlayer())
1292 {
1293 //force of nature
1294 if (GetEntry() == ENTRY_TREANT)
1295 {
1296 int32 spellDmg = playerOwner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_NATURE] - playerOwner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_NATURE];
1297 if (spellDmg > 0)
1298 bonusDamage = spellDmg * 0.09f;
1299 }
1300 //greater fire elemental
1301 else if (GetEntry() == ENTRY_FIRE_ELEMENTAL)
1302 {
1303 int32 spellDmg = playerOwner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE] - playerOwner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FIRE];
1304 if (spellDmg > 0)
1305 bonusDamage = spellDmg * 0.4f;
1306 }
1307 }
1308
1310
1311 float att_speed = float(GetBaseAttackTime(BASE_ATTACK))/1000.0f;
1312
1313 float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType, false) / 3.5f * att_speed + bonusDamage;
1314 float base_pct = GetPctModifierValue(unitMod, BASE_PCT);
1315 float total_value = GetFlatModifierValue(unitMod, TOTAL_VALUE);
1316 float total_pct = GetPctModifierValue(unitMod, TOTAL_PCT);
1317
1318 float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
1319 float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
1320
1321 float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
1322 float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
1323
1326}
1327
1329{
1330 m_bonusSpellDamage = damage;
1331 if (Player* playerOwner = GetOwner()->ToPlayer())
1332 playerOwner->SetPetSpellPower(damage);
1333}
@ IN_MILLISECONDS
Definition: Common.h:35
DB2Storage< ChrClassesEntry > sChrClassesStore("ChrClasses.db2", &ChrClassesLoadInfo::Instance)
DB2Storage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore("SpellShapeshiftForm.db2", &SpellShapeshiftFormLoadInfo::Instance)
DB2Storage< CorruptionEffectsEntry > sCorruptionEffectsStore("CorruptionEffects.db2", &CorruptionEffectsLoadInfo::Instance)
DB2Storage< PlayerConditionEntry > sPlayerConditionStore("PlayerCondition.db2", &PlayerConditionLoadInfo::Instance)
#define sDB2Manager
Definition: DB2Stores.h:538
CorruptionEffectsFlag
Definition: DBCEnums.h:417
uint8_t uint8
Definition: Define.h:144
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
GameTable< GtHpPerStaEntry > sHpPerStaGameTable
Definition: GameTables.cpp:35
@ ITEM_FLAG3_ALWAYS_ALLOW_DUAL_WIELD
Definition: ItemTemplate.h:267
#define sObjectMgr
Definition: ObjectMgr.h:1946
#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_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
float const dodge_cap[MAX_CLASSES]
Definition: StatSystem.cpp:678
#define ENTRY_FELGUARD
#define ENTRY_FIRE_ELEMENTAL
#define ENTRY_BLOODWORM
#define ENTRY_VOIDWALKER
#define ENTRY_FELHUNTER
float CalculateDiminishingReturns(float const (&capArray)[MAX_CLASSES], uint8 playerClass, float nonDiminishValue, float diminishValue)
Definition: StatSystem.cpp:615
float const parry_cap[MAX_CLASSES]
Definition: StatSystem.cpp:637
#define ENTRY_TREANT
bool _ModifyUInt32(bool apply, uint32 &baseValue, int32 &amount)
Definition: StatSystem.cpp:32
#define ENTRY_WATER_ELEMENTAL
#define ENTRY_SUCCUBUS
float const m_diminishing_k[MAX_CLASSES]
Definition: StatSystem.cpp:596
#define ENTRY_IMP
#define BASE_MAXDAMAGE
Definition: UnitDefines.h:34
#define BASE_MINDAMAGE
Definition: UnitDefines.h:33
@ BASE_VALUE
Definition: Unit.h:152
@ TOTAL_VALUE
Definition: Unit.h:154
@ FLAT_MOD
Definition: Unit.h:239
@ PCT_MOD
Definition: Unit.h:240
@ MINDAMAGE
Definition: Unit.h:167
@ MAXDAMAGE
Definition: Unit.h:168
UnitMods
Definition: Unit.h:172
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:214
@ UNIT_MOD_ARMOR
Definition: Unit.h:204
@ UNIT_MOD_ATTACK_POWER
Definition: Unit.h:211
@ UNIT_MOD_RESISTANCE_START
Definition: Unit.h:220
@ UNIT_MOD_HEALTH
Definition: Unit.h:177
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:215
@ UNIT_MOD_POWER_START
Definition: Unit.h:222
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:213
@ UNIT_MOD_ATTACK_POWER_RANGED
Definition: Unit.h:212
@ OFFHAND_CRIT_PERCENTAGE
Definition: Unit.h:232
@ CRIT_PERCENTAGE
Definition: Unit.h:230
@ RANGED_CRIT_PERCENTAGE
Definition: Unit.h:231
@ CR_EXPERTISE
Definition: Unit.h:334
@ CR_CORRUPTION
Definition: Unit.h:322
@ CR_HIT_MELEE
Definition: Unit.h:316
@ CR_ARMOR_PENETRATION
Definition: Unit.h:335
@ CR_CRIT_MELEE
Definition: Unit.h:319
@ CR_CRIT_RANGED
Definition: Unit.h:320
@ CR_VERSATILITY_HEALING_DONE
Definition: Unit.h:340
@ CR_PARRY
Definition: Unit.h:314
@ CR_DODGE
Definition: Unit.h:313
@ CR_CORRUPTION_RESISTANCE
Definition: Unit.h:323
@ CR_BLOCK
Definition: Unit.h:315
@ CR_VERSATILITY_DAMAGE_DONE
Definition: Unit.h:339
@ CR_HIT_SPELL
Definition: Unit.h:318
@ CR_MASTERY
Definition: Unit.h:336
@ CR_CRIT_SPELL
Definition: Unit.h:321
@ CR_HIT_RANGED
Definition: Unit.h:317
@ TOTAL_PCT
Definition: Unit.h:161
@ BASE_PCT
Definition: Unit.h:160
T AddPct(T &base, U pct)
Definition: Util.h:85
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:491
T CalculatePct(T base, U pct)
Definition: Util.h:72
SpellInfo const * GetSpellInfo() const
int32 GetMiscValue() const
int32 GetAmount() const
static bool IsPlayerMeetingCondition(Player const *player, PlayerConditionEntry const *condition)
bool UpdateAllStats() override
Definition: StatSystem.cpp:902
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:252
bool UpdateStats(Stats stat) override
Definition: StatSystem.cpp:897
uint32 GetPowerIndex(Powers power) const override
Definition: StatSystem.cpp:929
int32 GetCreatePowerValue(Powers power) const override
Definition: StatSystem.cpp:888
void UpdateAttackPowerAndDamage(bool ranged=false) override
Definition: StatSystem.cpp:966
void UpdateArmor() override
Definition: StatSystem.cpp:916
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:250
void UpdateMaxPower(Powers power) override
Definition: StatSystem.cpp:951
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const override
Definition: StatSystem.cpp:994
void UpdateMaxHealth() override
Definition: StatSystem.cpp:923
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:170
Unit * GetOwner() const
bool IsSpiritWolf() const
Unit *const m_owner
bool IsPetGhoul() const
Player * ToPlayer()
Definition: Object.h:215
void SetUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:287
uint32 GetEntry() const
Definition: Object.h:161
UF::UpdateFieldHolder m_values
Definition: Object.h:266
void SetUpdateFieldStatValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:344
void ApplyModUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type mod, bool apply)
Definition: Object.h:351
static Player * ToPlayer(Object *o)
Definition: Object.h:213
Definition: Pet.h:40
void UpdateParryPercentage()
Definition: StatSystem.cpp:655
void UpdateMastery()
Definition: StatSystem.cpp:537
void UpdateArmorPenetration(int32 amount)
Definition: StatSystem.cpp:755
void UpdateDodgePercentage()
Definition: StatSystem.cpp:696
void ApplyModTargetResistance(int32 mod, bool apply)
Definition: Player.h:2034
void UpdateMaxPower(Powers power) override
Definition: StatSystem.cpp:327
bool CanUseMastery() const
Definition: Player.cpp:29531
bool CanParry() const
Definition: Player.h:2298
void UpdateCritPercentage(WeaponAttackType attType)
Definition: StatSystem.cpp:497
uint32 GetPowerIndex(Powers power) const override
Definition: StatSystem.cpp:322
float GetRatingBonusValue(CombatRating cr) const
Definition: Player.cpp:5286
uint32 GetRuneBaseCooldown() const
Definition: Player.cpp:26313
bool CanBlock() const
Definition: Player.h:2300
void UpdateVersatilityDamageDone()
Definition: StatSystem.cpp:572
void UpdateCorruption()
Definition: StatSystem.cpp:728
void UpdateBlockPercentage()
Definition: StatSystem.cpp:478
void ApplyModDamageDonePos(SpellSchools school, int32 mod, bool apply)
Definition: Player.h:2044
void ApplySpellPenetrationBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:229
void UpdateArmor() override
Definition: StatSystem.cpp:249
void UpdateManaRegen()
Definition: StatSystem.cpp:817
void RecalculateRating(CombatRating cr)
Definition: Player.h:2058
Pet * GetPet() const
Definition: Player.cpp:21513
bool UpdateStats(Stats stat) override
Definition: StatSystem.cpp:106
void _RemoveAllItemMods()
Definition: Player.cpp:8902
void _ApplyAllItemMods()
Definition: Player.cpp:8942
void UpdateSpellHitChances()
Definition: StatSystem.cpp:771
void UpdateExpertise(WeaponAttackType attType)
Definition: StatSystem.cpp:777
void _ApplyAllStatBonuses()
Definition: StatSystem.cpp:856
float GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
Definition: Player.cpp:5121
void ApplyAllAzeriteItemMods(bool apply)
Definition: Player.cpp:9009
void UpdateHealingDonePercentMod()
Definition: StatSystem.cpp:583
void ApplyManaRegenBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:806
void GetDodgeFromAgility(float &diminishing, float &nondiminishing) const
Definition: Player.cpp:5145
void SetBaseModPctValue(BaseModGroup modGroup, float val)
Definition: Player.cpp:5043
void UpdateResistances(uint32 school) override
Definition: StatSystem.cpp:235
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const override
Definition: StatSystem.cpp:423
void UpdateSpellDamageAndHealingBonus()
Definition: StatSystem.cpp:169
uint32 m_baseSpellPower
Definition: Player.h:3054
void UpdateMaxHealth() override
Definition: StatSystem.cpp:310
void UpdateMeleeHitChances()
Definition: StatSystem.cpp:761
void UpdateAllRunesRegen()
Definition: StatSystem.cpp:840
uint32 m_baseHealthRegen
Definition: Player.h:3056
void UpdateRangedHitChances()
Definition: StatSystem.cpp:766
uint32 m_baseManaRegen
Definition: Player.h:3055
void UpdateAllRatings()
Definition: Player.cpp:5508
void ApplySpellPowerBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:150
void UpdateAllCritPercentages()
Definition: StatSystem.cpp:524
UF::UpdateField< UF::ActivePlayerData, 0, TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition: Player.h:2864
bool UpdateAllStats() override
Definition: StatSystem.cpp:197
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: Player.cpp:9643
void _RemoveAllStatBonuses()
Definition: StatSystem.cpp:869
int32 m_spellPenetrationItemMod
Definition: Player.h:3057
Stats GetPrimaryStat() const
Definition: StatSystem.cpp:291
void ApplyHealthRegenBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:812
void UpdateSpellCritChance()
Definition: StatSystem.cpp:714
ChrSpecializationEntry const * GetPrimarySpecializationEntry() const
Definition: Player.cpp:29827
float GetHealthBonusFromStamina() const
Definition: StatSystem.cpp:279
void UpdateAttackPowerAndDamage(bool ranged=false) override
Definition: StatSystem.cpp:343
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:683
Definition: Unit.h:627
float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
Definition: Unit.cpp:9041
virtual void UpdateResistances(uint32 school)
Definition: Unit.cpp:9264
bool IsHunterPet() const
Definition: Unit.h:741
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1321
void SetStat(Stats stat, int32 val)
Definition: Unit.h:761
float GetTotalAuraModValue(UnitMods unitMod) const
Definition: Unit.cpp:9211
float GetTotalStatValue(Stats stat) const
Definition: Unit.cpp:9197
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3685
virtual int32 GetCreatePowerValue(Powers power) const
Definition: StatSystem.cpp:89
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1814
uint8 GetClass() const
Definition: Unit.h:752
void SetArmor(int32 val, int32 bonusVal)
Definition: Unit.h:763
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.cpp:2492
virtual void UpdateAllResistances()
Definition: StatSystem.cpp:58
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1463
std::forward_list< AuraEffect * > AuraEffectList
Definition: Unit.h:644
bool haveOffhandWeapon() const
Definition: Unit.cpp:498
bool IsPet() const
Definition: Unit.h:740
Powers GetPowerType() const
Definition: Unit.h:799
bool CanDualWield() const
Definition: Unit.h:692
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition: Unit.cpp:10303
float m_modRangedHitChance
Definition: Unit.h:1472
void SetBonusResistanceMod(SpellSchools school, int32 val)
Definition: Unit.h:773
void SetRangedAttackPowerModPos(int32 attackPowerMod)
Definition: Unit.h:1521
float GetTotalAuraMultiplier(AuraType auraType) const
Definition: Unit.cpp:4934
virtual void UpdateDamagePhysical(WeaponAttackType attType)
Definition: StatSystem.cpp:64
void _ApplyAllAuraStatMods()
Definition: Unit.cpp:4458
void SetRangedAttackPowerMultiplier(float attackPowerMult)
Definition: Unit.h:1523
void SetResistance(SpellSchools school, int32 val)
Definition: Unit.h:772
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:4999
float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const
Definition: Unit.cpp:9315
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4560
uint32 GetCreateHealth() const
Definition: Unit.h:1394
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4674
uint32 GetArmor() const
Definition: Unit.h:762
float m_modMeleeHitChance
Definition: Unit.h:1471
void _RemoveAllAuraStatMods()
Definition: Unit.cpp:4452
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4929
float GetAPMultiplier(WeaponAttackType attType, bool normalized) const
Definition: Unit.cpp:10403
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const =0
void SetAttackPower(int32 attackPower)
Definition: Unit.h:1516
void SetMaxHealth(uint64 val)
Definition: Unit.cpp:9377
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
Definition: Unit.cpp:7338
float GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon=true) const
Definition: Unit.cpp:9285
float GetCreateStat(Stats stat) const
Definition: Unit.h:1400
int32 GetBonusResistanceMod(SpellSchools school) const
Definition: Unit.h:770
void SetCanModifyStats(bool modifyStats)
Definition: Unit.h:1506
float GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType) const
Definition: Unit.cpp:9030
float GetStat(Stats stat) const
Definition: Unit.h:760
int32 GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:4989
void SetMaxPower(Powers power, int32 val)
Definition: Unit.cpp:9456
uint32 GetCreateMana() const
Definition: Unit.h:1396
void SetRangedAttackPower(int32 attackPower)
Definition: Unit.h:1520
int32 GetResistance(SpellSchools school) const
Definition: Unit.h:769
float m_modSpellHitChance
Definition: Unit.h:1473
Guardian * GetGuardianPet() const
Definition: Unit.cpp:6046
void SetAttackPowerMultiplier(float attackPowerMult)
Definition: Unit.h:1519
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition: Unit.cpp:6894
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
Definition: Unit.cpp:9012
void SetAttackPowerModPos(int32 attackPowerMod)
Definition: Unit.h:1517
uint8 GetLevel() const
Definition: Unit.h:746
void UpdateStatBuffMod(Stats stat)
Definition: Unit.cpp:5079
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2896
#define sWorld
Definition: World.h:931
@ CONFIG_STATS_LIMITS_ENABLE
Definition: World.h:172
@ 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
void apply(T *val)
Definition: ByteConverter.h:41
uint8 AttackPowerPerAgility
Definition: DB2Structure.h:667
uint8 RangedAttackPowerPerAgility
Definition: DB2Structure.h:666
uint8 AttackPowerPerStrength
Definition: DB2Structure.h:668
std::array< int32, MAX_MASTERY_SPELLS > MasterySpellID
Definition: DB2Structure.h:870
UpdateField< float, 32, 61 > ParryPercentage
Definition: UpdateFields.h:937
UpdateFieldArray< int32, 32, 428, 429 > CombatRatings
UpdateField< float, 32, 63 > CritPercentage
Definition: UpdateFields.h:939
UpdateField< float, 32, 64 > RangedCritPercentage
Definition: UpdateFields.h:940
UpdateField< float, 32, 54 > MainhandExpertise
Definition: UpdateFields.h:930
UpdateField< float, 32, 69 > Mastery
Definition: UpdateFields.h:945
UpdateField< int32, 72, 78 > ModHealingDonePos
Definition: UpdateFields.h:953
UpdateField< float, 32, 59 > DodgePercentage
Definition: UpdateFields.h:935
UpdateField< int32, 72, 74 > Versatility
Definition: UpdateFields.h:949
UpdateFieldArray< int32, 7, 367, 375 > ModDamageDoneNeg
UpdateFieldArray< float, 7, 367, 389 > ModHealingDonePercent
UpdateFieldArray< int32, 7, 367, 368 > ModDamageDonePos
UpdateField< float, 32, 55 > OffhandExpertise
Definition: UpdateFields.h:931
UpdateField< float, 32, 66 > SpellCritPercentage
Definition: UpdateFields.h:942
UpdateField< float, 32, 58 > BlockPercentage
Definition: UpdateFields.h:934
UpdateField< float, 32, 65 > OffhandCritPercentage
Definition: UpdateFields.h:941
UpdateFieldArray< float, 10, 130, 161 > PowerRegenInterruptedFlatModifier
Definition: UpdateFields.h:397
UpdateField< float, 96, 102 > MinRangedDamage
Definition: UpdateFields.h:366
UpdateField< float, 32, 60 > MinOffHandDamage
Definition: UpdateFields.h:325
UpdateField< float, 32, 59 > MaxDamage
Definition: UpdateFields.h:324
UpdateField< float, 32, 61 > MaxOffHandDamage
Definition: UpdateFields.h:326
UpdateField< float, 32, 58 > MinDamage
Definition: UpdateFields.h:323
UpdateField< float, 96, 103 > MaxRangedDamage
Definition: UpdateFields.h:367
UpdateFieldArray< float, 10, 130, 151 > PowerRegenFlatModifier
Definition: UpdateFields.h:396