Core/Auras: reworked multiplicative AuraEffects calculation
Port From (https://github.com/TrinityCore/TrinityCore/commit/ebc06b1d0401be69066986e18d0e926170c58023)
This commit is contained in:
@@ -157,7 +157,7 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
// @todo research if talents/effects that increase total agility by x% should increase non-diminishing part
|
||||
float base_agility = GetCreateStat(Stats.Agility) * m_auraModifiersGroup[(int)UnitMods.StatAgility][(int)UnitModifierType.BasePCT];
|
||||
float base_agility = GetCreateStat(Stats.Agility) * GetPctModifierValue(UnitMods(UNIT_MOD_STAT_START + STAT_AGILITY), BASE_PCT);
|
||||
float bonus_agility = GetStat(Stats.Agility) - base_agility;
|
||||
|
||||
// calculate diminishing (green in char screen) and non-diminishing (white) contribution
|
||||
@@ -166,11 +166,6 @@ namespace Game.Entities
|
||||
*/
|
||||
}
|
||||
|
||||
float GetTotalPercentageModValue(BaseModGroup modGroup)
|
||||
{
|
||||
return m_auraBaseMod[(int)modGroup][0] + m_auraBaseMod[(int)modGroup][1];
|
||||
}
|
||||
|
||||
public float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType)
|
||||
{
|
||||
float baseExpertise = 7.5f;
|
||||
|
||||
@@ -141,7 +141,8 @@ namespace Game.Entities
|
||||
|
||||
//Combat
|
||||
int[] baseRatingValue = new int[(int)CombatRating.Max];
|
||||
public float[][] m_auraBaseMod = new float[(int)BaseModGroup.End][];
|
||||
float[] m_auraBaseFlatMod = new float[(int)BaseModGroup.End];
|
||||
float[] m_auraBasePctMod = new float[(int)BaseModGroup.End];
|
||||
public DuelInfo duel;
|
||||
bool m_canParry;
|
||||
bool m_canBlock;
|
||||
|
||||
@@ -1098,8 +1098,7 @@ namespace Game.Entities
|
||||
}
|
||||
public InventoryResult CanStoreNewItem(byte bag, byte slot, List<ItemPosCount> dest, uint item, uint count)
|
||||
{
|
||||
uint notused;
|
||||
return CanStoreItem(bag, slot, dest, item, count, null, false, out notused);
|
||||
return CanStoreItem(bag, slot, dest, item, count, null, false, out _);
|
||||
}
|
||||
|
||||
Item _StoreItem(ushort pos, Item pItem, uint count, bool clone, bool update)
|
||||
@@ -1233,8 +1232,7 @@ namespace Game.Entities
|
||||
// attempt equip by one
|
||||
while (titem_amount > 0)
|
||||
{
|
||||
ushort eDest = 0;
|
||||
msg = CanEquipNewItem(ItemConst.NullSlot, out eDest, titem_id, false);
|
||||
msg = CanEquipNewItem(ItemConst.NullSlot, out ushort eDest, titem_id, false);
|
||||
if (msg != InventoryResult.Ok)
|
||||
break;
|
||||
|
||||
@@ -1890,7 +1888,7 @@ namespace Game.Entities
|
||||
//Add/Remove/Misc Item
|
||||
public bool AddItem(uint itemId, uint count)
|
||||
{
|
||||
uint noSpaceForCount = 0;
|
||||
uint noSpaceForCount;
|
||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||
InventoryResult msg = CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemId, count, out noSpaceForCount);
|
||||
if (msg != InventoryResult.Ok)
|
||||
@@ -3525,7 +3523,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
uint stacks = count / crItem.maxcount;
|
||||
ItemExtendedCostRecord iece = null;
|
||||
ItemExtendedCostRecord iece;
|
||||
if (crItem.ExtendedCost != 0)
|
||||
{
|
||||
iece = CliDB.ItemExtendedCostStorage.LookupByKey(crItem.ExtendedCost);
|
||||
@@ -3991,8 +3989,15 @@ namespace Game.Entities
|
||||
|
||||
_ApplyItemBonuses(item, slot, apply);
|
||||
ApplyItemEquipSpell(item, apply);
|
||||
|
||||
if (updateItemAuras)
|
||||
{
|
||||
ApplyItemDependentAuras(item, apply);
|
||||
WeaponAttackType attackType = Player.GetAttackBySlot(slot, item.GetTemplate().GetInventoryType());
|
||||
if (attackType != WeaponAttackType.Max)
|
||||
UpdateWeaponDependentAuras(attackType);
|
||||
}
|
||||
|
||||
ApplyArtifactPowers(item, apply);
|
||||
ApplyAzeritePowers(item, apply);
|
||||
ApplyEnchantment(item, apply);
|
||||
@@ -4025,22 +4030,22 @@ namespace Game.Entities
|
||||
switch ((ItemModType)statType)
|
||||
{
|
||||
case ItemModType.Mana:
|
||||
HandleStatModifier(UnitMods.Mana, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.Mana, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.Health: // modify HP
|
||||
HandleStatModifier(UnitMods.Health, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.Agility: // modify agility
|
||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, (float)val, apply);
|
||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, (float)val, apply);
|
||||
UpdateStatBuffMod(Stats.Agility);
|
||||
break;
|
||||
case ItemModType.Strength: //modify strength
|
||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, (float)val, apply);
|
||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, (float)val, apply);
|
||||
UpdateStatBuffMod(Stats.Strength);
|
||||
break;
|
||||
case ItemModType.Intellect: //modify intellect
|
||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, (float)val, apply);
|
||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, (float)val, apply);
|
||||
UpdateStatBuffMod(Stats.Intellect);
|
||||
break;
|
||||
//case ItemModType.Spirit: //modify spirit
|
||||
//HandleStatModifier(UnitMods.StatSpirit, UnitModifierType.BaseValue, (float)val, apply);
|
||||
@@ -4051,8 +4056,8 @@ namespace Game.Entities
|
||||
if (staminaMult != null)
|
||||
val = (int)(val * CliDB.GetIlvlStatMultiplier(staminaMult, proto.GetInventoryType()));
|
||||
|
||||
HandleStatModifier(UnitMods.StatStamina, UnitModifierType.BaseValue, (float)val, apply);
|
||||
ApplyStatBuffMod(Stats.Stamina, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStamina, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStamina, UnitModifierFlatType.Base, (float)val, apply);
|
||||
UpdateStatBuffMod(Stats.Stamina);
|
||||
break;
|
||||
case ItemModType.DefenseSkillRating:
|
||||
ApplyRatingMod(CombatRating.DefenseSkill, (int)(val * combatRatingMultiplier), apply);
|
||||
@@ -4118,11 +4123,11 @@ namespace Game.Entities
|
||||
ApplyRatingMod(CombatRating.Expertise, (int)(val * combatRatingMultiplier), apply);
|
||||
break;
|
||||
case ItemModType.AttackPower:
|
||||
HandleStatModifier(UnitMods.AttackPower, UnitModifierType.TotalValue, (float)val, apply);
|
||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Total, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.RangedAttackPower:
|
||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.Versatility:
|
||||
ApplyRatingMod(CombatRating.VersatilityDamageDone, (int)(val * combatRatingMultiplier), apply);
|
||||
@@ -4148,25 +4153,25 @@ namespace Game.Entities
|
||||
ApplyRatingMod(CombatRating.Mastery, (int)(val * combatRatingMultiplier), apply);
|
||||
break;
|
||||
case ItemModType.ExtraArmor:
|
||||
HandleStatModifier(UnitMods.Armor, UnitModifierType.TotalValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Total, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.FireResistance:
|
||||
HandleStatModifier(UnitMods.ResistanceFire, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.ResistanceFire, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.FrostResistance:
|
||||
HandleStatModifier(UnitMods.ResistanceFrost, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.ResistanceFrost, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.HolyResistance:
|
||||
HandleStatModifier(UnitMods.ResistanceHoly, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.ResistanceHoly, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.ShadowResistance:
|
||||
HandleStatModifier(UnitMods.ResistanceShadow, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.ResistanceShadow, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.NatureResistance:
|
||||
HandleStatModifier(UnitMods.ResistanceNature, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.ResistanceNature, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.ArcaneResistance:
|
||||
HandleStatModifier(UnitMods.ResistanceArcane, UnitModifierType.BaseValue, (float)val, apply);
|
||||
HandleStatFlatModifier(UnitMods.ResistanceArcane, UnitModifierFlatType.Base, (float)val, apply);
|
||||
break;
|
||||
case ItemModType.PvpPower:
|
||||
ApplyRatingMod(CombatRating.PvpPower, val, apply);
|
||||
@@ -4202,37 +4207,37 @@ namespace Game.Entities
|
||||
ApplyRatingMod(CombatRating.Unused12, val, apply);
|
||||
break;
|
||||
case ItemModType.AgiStrInt:
|
||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, val, apply);
|
||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, val, apply);
|
||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, val, apply);
|
||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, val, apply);
|
||||
UpdateStatBuffMod(Stats.Agility);
|
||||
UpdateStatBuffMod(Stats.Strength);
|
||||
UpdateStatBuffMod(Stats.Intellect);
|
||||
break;
|
||||
case ItemModType.AgiStr:
|
||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, val, apply);
|
||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, val, apply);
|
||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply);
|
||||
UpdateStatBuffMod(Stats.Agility);
|
||||
UpdateStatBuffMod(Stats.Strength);
|
||||
break;
|
||||
case ItemModType.AgiInt:
|
||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, val, apply);
|
||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, val, apply);
|
||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, val, apply);
|
||||
UpdateStatBuffMod(Stats.Agility);
|
||||
UpdateStatBuffMod(Stats.Intellect);
|
||||
break;
|
||||
case ItemModType.StrInt:
|
||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, val, apply);
|
||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, val, apply);
|
||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, val, apply);
|
||||
UpdateStatBuffMod(Stats.Strength);
|
||||
UpdateStatBuffMod(Stats.Intellect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint armor = item.GetArmor(this);
|
||||
if (armor != 0)
|
||||
HandleStatModifier(UnitMods.Armor, UnitModifierType.BaseValue, (float)armor, apply);
|
||||
HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, (float)armor, apply);
|
||||
|
||||
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
||||
if (slot == EquipmentSlot.MainHand && (proto.GetInventoryType() == InventoryType.Ranged || proto.GetInventoryType() == InventoryType.RangedRight))
|
||||
@@ -4425,6 +4430,10 @@ namespace Game.Entities
|
||||
|
||||
ApplyItemDependentAuras(m_items[i], true);
|
||||
_ApplyItemBonuses(m_items[i], i, true);
|
||||
|
||||
WeaponAttackType attackType = Player.GetAttackBySlot(i, m_items[i].GetTemplate().GetInventoryType());
|
||||
if (attackType != WeaponAttackType.Max)
|
||||
UpdateWeaponDependentAuras(attackType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6229,11 +6238,7 @@ namespace Game.Entities
|
||||
public void SetLootGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.LootTargetGUID), guid); }
|
||||
public void StoreLootItem(byte lootSlot, Loot loot, AELootResult aeResult = null)
|
||||
{
|
||||
NotNormalLootItem qitem = null;
|
||||
NotNormalLootItem ffaitem = null;
|
||||
NotNormalLootItem conditem = null;
|
||||
|
||||
LootItem item = loot.LootItemInSlot(lootSlot, this, out qitem, out ffaitem, out conditem);
|
||||
LootItem item = loot.LootItemInSlot(lootSlot, this, out NotNormalLootItem qitem, out NotNormalLootItem ffaitem, out NotNormalLootItem conditem);
|
||||
if (item == null)
|
||||
{
|
||||
SendEquipError(InventoryResult.LootGone);
|
||||
@@ -6385,7 +6390,7 @@ namespace Game.Entities
|
||||
if (!currentLootGuid.IsEmpty() && !aeLooting)
|
||||
Session.DoLootRelease(currentLootGuid);
|
||||
|
||||
Loot loot = null;
|
||||
Loot loot;
|
||||
PermissionTypes permission = PermissionTypes.All;
|
||||
|
||||
Log.outDebug(LogFilter.Loot, "Player.SendLoot");
|
||||
|
||||
@@ -153,9 +153,6 @@ namespace Game.Entities
|
||||
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||
return 0;
|
||||
|
||||
var field = (ushort)(skillStatusData.Pos / 2);
|
||||
var offset = (byte)(skillStatusData.Pos & 1);
|
||||
|
||||
return skillInfo.SkillStep[skillStatusData.Pos];
|
||||
}
|
||||
|
||||
@@ -613,15 +610,11 @@ namespace Game.Entities
|
||||
// processed in Player.CastItemCombatSpell
|
||||
break;
|
||||
case ItemEnchantmentType.Damage:
|
||||
if (item.GetSlot() == EquipmentSlot.MainHand)
|
||||
{
|
||||
if (item.GetTemplate().GetInventoryType() != InventoryType.Ranged && item.GetTemplate().GetInventoryType() != InventoryType.RangedRight)
|
||||
HandleStatModifier(UnitMods.DamageMainHand, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
else
|
||||
HandleStatModifier(UnitMods.DamageRanged, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
WeaponAttackType attackType = Player.GetAttackBySlot(item.GetSlot(), item.GetTemplate().GetInventoryType());
|
||||
if (attackType != WeaponAttackType.Max)
|
||||
UpdateDamageDoneMods(attackType);
|
||||
}
|
||||
else if (item.GetSlot() == EquipmentSlot.OffHand)
|
||||
HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
break;
|
||||
case ItemEnchantmentType.EquipSpell:
|
||||
if (enchant_spell_id != 0)
|
||||
@@ -654,7 +647,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
enchant_amount = Math.Max(enchant_amount, 1u);
|
||||
HandleStatModifier((UnitMods)((uint)UnitMods.ResistanceStart + enchant_spell_id), UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
HandleStatFlatModifier((UnitMods)((uint)UnitMods.ResistanceStart + enchant_spell_id), UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
break;
|
||||
case ItemEnchantmentType.Stat:
|
||||
{
|
||||
@@ -685,26 +678,26 @@ namespace Game.Entities
|
||||
{
|
||||
case ItemModType.Mana:
|
||||
Log.outDebug(LogFilter.Player, "+ {0} MANA", enchant_amount);
|
||||
HandleStatModifier(UnitMods.Mana, UnitModifierType.BaseValue, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.Mana, UnitModifierFlatType.Base, enchant_amount, apply);
|
||||
break;
|
||||
case ItemModType.Health:
|
||||
Log.outDebug(LogFilter.Player, "+ {0} HEALTH", enchant_amount);
|
||||
HandleStatModifier(UnitMods.Health, UnitModifierType.BaseValue, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Base, enchant_amount, apply);
|
||||
break;
|
||||
case ItemModType.Agility:
|
||||
Log.outDebug(LogFilter.Player, "+ {0} AGILITY", enchant_amount);
|
||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
ApplyStatBuffMod(Stats.Agility, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
UpdateStatBuffMod(Stats.Agility);
|
||||
break;
|
||||
case ItemModType.Strength:
|
||||
Log.outDebug(LogFilter.Player, "+ {0} STRENGTH", enchant_amount);
|
||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
ApplyStatBuffMod(Stats.Strength, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
UpdateStatBuffMod(Stats.Strength);
|
||||
break;
|
||||
case ItemModType.Intellect:
|
||||
Log.outDebug(LogFilter.Player, "+ {0} INTELLECT", enchant_amount);
|
||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
ApplyStatBuffMod(Stats.Intellect, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
UpdateStatBuffMod(Stats.Intellect);
|
||||
break;
|
||||
//case ItemModType.Spirit:
|
||||
//Log.outDebug(LogFilter.Player, "+ {0} SPIRIT", enchant_amount);
|
||||
@@ -713,8 +706,8 @@ namespace Game.Entities
|
||||
//break;
|
||||
case ItemModType.Stamina:
|
||||
Log.outDebug(LogFilter.Player, "+ {0} STAMINA", enchant_amount);
|
||||
HandleStatModifier(UnitMods.StatStamina, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
ApplyStatBuffMod(Stats.Stamina, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.StatStamina, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
UpdateStatBuffMod(Stats.Stamina);
|
||||
break;
|
||||
case ItemModType.DefenseSkillRating:
|
||||
ApplyRatingMod(CombatRating.DefenseSkill, (int)enchant_amount, apply);
|
||||
@@ -786,12 +779,12 @@ namespace Game.Entities
|
||||
Log.outDebug(LogFilter.Player, "+ {0} EXPERTISE", enchant_amount);
|
||||
break;
|
||||
case ItemModType.AttackPower:
|
||||
HandleStatModifier(UnitMods.AttackPower, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
Log.outDebug(LogFilter.Player, "+ {0} ATTACK_POWER", enchant_amount);
|
||||
break;
|
||||
case ItemModType.RangedAttackPower:
|
||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, enchant_amount, apply);
|
||||
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||
Log.outDebug(LogFilter.Player, "+ {0} RANGED_ATTACK_POWER", enchant_amount);
|
||||
break;
|
||||
case ItemModType.ManaRegeneration:
|
||||
@@ -815,7 +808,7 @@ namespace Game.Entities
|
||||
Log.outDebug(LogFilter.Player, "+ {0} SPELL_PENETRATION", enchant_amount);
|
||||
break;
|
||||
case ItemModType.BlockValue:
|
||||
HandleBaseModValue(BaseModGroup.ShieldBlockValue, BaseModType.FlatMod, enchant_amount, apply);
|
||||
HandleBaseModFlatValue(BaseModGroup.ShieldBlockValue, enchant_amount, apply);
|
||||
Log.outDebug(LogFilter.Player, "+ {0} BLOCK_VALUE", enchant_amount);
|
||||
break;
|
||||
case ItemModType.MasteryRating:
|
||||
@@ -835,20 +828,9 @@ namespace Game.Entities
|
||||
}
|
||||
case ItemEnchantmentType.Totem: // Shaman Rockbiter Weapon
|
||||
{
|
||||
if (GetClass() == Class.Shaman)
|
||||
{
|
||||
float addValue = 0.0f;
|
||||
if (item.GetSlot() == EquipmentSlot.MainHand)
|
||||
{
|
||||
addValue = enchant_amount * item.GetTemplate().GetDelay() / 1000.0f;
|
||||
HandleStatModifier(UnitMods.DamageMainHand, UnitModifierType.TotalValue, addValue, apply);
|
||||
}
|
||||
else if (item.GetSlot() == EquipmentSlot.OffHand)
|
||||
{
|
||||
addValue = enchant_amount * item.GetTemplate().GetDelay() / 1000.0f;
|
||||
HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalValue, addValue, apply);
|
||||
}
|
||||
}
|
||||
WeaponAttackType attackType = Player.GetAttackBySlot(item.GetSlot(), item.GetTemplate().GetInventoryType());
|
||||
if (attackType != WeaponAttackType.Max)
|
||||
UpdateDamageDoneMods(attackType);
|
||||
break;
|
||||
}
|
||||
case ItemEnchantmentType.UseSpell:
|
||||
@@ -1187,14 +1169,14 @@ namespace Game.Entities
|
||||
|
||||
if (skillSlot == 0)
|
||||
{
|
||||
Log.outError(LogFilter.Misc, $"Tried to add skill {id} but player {GetName()} ({GetGUID().ToString()}) cannot have additional skills");
|
||||
Log.outError(LogFilter.Misc, $"Tried to add skill {id} but player {GetName()} ({GetGUID()}) cannot have additional skills");
|
||||
return;
|
||||
}
|
||||
|
||||
SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(id);
|
||||
if (skillEntry == null)
|
||||
{
|
||||
Log.outError(LogFilter.Misc, $"Player.SetSkill: Skill (SkillID: {id}) not found in SkillLineStore for player '{GetName()}' ({GetGUID().ToString()})");
|
||||
Log.outError(LogFilter.Misc, $"Player.SetSkill: Skill (SkillID: {id}) not found in SkillLineStore for player '{GetName()}' ({GetGUID()})");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1829,6 +1811,48 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
// this one rechecks weapon auras and stores them in BaseModGroup container
|
||||
// needed for things like axe specialization applying only to axe weapons in case of dual-wield
|
||||
void UpdateWeaponDependentCritAuras(WeaponAttackType attackType)
|
||||
{
|
||||
BaseModGroup modGroup;
|
||||
switch (attackType)
|
||||
{
|
||||
case WeaponAttackType.BaseAttack:
|
||||
modGroup = BaseModGroup.CritPercentage;
|
||||
break;
|
||||
case WeaponAttackType.OffAttack:
|
||||
modGroup = BaseModGroup.OffhandCritPercentage;
|
||||
break;
|
||||
case WeaponAttackType.RangedAttack:
|
||||
modGroup = BaseModGroup.RangedCritPercentage;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
float amount = 0.0f;
|
||||
amount += GetTotalAuraModifier(AuraType.ModWeaponCritPercent, auraEffect => CheckAttackFitToAuraRequirement(attackType, auraEffect));
|
||||
|
||||
// these auras don't have item requirement (only Combat Expertise in 3.3.5a)
|
||||
amount += GetTotalAuraModifier(AuraType.ModCritPct);
|
||||
|
||||
SetBaseModFlatValue(modGroup, amount);
|
||||
}
|
||||
|
||||
public void UpdateAllWeaponDependentCritAuras()
|
||||
{
|
||||
for (var attackType = WeaponAttackType.BaseAttack; attackType < WeaponAttackType.Max; ++attackType)
|
||||
UpdateWeaponDependentCritAuras(attackType);
|
||||
}
|
||||
|
||||
public void UpdateWeaponDependentAuras(WeaponAttackType attackType)
|
||||
{
|
||||
UpdateWeaponDependentCritAuras(attackType);
|
||||
UpdateDamageDoneMods(attackType);
|
||||
UpdateDamagePctDoneMods(attackType);
|
||||
}
|
||||
|
||||
public void ApplyItemDependentAuras(Item item, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
@@ -1851,6 +1875,19 @@ namespace Game.Entities
|
||||
RemoveItemDependentAurasAndCasts(item);
|
||||
}
|
||||
|
||||
public override bool CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect aurEff)
|
||||
{
|
||||
SpellInfo spellInfo = aurEff.GetSpellInfo();
|
||||
if (spellInfo.EquippedItemClass == ItemClass.None)
|
||||
return true;
|
||||
|
||||
Item item = GetWeaponForAttack(attackType, true);
|
||||
if (item == null || !item.IsFitToSpellRequirements(spellInfo))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AddTemporarySpell(uint spellId)
|
||||
{
|
||||
var spell = m_spells.LookupByKey(spellId);
|
||||
|
||||
@@ -83,7 +83,10 @@ namespace Game.Entities
|
||||
_specializationInfo = new SpecializationInfo();
|
||||
|
||||
for (byte i = 0; i < (byte)BaseModGroup.End; ++i)
|
||||
m_auraBaseMod[i] = new float[] { 0.0f, 1.0f };
|
||||
{
|
||||
m_auraBaseFlatMod[i] = 0.0f;
|
||||
m_auraBasePctMod[i] = 1.0f;
|
||||
}
|
||||
|
||||
for (var i = 0; i < (int)SpellModOp.Max; ++i)
|
||||
{
|
||||
@@ -3791,7 +3794,7 @@ namespace Game.Entities
|
||||
if (powerType == null)
|
||||
return;
|
||||
|
||||
float addvalue = 0.0f;
|
||||
float addvalue;
|
||||
|
||||
if (!IsInCombat())
|
||||
{
|
||||
@@ -4695,7 +4698,7 @@ namespace Game.Entities
|
||||
SpawnCorpseBones();
|
||||
}
|
||||
|
||||
WorldSafeLocsEntry ClosestGrave = null;
|
||||
WorldSafeLocsEntry ClosestGrave;
|
||||
|
||||
// Special handle for Battlegroundmaps
|
||||
Battleground bg = GetBattleground();
|
||||
@@ -5333,8 +5336,7 @@ namespace Game.Entities
|
||||
|
||||
PlayerLevelInfo info = Global.ObjectMgr.GetPlayerLevelInfo(GetRace(), GetClass(), level);
|
||||
|
||||
uint basemana = 0;
|
||||
Global.ObjectMgr.GetPlayerClassLevelInfo(GetClass(), level, out basemana);
|
||||
Global.ObjectMgr.GetPlayerClassLevelInfo(GetClass(), level, out uint basemana);
|
||||
|
||||
LevelUpInfo packet = new LevelUpInfo();
|
||||
packet.Level = level;
|
||||
@@ -6567,7 +6569,7 @@ namespace Game.Entities
|
||||
if (level >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
|
||||
return;
|
||||
|
||||
uint bonus_xp = 0;
|
||||
uint bonus_xp;
|
||||
bool recruitAFriend = GetsRecruitAFriendBonus(true);
|
||||
|
||||
// RaF does NOT stack with rested experience
|
||||
@@ -6603,36 +6605,104 @@ namespace Game.Entities
|
||||
SetXP(newXP);
|
||||
}
|
||||
|
||||
public void HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply)
|
||||
public void HandleBaseModFlatValue(BaseModGroup modGroup, float amount, bool apply)
|
||||
{
|
||||
if (modGroup >= BaseModGroup.End || modType >= BaseModType.End)
|
||||
if (modGroup >= BaseModGroup.End)
|
||||
{
|
||||
Log.outError(LogFilter.Spells, "ERROR in HandleBaseModValue(): non existed BaseModGroup of wrong BaseModType!");
|
||||
Log.outError(LogFilter.Spells, $"Player.HandleBaseModFlatValue: Invalid BaseModGroup ({modGroup}) for player '{GetName()}' ({GetGUID()})");
|
||||
return;
|
||||
}
|
||||
m_auraBaseFlatMod[(int)modGroup] += apply ? amount : -amount;
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
public void ApplyBaseModPctValue(BaseModGroup modGroup, float pct)
|
||||
{
|
||||
if (modGroup >= BaseModGroup.End)
|
||||
{
|
||||
Log.outError(LogFilter.Spells, $"Player.ApplyBaseModPctValue: Invalid BaseModGroup/BaseModType ({modGroup}/{BaseModType.FlatMod}) for player '{GetName()}' ({GetGUID()})");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (modType)
|
||||
MathFunctions.AddPct(ref m_auraBasePctMod[(int)modGroup], pct);
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
public void SetBaseModFlatValue(BaseModGroup modGroup, float val)
|
||||
{
|
||||
if (m_auraBaseFlatMod[(int)modGroup] == val)
|
||||
return;
|
||||
|
||||
m_auraBaseFlatMod[(int)modGroup] = val;
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
public void SetBaseModPctValue(BaseModGroup modGroup, float val)
|
||||
{
|
||||
if (m_auraBasePctMod[(int)modGroup] == val)
|
||||
return;
|
||||
|
||||
m_auraBasePctMod[(int)modGroup] = val;
|
||||
UpdateBaseModGroup(modGroup);
|
||||
}
|
||||
|
||||
public override void UpdateDamageDoneMods(WeaponAttackType attackType)
|
||||
{
|
||||
base.UpdateDamageDoneMods(attackType);
|
||||
|
||||
UnitMods unitMod = attackType switch
|
||||
{
|
||||
case BaseModType.FlatMod:
|
||||
m_auraBaseMod[(int)modGroup][(int)modType] += apply ? amount : -amount;
|
||||
break;
|
||||
case BaseModType.PCTmod:
|
||||
MathFunctions.ApplyPercentModFloatVar(ref m_auraBaseMod[(int)modGroup][(int)modType], amount, apply);
|
||||
break;
|
||||
WeaponAttackType.BaseAttack => UnitMods.DamageMainHand,
|
||||
WeaponAttackType.OffAttack => UnitMods.DamageOffHand,
|
||||
WeaponAttackType.RangedAttack => UnitMods.DamageRanged,
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
|
||||
float amount = 0.0f;
|
||||
Item item = GetWeaponForAttack(attackType, true);
|
||||
if (item == null)
|
||||
return;
|
||||
|
||||
for (var slot = EnchantmentSlot.Perm; slot < EnchantmentSlot.Max; ++slot)
|
||||
{
|
||||
SpellItemEnchantmentRecord enchantmentEntry = CliDB.SpellItemEnchantmentStorage.LookupByKey(item.GetEnchantmentId(slot));
|
||||
if (enchantmentEntry == null)
|
||||
continue;
|
||||
|
||||
for (byte i = 0; i < ItemConst.MaxItemEnchantmentEffects; ++i)
|
||||
{
|
||||
switch (enchantmentEntry.Effect[i])
|
||||
{
|
||||
case ItemEnchantmentType.Damage:
|
||||
amount += enchantmentEntry.EffectScalingPoints[i];
|
||||
break;
|
||||
case ItemEnchantmentType.Totem:
|
||||
if (GetClass() == Class.Shaman)
|
||||
amount += enchantmentEntry.EffectScalingPoints[i] * item.GetTemplate().GetDelay() / 1000.0f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HandleStatFlatModifier(unitMod, UnitModifierFlatType.Total, amount, true);
|
||||
}
|
||||
|
||||
void UpdateBaseModGroup(BaseModGroup modGroup)
|
||||
{
|
||||
if (!CanModifyStats())
|
||||
return;
|
||||
|
||||
switch (modGroup)
|
||||
{
|
||||
case BaseModGroup.CritPercentage:
|
||||
UpdateCritPercentage(WeaponAttackType.BaseAttack);
|
||||
case BaseModGroup.CritPercentage:
|
||||
UpdateCritPercentage(WeaponAttackType.BaseAttack);
|
||||
break;
|
||||
case BaseModGroup.RangedCritPercentage:
|
||||
UpdateCritPercentage(WeaponAttackType.RangedAttack);
|
||||
case BaseModGroup.RangedCritPercentage:
|
||||
UpdateCritPercentage(WeaponAttackType.RangedAttack);
|
||||
break;
|
||||
case BaseModGroup.OffhandCritPercentage:
|
||||
case BaseModGroup.OffhandCritPercentage:
|
||||
UpdateCritPercentage(WeaponAttackType.OffAttack);
|
||||
break;
|
||||
default:
|
||||
@@ -6640,6 +6710,28 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
float GetBaseModValue(BaseModGroup modGroup, BaseModType modType)
|
||||
{
|
||||
if (modGroup >= BaseModGroup.End || modType >= BaseModType.End)
|
||||
{
|
||||
Log.outError(LogFilter.Spells, $"Player.GetBaseModValue: Invalid BaseModGroup/BaseModType ({modGroup}/{modType}) for player '{GetName()}' ({GetGUID()})");
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return (modType == BaseModType.FlatMod ? m_auraBaseFlatMod[(int)modGroup] : m_auraBasePctMod[(int)modGroup]);
|
||||
}
|
||||
|
||||
float GetTotalBaseModValue(BaseModGroup modGroup)
|
||||
{
|
||||
if (modGroup >= BaseModGroup.End)
|
||||
{
|
||||
Log.outError(LogFilter.Spells, $"Player.GetTotalBaseModValue: Invalid BaseModGroup ({modGroup}) for player '{GetName()}' ({GetGUID()})");
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
return m_auraBaseFlatMod[(int)modGroup] * m_auraBasePctMod[(int)modGroup];
|
||||
}
|
||||
|
||||
public void AddComboPoints(sbyte count, Spell spell = null)
|
||||
{
|
||||
if (count == 0)
|
||||
@@ -6898,7 +6990,7 @@ namespace Game.Entities
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.InstantTaxi))
|
||||
{
|
||||
var lastPathNode = CliDB.TaxiNodesStorage.LookupByKey(nodes[nodes.Count - 1]);
|
||||
var lastPathNode = CliDB.TaxiNodesStorage.LookupByKey(nodes[^1]);
|
||||
m_taxi.ClearTaxiDestinations();
|
||||
ModifyMoney(-totalcost);
|
||||
UpdateCriteria(CriteriaTypes.GoldSpentForTravelling, totalcost);
|
||||
@@ -6956,7 +7048,7 @@ namespace Game.Entities
|
||||
|
||||
var nodeList = CliDB.TaxiPathNodesByPath[path];
|
||||
|
||||
float distPrev = MapConst.MapSize * MapConst.MapSize;
|
||||
float distPrev;
|
||||
float distNext = GetExactDistSq(nodeList[0].Loc.X, nodeList[0].Loc.Y, nodeList[0].Loc.Z);
|
||||
|
||||
for (int i = 1; i < nodeList.Length; ++i)
|
||||
@@ -7277,7 +7369,7 @@ namespace Game.Entities
|
||||
return null;
|
||||
}
|
||||
|
||||
Item item = null;
|
||||
Item item;
|
||||
if (useable)
|
||||
item = GetUseableItemByPos(InventorySlots.Bag0, slot);
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user