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 float mult = auraEff->GetSpellEffectInfo().BonusCoefficient;
560 if (G3D::fuzzyEq(mult, 0.0f))
561 continue;
562
563 auraEff->ChangeAmount(int32(value * mult));
564 }
565 }
566 }
567}
568
570{
571 // No proof that CR_VERSATILITY_DAMAGE_DONE is allways = ActivePlayerData::Versatility
573
574 if (GetClass() == CLASS_HUNTER)
576 else
578}
579
581{
582 float value = 1.0f;
583
585
587 AddPct(value, auraEffect->GetAmount());
588
589 for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
591}
592
594{
595 0.9560f, // Warrior
596 0.9560f, // Paladin
597 0.9880f, // Hunter
598 0.9880f, // Rogue
599 0.9830f, // Priest
600 0.9560f, // DK
601 0.9880f, // Shaman
602 0.9830f, // Mage
603 0.9830f, // Warlock
604 0.9830f, // Monk
605 0.9720f, // Druid
606 0.9830f, // Demon Hunter
607 0.9880f, // Evoker
608 1.0f, // Adventurer
609};
610
611// helper function
612float CalculateDiminishingReturns(float const (&capArray)[MAX_CLASSES], uint8 playerClass, float nonDiminishValue, float diminishValue)
613{
614 // 1 1 k cx
615 // --- = --- + --- <=> x' = --------
616 // x' c x x + ck
617
618 // where:
619 // k is m_diminishing_k for that class
620 // c is capArray for that class
621 // x is chance before DR (diminishValue)
622 // x' is chance after DR (our result)
623
624 uint32 const classIdx = playerClass - 1;
625
626 float const k = m_diminishing_k[classIdx];
627 float const c = capArray[classIdx];
628
629 float result = c * diminishValue / (diminishValue + c * k);
630 result += nonDiminishValue;
631 return result;
632}
633
634float const parry_cap[MAX_CLASSES] =
635{
636 65.631440f, // Warrior
637 65.631440f, // Paladin
638 145.560408f, // Hunter
639 145.560408f, // Rogue
640 0.0f, // Priest
641 65.631440f, // DK
642 145.560408f, // Shaman
643 0.0f, // Mage
644 0.0f, // Warlock
645 90.6425f, // Monk
646 0.0f, // Druid
647 65.631440f, // Demon Hunter
648 0.0f, // Evoker
649 0.0f, // Adventurer
650};
651
653{
654 // No parry
655 float value = 0.0f;
656 uint32 pclass = GetClass() - 1;
657 if (CanParry() && parry_cap[pclass] > 0.0f)
658 {
659 float nondiminishing = 5.0f;
660 // Parry from rating
661 float diminishing = GetRatingBonusValue(CR_PARRY);
662 // Parry from SPELL_AURA_MOD_PARRY_PERCENT aura
664
665 // apply diminishing formula to diminishing parry chance
666 value = CalculateDiminishingReturns(parry_cap, GetClass(), nondiminishing, diminishing);
667
668 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
669 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_PARRY) : value;
670
671 }
673}
674
675float const dodge_cap[MAX_CLASSES] =
676{
677 65.631440f, // Warrior
678 65.631440f, // Paladin
679 145.560408f, // Hunter
680 145.560408f, // Rogue
681 150.375940f, // Priest
682 65.631440f, // DK
683 145.560408f, // Shaman
684 150.375940f, // Mage
685 150.375940f, // Warlock
686 145.560408f, // Monk
687 116.890707f, // Druid
688 145.560408f, // Demon Hunter
689 145.560408f, // Evoker
690 0.0f, // Adventurer
691};
692
694{
695 float diminishing = 0.0f, nondiminishing = 0.0f;
696 GetDodgeFromAgility(diminishing, nondiminishing);
697 // Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura
699 // Dodge from rating
700 diminishing += GetRatingBonusValue(CR_DODGE);
701
702 // apply diminishing formula to diminishing dodge chance
703 float value = CalculateDiminishingReturns(dodge_cap, GetClass(), nondiminishing, diminishing);
704
705 if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
706 value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_DODGE) : value;
707
709}
710
712{
713 float crit = 5.0f;
714 // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
716 // Increase crit from SPELL_AURA_MOD_CRIT_PCT
718 // Increase crit from spell crit ratings
720
721 // Store crit value
723}
724
726{
728 for (CorruptionEffectsEntry const* corruptionEffect : sCorruptionEffectsStore)
729 {
731 continue;
732
733 if (effectiveCorruption < corruptionEffect->MinCorruption)
734 {
735 RemoveAura(corruptionEffect->Aura);
736 continue;
737 }
738
739 if (!ConditionMgr::IsPlayerMeetingCondition(this, corruptionEffect->PlayerConditionID))
740 {
741 RemoveAura(corruptionEffect->Aura);
742 continue;
743 }
744
745 CastSpell(this, corruptionEffect->Aura, true);
746 }
747}
748
750{
751 // Store Rating Value
753}
754
756{
758}
759
761{
763}
764
766{
769}
770
772{
773 if (attack == RANGED_ATTACK)
774 return;
775
777
778 Item const* weapon = GetWeaponForAttack(attack, true);
779 expertise += GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE, [weapon](AuraEffect const* aurEff) -> bool
780 {
781 return aurEff->GetSpellInfo()->IsItemFitToSpellRequirements(weapon);
782 });
783
784 if (expertise < 0)
785 expertise = 0;
786
787 switch (attack)
788 {
789 case BASE_ATTACK:
791 break;
792 case OFF_ATTACK:
794 break;
795 default:
796 break;
797 }
798}
799
801{
804}
805
807{
809}
810
812{
813 uint32 manaIndex = GetPowerIndex(POWER_MANA);
814 if (manaIndex == MAX_POWERS)
815 return;
816
817 // Get base of Mana Pool in sBaseMPGameTable
818 uint32 basemana = 0;
819 sObjectMgr->GetPlayerClassLevelInfo(GetClass(), GetLevel(), basemana);
820 float base_regen = basemana / 100.f;
821
823
824 // Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT
826
827 // Apply PCT bonus from SPELL_AURA_MOD_MANA_REGEN_PCT
829
832}
833
835{
837 return;
838
839 uint32 runeIndex = GetPowerIndex(POWER_RUNES);
840 if (runeIndex == MAX_POWERS)
841 return;
842
843 PowerTypeEntry const* runeEntry = sDB2Manager.GetPowerTypeEntry(POWER_RUNES);
844
845 uint32 cooldown = GetRuneBaseCooldown();
846 SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::PowerRegenFlatModifier, runeIndex), float(1 * IN_MILLISECONDS) / float(cooldown) - runeEntry->RegenPeace);
848}
849
851{
852 SetCanModifyStats(false);
853
857
858 SetCanModifyStats(true);
859
861}
862
864{
865 SetCanModifyStats(false);
866
870
871 SetCanModifyStats(true);
872
874}
875
876/*#######################################
877######## ########
878######## MOBS STAT SYSTEM ########
879######## ########
880#######################################*/
881
883{
884 if (PowerTypeEntry const* powerType = sDB2Manager.GetPowerTypeEntry(power))
885 if (!powerType->GetFlags().HasFlag(PowerTypeFlags::IsUsedByNPCs))
886 return 0;
887
888 return Unit::GetCreatePowerValue(power);
889}
890
892{
893 return true;
894}
895
897{
901
902 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
904
906
907 return true;
908}
909
911{
914 SetArmor(int32(baseValue), int32(value - baseValue));
915}
916
918{
920 SetMaxHealth(uint32(value));
921}
922
924{
925 if (power == GetPowerType())
926 return 0;
927 switch (power)
928 {
930 return 2;
932 return 1;
934 return 3;
936 return 4;
938 return 5;
939 default:
940 break;
941 }
942 return MAX_POWERS;
943}
944
946{
947 if (GetPowerIndex(power) == MAX_POWERS)
948 return;
949
951
952 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
953 value *= GetPctModifierValue(unitMod, BASE_PCT);
954 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
955 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
956
957 SetMaxPower(power, (int32)std::lroundf(value));
958}
959
961{
963
964 float baseAttackPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
965 float attackPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
966
967 if (ranged)
968 {
969 SetRangedAttackPower(int32(baseAttackPower));
970 SetRangedAttackPowerMultiplier(attackPowerMultiplier);
971 }
972 else
973 {
974 SetAttackPower(int32(baseAttackPower));
975 SetAttackPowerMultiplier(attackPowerMultiplier);
976 }
977
978 // automatically update weapon damage after attack power modification
979 if (ranged)
981 else
982 {
985 }
986}
987
988void Creature::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) const
989{
990 float variance = 1.0f;
991 UnitMods unitMod;
992 switch (attType)
993 {
994 case BASE_ATTACK:
995 default:
996 variance = GetCreatureTemplate()->BaseVariance;
997 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
998 break;
999 case OFF_ATTACK:
1000 variance = GetCreatureTemplate()->BaseVariance;
1001 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
1002 break;
1003 case RANGED_ATTACK:
1004 variance = GetCreatureTemplate()->RangeVariance;
1005 unitMod = UNIT_MOD_DAMAGE_RANGED;
1006 break;
1007 }
1008
1009 if (attType == OFF_ATTACK && !haveOffhandWeapon())
1010 {
1011 minDamage = 0.0f;
1012 maxDamage = 0.0f;
1013 return;
1014 }
1015
1016 float weaponMinDamage = GetWeaponDamageRange(attType, MINDAMAGE);
1017 float weaponMaxDamage = GetWeaponDamageRange(attType, MAXDAMAGE);
1018
1019 if (!CanUseAttackType(attType)) // disarm case
1020 {
1021 weaponMinDamage = 0.0f;
1022 weaponMaxDamage = 0.0f;
1023 }
1024
1025 float attackPower = GetTotalAttackPowerValue(attType, false);
1026 float attackSpeedMulti = GetAPMultiplier(attType, normalized);
1027 float baseValue = GetFlatModifierValue(unitMod, BASE_VALUE) + (attackPower / 3.5f) * variance;
1028 float basePct = GetPctModifierValue(unitMod, BASE_PCT) * attackSpeedMulti;
1029 float totalValue = GetFlatModifierValue(unitMod, TOTAL_VALUE);
1030 float totalPct = addTotalPct ? GetPctModifierValue(unitMod, TOTAL_PCT) : 1.0f;
1031 float dmgMultiplier = GetCreatureDifficulty()->DamageModifier; // = DamageModifier * GetDamageMod(rank);
1032
1033 minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
1034 maxDamage = ((weaponMaxDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
1035}
1036
1037/*#######################################
1038######## ########
1039######## PETS STAT SYSTEM ########
1040######## ########
1041#######################################*/
1042
1043#define ENTRY_IMP 416
1044#define ENTRY_VOIDWALKER 1860
1045#define ENTRY_SUCCUBUS 1863
1046#define ENTRY_FELHUNTER 417
1047#define ENTRY_FELGUARD 17252
1048#define ENTRY_WATER_ELEMENTAL 510
1049#define ENTRY_TREANT 1964
1050#define ENTRY_FIRE_ELEMENTAL 15438
1051#define ENTRY_GHOUL 26125
1052#define ENTRY_BLOODWORM 28017
1053
1055{
1056 // value = ((base_value * base_pct) + total_value) * total_pct
1057 float value = GetTotalStatValue(stat);
1058 UpdateStatBuffMod(stat);
1059 float ownersBonus = 0.0f;
1060
1061 Unit* owner = GetOwner();
1062 // Handle Death Knight Glyphs and Talents
1063 float mod = 0.75f;
1064 if (IsPetGhoul() && (stat == STAT_STAMINA || stat == STAT_STRENGTH))
1065 {
1066 if (stat == STAT_STAMINA)
1067 mod = 0.3f; // Default Owner's Stamina scale
1068 else
1069 mod = 0.7f; // Default Owner's Strength scale
1070
1071 ownersBonus = float(owner->GetStat(stat)) * mod;
1072 value += ownersBonus;
1073 }
1074 else if (stat == STAT_STAMINA)
1075 {
1076 ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 30);
1077 value += ownersBonus;
1078 }
1079 //warlock's and mage's pets gain 30% of owner's intellect
1080 else if (stat == STAT_INTELLECT)
1081 {
1082 if (owner->GetClass() == CLASS_WARLOCK || owner->GetClass() == CLASS_MAGE)
1083 {
1084 ownersBonus = CalculatePct(owner->GetStat(stat), 30);
1085 value += ownersBonus;
1086 }
1087 }
1088/*
1089 else if (stat == STAT_STRENGTH)
1090 {
1091 if (IsPetGhoul())
1092 value += float(owner->GetStat(stat)) * 0.3f;
1093 }
1094*/
1095
1096 SetStat(stat, int32(value));
1097 m_statFromOwner[stat] = ownersBonus;
1098 UpdateStatBuffMod(stat);
1099
1100 switch (stat)
1101 {
1103 case STAT_AGILITY: UpdateArmor(); break;
1104 case STAT_STAMINA: UpdateMaxHealth(); break;
1106 default:
1107 break;
1108 }
1109
1110 return true;
1111}
1112
1114{
1116
1117 for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
1118 UpdateStats(Stats(i));
1119
1120 for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
1122
1124
1125 return true;
1126}
1127
1129{
1130 if (school > SPELL_SCHOOL_NORMAL)
1131 {
1133 float bonusValue = GetTotalAuraModValue(UnitMods(UNIT_MOD_RESISTANCE_START + school)) - baseValue;
1134
1135 // hunter and warlock pets gain 40% of owner's resistance
1136 if (IsPet())
1137 {
1138 baseValue += float(CalculatePct(m_owner->GetResistance(SpellSchools(school)), 40));
1139 bonusValue += float(CalculatePct(m_owner->GetBonusResistanceMod(SpellSchools(school)), 40));
1140 }
1141
1142 SetResistance(SpellSchools(school), int32(baseValue));
1143 SetBonusResistanceMod(SpellSchools(school), int32(bonusValue));
1144 }
1145 else
1146 UpdateArmor();
1147}
1148
1150{
1151 float baseValue = 0.0f;
1152 float value = 0.0f;
1153 float bonus_armor = 0.0f;
1154 UnitMods unitMod = UNIT_MOD_ARMOR;
1155
1156 // hunter pets gain 35% of owner's armor value, warlock pets gain 100% of owner's armor
1157 if (IsHunterPet())
1158 bonus_armor = float(CalculatePct(m_owner->GetArmor(), 70));
1159 else if (IsPet())
1160 bonus_armor = m_owner->GetArmor();
1161
1162 value = GetFlatModifierValue(unitMod, BASE_VALUE);
1163 baseValue = value;
1164 value *= GetPctModifierValue(unitMod, BASE_PCT);
1165 value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
1166 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1167
1168 SetArmor(int32(baseValue), int32(value - baseValue));
1169}
1170
1172{
1173 UnitMods unitMod = UNIT_MOD_HEALTH;
1174 float stamina = GetStat(STAT_STAMINA) - GetCreateStat(STAT_STAMINA);
1175
1176 float multiplicator;
1177 switch (GetEntry())
1178 {
1179 case ENTRY_IMP: multiplicator = 8.4f; break;
1180 case ENTRY_VOIDWALKER: multiplicator = 11.0f; break;
1181 case ENTRY_SUCCUBUS: multiplicator = 9.1f; break;
1182 case ENTRY_FELHUNTER: multiplicator = 9.5f; break;
1183 case ENTRY_FELGUARD: multiplicator = 11.0f; break;
1184 case ENTRY_BLOODWORM: multiplicator = 1.0f; break;
1185 default: multiplicator = 10.0f; break;
1186 }
1187
1188 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreateHealth();
1189 value *= GetPctModifierValue(unitMod, BASE_PCT);
1190 value += GetFlatModifierValue(unitMod, TOTAL_VALUE) + stamina * multiplicator;
1191 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1192
1193 SetMaxHealth((uint32)value);
1194}
1195
1197{
1198 if (GetPowerIndex(power) == MAX_POWERS)
1199 return;
1200
1202
1203 float value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetCreatePowerValue(power);
1204 value *= GetPctModifierValue(unitMod, BASE_PCT);
1205 value += GetFlatModifierValue(unitMod, TOTAL_VALUE);
1206 value *= GetPctModifierValue(unitMod, TOTAL_PCT);
1207
1208 SetMaxPower(power, int32(value));
1209}
1210
1212{
1213 if (ranged)
1214 return;
1215
1216 float val = 0.0f;
1217 float bonusAP = 0.0f;
1219
1220 if (GetEntry() == ENTRY_IMP) // imp's attack power
1221 val = GetStat(STAT_STRENGTH) - 10.0f;
1222 else
1223 val = 2 * GetStat(STAT_STRENGTH) - 20.0f;
1224
1225 Player* owner = GetOwner() ? GetOwner()->ToPlayer() : nullptr;
1226 if (owner)
1227 {
1228 if (IsHunterPet()) //hunter pets benefit from owner's attack power
1229 {
1230 float mod = 1.0f; //Hunter contribution modifier
1231 bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
1233 }
1234 else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
1235 {
1236 bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
1238 }
1239 else if (IsSpiritWolf()) //wolf benefit from shaman's attack power
1240 {
1241 float dmg_multiplier = 0.31f;
1242 bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier;
1243 SetBonusDamage(int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * dmg_multiplier));
1244 }
1245 //demons benefit from warlocks shadow or fire damage
1246 else if (IsPet())
1247 {
1248 int32 fire = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FIRE];
1249 int32 shadow = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_SHADOW] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_SHADOW];
1250 int32 maximum = (fire > shadow) ? fire : shadow;
1251 if (maximum < 0)
1252 maximum = 0;
1253 SetBonusDamage(int32(maximum * 0.15f));
1254 bonusAP = maximum * 0.57f;
1255 }
1256 //water elementals benefit from mage's frost damage
1257 else if (GetEntry() == ENTRY_WATER_ELEMENTAL)
1258 {
1259 int32 frost = owner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FROST] - owner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FROST];
1260 if (frost < 0)
1261 frost = 0;
1262 SetBonusDamage(int32(frost * 0.4f));
1263 }
1264 }
1265
1267
1268 //in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
1269 float base_attPower = GetFlatModifierValue(unitMod, BASE_VALUE) * GetPctModifierValue(unitMod, BASE_PCT);
1270 float attPowerMultiplier = GetPctModifierValue(unitMod, TOTAL_PCT) - 1.0f;
1271
1272 SetAttackPower(int32(base_attPower));
1273 SetAttackPowerMultiplier(attPowerMultiplier);
1274
1275 //automatically update weapon damage after attack power modification
1277}
1278
1280{
1281 if (attType > BASE_ATTACK)
1282 return;
1283
1284 float bonusDamage = 0.0f;
1285 if (Player* playerOwner = m_owner->ToPlayer())
1286 {
1287 //force of nature
1288 if (GetEntry() == ENTRY_TREANT)
1289 {
1290 int32 spellDmg = playerOwner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_NATURE] - playerOwner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_NATURE];
1291 if (spellDmg > 0)
1292 bonusDamage = spellDmg * 0.09f;
1293 }
1294 //greater fire elemental
1295 else if (GetEntry() == ENTRY_FIRE_ELEMENTAL)
1296 {
1297 int32 spellDmg = playerOwner->m_activePlayerData->ModDamageDonePos[SPELL_SCHOOL_FIRE] - playerOwner->m_activePlayerData->ModDamageDoneNeg[SPELL_SCHOOL_FIRE];
1298 if (spellDmg > 0)
1299 bonusDamage = spellDmg * 0.4f;
1300 }
1301 }
1302
1304
1305 float att_speed = float(GetBaseAttackTime(BASE_ATTACK))/1000.0f;
1306
1307 float base_value = GetFlatModifierValue(unitMod, BASE_VALUE) + GetTotalAttackPowerValue(attType, false) / 3.5f * att_speed + bonusDamage;
1308 float base_pct = GetPctModifierValue(unitMod, BASE_PCT);
1309 float total_value = GetFlatModifierValue(unitMod, TOTAL_VALUE);
1310 float total_pct = GetPctModifierValue(unitMod, TOTAL_PCT);
1311
1312 float weapon_mindamage = GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
1313 float weapon_maxdamage = GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
1314
1315 float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
1316 float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
1317
1320}
1321
1323{
1324 m_bonusSpellDamage = damage;
1325 if (Player* playerOwner = GetOwner()->ToPlayer())
1326 playerOwner->SetPetSpellPower(damage);
1327}
@ 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)
#define sDB2Manager
Definition: DB2Stores.h:553
CorruptionEffectsFlag
Definition: DBCEnums.h:451
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:273
#define sObjectMgr
Definition: ObjectMgr.h:1995
#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:675
#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:612
float const parry_cap[MAX_CLASSES]
Definition: StatSystem.cpp:634
#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:593
#define ENTRY_IMP
#define BASE_MAXDAMAGE
Definition: UnitDefines.h:34
#define BASE_MINDAMAGE
Definition: UnitDefines.h:33
@ BASE_VALUE
Definition: Unit.h:154
@ TOTAL_VALUE
Definition: Unit.h:156
@ FLAT_MOD
Definition: Unit.h:241
@ PCT_MOD
Definition: Unit.h:242
@ MINDAMAGE
Definition: Unit.h:169
@ MAXDAMAGE
Definition: Unit.h:170
UnitMods
Definition: Unit.h:174
@ UNIT_MOD_DAMAGE_OFFHAND
Definition: Unit.h:216
@ UNIT_MOD_ARMOR
Definition: Unit.h:206
@ UNIT_MOD_ATTACK_POWER
Definition: Unit.h:213
@ UNIT_MOD_RESISTANCE_START
Definition: Unit.h:222
@ UNIT_MOD_HEALTH
Definition: Unit.h:179
@ UNIT_MOD_DAMAGE_RANGED
Definition: Unit.h:217
@ UNIT_MOD_POWER_START
Definition: Unit.h:224
@ UNIT_MOD_DAMAGE_MAINHAND
Definition: Unit.h:215
@ UNIT_MOD_ATTACK_POWER_RANGED
Definition: Unit.h:214
@ OFFHAND_CRIT_PERCENTAGE
Definition: Unit.h:234
@ CRIT_PERCENTAGE
Definition: Unit.h:232
@ RANGED_CRIT_PERCENTAGE
Definition: Unit.h:233
@ CR_EXPERTISE
Definition: Unit.h:336
@ CR_CORRUPTION
Definition: Unit.h:324
@ CR_HIT_MELEE
Definition: Unit.h:318
@ CR_ARMOR_PENETRATION
Definition: Unit.h:337
@ CR_CRIT_MELEE
Definition: Unit.h:321
@ CR_CRIT_RANGED
Definition: Unit.h:322
@ CR_VERSATILITY_HEALING_DONE
Definition: Unit.h:342
@ CR_PARRY
Definition: Unit.h:316
@ CR_DODGE
Definition: Unit.h:315
@ CR_CORRUPTION_RESISTANCE
Definition: Unit.h:325
@ CR_BLOCK
Definition: Unit.h:317
@ CR_VERSATILITY_DAMAGE_DONE
Definition: Unit.h:341
@ CR_HIT_SPELL
Definition: Unit.h:320
@ CR_MASTERY
Definition: Unit.h:338
@ CR_CRIT_SPELL
Definition: Unit.h:323
@ CR_HIT_RANGED
Definition: Unit.h:319
@ TOTAL_PCT
Definition: Unit.h:163
@ BASE_PCT
Definition: Unit.h:162
T AddPct(T &base, U pct)
Definition: Util.h:85
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition: Util.h:528
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, uint32 conditionId)
bool UpdateAllStats() override
Definition: StatSystem.cpp:896
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:268
bool UpdateStats(Stats stat) override
Definition: StatSystem.cpp:891
uint32 GetPowerIndex(Powers power) const override
Definition: StatSystem.cpp:923
int32 GetCreatePowerValue(Powers power) const override
Definition: StatSystem.cpp:882
void UpdateAttackPowerAndDamage(bool ranged=false) override
Definition: StatSystem.cpp:960
void UpdateArmor() override
Definition: StatSystem.cpp:910
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:266
void UpdateMaxPower(Powers power) override
Definition: StatSystem.cpp:945
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const override
Definition: StatSystem.cpp:988
void UpdateMaxHealth() override
Definition: StatSystem.cpp:917
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:171
Unit * GetOwner() const
bool IsSpiritWolf() const
Unit *const m_owner
bool IsPetGhoul() const
Player * ToPlayer()
Definition: Object.h:251
void SetUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:326
uint32 GetEntry() const
Definition: Object.h:197
UF::UpdateFieldHolder m_values
Definition: Object.h:303
void SetUpdateFieldStatValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:383
void ApplyModUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type mod, bool apply)
Definition: Object.h:390
static Player * ToPlayer(Object *o)
Definition: Object.h:249
Definition: Pet.h:40
void UpdateParryPercentage()
Definition: StatSystem.cpp:652
void UpdateMastery()
Definition: StatSystem.cpp:537
void UpdateArmorPenetration(int32 amount)
Definition: StatSystem.cpp:749
void UpdateDodgePercentage()
Definition: StatSystem.cpp:693
void ApplyModTargetResistance(int32 mod, bool apply)
Definition: Player.h:2128
void UpdateMaxPower(Powers power) override
Definition: StatSystem.cpp:327
bool CanUseMastery() const
Definition: Player.cpp:30108
bool CanParry() const
Definition: Player.h:2400
void UpdateCritPercentage(WeaponAttackType attType)
Definition: StatSystem.cpp:497
UF::UpdateField< UF::ActivePlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition: Player.h:2965
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:26767
bool CanBlock() const
Definition: Player.h:2402
void UpdateVersatilityDamageDone()
Definition: StatSystem.cpp:569
void UpdateCorruption()
Definition: StatSystem.cpp:725
void UpdateBlockPercentage()
Definition: StatSystem.cpp:478
void ApplyModDamageDonePos(SpellSchools school, int32 mod, bool apply)
Definition: Player.h:2138
void ApplySpellPenetrationBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:229
void UpdateArmor() override
Definition: StatSystem.cpp:249
void UpdateManaRegen()
Definition: StatSystem.cpp:811
void RecalculateRating(CombatRating cr)
Definition: Player.h:2152
Pet * GetPet() const
Definition: Player.cpp:21839
bool UpdateStats(Stats stat) override
Definition: StatSystem.cpp:106
void _RemoveAllItemMods()
Definition: Player.cpp:8981
void _ApplyAllItemMods()
Definition: Player.cpp:9021
void UpdateSpellHitChances()
Definition: StatSystem.cpp:765
void UpdateExpertise(WeaponAttackType attType)
Definition: StatSystem.cpp:771
void _ApplyAllStatBonuses()
Definition: StatSystem.cpp:850
float GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const
Definition: Player.cpp:5121
void ApplyAllAzeriteItemMods(bool apply)
Definition: Player.cpp:9088
void UpdateHealingDonePercentMod()
Definition: StatSystem.cpp:580
void ApplyManaRegenBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:800
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:3156
void UpdateMaxHealth() override
Definition: StatSystem.cpp:310
void UpdateMeleeHitChances()
Definition: StatSystem.cpp:755
void UpdateAllRunesRegen()
Definition: StatSystem.cpp:834
uint32 m_baseHealthRegen
Definition: Player.h:3158
void UpdateRangedHitChances()
Definition: StatSystem.cpp:760
uint32 m_baseManaRegen
Definition: Player.h:3157
void UpdateAllRatings()
Definition: Player.cpp:5508
void ApplySpellPowerBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:150
void UpdateAllCritPercentages()
Definition: StatSystem.cpp:524
bool UpdateAllStats() override
Definition: StatSystem.cpp:197
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: Player.cpp:9696
void _RemoveAllStatBonuses()
Definition: StatSystem.cpp:863
int32 m_spellPenetrationItemMod
Definition: Player.h:3159
Stats GetPrimaryStat() const
Definition: StatSystem.cpp:291
void ApplyHealthRegenBonus(int32 amount, bool apply)
Definition: StatSystem.cpp:806
void UpdateSpellCritChance()
Definition: StatSystem.cpp:711
ChrSpecializationEntry const * GetPrimarySpecializationEntry() const
Definition: Player.cpp:30406
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: Unit.h:630
float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType) const
Definition: Unit.cpp:9419
virtual void UpdateResistances(uint32 school)
Definition: Unit.cpp:9644
bool IsHunterPet() const
Definition: Unit.h:747
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1332
void SetStat(Stats stat, int32 val)
Definition: Unit.h:768
float GetTotalAuraModValue(UnitMods unitMod) const
Definition: Unit.cpp:9591
float GetTotalStatValue(Stats stat) const
Definition: Unit.cpp:9575
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3751
virtual int32 GetCreatePowerValue(Powers power) const
Definition: StatSystem.cpp:89
uint8 GetClass() const
Definition: Unit.h:759
void SetArmor(int32 val, int32 bonusVal)
Definition: Unit.h:770
bool CanUseAttackType(uint8 attacktype) const
Definition: Unit.cpp:2552
virtual void UpdateAllResistances()
Definition: StatSystem.cpp:58
ShapeshiftForm GetShapeshiftForm() const
Definition: Unit.h:1481
std::forward_list< AuraEffect * > AuraEffectList
Definition: Unit.h:647
bool haveOffhandWeapon() const
Definition: Unit.cpp:525
bool IsPet() const
Definition: Unit.h:746
Powers GetPowerType() const
Definition: Unit.h:806
bool CanDualWield() const
Definition: Unit.h:698
uint32 GetBaseAttackTime(WeaponAttackType att) const
Definition: Unit.cpp:10683
float m_modRangedHitChance
Definition: Unit.h:1492
void SetBonusResistanceMod(SpellSchools school, int32 val)
Definition: Unit.h:780
void SetRangedAttackPowerModPos(int32 attackPowerMod)
Definition: Unit.h:1541
float GetTotalAuraMultiplier(AuraType auraType) const
Definition: Unit.cpp:5003
virtual void UpdateDamagePhysical(WeaponAttackType attType)
Definition: StatSystem.cpp:64
void _ApplyAllAuraStatMods()
Definition: Unit.cpp:4527
void SetRangedAttackPowerMultiplier(float attackPowerMult)
Definition: Unit.h:1543
void SetResistance(SpellSchools school, int32 val)
Definition: Unit.h:779
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:5068
float GetWeaponDamageRange(WeaponAttackType attType, WeaponDamageRange type) const
Definition: Unit.cpp:9695
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4629
uint32 GetCreateHealth() const
Definition: Unit.h:1405
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4743
uint32 GetArmor() const
Definition: Unit.h:769
float m_modMeleeHitChance
Definition: Unit.h:1491
void _RemoveAllAuraStatMods()
Definition: Unit.cpp:4521
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4998
float GetAPMultiplier(WeaponAttackType attType, bool normalized) const
Definition: Unit.cpp:10783
virtual void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float &minDamage, float &maxDamage) const =0
void SetAttackPower(int32 attackPower)
Definition: Unit.h:1536
void SetMaxHealth(uint64 val)
Definition: Unit.cpp:9757
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
Definition: Unit.h:1844
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
Definition: Unit.cpp:7472
float GetTotalAttackPowerValue(WeaponAttackType attType, bool includeWeapon=true) const
Definition: Unit.cpp:9665
float GetCreateStat(Stats stat) const
Definition: Unit.h:1411
int32 GetBonusResistanceMod(SpellSchools school) const
Definition: Unit.h:777
void SetCanModifyStats(bool modifyStats)
Definition: Unit.h:1526
float GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType) const
Definition: Unit.cpp:9408
float GetStat(Stats stat) const
Definition: Unit.h:767
int32 GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:5058
void SetMaxPower(Powers power, int32 val)
Definition: Unit.cpp:9836
uint32 GetCreateMana() const
Definition: Unit.h:1407
void SetRangedAttackPower(int32 attackPower)
Definition: Unit.h:1540
int32 GetResistance(SpellSchools school) const
Definition: Unit.h:776
float m_modSpellHitChance
Definition: Unit.h:1493
Guardian * GetGuardianPet() const
Definition: Unit.cpp:6136
void SetAttackPowerMultiplier(float attackPowerMult)
Definition: Unit.h:1539
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition: Unit.cpp:6989
void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
Definition: Unit.cpp:9390
void SetAttackPowerModPos(int32 attackPowerMod)
Definition: Unit.h:1537
uint8 GetLevel() const
Definition: Unit.h:752
void UpdateStatBuffMod(Stats stat)
Definition: Unit.cpp:5148
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition: Object.cpp:2977
#define sWorld
Definition: World.h:927
@ CONFIG_STATS_LIMITS_ENABLE
Definition: World.h:171
@ 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:689
uint8 RangedAttackPowerPerAgility
Definition: DB2Structure.h:688
uint8 AttackPowerPerStrength
Definition: DB2Structure.h:690
std::array< int32, MAX_MASTERY_SPELLS > MasterySpellID
Definition: DB2Structure.h:892
UpdateFieldArray< float, 7, 381, 403 > ModHealingDonePercent
UpdateField< float, 32, 68 > OffhandCritPercentage
UpdateField< float, 32, 58 > OffhandExpertise
UpdateField< float, 32, 67 > RangedCritPercentage
UpdateField< float, 32, 62 > DodgePercentage
UpdateField< float, 32, 69 > SpellCritPercentage
UpdateField< float, 32, 64 > ParryPercentage
UpdateField< float, 70, 73 > Mastery
UpdateField< int32, 70, 77 > Versatility
UpdateField< float, 32, 61 > BlockPercentage
UpdateField< float, 32, 66 > CritPercentage
UpdateFieldArray< int32, 32, 442, 443 > CombatRatings
UpdateField< int32, 70, 82 > ModHealingDonePos
UpdateField< float, 32, 57 > MainhandExpertise
UpdateFieldArray< int32, 7, 381, 389 > ModDamageDoneNeg
UpdateFieldArray< int32, 7, 381, 382 > ModDamageDonePos
UpdateFieldArray< float, 10, 133, 164 > PowerRegenInterruptedFlatModifier
Definition: UpdateFields.h:408
UpdateFieldArray< float, 10, 133, 154 > PowerRegenFlatModifier
Definition: UpdateFields.h:407
UpdateField< float, 32, 62 > MaxOffHandDamage
Definition: UpdateFields.h:335
UpdateField< float, 96, 104 > MaxRangedDamage
Definition: UpdateFields.h:376
UpdateField< float, 96, 103 > MinRangedDamage
Definition: UpdateFields.h:375
UpdateField< float, 32, 61 > MinOffHandDamage
Definition: UpdateFields.h:334
UpdateField< float, 32, 59 > MinDamage
Definition: UpdateFields.h:332
UpdateField< float, 32, 60 > MaxDamage
Definition: UpdateFields.h:333