Core/Auras: reworked multiplicative AuraEffects calculation
Port From (https://github.com/TrinityCore/TrinityCore/commit/ebc06b1d0401be69066986e18d0e926170c58023)
This commit is contained in:
@@ -87,7 +87,7 @@ namespace Framework.Constants
|
|||||||
public enum BaseModType
|
public enum BaseModType
|
||||||
{
|
{
|
||||||
FlatMod,
|
FlatMod,
|
||||||
PCTmod,
|
PctMod,
|
||||||
End
|
End
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,14 +178,18 @@ namespace Framework.Constants
|
|||||||
PowerStart = Mana,
|
PowerStart = Mana,
|
||||||
PowerEnd = Pain + 1
|
PowerEnd = Pain + 1
|
||||||
}
|
}
|
||||||
public enum UnitModifierType
|
public enum UnitModifierFlatType
|
||||||
{
|
{
|
||||||
BaseValue = 0,
|
Base = 0,
|
||||||
BasePCTExcludeCreate = 1, // percent modifier affecting all stat values from auras and gear but not player base for level
|
BasePCTExcludeCreate = 1, // percent modifier affecting all stat values from auras and gear but not player base for level
|
||||||
BasePCT = 2,
|
Total = 2,
|
||||||
TotalValue = 3,
|
End = 3
|
||||||
TotalPCT = 4,
|
}
|
||||||
End = 5
|
public enum UnitModifierPctType
|
||||||
|
{
|
||||||
|
Base = 0,
|
||||||
|
Total = 1,
|
||||||
|
End = 2
|
||||||
}
|
}
|
||||||
public enum VictimState
|
public enum VictimState
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -312,12 +312,12 @@ namespace Game.Entities
|
|||||||
UpdateLevelDependantStats(); // We still re-initialize level dependant stats on entry update
|
UpdateLevelDependantStats(); // We still re-initialize level dependant stats on entry update
|
||||||
|
|
||||||
SetMeleeDamageSchool((SpellSchools)cInfo.DmgSchool);
|
SetMeleeDamageSchool((SpellSchools)cInfo.DmgSchool);
|
||||||
SetModifierValue(UnitMods.ResistanceHoly, UnitModifierType.BaseValue, cInfo.Resistance[(int)SpellSchools.Holy]);
|
SetStatFlatModifier(UnitMods.ResistanceHoly, UnitModifierFlatType.Base, cInfo.Resistance[(int)SpellSchools.Holy]);
|
||||||
SetModifierValue(UnitMods.ResistanceFire, UnitModifierType.BaseValue, cInfo.Resistance[(int)SpellSchools.Fire]);
|
SetStatFlatModifier(UnitMods.ResistanceFire, UnitModifierFlatType.Base, cInfo.Resistance[(int)SpellSchools.Fire]);
|
||||||
SetModifierValue(UnitMods.ResistanceNature, UnitModifierType.BaseValue, cInfo.Resistance[(int)SpellSchools.Nature]);
|
SetStatFlatModifier(UnitMods.ResistanceNature, UnitModifierFlatType.Base, cInfo.Resistance[(int)SpellSchools.Nature]);
|
||||||
SetModifierValue(UnitMods.ResistanceFrost, UnitModifierType.BaseValue, cInfo.Resistance[(int)SpellSchools.Frost]);
|
SetStatFlatModifier(UnitMods.ResistanceFrost, UnitModifierFlatType.Base, cInfo.Resistance[(int)SpellSchools.Frost]);
|
||||||
SetModifierValue(UnitMods.ResistanceShadow, UnitModifierType.BaseValue, cInfo.Resistance[(int)SpellSchools.Shadow]);
|
SetStatFlatModifier(UnitMods.ResistanceShadow, UnitModifierFlatType.Base, cInfo.Resistance[(int)SpellSchools.Shadow]);
|
||||||
SetModifierValue(UnitMods.ResistanceArcane, UnitModifierType.BaseValue, cInfo.Resistance[(int)SpellSchools.Arcane]);
|
SetStatFlatModifier(UnitMods.ResistanceArcane, UnitModifierFlatType.Base, cInfo.Resistance[(int)SpellSchools.Arcane]);
|
||||||
|
|
||||||
SetCanModifyStats(true);
|
SetCanModifyStats(true);
|
||||||
UpdateAllStats();
|
UpdateAllStats();
|
||||||
@@ -563,7 +563,7 @@ namespace Game.Entities
|
|||||||
if (curValue >= maxValue)
|
if (curValue >= maxValue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float addvalue = 0.0f;
|
float addvalue;
|
||||||
|
|
||||||
switch (power)
|
switch (power)
|
||||||
{
|
{
|
||||||
@@ -614,7 +614,7 @@ namespace Game.Entities
|
|||||||
if (curValue >= maxValue)
|
if (curValue >= maxValue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
long addvalue = 0;
|
long addvalue;
|
||||||
|
|
||||||
// Not only pet, but any controlled creature (and not polymorphed)
|
// Not only pet, but any controlled creature (and not polymorphed)
|
||||||
if (!GetCharmerOrOwnerGUID().IsEmpty() && !IsPolymorphed())
|
if (!GetCharmerOrOwnerGUID().IsEmpty() && !IsPolymorphed())
|
||||||
@@ -1166,7 +1166,7 @@ namespace Game.Entities
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetModifierValue(UnitMods.Health, UnitModifierType.BaseValue, health);
|
SetStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Base, health);
|
||||||
|
|
||||||
//Damage
|
//Damage
|
||||||
float basedamage = stats.GenerateBaseDamage(cInfo);
|
float basedamage = stats.GenerateBaseDamage(cInfo);
|
||||||
@@ -1182,11 +1182,11 @@ namespace Game.Entities
|
|||||||
SetBaseWeaponDamage(WeaponAttackType.RangedAttack, WeaponDamageRange.MinDamage, weaponBaseMinDamage);
|
SetBaseWeaponDamage(WeaponAttackType.RangedAttack, WeaponDamageRange.MinDamage, weaponBaseMinDamage);
|
||||||
SetBaseWeaponDamage(WeaponAttackType.RangedAttack, WeaponDamageRange.MaxDamage, weaponBaseMaxDamage);
|
SetBaseWeaponDamage(WeaponAttackType.RangedAttack, WeaponDamageRange.MaxDamage, weaponBaseMaxDamage);
|
||||||
|
|
||||||
SetModifierValue(UnitMods.AttackPower, UnitModifierType.BaseValue, stats.AttackPower);
|
SetStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Base, stats.AttackPower);
|
||||||
SetModifierValue(UnitMods.AttackPowerRanged, UnitModifierType.BaseValue, stats.RangedAttackPower);
|
SetStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Base, stats.RangedAttackPower);
|
||||||
|
|
||||||
float armor = stats.GenerateArmor(cInfo); // @todo Why is this treated as uint32 when it's a float?
|
float armor = stats.GenerateArmor(cInfo); // @todo Why is this treated as uint32 when it's a float?
|
||||||
SetModifierValue(UnitMods.Armor, UnitModifierType.BaseValue, armor);
|
SetStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, armor);
|
||||||
}
|
}
|
||||||
|
|
||||||
float _GetHealthMod(CreatureEliteType Rank)
|
float _GetHealthMod(CreatureEliteType Rank)
|
||||||
@@ -2026,7 +2026,6 @@ namespace Game.Entities
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit myVictim = GetAttackerForHelper();
|
|
||||||
Unit targetVictim = target.GetAttackerForHelper();
|
Unit targetVictim = target.GetAttackerForHelper();
|
||||||
|
|
||||||
// if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
|
// if I'm already fighting target, or I'm hostile towards the target, the target is acceptable
|
||||||
@@ -2263,13 +2262,11 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void GetRespawnPosition(out float x, out float y, out float z)
|
public void GetRespawnPosition(out float x, out float y, out float z)
|
||||||
{
|
{
|
||||||
float notUsed;
|
GetRespawnPosition(out x, out y, out z, out _, out _);
|
||||||
GetRespawnPosition(out x, out y, out z, out notUsed, out notUsed);
|
|
||||||
}
|
}
|
||||||
public void GetRespawnPosition(out float x, out float y, out float z, out float ori)
|
public void GetRespawnPosition(out float x, out float y, out float z, out float ori)
|
||||||
{
|
{
|
||||||
float notUsed;
|
GetRespawnPosition(out x, out y, out z, out ori, out _);
|
||||||
GetRespawnPosition(out x, out y, out z, out ori, out notUsed);
|
|
||||||
}
|
}
|
||||||
public void GetRespawnPosition(out float x, out float y, out float z, out float ori, out float dist)
|
public void GetRespawnPosition(out float x, out float y, out float z, out float ori, out float dist)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// @todo research if talents/effects that increase total agility by x% should increase non-diminishing part
|
// @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;
|
float bonus_agility = GetStat(Stats.Agility) - base_agility;
|
||||||
|
|
||||||
// calculate diminishing (green in char screen) and non-diminishing (white) contribution
|
// 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)
|
public float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType)
|
||||||
{
|
{
|
||||||
float baseExpertise = 7.5f;
|
float baseExpertise = 7.5f;
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ namespace Game.Entities
|
|||||||
|
|
||||||
//Combat
|
//Combat
|
||||||
int[] baseRatingValue = new int[(int)CombatRating.Max];
|
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;
|
public DuelInfo duel;
|
||||||
bool m_canParry;
|
bool m_canParry;
|
||||||
bool m_canBlock;
|
bool m_canBlock;
|
||||||
|
|||||||
@@ -1098,8 +1098,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
public InventoryResult CanStoreNewItem(byte bag, byte slot, List<ItemPosCount> dest, uint item, uint count)
|
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 _);
|
||||||
return CanStoreItem(bag, slot, dest, item, count, null, false, out notused);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item _StoreItem(ushort pos, Item pItem, uint count, bool clone, bool update)
|
Item _StoreItem(ushort pos, Item pItem, uint count, bool clone, bool update)
|
||||||
@@ -1233,8 +1232,7 @@ namespace Game.Entities
|
|||||||
// attempt equip by one
|
// attempt equip by one
|
||||||
while (titem_amount > 0)
|
while (titem_amount > 0)
|
||||||
{
|
{
|
||||||
ushort eDest = 0;
|
msg = CanEquipNewItem(ItemConst.NullSlot, out ushort eDest, titem_id, false);
|
||||||
msg = CanEquipNewItem(ItemConst.NullSlot, out eDest, titem_id, false);
|
|
||||||
if (msg != InventoryResult.Ok)
|
if (msg != InventoryResult.Ok)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1890,7 +1888,7 @@ namespace Game.Entities
|
|||||||
//Add/Remove/Misc Item
|
//Add/Remove/Misc Item
|
||||||
public bool AddItem(uint itemId, uint count)
|
public bool AddItem(uint itemId, uint count)
|
||||||
{
|
{
|
||||||
uint noSpaceForCount = 0;
|
uint noSpaceForCount;
|
||||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||||
InventoryResult msg = CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemId, count, out noSpaceForCount);
|
InventoryResult msg = CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemId, count, out noSpaceForCount);
|
||||||
if (msg != InventoryResult.Ok)
|
if (msg != InventoryResult.Ok)
|
||||||
@@ -3525,7 +3523,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint stacks = count / crItem.maxcount;
|
uint stacks = count / crItem.maxcount;
|
||||||
ItemExtendedCostRecord iece = null;
|
ItemExtendedCostRecord iece;
|
||||||
if (crItem.ExtendedCost != 0)
|
if (crItem.ExtendedCost != 0)
|
||||||
{
|
{
|
||||||
iece = CliDB.ItemExtendedCostStorage.LookupByKey(crItem.ExtendedCost);
|
iece = CliDB.ItemExtendedCostStorage.LookupByKey(crItem.ExtendedCost);
|
||||||
@@ -3991,8 +3989,15 @@ namespace Game.Entities
|
|||||||
|
|
||||||
_ApplyItemBonuses(item, slot, apply);
|
_ApplyItemBonuses(item, slot, apply);
|
||||||
ApplyItemEquipSpell(item, apply);
|
ApplyItemEquipSpell(item, apply);
|
||||||
|
|
||||||
if (updateItemAuras)
|
if (updateItemAuras)
|
||||||
|
{
|
||||||
ApplyItemDependentAuras(item, apply);
|
ApplyItemDependentAuras(item, apply);
|
||||||
|
WeaponAttackType attackType = Player.GetAttackBySlot(slot, item.GetTemplate().GetInventoryType());
|
||||||
|
if (attackType != WeaponAttackType.Max)
|
||||||
|
UpdateWeaponDependentAuras(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
ApplyArtifactPowers(item, apply);
|
ApplyArtifactPowers(item, apply);
|
||||||
ApplyAzeritePowers(item, apply);
|
ApplyAzeritePowers(item, apply);
|
||||||
ApplyEnchantment(item, apply);
|
ApplyEnchantment(item, apply);
|
||||||
@@ -4025,22 +4030,22 @@ namespace Game.Entities
|
|||||||
switch ((ItemModType)statType)
|
switch ((ItemModType)statType)
|
||||||
{
|
{
|
||||||
case ItemModType.Mana:
|
case ItemModType.Mana:
|
||||||
HandleStatModifier(UnitMods.Mana, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.Mana, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Health: // modify HP
|
case ItemModType.Health: // modify HP
|
||||||
HandleStatModifier(UnitMods.Health, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Agility: // modify agility
|
case ItemModType.Agility: // modify agility
|
||||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Agility);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Strength: //modify strength
|
case ItemModType.Strength: //modify strength
|
||||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Strength);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Intellect: //modify intellect
|
case ItemModType.Intellect: //modify intellect
|
||||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Intellect);
|
||||||
break;
|
break;
|
||||||
//case ItemModType.Spirit: //modify spirit
|
//case ItemModType.Spirit: //modify spirit
|
||||||
//HandleStatModifier(UnitMods.StatSpirit, UnitModifierType.BaseValue, (float)val, apply);
|
//HandleStatModifier(UnitMods.StatSpirit, UnitModifierType.BaseValue, (float)val, apply);
|
||||||
@@ -4051,8 +4056,8 @@ namespace Game.Entities
|
|||||||
if (staminaMult != null)
|
if (staminaMult != null)
|
||||||
val = (int)(val * CliDB.GetIlvlStatMultiplier(staminaMult, proto.GetInventoryType()));
|
val = (int)(val * CliDB.GetIlvlStatMultiplier(staminaMult, proto.GetInventoryType()));
|
||||||
|
|
||||||
HandleStatModifier(UnitMods.StatStamina, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.StatStamina, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
ApplyStatBuffMod(Stats.Stamina, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStamina, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Stamina);
|
||||||
break;
|
break;
|
||||||
case ItemModType.DefenseSkillRating:
|
case ItemModType.DefenseSkillRating:
|
||||||
ApplyRatingMod(CombatRating.DefenseSkill, (int)(val * combatRatingMultiplier), apply);
|
ApplyRatingMod(CombatRating.DefenseSkill, (int)(val * combatRatingMultiplier), apply);
|
||||||
@@ -4118,11 +4123,11 @@ namespace Game.Entities
|
|||||||
ApplyRatingMod(CombatRating.Expertise, (int)(val * combatRatingMultiplier), apply);
|
ApplyRatingMod(CombatRating.Expertise, (int)(val * combatRatingMultiplier), apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.AttackPower:
|
case ItemModType.AttackPower:
|
||||||
HandleStatModifier(UnitMods.AttackPower, UnitModifierType.TotalValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Total, (float)val, apply);
|
||||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.RangedAttackPower:
|
case ItemModType.RangedAttackPower:
|
||||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Versatility:
|
case ItemModType.Versatility:
|
||||||
ApplyRatingMod(CombatRating.VersatilityDamageDone, (int)(val * combatRatingMultiplier), apply);
|
ApplyRatingMod(CombatRating.VersatilityDamageDone, (int)(val * combatRatingMultiplier), apply);
|
||||||
@@ -4148,25 +4153,25 @@ namespace Game.Entities
|
|||||||
ApplyRatingMod(CombatRating.Mastery, (int)(val * combatRatingMultiplier), apply);
|
ApplyRatingMod(CombatRating.Mastery, (int)(val * combatRatingMultiplier), apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.ExtraArmor:
|
case ItemModType.ExtraArmor:
|
||||||
HandleStatModifier(UnitMods.Armor, UnitModifierType.TotalValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Total, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.FireResistance:
|
case ItemModType.FireResistance:
|
||||||
HandleStatModifier(UnitMods.ResistanceFire, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.ResistanceFire, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.FrostResistance:
|
case ItemModType.FrostResistance:
|
||||||
HandleStatModifier(UnitMods.ResistanceFrost, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.ResistanceFrost, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.HolyResistance:
|
case ItemModType.HolyResistance:
|
||||||
HandleStatModifier(UnitMods.ResistanceHoly, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.ResistanceHoly, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.ShadowResistance:
|
case ItemModType.ShadowResistance:
|
||||||
HandleStatModifier(UnitMods.ResistanceShadow, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.ResistanceShadow, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.NatureResistance:
|
case ItemModType.NatureResistance:
|
||||||
HandleStatModifier(UnitMods.ResistanceNature, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.ResistanceNature, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.ArcaneResistance:
|
case ItemModType.ArcaneResistance:
|
||||||
HandleStatModifier(UnitMods.ResistanceArcane, UnitModifierType.BaseValue, (float)val, apply);
|
HandleStatFlatModifier(UnitMods.ResistanceArcane, UnitModifierFlatType.Base, (float)val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.PvpPower:
|
case ItemModType.PvpPower:
|
||||||
ApplyRatingMod(CombatRating.PvpPower, val, apply);
|
ApplyRatingMod(CombatRating.PvpPower, val, apply);
|
||||||
@@ -4202,37 +4207,37 @@ namespace Game.Entities
|
|||||||
ApplyRatingMod(CombatRating.Unused12, val, apply);
|
ApplyRatingMod(CombatRating.Unused12, val, apply);
|
||||||
break;
|
break;
|
||||||
case ItemModType.AgiStrInt:
|
case ItemModType.AgiStrInt:
|
||||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply);
|
||||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply);
|
||||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, val, apply);
|
||||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Agility);
|
||||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Strength);
|
||||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Intellect);
|
||||||
break;
|
break;
|
||||||
case ItemModType.AgiStr:
|
case ItemModType.AgiStr:
|
||||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply);
|
||||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply);
|
||||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Agility);
|
||||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Strength);
|
||||||
break;
|
break;
|
||||||
case ItemModType.AgiInt:
|
case ItemModType.AgiInt:
|
||||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Base, val, apply);
|
||||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, val, apply);
|
||||||
ApplyStatBuffMod(Stats.Agility, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatAgility, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Agility);
|
||||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Intellect);
|
||||||
break;
|
break;
|
||||||
case ItemModType.StrInt:
|
case ItemModType.StrInt:
|
||||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Base, val, apply);
|
||||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.BaseValue, val, apply);
|
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Base, val, apply);
|
||||||
ApplyStatBuffMod(Stats.Strength, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatStrength, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Strength);
|
||||||
ApplyStatBuffMod(Stats.Intellect, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatIntellect, UnitModifierType.BasePCTExcludeCreate)), apply);
|
UpdateStatBuffMod(Stats.Intellect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint armor = item.GetArmor(this);
|
uint armor = item.GetArmor(this);
|
||||||
if (armor != 0)
|
if (armor != 0)
|
||||||
HandleStatModifier(UnitMods.Armor, UnitModifierType.BaseValue, (float)armor, apply);
|
HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, (float)armor, apply);
|
||||||
|
|
||||||
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
WeaponAttackType attType = WeaponAttackType.BaseAttack;
|
||||||
if (slot == EquipmentSlot.MainHand && (proto.GetInventoryType() == InventoryType.Ranged || proto.GetInventoryType() == InventoryType.RangedRight))
|
if (slot == EquipmentSlot.MainHand && (proto.GetInventoryType() == InventoryType.Ranged || proto.GetInventoryType() == InventoryType.RangedRight))
|
||||||
@@ -4425,6 +4430,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
ApplyItemDependentAuras(m_items[i], true);
|
ApplyItemDependentAuras(m_items[i], true);
|
||||||
_ApplyItemBonuses(m_items[i], 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 SetLootGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.LootTargetGUID), guid); }
|
||||||
public void StoreLootItem(byte lootSlot, Loot loot, AELootResult aeResult = null)
|
public void StoreLootItem(byte lootSlot, Loot loot, AELootResult aeResult = null)
|
||||||
{
|
{
|
||||||
NotNormalLootItem qitem = null;
|
LootItem item = loot.LootItemInSlot(lootSlot, this, out NotNormalLootItem qitem, out NotNormalLootItem ffaitem, out NotNormalLootItem conditem);
|
||||||
NotNormalLootItem ffaitem = null;
|
|
||||||
NotNormalLootItem conditem = null;
|
|
||||||
|
|
||||||
LootItem item = loot.LootItemInSlot(lootSlot, this, out qitem, out ffaitem, out conditem);
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
{
|
{
|
||||||
SendEquipError(InventoryResult.LootGone);
|
SendEquipError(InventoryResult.LootGone);
|
||||||
@@ -6385,7 +6390,7 @@ namespace Game.Entities
|
|||||||
if (!currentLootGuid.IsEmpty() && !aeLooting)
|
if (!currentLootGuid.IsEmpty() && !aeLooting)
|
||||||
Session.DoLootRelease(currentLootGuid);
|
Session.DoLootRelease(currentLootGuid);
|
||||||
|
|
||||||
Loot loot = null;
|
Loot loot;
|
||||||
PermissionTypes permission = PermissionTypes.All;
|
PermissionTypes permission = PermissionTypes.All;
|
||||||
|
|
||||||
Log.outDebug(LogFilter.Loot, "Player.SendLoot");
|
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)
|
if (skillStatusData == null || skillStatusData.State == SkillState.Deleted || skillInfo.SkillRank[skillStatusData.Pos] == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
var field = (ushort)(skillStatusData.Pos / 2);
|
|
||||||
var offset = (byte)(skillStatusData.Pos & 1);
|
|
||||||
|
|
||||||
return skillInfo.SkillStep[skillStatusData.Pos];
|
return skillInfo.SkillStep[skillStatusData.Pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -613,15 +610,11 @@ namespace Game.Entities
|
|||||||
// processed in Player.CastItemCombatSpell
|
// processed in Player.CastItemCombatSpell
|
||||||
break;
|
break;
|
||||||
case ItemEnchantmentType.Damage:
|
case ItemEnchantmentType.Damage:
|
||||||
if (item.GetSlot() == EquipmentSlot.MainHand)
|
|
||||||
{
|
{
|
||||||
if (item.GetTemplate().GetInventoryType() != InventoryType.Ranged && item.GetTemplate().GetInventoryType() != InventoryType.RangedRight)
|
WeaponAttackType attackType = Player.GetAttackBySlot(item.GetSlot(), item.GetTemplate().GetInventoryType());
|
||||||
HandleStatModifier(UnitMods.DamageMainHand, UnitModifierType.TotalValue, enchant_amount, apply);
|
if (attackType != WeaponAttackType.Max)
|
||||||
else
|
UpdateDamageDoneMods(attackType);
|
||||||
HandleStatModifier(UnitMods.DamageRanged, UnitModifierType.TotalValue, enchant_amount, apply);
|
|
||||||
}
|
}
|
||||||
else if (item.GetSlot() == EquipmentSlot.OffHand)
|
|
||||||
HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalValue, enchant_amount, apply);
|
|
||||||
break;
|
break;
|
||||||
case ItemEnchantmentType.EquipSpell:
|
case ItemEnchantmentType.EquipSpell:
|
||||||
if (enchant_spell_id != 0)
|
if (enchant_spell_id != 0)
|
||||||
@@ -654,7 +647,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
enchant_amount = Math.Max(enchant_amount, 1u);
|
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;
|
break;
|
||||||
case ItemEnchantmentType.Stat:
|
case ItemEnchantmentType.Stat:
|
||||||
{
|
{
|
||||||
@@ -685,26 +678,26 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
case ItemModType.Mana:
|
case ItemModType.Mana:
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} MANA", enchant_amount);
|
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;
|
break;
|
||||||
case ItemModType.Health:
|
case ItemModType.Health:
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} HEALTH", enchant_amount);
|
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;
|
break;
|
||||||
case ItemModType.Agility:
|
case ItemModType.Agility:
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} AGILITY", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} AGILITY", enchant_amount);
|
||||||
HandleStatModifier(UnitMods.StatAgility, UnitModifierType.TotalValue, enchant_amount, apply);
|
HandleStatFlatModifier(UnitMods.StatAgility, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||||
ApplyStatBuffMod(Stats.Agility, enchant_amount, apply);
|
UpdateStatBuffMod(Stats.Agility);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Strength:
|
case ItemModType.Strength:
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} STRENGTH", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} STRENGTH", enchant_amount);
|
||||||
HandleStatModifier(UnitMods.StatStrength, UnitModifierType.TotalValue, enchant_amount, apply);
|
HandleStatFlatModifier(UnitMods.StatStrength, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||||
ApplyStatBuffMod(Stats.Strength, enchant_amount, apply);
|
UpdateStatBuffMod(Stats.Strength);
|
||||||
break;
|
break;
|
||||||
case ItemModType.Intellect:
|
case ItemModType.Intellect:
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} INTELLECT", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} INTELLECT", enchant_amount);
|
||||||
HandleStatModifier(UnitMods.StatIntellect, UnitModifierType.TotalValue, enchant_amount, apply);
|
HandleStatFlatModifier(UnitMods.StatIntellect, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||||
ApplyStatBuffMod(Stats.Intellect, enchant_amount, apply);
|
UpdateStatBuffMod(Stats.Intellect);
|
||||||
break;
|
break;
|
||||||
//case ItemModType.Spirit:
|
//case ItemModType.Spirit:
|
||||||
//Log.outDebug(LogFilter.Player, "+ {0} SPIRIT", enchant_amount);
|
//Log.outDebug(LogFilter.Player, "+ {0} SPIRIT", enchant_amount);
|
||||||
@@ -713,8 +706,8 @@ namespace Game.Entities
|
|||||||
//break;
|
//break;
|
||||||
case ItemModType.Stamina:
|
case ItemModType.Stamina:
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} STAMINA", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} STAMINA", enchant_amount);
|
||||||
HandleStatModifier(UnitMods.StatStamina, UnitModifierType.TotalValue, enchant_amount, apply);
|
HandleStatFlatModifier(UnitMods.StatStamina, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||||
ApplyStatBuffMod(Stats.Stamina, enchant_amount, apply);
|
UpdateStatBuffMod(Stats.Stamina);
|
||||||
break;
|
break;
|
||||||
case ItemModType.DefenseSkillRating:
|
case ItemModType.DefenseSkillRating:
|
||||||
ApplyRatingMod(CombatRating.DefenseSkill, (int)enchant_amount, apply);
|
ApplyRatingMod(CombatRating.DefenseSkill, (int)enchant_amount, apply);
|
||||||
@@ -786,12 +779,12 @@ namespace Game.Entities
|
|||||||
Log.outDebug(LogFilter.Player, "+ {0} EXPERTISE", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} EXPERTISE", enchant_amount);
|
||||||
break;
|
break;
|
||||||
case ItemModType.AttackPower:
|
case ItemModType.AttackPower:
|
||||||
HandleStatModifier(UnitMods.AttackPower, UnitModifierType.TotalValue, enchant_amount, apply);
|
HandleStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||||
HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, enchant_amount, apply);
|
HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, enchant_amount, apply);
|
||||||
Log.outDebug(LogFilter.Player, "+ {0} ATTACK_POWER", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} ATTACK_POWER", enchant_amount);
|
||||||
break;
|
break;
|
||||||
case ItemModType.RangedAttackPower:
|
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);
|
Log.outDebug(LogFilter.Player, "+ {0} RANGED_ATTACK_POWER", enchant_amount);
|
||||||
break;
|
break;
|
||||||
case ItemModType.ManaRegeneration:
|
case ItemModType.ManaRegeneration:
|
||||||
@@ -815,7 +808,7 @@ namespace Game.Entities
|
|||||||
Log.outDebug(LogFilter.Player, "+ {0} SPELL_PENETRATION", enchant_amount);
|
Log.outDebug(LogFilter.Player, "+ {0} SPELL_PENETRATION", enchant_amount);
|
||||||
break;
|
break;
|
||||||
case ItemModType.BlockValue:
|
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);
|
Log.outDebug(LogFilter.Player, "+ {0} BLOCK_VALUE", enchant_amount);
|
||||||
break;
|
break;
|
||||||
case ItemModType.MasteryRating:
|
case ItemModType.MasteryRating:
|
||||||
@@ -835,20 +828,9 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
case ItemEnchantmentType.Totem: // Shaman Rockbiter Weapon
|
case ItemEnchantmentType.Totem: // Shaman Rockbiter Weapon
|
||||||
{
|
{
|
||||||
if (GetClass() == Class.Shaman)
|
WeaponAttackType attackType = Player.GetAttackBySlot(item.GetSlot(), item.GetTemplate().GetInventoryType());
|
||||||
{
|
if (attackType != WeaponAttackType.Max)
|
||||||
float addValue = 0.0f;
|
UpdateDamageDoneMods(attackType);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ItemEnchantmentType.UseSpell:
|
case ItemEnchantmentType.UseSpell:
|
||||||
@@ -1187,14 +1169,14 @@ namespace Game.Entities
|
|||||||
|
|
||||||
if (skillSlot == 0)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(id);
|
SkillLineRecord skillEntry = CliDB.SkillLineStorage.LookupByKey(id);
|
||||||
if (skillEntry == null)
|
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;
|
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)
|
public void ApplyItemDependentAuras(Item item, bool apply)
|
||||||
{
|
{
|
||||||
if (apply)
|
if (apply)
|
||||||
@@ -1851,6 +1875,19 @@ namespace Game.Entities
|
|||||||
RemoveItemDependentAurasAndCasts(item);
|
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)
|
public void AddTemporarySpell(uint spellId)
|
||||||
{
|
{
|
||||||
var spell = m_spells.LookupByKey(spellId);
|
var spell = m_spells.LookupByKey(spellId);
|
||||||
|
|||||||
@@ -83,7 +83,10 @@ namespace Game.Entities
|
|||||||
_specializationInfo = new SpecializationInfo();
|
_specializationInfo = new SpecializationInfo();
|
||||||
|
|
||||||
for (byte i = 0; i < (byte)BaseModGroup.End; ++i)
|
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)
|
for (var i = 0; i < (int)SpellModOp.Max; ++i)
|
||||||
{
|
{
|
||||||
@@ -3791,7 +3794,7 @@ namespace Game.Entities
|
|||||||
if (powerType == null)
|
if (powerType == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float addvalue = 0.0f;
|
float addvalue;
|
||||||
|
|
||||||
if (!IsInCombat())
|
if (!IsInCombat())
|
||||||
{
|
{
|
||||||
@@ -4695,7 +4698,7 @@ namespace Game.Entities
|
|||||||
SpawnCorpseBones();
|
SpawnCorpseBones();
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldSafeLocsEntry ClosestGrave = null;
|
WorldSafeLocsEntry ClosestGrave;
|
||||||
|
|
||||||
// Special handle for Battlegroundmaps
|
// Special handle for Battlegroundmaps
|
||||||
Battleground bg = GetBattleground();
|
Battleground bg = GetBattleground();
|
||||||
@@ -5333,8 +5336,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
PlayerLevelInfo info = Global.ObjectMgr.GetPlayerLevelInfo(GetRace(), GetClass(), level);
|
PlayerLevelInfo info = Global.ObjectMgr.GetPlayerLevelInfo(GetRace(), GetClass(), level);
|
||||||
|
|
||||||
uint basemana = 0;
|
Global.ObjectMgr.GetPlayerClassLevelInfo(GetClass(), level, out uint basemana);
|
||||||
Global.ObjectMgr.GetPlayerClassLevelInfo(GetClass(), level, out basemana);
|
|
||||||
|
|
||||||
LevelUpInfo packet = new LevelUpInfo();
|
LevelUpInfo packet = new LevelUpInfo();
|
||||||
packet.Level = level;
|
packet.Level = level;
|
||||||
@@ -6567,7 +6569,7 @@ namespace Game.Entities
|
|||||||
if (level >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
|
if (level >= WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint bonus_xp = 0;
|
uint bonus_xp;
|
||||||
bool recruitAFriend = GetsRecruitAFriendBonus(true);
|
bool recruitAFriend = GetsRecruitAFriendBonus(true);
|
||||||
|
|
||||||
// RaF does NOT stack with rested experience
|
// RaF does NOT stack with rested experience
|
||||||
@@ -6603,36 +6605,104 @@ namespace Game.Entities
|
|||||||
SetXP(newXP);
|
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;
|
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:
|
WeaponAttackType.BaseAttack => UnitMods.DamageMainHand,
|
||||||
m_auraBaseMod[(int)modGroup][(int)modType] += apply ? amount : -amount;
|
WeaponAttackType.OffAttack => UnitMods.DamageOffHand,
|
||||||
break;
|
WeaponAttackType.RangedAttack => UnitMods.DamageRanged,
|
||||||
case BaseModType.PCTmod:
|
_ => throw new NotImplementedException(),
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref m_auraBaseMod[(int)modGroup][(int)modType], amount, apply);
|
};
|
||||||
break;
|
|
||||||
|
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())
|
if (!CanModifyStats())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (modGroup)
|
switch (modGroup)
|
||||||
{
|
{
|
||||||
case BaseModGroup.CritPercentage:
|
case BaseModGroup.CritPercentage:
|
||||||
UpdateCritPercentage(WeaponAttackType.BaseAttack);
|
UpdateCritPercentage(WeaponAttackType.BaseAttack);
|
||||||
break;
|
break;
|
||||||
case BaseModGroup.RangedCritPercentage:
|
case BaseModGroup.RangedCritPercentage:
|
||||||
UpdateCritPercentage(WeaponAttackType.RangedAttack);
|
UpdateCritPercentage(WeaponAttackType.RangedAttack);
|
||||||
break;
|
break;
|
||||||
case BaseModGroup.OffhandCritPercentage:
|
case BaseModGroup.OffhandCritPercentage:
|
||||||
UpdateCritPercentage(WeaponAttackType.OffAttack);
|
UpdateCritPercentage(WeaponAttackType.OffAttack);
|
||||||
break;
|
break;
|
||||||
default:
|
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)
|
public void AddComboPoints(sbyte count, Spell spell = null)
|
||||||
{
|
{
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
@@ -6898,7 +6990,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
if (WorldConfig.GetBoolValue(WorldCfg.InstantTaxi))
|
if (WorldConfig.GetBoolValue(WorldCfg.InstantTaxi))
|
||||||
{
|
{
|
||||||
var lastPathNode = CliDB.TaxiNodesStorage.LookupByKey(nodes[nodes.Count - 1]);
|
var lastPathNode = CliDB.TaxiNodesStorage.LookupByKey(nodes[^1]);
|
||||||
m_taxi.ClearTaxiDestinations();
|
m_taxi.ClearTaxiDestinations();
|
||||||
ModifyMoney(-totalcost);
|
ModifyMoney(-totalcost);
|
||||||
UpdateCriteria(CriteriaTypes.GoldSpentForTravelling, totalcost);
|
UpdateCriteria(CriteriaTypes.GoldSpentForTravelling, totalcost);
|
||||||
@@ -6956,7 +7048,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
var nodeList = CliDB.TaxiPathNodesByPath[path];
|
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);
|
float distNext = GetExactDistSq(nodeList[0].Loc.X, nodeList[0].Loc.Y, nodeList[0].Loc.Z);
|
||||||
|
|
||||||
for (int i = 1; i < nodeList.Length; ++i)
|
for (int i = 1; i < nodeList.Length; ++i)
|
||||||
@@ -7277,7 +7369,7 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item item = null;
|
Item item;
|
||||||
if (useable)
|
if (useable)
|
||||||
item = GetUseableItemByPos(InventorySlots.Bag0, slot);
|
item = GetUseableItemByPos(InventorySlots.Bag0, slot);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -27,35 +27,99 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
public partial class Unit
|
public partial class Unit
|
||||||
{
|
{
|
||||||
public bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, int amount, bool apply)
|
public void HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply)
|
||||||
{
|
{
|
||||||
return HandleStatModifier(unitMod, modifierType, (float)amount, apply);
|
if (unitMod >= UnitMods.End || modifierType >= UnitModifierFlatType.End)
|
||||||
}
|
|
||||||
public bool HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, float amount, bool apply)
|
|
||||||
{
|
|
||||||
if (unitMod >= UnitMods.End || modifierType >= UnitModifierType.End)
|
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Unit, "ERROR in HandleStatModifier(): non-existing UnitMods or wrong UnitModifierType!");
|
Log.outError(LogFilter.Unit, "ERROR in HandleStatFlatModifier(): non-existing UnitMods or wrong UnitModifierFlatType!");
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (amount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (modifierType)
|
switch (modifierType)
|
||||||
{
|
{
|
||||||
case UnitModifierType.BaseValue:
|
case UnitModifierFlatType.Base:
|
||||||
case UnitModifierType.BasePCTExcludeCreate:
|
case UnitModifierFlatType.BasePCTExcludeCreate:
|
||||||
case UnitModifierType.TotalValue:
|
case UnitModifierFlatType.Total:
|
||||||
m_auraModifiersGroup[(int)unitMod][(int)modifierType] += apply ? amount : -amount;
|
m_auraFlatModifiersGroup[(int)unitMod][(int)modifierType] += apply ? amount : -amount;
|
||||||
break;
|
|
||||||
case UnitModifierType.BasePCT:
|
|
||||||
case UnitModifierType.TotalPCT:
|
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref m_auraModifiersGroup[(int)unitMod][(int)modifierType], amount, apply);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateUnitMod(unitMod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float pct)
|
||||||
|
{
|
||||||
|
if (unitMod >= UnitMods.End || modifierType >= UnitModifierPctType.End)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Unit, "ERROR in ApplyStatPctModifier(): non-existing UnitMods or wrong UnitModifierPctType!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pct == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (modifierType)
|
||||||
|
{
|
||||||
|
case UnitModifierPctType.Base:
|
||||||
|
case UnitModifierPctType.Total:
|
||||||
|
MathFunctions.AddPct(ref m_auraPctModifiersGroup[(int)unitMod][(int)modifierType], pct);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateUnitMod(unitMod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float val)
|
||||||
|
{
|
||||||
|
if (m_auraFlatModifiersGroup[(int)unitMod][(int)modifierType] == val)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_auraFlatModifiersGroup[(int)unitMod][(int)modifierType] = val;
|
||||||
|
UpdateUnitMod(unitMod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float val)
|
||||||
|
{
|
||||||
|
if (m_auraPctModifiersGroup[(int)unitMod][(int)modifierType] == val)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_auraPctModifiersGroup[(int)unitMod][(int)modifierType] = val;
|
||||||
|
UpdateUnitMod(unitMod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetFlatModifierValue(UnitMods unitMod, UnitModifierFlatType modifierType)
|
||||||
|
{
|
||||||
|
if (unitMod >= UnitMods.End || modifierType >= UnitModifierFlatType.End)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Unit, "attempt to access non-existing modifier value from UnitMods!");
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_auraFlatModifiersGroup[(int)unitMod][(int)modifierType];
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetPctModifierValue(UnitMods unitMod, UnitModifierPctType modifierType)
|
||||||
|
{
|
||||||
|
if (unitMod >= UnitMods.End || modifierType >= UnitModifierPctType.End)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Unit, "attempt to access non-existing modifier value from UnitMods!");
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_auraPctModifiersGroup[(int)unitMod][(int)modifierType];
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateUnitMod(UnitMods unitMod)
|
||||||
|
{
|
||||||
if (!CanModifyStats())
|
if (!CanModifyStats())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
switch (unitMod)
|
switch (unitMod)
|
||||||
{
|
{
|
||||||
@@ -118,8 +182,6 @@ namespace Game.Entities
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetMinPower(PowerType power) { return power == PowerType.LunarPower ? -100 : 0; }
|
int GetMinPower(PowerType power) { return power == PowerType.LunarPower ? -100 : 0; }
|
||||||
@@ -181,16 +243,71 @@ namespace Game.Entities
|
|||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyStatBuffMod(Stats stat, float val, bool apply)
|
public void UpdateStatBuffMod(Stats stat)
|
||||||
{
|
{
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref (val > 0 ? ref m_floatStatPosBuff[(int)stat] : ref m_floatStatNegBuff[(int)stat]), val, apply);
|
float modPos = 0.0f;
|
||||||
|
float modNeg = 0.0f;
|
||||||
|
float factor = 0.0f;
|
||||||
|
|
||||||
|
UnitMods unitMod = UnitMods.StatStart + (int)stat;
|
||||||
|
|
||||||
|
// includes value from items and enchantments
|
||||||
|
float modValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base);
|
||||||
|
if (modValue > 0.0f)
|
||||||
|
modPos += modValue;
|
||||||
|
else
|
||||||
|
modNeg += modValue;
|
||||||
|
|
||||||
|
if (IsGuardian())
|
||||||
|
{
|
||||||
|
modValue = ((Guardian)this).GetBonusStatFromOwner(stat);
|
||||||
|
if (modValue > 0.0f)
|
||||||
|
modPos += modValue;
|
||||||
|
else
|
||||||
|
modNeg += modValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SPELL_AURA_MOD_STAT_BONUS_PCT only affects BASE_VALUE
|
||||||
|
modPos = MathFunctions.CalculatePct(modPos, Math.Max(GetFlatModifierValue(unitMod, UnitModifierFlatType.BasePCTExcludeCreate), -100.0f));
|
||||||
|
modNeg = MathFunctions.CalculatePct(modPos, Math.Max(GetFlatModifierValue(unitMod, UnitModifierFlatType.BasePCTExcludeCreate), -100.0f));
|
||||||
|
|
||||||
|
modPos += GetTotalAuraModifier(AuraType.ModStat, aurEff =>
|
||||||
|
{
|
||||||
|
if ((aurEff.GetMiscValue() < 0 || aurEff.GetMiscValue() == (int)stat) && aurEff.GetAmount() > 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
modNeg += GetTotalAuraModifier(AuraType.ModStat, aurEff =>
|
||||||
|
{
|
||||||
|
if ((aurEff.GetMiscValue() < 0 || aurEff.GetMiscValue() == (int)stat) && aurEff.GetAmount() < 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
factor = GetTotalAuraMultiplier(AuraType.ModPercentStat, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == -1 || aurEff.GetMiscValue() == (int)stat)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
factor *= GetTotalAuraMultiplier(AuraType.ModTotalStatPercentage, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == -1 || aurEff.GetMiscValue() == (int)stat)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
modPos *= factor;
|
||||||
|
modNeg *= factor;
|
||||||
|
|
||||||
|
m_floatStatPosBuff[(int)stat] = modPos;
|
||||||
|
m_floatStatNegBuff[(int)stat] = modNeg;
|
||||||
|
|
||||||
UpdateStatBuffModForClient(stat);
|
UpdateStatBuffModForClient(stat);
|
||||||
}
|
}
|
||||||
public void ApplyStatPercentBuffMod(Stats stat, float val, bool apply)
|
|
||||||
{
|
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref m_floatStatPosBuff[(int)stat], val, apply);
|
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref m_floatStatNegBuff[(int)stat], val, apply);
|
|
||||||
}
|
|
||||||
void UpdateStatBuffModForClient(Stats stat)
|
void UpdateStatBuffModForClient(Stats stat)
|
||||||
{
|
{
|
||||||
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StatPosBuff, (int)stat), (int)m_floatStatPosBuff[(int)stat]);
|
SetUpdateFieldValue(ref m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.StatPosBuff, (int)stat), (int)m_floatStatPosBuff[(int)stat]);
|
||||||
@@ -204,7 +321,7 @@ namespace Game.Entities
|
|||||||
if (school > SpellSchools.Normal)
|
if (school > SpellSchools.Normal)
|
||||||
{
|
{
|
||||||
UnitMods unitMod = UnitMods.ResistanceStart + (int)school;
|
UnitMods unitMod = UnitMods.ResistanceStart + (int)school;
|
||||||
SetResistance(school, (int)m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BaseValue]);
|
SetResistance(school, (int)GetFlatModifierValue(unitMod, UnitModifierFlatType.Base));
|
||||||
SetBonusResistanceMod(school, (int)(GetTotalAuraModValue(unitMod) - GetResistance(school)));
|
SetBonusResistanceMod(school, (int)(GetTotalAuraModValue(unitMod) - GetResistance(school)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -216,10 +333,7 @@ namespace Game.Entities
|
|||||||
public virtual void UpdateAttackPowerAndDamage(bool ranged = false) { }
|
public virtual void UpdateAttackPowerAndDamage(bool ranged = false) { }
|
||||||
public virtual void UpdateDamagePhysical(WeaponAttackType attType)
|
public virtual void UpdateDamagePhysical(WeaponAttackType attType)
|
||||||
{
|
{
|
||||||
float minDamage = 0.0f;
|
CalculateMinMaxDamage(attType, false, true, out float minDamage, out float maxDamage);
|
||||||
float maxDamage = 0.0f;
|
|
||||||
|
|
||||||
CalculateMinMaxDamage(attType, false, true, out minDamage, out maxDamage);
|
|
||||||
|
|
||||||
switch (attType)
|
switch (attType)
|
||||||
{
|
{
|
||||||
@@ -326,14 +440,11 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
UnitMods unitMod = UnitMods.StatStart + (int)stat;
|
UnitMods unitMod = UnitMods.StatStart + (int)stat;
|
||||||
|
|
||||||
if (m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.TotalPCT] <= 0.0f)
|
float value = MathFunctions.CalculatePct(GetFlatModifierValue(unitMod, UnitModifierFlatType.Base), Math.Max(GetFlatModifierValue(unitMod, UnitModifierFlatType.BasePCTExcludeCreate), -100.0f));
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
float value = MathFunctions.CalculatePct(m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BaseValue], Math.Max(m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BasePCTExcludeCreate], -100.0f));
|
|
||||||
value += GetCreateStat(stat);
|
value += GetCreateStat(stat);
|
||||||
value *= m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BasePCT];
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.TotalValue];
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
value *= m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.TotalPCT];
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -940,6 +1051,7 @@ namespace Game.Entities
|
|||||||
public void ApplyModDamageDonePos(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePos, (int)school), mod, apply); }
|
public void ApplyModDamageDonePos(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePos, (int)school), mod, apply); }
|
||||||
public void ApplyModDamageDoneNeg(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDoneNeg, (int)school), mod, apply); }
|
public void ApplyModDamageDoneNeg(SpellSchools school, int mod, bool apply) { ApplyModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDoneNeg, (int)school), mod, apply); }
|
||||||
public void ApplyModDamageDonePercent(SpellSchools school, float pct, bool apply) { ApplyPercentModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePercent, (int)school), pct, apply); }
|
public void ApplyModDamageDonePercent(SpellSchools school, float pct, bool apply) { ApplyPercentModUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePercent, (int)school), pct, apply); }
|
||||||
|
public void SetModDamageDonePercent(SpellSchools school, float pct) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ModDamageDonePercent, (int)school), pct); }
|
||||||
|
|
||||||
public void ApplyRatingMod(CombatRating combatRating, int value, bool apply)
|
public void ApplyRatingMod(CombatRating combatRating, int value, bool apply)
|
||||||
{
|
{
|
||||||
@@ -968,10 +1080,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
float attackPowerMod = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
float attackPowerMod = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
||||||
|
|
||||||
float baseValue = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod;
|
float baseValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetTotalAttackPowerValue(attType) / 3.5f * attackPowerMod;
|
||||||
float basePct = GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
float basePct = GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float totalValue = GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
float totalValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float totalPct = addTotalPct ? GetModifierValue(unitMod, UnitModifierType.TotalPCT) : 1.0f;
|
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, UnitModifierPctType.Total) : 1.0f;
|
||||||
|
|
||||||
float weaponMinDamage = GetWeaponDamageRange(attType, WeaponDamageRange.MinDamage);
|
float weaponMinDamage = GetWeaponDamageRange(attType, WeaponDamageRange.MinDamage);
|
||||||
float weaponMaxDamage = GetWeaponDamageRange(attType, WeaponDamageRange.MaxDamage);
|
float weaponMaxDamage = GetWeaponDamageRange(attType, WeaponDamageRange.MaxDamage);
|
||||||
@@ -1007,9 +1119,9 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
float value = 5.0f;
|
float value = 5.0f;
|
||||||
|
|
||||||
SetBaseModValue(BaseModGroup.CritPercentage, BaseModType.PCTmod, value);
|
SetBaseModPctValue(BaseModGroup.CritPercentage, value);
|
||||||
SetBaseModValue(BaseModGroup.OffhandCritPercentage, BaseModType.PCTmod, value);
|
SetBaseModPctValue(BaseModGroup.OffhandCritPercentage, value);
|
||||||
SetBaseModValue(BaseModGroup.RangedCritPercentage, BaseModType.PCTmod, value);
|
SetBaseModPctValue(BaseModGroup.RangedCritPercentage, value);
|
||||||
|
|
||||||
UpdateCritPercentage(WeaponAttackType.BaseAttack);
|
UpdateCritPercentage(WeaponAttackType.BaseAttack);
|
||||||
UpdateCritPercentage(WeaponAttackType.OffAttack);
|
UpdateCritPercentage(WeaponAttackType.OffAttack);
|
||||||
@@ -1101,11 +1213,11 @@ namespace Game.Entities
|
|||||||
val2 = MathFunctions.CalculatePct(minSpellPower, m_activePlayerData.OverrideAPBySpellPowerPercent);
|
val2 = MathFunctions.CalculatePct(minSpellPower, m_activePlayerData.OverrideAPBySpellPowerPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetModifierValue(unitMod, UnitModifierType.BaseValue, val2);
|
SetStatFlatModifier(unitMod, UnitModifierFlatType.Base, val2);
|
||||||
|
|
||||||
float base_attPower = GetModifierValue(unitMod, UnitModifierType.BaseValue) * GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
float base_attPower = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) * GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float attPowerMod = GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
float attPowerMod = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float attPowerMultiplier = GetModifierValue(unitMod, UnitModifierType.TotalPCT) - 1.0f;
|
float attPowerMultiplier = GetPctModifierValue(unitMod, UnitModifierPctType.Total) - 1.0f;
|
||||||
|
|
||||||
if (ranged)
|
if (ranged)
|
||||||
{
|
{
|
||||||
@@ -1154,10 +1266,10 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
UnitMods unitMod = UnitMods.Armor;
|
UnitMods unitMod = UnitMods.Armor;
|
||||||
|
|
||||||
float value = GetModifierValue(unitMod, UnitModifierType.BaseValue); // base armor (from items)
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base); // base armor (from items)
|
||||||
float baseValue = value;
|
float baseValue = value;
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT); // armor percent from items
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base); // armor percent from items
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
|
|
||||||
//add dynamic flat mods
|
//add dynamic flat mods
|
||||||
var mResbyIntellect = GetAuraEffectsByType(AuraType.ModResistanceOfStatPercent);
|
var mResbyIntellect = GetAuraEffectsByType(AuraType.ModResistanceOfStatPercent);
|
||||||
@@ -1167,7 +1279,7 @@ namespace Game.Entities
|
|||||||
value += MathFunctions.CalculatePct(GetStat((Stats)i.GetMiscValueB()), i.GetAmount());
|
value += MathFunctions.CalculatePct(GetStat((Stats)i.GetMiscValueB()), i.GetAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetArmor((int)baseValue, (int)(value - baseValue));
|
SetArmor((int)baseValue, (int)(value - baseValue));
|
||||||
|
|
||||||
@@ -1477,7 +1589,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void UpdateCritPercentage(WeaponAttackType attType)
|
public void UpdateCritPercentage(WeaponAttackType attType)
|
||||||
{
|
{
|
||||||
float applyCritLimit(float value)
|
static float applyCritLimit(float value)
|
||||||
{
|
{
|
||||||
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
if (WorldConfig.GetBoolValue(WorldCfg.StatsLimitsEnable))
|
||||||
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) : value;
|
value = value > WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) ? WorldConfig.GetFloatValue(WorldCfg.StatsLimitsCrit) : value;
|
||||||
@@ -1488,16 +1600,16 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
case WeaponAttackType.OffAttack:
|
case WeaponAttackType.OffAttack:
|
||||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OffhandCritPercentage),
|
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.OffhandCritPercentage),
|
||||||
applyCritLimit(GetTotalPercentageModValue(BaseModGroup.OffhandCritPercentage) + GetRatingBonusValue(CombatRating.CritMelee)));
|
applyCritLimit(GetBaseModValue(BaseModGroup.OffhandCritPercentage, BaseModType.FlatMod) + GetBaseModValue(BaseModGroup.OffhandCritPercentage, BaseModType.PctMod) + GetRatingBonusValue(CombatRating.CritMelee)));
|
||||||
break;
|
break;
|
||||||
case WeaponAttackType.RangedAttack:
|
case WeaponAttackType.RangedAttack:
|
||||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RangedCritPercentage),
|
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RangedCritPercentage),
|
||||||
applyCritLimit(GetTotalPercentageModValue(BaseModGroup.RangedCritPercentage) + GetRatingBonusValue(CombatRating.CritRanged)));
|
applyCritLimit(GetBaseModValue(BaseModGroup.RangedCritPercentage, BaseModType.FlatMod) + GetBaseModValue(BaseModGroup.RangedCritPercentage, BaseModType.PctMod) + GetRatingBonusValue(CombatRating.CritRanged)));
|
||||||
break;
|
break;
|
||||||
case WeaponAttackType.BaseAttack:
|
case WeaponAttackType.BaseAttack:
|
||||||
default:
|
default:
|
||||||
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CritPercentage),
|
SetUpdateFieldStatValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.CritPercentage),
|
||||||
applyCritLimit(GetTotalPercentageModValue(BaseModGroup.CritPercentage) + GetRatingBonusValue(CombatRating.CritMelee)));
|
applyCritLimit(GetBaseModValue(BaseModGroup.CritPercentage, BaseModType.FlatMod) + GetBaseModValue(BaseModGroup.CritPercentage, BaseModType.PctMod) + GetRatingBonusValue(CombatRating.CritMelee)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1638,10 +1750,10 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
UnitMods unitMod = UnitMods.Health;
|
UnitMods unitMod = UnitMods.Health;
|
||||||
|
|
||||||
float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreateHealth();
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetCreateHealth();
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue) + GetHealthBonusFromStamina();
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total) + GetHealthBonusFromStamina();
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetMaxHealth((uint)value);
|
SetMaxHealth((uint)value);
|
||||||
}
|
}
|
||||||
@@ -1669,10 +1781,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
UnitMods unitMod = UnitMods.PowerStart + (int)power;
|
UnitMods unitMod = UnitMods.PowerStart + (int)power;
|
||||||
|
|
||||||
float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreatePowers(power);
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetCreatePowers(power);
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetMaxPower(power, (int)Math.Round(value));
|
SetMaxPower(power, (int)Math.Round(value));
|
||||||
}
|
}
|
||||||
@@ -1748,8 +1860,6 @@ namespace Game.Entities
|
|||||||
0.9720f, // Druid
|
0.9720f, // Druid
|
||||||
0.9830f // Demon Hunter
|
0.9830f // Demon Hunter
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[(int)modGroup][(int)modType] = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public partial class Creature
|
public partial class Creature
|
||||||
@@ -1775,7 +1885,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public override void UpdateArmor()
|
public override void UpdateArmor()
|
||||||
{
|
{
|
||||||
float baseValue = GetModifierValue(UnitMods.Armor, UnitModifierType.BaseValue);
|
float baseValue = GetFlatModifierValue(UnitMods.Armor, UnitModifierFlatType.Base);
|
||||||
float value = GetTotalAuraModValue(UnitMods.Armor);
|
float value = GetTotalAuraModValue(UnitMods.Armor);
|
||||||
SetArmor((int)baseValue, (int)(value - baseValue));
|
SetArmor((int)baseValue, (int)(value - baseValue));
|
||||||
}
|
}
|
||||||
@@ -1805,10 +1915,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
UnitMods unitMod = UnitMods.PowerStart + (int)power;
|
UnitMods unitMod = UnitMods.PowerStart + (int)power;
|
||||||
|
|
||||||
float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreatePowers(power);
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetCreatePowers(power);
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetMaxPower(power, (int)Math.Round(value));
|
SetMaxPower(power, (int)Math.Round(value));
|
||||||
}
|
}
|
||||||
@@ -1817,8 +1927,8 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
UnitMods unitMod = ranged ? UnitMods.AttackPowerRanged : UnitMods.AttackPower;
|
UnitMods unitMod = ranged ? UnitMods.AttackPowerRanged : UnitMods.AttackPower;
|
||||||
|
|
||||||
float baseAttackPower = GetModifierValue(unitMod, UnitModifierType.BaseValue) * GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
float baseAttackPower = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) * GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float attackPowerMultiplier = GetModifierValue(unitMod, UnitModifierType.TotalPCT) - 1.0f;
|
float attackPowerMultiplier = GetPctModifierValue(unitMod, UnitModifierPctType.Total) - 1.0f;
|
||||||
|
|
||||||
if (ranged)
|
if (ranged)
|
||||||
{
|
{
|
||||||
@@ -1881,10 +1991,10 @@ namespace Game.Entities
|
|||||||
float attackPower = GetTotalAttackPowerValue(attType);
|
float attackPower = GetTotalAttackPowerValue(attType);
|
||||||
float attackSpeedMulti = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
float attackSpeedMulti = Math.Max(GetAPMultiplier(attType, normalized), 0.25f);
|
||||||
|
|
||||||
float baseValue = GetModifierValue(unitMod, UnitModifierType.BaseValue) + (attackPower / 3.5f) * variance;
|
float baseValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + (attackPower / 3.5f) * variance;
|
||||||
float basePct = GetModifierValue(unitMod, UnitModifierType.BasePCT) * attackSpeedMulti;
|
float basePct = GetPctModifierValue(unitMod, UnitModifierPctType.Base) * attackSpeedMulti;
|
||||||
float totalValue = GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
float totalValue = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float totalPct = addTotalPct ? GetModifierValue(unitMod, UnitModifierType.TotalPCT) : 1.0f;
|
float totalPct = addTotalPct ? GetPctModifierValue(unitMod, UnitModifierPctType.Total) : 1.0f;
|
||||||
float dmgMultiplier = GetCreatureTemplate().ModDamage; // = ModDamage * _GetDamageMod(rank);
|
float dmgMultiplier = GetCreatureTemplate().ModDamage; // = ModDamage * _GetDamageMod(rank);
|
||||||
|
|
||||||
minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
|
minDamage = ((weaponMinDamage + baseValue) * dmgMultiplier * basePct + totalValue) * totalPct;
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SetMeleeDamageSchool((SpellSchools)cinfo.DmgSchool);
|
SetMeleeDamageSchool((SpellSchools)cinfo.DmgSchool);
|
||||||
|
|
||||||
SetModifierValue(UnitMods.Armor, UnitModifierType.BaseValue, (float)petlevel * 50);
|
SetStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, (float)petlevel * 50);
|
||||||
|
|
||||||
SetBaseAttackTime(WeaponAttackType.BaseAttack, SharedConst.BaseAttackTime);
|
SetBaseAttackTime(WeaponAttackType.BaseAttack, SharedConst.BaseAttackTime);
|
||||||
SetBaseAttackTime(WeaponAttackType.OffAttack, SharedConst.BaseAttackTime);
|
SetBaseAttackTime(WeaponAttackType.OffAttack, SharedConst.BaseAttackTime);
|
||||||
@@ -467,7 +467,7 @@ namespace Game.Entities
|
|||||||
if (!IsHunterPet())
|
if (!IsHunterPet())
|
||||||
{
|
{
|
||||||
for (int i = (int)SpellSchools.Holy; i < (int)SpellSchools.Max; ++i)
|
for (int i = (int)SpellSchools.Holy; i < (int)SpellSchools.Max; ++i)
|
||||||
SetModifierValue(UnitMods.ResistanceStart + i, UnitModifierType.BaseValue, cinfo.Resistance[i]);
|
SetStatFlatModifier(UnitMods.ResistanceStart + i, UnitModifierFlatType.Base, cinfo.Resistance[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Health, Mana or Power, Armor
|
// Health, Mana or Power, Armor
|
||||||
@@ -478,7 +478,7 @@ namespace Game.Entities
|
|||||||
SetCreateMana(pInfo.mana);
|
SetCreateMana(pInfo.mana);
|
||||||
|
|
||||||
if (pInfo.armor > 0)
|
if (pInfo.armor > 0)
|
||||||
SetModifierValue(UnitMods.Armor, UnitModifierType.BaseValue, pInfo.armor);
|
SetStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, pInfo.armor);
|
||||||
|
|
||||||
for (byte stat = 0; stat < (int)Stats.Max; ++stat)
|
for (byte stat = 0; stat < (int)Stats.Max; ++stat)
|
||||||
SetCreateStat((Stats)stat, pInfo.stats[stat]);
|
SetCreateStat((Stats)stat, pInfo.stats[stat]);
|
||||||
@@ -584,7 +584,6 @@ namespace Game.Entities
|
|||||||
int bonus_dmg = (int)(GetOwner().SpellBaseDamageBonusDone(SpellSchoolMask.Shadow) * 0.3f);
|
int bonus_dmg = (int)(GetOwner().SpellBaseDamageBonusDone(SpellSchoolMask.Shadow) * 0.3f);
|
||||||
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage, (petlevel * 4 - petlevel) + bonus_dmg);
|
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage, (petlevel * 4 - petlevel) + bonus_dmg);
|
||||||
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage, (petlevel * 4 + petlevel) + bonus_dmg);
|
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage, (petlevel * 4 + petlevel) + bonus_dmg);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 19833: //Snake Trap - Venomous Snake
|
case 19833: //Snake Trap - Venomous Snake
|
||||||
@@ -610,8 +609,8 @@ namespace Game.Entities
|
|||||||
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage, (petlevel * 4 - petlevel));
|
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage, (petlevel * 4 - petlevel));
|
||||||
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage, (petlevel * 4 + petlevel));
|
SetBaseWeaponDamage(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage, (petlevel * 4 + petlevel));
|
||||||
|
|
||||||
SetModifierValue(UnitMods.Armor, UnitModifierType.BaseValue, GetOwner().GetArmor() * 0.35f); // Bonus Armor (35% of player armor)
|
SetStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Base, GetOwner().GetArmor() * 0.35f); // Bonus Armor (35% of player armor)
|
||||||
SetModifierValue(UnitMods.StatStamina, UnitModifierType.BaseValue, GetOwner().GetStat(Stats.Stamina) * 0.3f); // Bonus Stamina (30% of player stamina)
|
SetStatFlatModifier(UnitMods.StatStamina, UnitModifierFlatType.Base, GetOwner().GetStat(Stats.Stamina) * 0.3f); // Bonus Stamina (30% of player stamina)
|
||||||
if (!HasAura(58877))//prevent apply twice for the 2 wolves
|
if (!HasAura(58877))//prevent apply twice for the 2 wolves
|
||||||
AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done.
|
AddAura(58877, this);//Spirit Hunt, passive, Spirit Wolves' attacks heal them and their master for 150% of damage done.
|
||||||
break;
|
break;
|
||||||
@@ -673,7 +672,7 @@ namespace Game.Entities
|
|||||||
public override bool UpdateStats(Stats stat)
|
public override bool UpdateStats(Stats stat)
|
||||||
{
|
{
|
||||||
float value = GetTotalStatValue(stat);
|
float value = GetTotalStatValue(stat);
|
||||||
ApplyStatBuffMod(stat, m_statFromOwner[(int)stat], false);
|
UpdateStatBuffMod(stat);
|
||||||
float ownersBonus = 0.0f;
|
float ownersBonus = 0.0f;
|
||||||
|
|
||||||
Unit owner = GetOwner();
|
Unit owner = GetOwner();
|
||||||
@@ -712,7 +711,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SetStat(stat, (int)value);
|
SetStat(stat, (int)value);
|
||||||
m_statFromOwner[(int)stat] = ownersBonus;
|
m_statFromOwner[(int)stat] = ownersBonus;
|
||||||
ApplyStatBuffMod(stat, m_statFromOwner[(int)stat], true);
|
UpdateStatBuffMod(stat);
|
||||||
|
|
||||||
switch (stat)
|
switch (stat)
|
||||||
{
|
{
|
||||||
@@ -754,7 +753,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
if (school > SpellSchools.Normal)
|
if (school > SpellSchools.Normal)
|
||||||
{
|
{
|
||||||
float baseValue = GetModifierValue( UnitMods.ResistanceStart + (int)school, UnitModifierType.BaseValue);
|
float baseValue = GetFlatModifierValue(UnitMods.ResistanceStart + (int)school, UnitModifierFlatType.Base);
|
||||||
float bonusValue = GetTotalAuraModValue(UnitMods.ResistanceStart + (int)school) - baseValue;
|
float bonusValue = GetTotalAuraModValue(UnitMods.ResistanceStart + (int)school) - baseValue;
|
||||||
|
|
||||||
// hunter and warlock pets gain 40% of owner's resistance
|
// hunter and warlock pets gain 40% of owner's resistance
|
||||||
@@ -773,8 +772,6 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public override void UpdateArmor()
|
public override void UpdateArmor()
|
||||||
{
|
{
|
||||||
float baseValue = 0.0f;
|
|
||||||
float value = 0.0f;
|
|
||||||
float bonus_armor = 0.0f;
|
float bonus_armor = 0.0f;
|
||||||
UnitMods unitMod = UnitMods.Armor;
|
UnitMods unitMod = UnitMods.Armor;
|
||||||
|
|
||||||
@@ -784,11 +781,11 @@ namespace Game.Entities
|
|||||||
else if (IsPet())
|
else if (IsPet())
|
||||||
bonus_armor = GetOwner().GetArmor();
|
bonus_armor = GetOwner().GetArmor();
|
||||||
|
|
||||||
value = GetModifierValue(unitMod, UnitModifierType.BaseValue);
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base);
|
||||||
baseValue = value;
|
float baseValue = value;
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue) + bonus_armor;
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total) + bonus_armor;
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetArmor((int)baseValue, (int)(value - baseValue));
|
SetArmor((int)baseValue, (int)(value - baseValue));
|
||||||
}
|
}
|
||||||
@@ -824,10 +821,10 @@ namespace Game.Entities
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreateHealth();
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetCreateHealth();
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue) + stamina * multiplicator;
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total) + stamina * multiplicator;
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetMaxHealth((uint)value);
|
SetMaxHealth((uint)value);
|
||||||
}
|
}
|
||||||
@@ -839,10 +836,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
UnitMods unitMod = UnitMods.PowerStart + (int)power;
|
UnitMods unitMod = UnitMods.PowerStart + (int)power;
|
||||||
|
|
||||||
float value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetCreatePowers(power);
|
float value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetCreatePowers(power);
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
value += GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
value *= GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
SetMaxPower(power, (int)value);
|
SetMaxPower(power, (int)value);
|
||||||
}
|
}
|
||||||
@@ -902,11 +899,11 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetModifierValue(UnitMods.AttackPower, UnitModifierType.BaseValue, val + bonusAP);
|
SetStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Base, val + bonusAP);
|
||||||
|
|
||||||
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
|
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
|
||||||
float base_attPower = GetModifierValue(unitMod, UnitModifierType.BaseValue) * GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
float base_attPower = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) * GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float attPowerMultiplier = GetModifierValue(unitMod, UnitModifierType.TotalPCT) - 1.0f;
|
float attPowerMultiplier = GetPctModifierValue(unitMod, UnitModifierPctType.Total) - 1.0f;
|
||||||
|
|
||||||
SetAttackPower((int)base_attPower);
|
SetAttackPower((int)base_attPower);
|
||||||
SetAttackPowerMultiplier(attPowerMultiplier);
|
SetAttackPowerMultiplier(attPowerMultiplier);
|
||||||
@@ -944,10 +941,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
float att_speed = GetBaseAttackTime(WeaponAttackType.BaseAttack) / 1000.0f;
|
float att_speed = GetBaseAttackTime(WeaponAttackType.BaseAttack) / 1000.0f;
|
||||||
|
|
||||||
float base_value = GetModifierValue(unitMod, UnitModifierType.BaseValue) + GetTotalAttackPowerValue(attType) / 3.5f * att_speed + bonusDamage;
|
float base_value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Base) + GetTotalAttackPowerValue(attType) / 3.5f * att_speed + bonusDamage;
|
||||||
float base_pct = GetModifierValue(unitMod, UnitModifierType.BasePCT);
|
float base_pct = GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
float total_value = GetModifierValue(unitMod, UnitModifierType.TotalValue);
|
float total_value = GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float total_pct = GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
float total_pct = GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
|
|
||||||
float weapon_mindamage = GetWeaponDamageRange(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage);
|
float weapon_mindamage = GetWeaponDamageRange(WeaponAttackType.BaseAttack, WeaponDamageRange.MinDamage);
|
||||||
float weapon_maxdamage = GetWeaponDamageRange(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage);
|
float weapon_maxdamage = GetWeaponDamageRange(WeaponAttackType.BaseAttack, WeaponDamageRange.MaxDamage);
|
||||||
@@ -968,6 +965,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int GetBonusDamage() { return m_bonusSpellDamage; }
|
public int GetBonusDamage() { return m_bonusSpellDamage; }
|
||||||
|
public float GetBonusStatFromOwner(Stats stat) { return m_statFromOwner[(int)stat]; }
|
||||||
|
|
||||||
int m_bonusSpellDamage;
|
int m_bonusSpellDamage;
|
||||||
float[] m_statFromOwner = new float[(int)Stats.Max];
|
float[] m_statFromOwner = new float[(int)Stats.Max];
|
||||||
|
|||||||
@@ -1351,7 +1351,7 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (PvP)
|
if (PvP)
|
||||||
{
|
{
|
||||||
combatTimer = 5000;
|
combatTimer = 5000;
|
||||||
Player me = ToPlayer();
|
Player me = ToPlayer();
|
||||||
if (me)
|
if (me)
|
||||||
@@ -2146,17 +2146,16 @@ namespace Game.Entities
|
|||||||
return MeleeHitOutcome.Normal;
|
return MeleeHitOutcome.Normal;
|
||||||
}
|
}
|
||||||
public uint CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct)
|
public uint CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct)
|
||||||
{
|
{
|
||||||
float minDamage, maxDamage = 0.0f;
|
float minDamage;
|
||||||
|
float maxDamage;
|
||||||
|
|
||||||
if (normalized || !addTotalPct)
|
if (normalized || !addTotalPct)
|
||||||
{
|
{
|
||||||
CalculateMinMaxDamage(attType, normalized, addTotalPct, out minDamage, out maxDamage);
|
CalculateMinMaxDamage(attType, normalized, addTotalPct, out minDamage, out maxDamage);
|
||||||
if (IsInFeralForm() && attType == WeaponAttackType.BaseAttack)
|
if (IsInFeralForm() && attType == WeaponAttackType.BaseAttack)
|
||||||
{
|
{
|
||||||
float minOffhandDamage = 0.0f;
|
CalculateMinMaxDamage(WeaponAttackType.OffAttack, normalized, addTotalPct, out float minOffhandDamage, out float maxOffhandDamage);
|
||||||
float maxOffhandDamage = 0.0f;
|
|
||||||
CalculateMinMaxDamage(WeaponAttackType.OffAttack, normalized, addTotalPct, out minOffhandDamage, out maxOffhandDamage);
|
|
||||||
minDamage += minOffhandDamage;
|
minDamage += minOffhandDamage;
|
||||||
maxDamage += maxOffhandDamage;
|
maxDamage += maxOffhandDamage;
|
||||||
}
|
}
|
||||||
@@ -2266,19 +2265,6 @@ namespace Game.Entities
|
|||||||
return ap * (1.0f + m_unitData.AttackPowerMultiplier);
|
return ap * (1.0f + m_unitData.AttackPowerMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public float GetModifierValue(UnitMods unitMod, UnitModifierType modifierType)
|
|
||||||
{
|
|
||||||
if (unitMod >= UnitMods.End || modifierType >= UnitModifierType.End)
|
|
||||||
{
|
|
||||||
Log.outError(LogFilter.Unit, "attempt to access non-existing modifier value from UnitMods!");
|
|
||||||
return 0.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (modifierType == UnitModifierType.TotalPCT && m_auraModifiersGroup[(int)unitMod][(int)modifierType] <= 0.0f)
|
|
||||||
return 0.0f;
|
|
||||||
|
|
||||||
return m_auraModifiersGroup[(int)unitMod][(int)modifierType];
|
|
||||||
}
|
|
||||||
public bool IsWithinMeleeRange(Unit obj)
|
public bool IsWithinMeleeRange(Unit obj)
|
||||||
{
|
{
|
||||||
if (!obj || !IsInMap(obj) || !IsInPhase(obj))
|
if (!obj || !IsInMap(obj) || !IsInPhase(obj))
|
||||||
@@ -2449,7 +2435,7 @@ namespace Game.Entities
|
|||||||
uint bossLevel = 83;
|
uint bossLevel = 83;
|
||||||
float bossResistanceConstant = 510.0f;
|
float bossResistanceConstant = 510.0f;
|
||||||
uint level = victim.GetLevelForTarget(this);
|
uint level = victim.GetLevelForTarget(this);
|
||||||
float resistanceConstant = 0.0f;
|
float resistanceConstant;
|
||||||
|
|
||||||
if (level == bossLevel)
|
if (level == bossLevel)
|
||||||
resistanceConstant = bossResistanceConstant;
|
resistanceConstant = bossResistanceConstant;
|
||||||
@@ -2492,7 +2478,7 @@ namespace Game.Entities
|
|||||||
vSchoolAbsorbCopy.Sort(new AbsorbAuraOrderPred());
|
vSchoolAbsorbCopy.Sort(new AbsorbAuraOrderPred());
|
||||||
|
|
||||||
// absorb without mana cost
|
// absorb without mana cost
|
||||||
for (var i = 0; i < vSchoolAbsorbCopy.Count; ++i )
|
for (var i = 0; i < vSchoolAbsorbCopy.Count; ++i)
|
||||||
{
|
{
|
||||||
var absorbAurEff = vSchoolAbsorbCopy[i];
|
var absorbAurEff = vSchoolAbsorbCopy[i];
|
||||||
if (damageInfo.GetDamage() == 0)
|
if (damageInfo.GetDamage() == 0)
|
||||||
@@ -2758,7 +2744,7 @@ namespace Game.Entities
|
|||||||
// no more than 100%
|
// no more than 100%
|
||||||
MathFunctions.RoundToInterval(ref arpPct, 0.0f, 100.0f);
|
MathFunctions.RoundToInterval(ref arpPct, 0.0f, 100.0f);
|
||||||
|
|
||||||
float maxArmorPen = 0.0f;
|
float maxArmorPen;
|
||||||
if (victim.GetLevelForTarget(attacker) < 60)
|
if (victim.GetLevelForTarget(attacker) < 60)
|
||||||
maxArmorPen = 400 + 85 * victim.GetLevelForTarget(attacker);
|
maxArmorPen = 400 + 85 * victim.GetLevelForTarget(attacker);
|
||||||
else
|
else
|
||||||
@@ -3014,10 +3000,15 @@ namespace Game.Entities
|
|||||||
return (CastingTime / 3500.0f) * DotFactor;
|
return (CastingTime / 3500.0f) * DotFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyPercentModFloatVar(ref float var, float val, bool apply)
|
||||||
|
{
|
||||||
|
var *= (apply ? (100.0f + val) / 100.0f : 100.0f / (100.0f + val));
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply)
|
public void ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply)
|
||||||
{
|
{
|
||||||
float remainingTimePct = m_attackTimer[(int)att] / (m_baseAttackSpeed[(int)att] * m_modAttackSpeedPct[(int)att]);
|
float remainingTimePct = m_attackTimer[(int)att] / (m_baseAttackSpeed[(int)att] * m_modAttackSpeedPct[(int)att]);
|
||||||
if (val > 0)
|
if (val > 0.0f)
|
||||||
{
|
{
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref m_modAttackSpeedPct[(int)att], val, !apply);
|
MathFunctions.ApplyPercentModFloatVar(ref m_modAttackSpeedPct[(int)att], val, !apply);
|
||||||
|
|
||||||
@@ -3265,5 +3256,58 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEffect aurEff) { return true; }
|
||||||
|
|
||||||
|
public virtual void UpdateDamageDoneMods(WeaponAttackType attackType)
|
||||||
|
{
|
||||||
|
UnitMods unitMod = attackType switch
|
||||||
|
{
|
||||||
|
WeaponAttackType.BaseAttack => UnitMods.DamageMainHand,
|
||||||
|
WeaponAttackType.OffAttack => UnitMods.DamageOffHand,
|
||||||
|
WeaponAttackType.RangedAttack => UnitMods.DamageRanged,
|
||||||
|
_ => throw new NotImplementedException(),
|
||||||
|
};
|
||||||
|
|
||||||
|
float amount = GetTotalAuraModifier(AuraType.ModDamageDone, auratype => CheckAttackFitToAuraRequirement(attackType, auratype));
|
||||||
|
SetStatFlatModifier(unitMod, UnitModifierFlatType.Total, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateAllDamageDoneMods()
|
||||||
|
{
|
||||||
|
for (var attackType = WeaponAttackType.BaseAttack; attackType < WeaponAttackType.Max; ++attackType)
|
||||||
|
UpdateDamageDoneMods(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateDamagePctDoneMods(WeaponAttackType attackType)
|
||||||
|
{
|
||||||
|
(UnitMods unitMod, float factor) = attackType switch
|
||||||
|
{
|
||||||
|
WeaponAttackType.BaseAttack => (UnitMods.DamageMainHand, 1.0f),
|
||||||
|
WeaponAttackType.OffAttack => (UnitMods.DamageOffHand, 0.5f),
|
||||||
|
WeaponAttackType.RangedAttack => (UnitMods.DamageRanged, 1.0f),
|
||||||
|
_ => throw new NotImplementedException(),
|
||||||
|
};
|
||||||
|
|
||||||
|
factor *= GetTotalAuraMultiplier(AuraType.ModDamagePercentDone, aurEff =>
|
||||||
|
{
|
||||||
|
if (!aurEff.GetMiscValue().HasAnyFlag((int)SpellSchoolMask.Normal))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return CheckAttackFitToAuraRequirement(attackType, aurEff);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (attackType == WeaponAttackType.OffAttack)
|
||||||
|
factor *= GetTotalAuraMultiplier(AuraType.ModOffhandDamagePct, auraEffect => CheckAttackFitToAuraRequirement(attackType, auraEffect));
|
||||||
|
|
||||||
|
SetStatPctModifier(unitMod, UnitModifierPctType.Total, factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateAllDamagePctDoneMods()
|
||||||
|
{
|
||||||
|
for (var attackType = WeaponAttackType.BaseAttack; attackType < WeaponAttackType.Max; ++attackType)
|
||||||
|
UpdateDamagePctDoneMods(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,8 @@ namespace Game.Entities
|
|||||||
MultiMap<uint, AuraApplication> m_appliedAuras = new MultiMap<uint, AuraApplication>();
|
MultiMap<uint, AuraApplication> m_appliedAuras = new MultiMap<uint, AuraApplication>();
|
||||||
MultiMap<uint, Aura> m_ownedAuras = new MultiMap<uint, Aura>();
|
MultiMap<uint, Aura> m_ownedAuras = new MultiMap<uint, Aura>();
|
||||||
List<Aura> m_scAuras = new List<Aura>();
|
List<Aura> m_scAuras = new List<Aura>();
|
||||||
protected float[][] m_auraModifiersGroup = new float[(int)UnitMods.End][];
|
protected float[][] m_auraFlatModifiersGroup = new float[(int)UnitMods.End][];
|
||||||
|
protected float[][] m_auraPctModifiersGroup = new float[(int)UnitMods.End][];
|
||||||
uint m_removedAurasCount;
|
uint m_removedAurasCount;
|
||||||
|
|
||||||
//General
|
//General
|
||||||
|
|||||||
@@ -951,7 +951,7 @@ namespace Game.Entities
|
|||||||
int levelBasedHitDiff = leveldif;
|
int levelBasedHitDiff = leveldif;
|
||||||
|
|
||||||
// Base hit chance from attacker and victim levels
|
// Base hit chance from attacker and victim levels
|
||||||
int modHitChance = 100;
|
int modHitChance;
|
||||||
if (levelBasedHitDiff >= 0)
|
if (levelBasedHitDiff >= 0)
|
||||||
{
|
{
|
||||||
if (!victim.IsTypeId(TypeId.Player))
|
if (!victim.IsTypeId(TypeId.Player))
|
||||||
@@ -2294,7 +2294,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public void ApplyCastTimePercentMod(float val, bool apply)
|
public void ApplyCastTimePercentMod(float val, bool apply)
|
||||||
{
|
{
|
||||||
if (val > 0)
|
if (val > 0.0f)
|
||||||
{
|
{
|
||||||
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModCastingSpeed), val, !apply);
|
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModCastingSpeed), val, !apply);
|
||||||
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModSpellHaste), val, !apply);
|
ApplyPercentModUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ModSpellHaste), val, !apply);
|
||||||
@@ -4547,13 +4547,10 @@ namespace Game.Entities
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.TotalPCT] <= 0.0f)
|
float value = MathFunctions.CalculatePct(GetFlatModifierValue(unitMod, UnitModifierFlatType.Base), Math.Max(GetFlatModifierValue(unitMod, UnitModifierFlatType.BasePCTExcludeCreate), -100.0f));
|
||||||
return 0.0f;
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Base);
|
||||||
|
value += GetFlatModifierValue(unitMod, UnitModifierFlatType.Total);
|
||||||
float value = MathFunctions.CalculatePct(m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BaseValue], Math.Max(m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BasePCTExcludeCreate], -100.0f));
|
value *= GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
value *= m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.BasePCT];
|
|
||||||
value += m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.TotalValue];
|
|
||||||
value *= m_auraModifiersGroup[(int)unitMod][(int)UnitModifierType.TotalPCT];
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,9 +57,18 @@ namespace Game.Entities
|
|||||||
m_spellImmune[i] = new MultiMap<uint, uint>();
|
m_spellImmune[i] = new MultiMap<uint, uint>();
|
||||||
|
|
||||||
for (byte i = 0; i < (int)UnitMods.End; ++i)
|
for (byte i = 0; i < (int)UnitMods.End; ++i)
|
||||||
m_auraModifiersGroup[i] = new float[] { 0.0f, 100.0f, 1.0f, 0.0f, 1.0f };
|
{
|
||||||
|
m_auraFlatModifiersGroup[i] = new float[(int)UnitModifierFlatType.End];
|
||||||
|
m_auraFlatModifiersGroup[i][(int)UnitModifierFlatType.Base] = 0.0f;
|
||||||
|
m_auraFlatModifiersGroup[i][(int)UnitModifierFlatType.BasePCTExcludeCreate] = 100.0f;
|
||||||
|
m_auraFlatModifiersGroup[i][(int)UnitModifierFlatType.Total] = 0.0f;
|
||||||
|
|
||||||
m_auraModifiersGroup[(int)UnitMods.DamageOffHand][(int)UnitModifierType.TotalPCT] = 0.5f;
|
m_auraPctModifiersGroup[i] = new float[(int)UnitModifierPctType.End];
|
||||||
|
m_auraPctModifiersGroup[i][(int)UnitModifierPctType.Base] = 1.0f;
|
||||||
|
m_auraPctModifiersGroup[i][(int)UnitModifierPctType.Total] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_auraPctModifiersGroup[(int)UnitMods.DamageOffHand][(int)UnitModifierPctType.Total] = 0.5f;
|
||||||
|
|
||||||
foreach (AuraType auraType in Enum.GetValues(typeof(AuraType)))
|
foreach (AuraType auraType in Enum.GetValues(typeof(AuraType)))
|
||||||
m_modAuras[auraType] = new List<AuraEffect>();
|
m_modAuras[auraType] = new List<AuraEffect>();
|
||||||
@@ -1239,7 +1248,7 @@ namespace Game.Entities
|
|||||||
else if (GetRace() == Race.Worgen)
|
else if (GetRace() == Race.Worgen)
|
||||||
{
|
{
|
||||||
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
||||||
hairColor = (byte)RandomHelper.URand(0, 9);
|
skinColor = (byte)RandomHelper.URand(0, 9);
|
||||||
|
|
||||||
// Male
|
// Male
|
||||||
if (GetGender() == Gender.Male)
|
if (GetGender() == Gender.Male)
|
||||||
@@ -1284,7 +1293,7 @@ namespace Game.Entities
|
|||||||
else if (GetRace() == Race.Tauren)
|
else if (GetRace() == Race.Tauren)
|
||||||
{
|
{
|
||||||
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
||||||
hairColor = (byte)RandomHelper.URand(0, 20);
|
skinColor = (byte)RandomHelper.URand(0, 20);
|
||||||
|
|
||||||
if (GetGender() == Gender.Male)
|
if (GetGender() == Gender.Male)
|
||||||
{
|
{
|
||||||
@@ -1393,7 +1402,7 @@ namespace Game.Entities
|
|||||||
else if (GetRace() == Race.Worgen)
|
else if (GetRace() == Race.Worgen)
|
||||||
{
|
{
|
||||||
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
||||||
hairColor = (byte)RandomHelper.URand(0, 8);
|
skinColor = (byte)RandomHelper.URand(0, 8);
|
||||||
|
|
||||||
// Male
|
// Male
|
||||||
if (GetGender() == Gender.Male)
|
if (GetGender() == Gender.Male)
|
||||||
@@ -1438,7 +1447,7 @@ namespace Game.Entities
|
|||||||
else if (GetRace() == Race.Tauren)
|
else if (GetRace() == Race.Tauren)
|
||||||
{
|
{
|
||||||
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
if (HasAura(210333)) // Glyph of the Feral Chameleon
|
||||||
hairColor = (byte)RandomHelper.URand(0, 20);
|
skinColor = (byte)RandomHelper.URand(0, 20);
|
||||||
|
|
||||||
if (GetGender() == Gender.Male)
|
if (GetGender() == Gender.Male)
|
||||||
{
|
{
|
||||||
@@ -1679,10 +1688,6 @@ namespace Game.Entities
|
|||||||
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ShapeshiftForm), (byte)form);
|
SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ShapeshiftForm), (byte)form);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetModifierValue(UnitMods unitMod, UnitModifierType modifierType, float value)
|
|
||||||
{
|
|
||||||
m_auraModifiersGroup[(int)unitMod][(int)modifierType] = value;
|
|
||||||
}
|
|
||||||
public int CalcSpellDuration(SpellInfo spellProto)
|
public int CalcSpellDuration(SpellInfo spellProto)
|
||||||
{
|
{
|
||||||
sbyte comboPoints = (sbyte)(m_playerMovingMe != null ? m_playerMovingMe.GetComboPoints() : 0);
|
sbyte comboPoints = (sbyte)(m_playerMovingMe != null ? m_playerMovingMe.GetComboPoints() : 0);
|
||||||
@@ -1932,20 +1937,16 @@ namespace Game.Entities
|
|||||||
FactionTemplateRecord entry = CliDB.FactionTemplateStorage.LookupByKey(GetFaction());
|
FactionTemplateRecord entry = CliDB.FactionTemplateStorage.LookupByKey(GetFaction());
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
{
|
{
|
||||||
ObjectGuid guid = ObjectGuid.Empty; // prevent repeating spam same faction problem
|
Player player = ToPlayer();
|
||||||
|
if (player != null)
|
||||||
if (GetGUID() != guid)
|
Log.outError(LogFilter.Unit, "Player {0} has invalid faction (faction template id) #{1}", player.GetName(), GetFaction());
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Player player = ToPlayer();
|
|
||||||
Creature creature = ToCreature();
|
Creature creature = ToCreature();
|
||||||
if (player != null)
|
if (creature != null)
|
||||||
Log.outError(LogFilter.Unit, "Player {0} has invalid faction (faction template id) #{1}", player.GetName(), GetFaction());
|
|
||||||
else if (creature != null)
|
|
||||||
Log.outError(LogFilter.Unit, "Creature (template id: {0}) has invalid faction (faction template id) #{1}", creature.GetCreatureTemplate().Entry, GetFaction());
|
Log.outError(LogFilter.Unit, "Creature (template id: {0}) has invalid faction (faction template id) #{1}", creature.GetCreatureTemplate().Entry, GetFaction());
|
||||||
else
|
else
|
||||||
Log.outError(LogFilter.Unit, "Unit (name={0}, type={1}) has invalid faction (faction template id) #{2}", GetName(), GetTypeId(), GetFaction());
|
Log.outError(LogFilter.Unit, "Unit (name={0}, type={1}) has invalid faction (faction template id) #{2}", GetName(), GetTypeId(), GetFaction());
|
||||||
|
|
||||||
guid = GetGUID();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
|
|||||||
@@ -235,8 +235,7 @@ namespace Game.Spells
|
|||||||
if (handleMask == 0)
|
if (handleMask == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<AuraApplication> effectApplications = new List<AuraApplication>();
|
GetApplicationList(out List<AuraApplication> effectApplications);
|
||||||
GetApplicationList(out effectApplications);
|
|
||||||
|
|
||||||
foreach (var aurApp in effectApplications)
|
foreach (var aurApp in effectApplications)
|
||||||
{
|
{
|
||||||
@@ -408,8 +407,7 @@ namespace Game.Spells
|
|||||||
m_periodicTimer += m_period - (int)diff;
|
m_periodicTimer += m_period - (int)diff;
|
||||||
UpdatePeriodic(caster);
|
UpdatePeriodic(caster);
|
||||||
|
|
||||||
List<AuraApplication> effectApplications = new List<AuraApplication>();
|
GetApplicationList(out List<AuraApplication> effectApplications);
|
||||||
GetApplicationList(out effectApplications);
|
|
||||||
// tick on targets of effects
|
// tick on targets of effects
|
||||||
foreach (var appt in effectApplications)
|
foreach (var appt in effectApplications)
|
||||||
if (appt.HasEffect(GetEffIndex()))
|
if (appt.HasEffect(GetEffIndex()))
|
||||||
@@ -1658,7 +1656,7 @@ namespace Game.Spells
|
|||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
float scale = target.GetObjectScale();
|
float scale = target.GetObjectScale();
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref scale, GetAmount(), apply);
|
scale += MathFunctions.CalculatePct(1.0f, apply ? GetAmount() : -GetAmount());
|
||||||
target.SetObjectScale(scale);
|
target.SetObjectScale(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1783,7 +1781,7 @@ namespace Game.Spells
|
|||||||
AuraType type = GetAuraType();
|
AuraType type = GetAuraType();
|
||||||
|
|
||||||
//Prevent handling aura twice
|
//Prevent handling aura twice
|
||||||
if ((apply) ? target.GetAuraEffectsByType(type).Count > 1 : target.HasAuraType(type))
|
if (apply ? target.GetAuraEffectsByType(type).Count > 1 : target.HasAuraType(type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Action<Unit> flagAddFn = null;
|
Action<Unit> flagAddFn = null;
|
||||||
@@ -1831,11 +1829,15 @@ namespace Game.Spells
|
|||||||
Item item = player.GetItemByPos(InventorySlots.Bag0, (byte)slot);
|
Item item = player.GetItemByPos(InventorySlots.Bag0, (byte)slot);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
WeaponAttackType attacktype = Player.GetAttackBySlot((byte)slot, item.GetTemplate().GetInventoryType());
|
WeaponAttackType attackType = Player.GetAttackBySlot((byte)slot, item.GetTemplate().GetInventoryType());
|
||||||
|
|
||||||
player.ApplyItemDependentAuras(item, !apply);
|
player.ApplyItemDependentAuras(item, !apply);
|
||||||
if (attacktype < WeaponAttackType.Max)
|
if (attackType < WeaponAttackType.Max)
|
||||||
|
{
|
||||||
player._ApplyWeaponDamage(slot, item, !apply);
|
player._ApplyWeaponDamage(slot, item, !apply);
|
||||||
|
if (!apply) // apply case already handled on item dependent aura removal (if any)
|
||||||
|
player.UpdateWeaponDependentAuras(attackType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2359,7 +2361,15 @@ namespace Game.Spells
|
|||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
for (byte i = 0; i < (int)SpellSchools.Max; ++i)
|
for (byte i = 0; i < (int)SpellSchools.Max; ++i)
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
||||||
MathFunctions.ApplyPercentModFloatVar(ref target.m_threatModifier[i], GetAmount(), apply);
|
{
|
||||||
|
if (apply)
|
||||||
|
MathFunctions.AddPct(ref target.m_threatModifier[i], GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplierByMiscMask(AuraType.ModThreat, 1u << i);
|
||||||
|
target.m_threatModifier[i] = amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModTotalThreat)]
|
[AuraEffectHandler(AuraType.ModTotalThreat)]
|
||||||
@@ -2882,7 +2892,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
for (byte x = (byte)SpellSchools.Normal; x < (byte)SpellSchools.Max; x++)
|
for (byte x = (byte)SpellSchools.Normal; x < (byte)SpellSchools.Max; x++)
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (1 << x)))
|
if (Convert.ToBoolean(GetMiscValue() & (1 << x)))
|
||||||
target.HandleStatModifier(UnitMods.ResistanceStart + x, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.ResistanceStart + x, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModBaseResistancePct)]
|
[AuraEffectHandler(AuraType.ModBaseResistancePct)]
|
||||||
@@ -2898,14 +2908,30 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
//pets only have base armor
|
//pets only have base armor
|
||||||
if (target.IsPet() && Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
if (target.IsPet() && Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
||||||
target.HandleStatModifier(UnitMods.Armor, UnitModifierType.BasePCT, GetAmount(), apply);
|
{
|
||||||
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.Armor, UnitModifierPctType.Base, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplierByMiscMask(AuraType.ModBaseResistancePct, (uint)SpellSchoolMask.Normal);
|
||||||
|
target.SetStatPctModifier(UnitMods.Armor, UnitModifierPctType.Base, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (byte x = (byte)SpellSchools.Normal; x < (byte)SpellSchools.Max; x++)
|
for (byte x = (byte)SpellSchools.Normal; x < (byte)SpellSchools.Max; x++)
|
||||||
{
|
{
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (1 << x)))
|
if (Convert.ToBoolean(GetMiscValue() & (1 << x)))
|
||||||
target.HandleStatModifier(UnitMods.ResistanceStart + x, UnitModifierType.BasePCT, GetAmount(), apply);
|
{
|
||||||
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.ResistanceStart + x, UnitModifierPctType.Base, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplierByMiscMask(AuraType.ModBaseResistancePct, 1u << x);
|
||||||
|
target.SetStatPctModifier(UnitMods.ResistanceStart + x, UnitModifierPctType.Base, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2917,18 +2943,16 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
int spellGroupVal = target.GetHighestExclusiveSameEffectSpellGroupValue(this, AuraType.ModResistancePct);
|
|
||||||
if (Math.Abs(spellGroupVal) >= Math.Abs(GetAmount()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (byte i = (byte)SpellSchools.Normal; i < (byte)SpellSchools.Max; i++)
|
for (byte i = (byte)SpellSchools.Normal; i < (byte)SpellSchools.Max; i++)
|
||||||
{
|
{
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
||||||
{
|
{
|
||||||
if (spellGroupVal != 0)
|
float amount = target.GetTotalAuraMultiplierByMiscMask(AuraType.ModResistancePct, 1u << i);
|
||||||
target.HandleStatModifier(UnitMods.ResistanceStart + i, UnitModifierType.TotalPCT, (float)spellGroupVal, !apply);
|
if (target.GetPctModifierValue(UnitMods.ResistanceStart + i, UnitModifierPctType.Total) == amount)
|
||||||
|
continue;
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.ResistanceStart + i, UnitModifierType.TotalPCT, GetAmount(), apply);
|
target.SetStatPctModifier(UnitMods.ResistanceStart + i, UnitModifierPctType.Total, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2946,13 +2970,13 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
//only pets have base stats
|
//only pets have base stats
|
||||||
if (target.IsPet() && Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
if (target.IsPet() && Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
||||||
target.HandleStatModifier(UnitMods.Armor, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.Armor, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (byte i = (byte)SpellSchools.Normal; i < (byte)SpellSchools.Max; i++)
|
for (byte i = (byte)SpellSchools.Normal; i < (byte)SpellSchools.Max; i++)
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
||||||
target.HandleStatModifier(UnitMods.ResistanceStart + i, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.ResistanceStart + i, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3004,14 +3028,14 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
if (spellGroupVal != 0)
|
if (spellGroupVal != 0)
|
||||||
{
|
{
|
||||||
target.HandleStatModifier((UnitMods.StatStart + (int)i), UnitModifierType.TotalValue, (float)spellGroupVal, !apply);
|
target.HandleStatFlatModifier((UnitMods.StatStart + (int)i), UnitModifierFlatType.Total, (float)spellGroupVal, !apply);
|
||||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
||||||
target.ApplyStatBuffMod(i, spellGroupVal, !apply);
|
target.UpdateStatBuffMod(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.StatStart + (int)i, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.StatStart + (int)i, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
||||||
target.ApplyStatBuffMod(i, GetAmount(), apply);
|
target.UpdateStatBuffMod(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3037,7 +3061,20 @@ namespace Game.Spells
|
|||||||
for (int i = (int)Stats.Strength; i < (int)Stats.Max; ++i)
|
for (int i = (int)Stats.Strength; i < (int)Stats.Max; ++i)
|
||||||
{
|
{
|
||||||
if (GetMiscValue() == i || GetMiscValue() == -1)
|
if (GetMiscValue() == i || GetMiscValue() == -1)
|
||||||
target.HandleStatModifier(UnitMods.StatStart + i, UnitModifierType.BasePCT, (float)m_amount, apply);
|
{
|
||||||
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.StatStart + i, UnitModifierPctType.Base, m_amount);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModPercentStat, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == i || aurEff.GetMiscValue() == -1)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
target.SetStatPctModifier(UnitMods.StatStart + i, UnitModifierPctType.Base, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3138,22 +3175,6 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
int spellGroupVal = target.GetHighestExclusiveSameEffectSpellGroupValue(this, AuraType.ModTotalStatPercentage, true, -1);
|
|
||||||
if (Math.Abs(spellGroupVal) >= Math.Abs(GetAmount()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (spellGroupVal != 0)
|
|
||||||
{
|
|
||||||
for (int i = (int)Stats.Strength; i < (int)Stats.Max; i++)
|
|
||||||
{
|
|
||||||
if (GetMiscValue() == i || GetMiscValue() == -1) // affect the same stats
|
|
||||||
{
|
|
||||||
target.HandleStatModifier((UnitMods.StatStart + i), UnitModifierType.TotalPCT, spellGroupVal, !apply);
|
|
||||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
|
||||||
target.ApplyStatPercentBuffMod((Stats)i, spellGroupVal, !apply);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// save current health state
|
// save current health state
|
||||||
float healthPct = target.GetHealthPct();
|
float healthPct = target.GetHealthPct();
|
||||||
@@ -3169,26 +3190,25 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
if (Convert.ToBoolean(GetMiscValueB() & 1 << i) || GetMiscValueB() == 0) // 0 is also used for all stats
|
if (Convert.ToBoolean(GetMiscValueB() & 1 << i) || GetMiscValueB() == 0) // 0 is also used for all stats
|
||||||
{
|
{
|
||||||
int spellGroupVal2 = target.GetHighestExclusiveSameEffectSpellGroupValue(this, AuraType.ModTotalStatPercentage, true, i);
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModTotalStatPercentage, aurEff =>
|
||||||
if (Math.Abs(spellGroupVal2) >= Math.Abs(GetAmount()))
|
{
|
||||||
|
if ((aurEff.GetMiscValueB() & 1 << i) != 0 || aurEff.GetMiscValueB() == 0)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (target.GetPctModifierValue(UnitMods.StatStart + i, UnitModifierPctType.Total) == amount)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (spellGroupVal2 != 0)
|
target.SetStatPctModifier(UnitMods.StatStart + i, UnitModifierPctType.Total, amount);
|
||||||
{
|
|
||||||
target.HandleStatModifier(UnitMods.StatStart + i, UnitModifierType.TotalPCT, spellGroupVal2, !apply);
|
|
||||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
|
||||||
target.ApplyStatPercentBuffMod((Stats)i, spellGroupVal2, !apply);
|
|
||||||
}
|
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.StatStart + i, UnitModifierType.TotalPCT, GetAmount(), apply);
|
|
||||||
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
if (target.IsTypeId(TypeId.Player) || target.IsPet())
|
||||||
target.ApplyStatPercentBuffMod((Stats)i, GetAmount(), apply);
|
target.UpdateStatBuffMod((Stats)i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_UNK4 0x00000010 flag)
|
// recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_ABILITY 0x00000010 flag)
|
||||||
// this check is total bullshit i think
|
// this check is total bullshit i think
|
||||||
if (Convert.ToBoolean(GetMiscValueB() & 1 << (int)Stats.Stamina) && m_spellInfo.HasAttribute(SpellAttr0.Ability))
|
if ((Convert.ToBoolean(GetMiscValueB() & 1 << (int)Stats.Stamina) || GetMiscValueB() == 0) && m_spellInfo.HasAttribute(SpellAttr0.Ability))
|
||||||
target.SetHealth(Math.Max(MathFunctions.CalculatePct(target.GetMaxHealth(), healthPct), (zeroHealth ? 0 : 1ul)));
|
target.SetHealth(Math.Max(MathFunctions.CalculatePct(target.GetMaxHealth(), healthPct), (zeroHealth ? 0 : 1ul)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3252,8 +3272,8 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
if (GetMiscValue() == (int)stat || GetMiscValue() == -1)
|
if (GetMiscValue() == (int)stat || GetMiscValue() == -1)
|
||||||
{
|
{
|
||||||
target.HandleStatModifier(UnitMods.StatStart + (int)stat, UnitModifierType.BasePCTExcludeCreate, m_amount, apply);
|
target.HandleStatFlatModifier(UnitMods.StatStart + (int)stat, UnitModifierFlatType.BasePCTExcludeCreate, m_amount, apply);
|
||||||
target.ApplyStatPercentBuffMod(stat, m_amount, apply);
|
target.UpdateStatBuffMod(stat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3313,7 +3333,7 @@ namespace Game.Spells
|
|||||||
PowerType power = (PowerType)GetMiscValue();
|
PowerType power = (PowerType)GetMiscValue();
|
||||||
UnitMods unitMod = (UnitMods)(UnitMods.PowerStart + (int)power);
|
UnitMods unitMod = (UnitMods)(UnitMods.PowerStart + (int)power);
|
||||||
|
|
||||||
target.HandleStatModifier(unitMod, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(unitMod, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
@@ -3385,7 +3405,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
if (apply)
|
if (apply)
|
||||||
{
|
{
|
||||||
target.HandleStatModifier(UnitMods.Health, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
target.ModifyHealth(GetAmount());
|
target.ModifyHealth(GetAmount());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3396,7 +3416,7 @@ namespace Game.Spells
|
|||||||
target.ModifyHealth(-value);
|
target.ModifyHealth(-value);
|
||||||
}
|
}
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.Health, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3409,7 +3429,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
float percent = target.GetHealthPct();
|
float percent = target.GetHealthPct();
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.Health, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.Health, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
|
|
||||||
// refresh percentage
|
// refresh percentage
|
||||||
if (target.GetHealth() > 0)
|
if (target.GetHealth() > 0)
|
||||||
@@ -3429,7 +3449,7 @@ namespace Game.Spells
|
|||||||
PowerType powerType = (PowerType)GetMiscValue();
|
PowerType powerType = (PowerType)GetMiscValue();
|
||||||
|
|
||||||
UnitMods unitMod = (UnitMods.PowerStart + (int)powerType);
|
UnitMods unitMod = (UnitMods.PowerStart + (int)powerType);
|
||||||
target.HandleStatModifier(unitMod, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(unitMod, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModIncreaseEnergyPercent)]
|
[AuraEffectHandler(AuraType.ModIncreaseEnergyPercent)]
|
||||||
@@ -3448,7 +3468,26 @@ namespace Game.Spells
|
|||||||
int oldMaxPower = target.GetMaxPower(powerType);
|
int oldMaxPower = target.GetMaxPower(powerType);
|
||||||
|
|
||||||
// Handle aura effect for max power
|
// Handle aura effect for max power
|
||||||
target.HandleStatModifier(unitMod, UnitModifierType.TotalPCT, GetAmount(), apply);
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(unitMod, UnitModifierPctType.Total, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModIncreaseEnergyPercent, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == (int)powerType)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
amount *= target.GetTotalAuraMultiplier(AuraType.ModMaxPowerPct, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == (int)powerType)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
target.SetStatPctModifier(unitMod, UnitModifierPctType.Total, amount);
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the current power change
|
// Calculate the current power change
|
||||||
int change = target.GetMaxPower(powerType) - oldMaxPower;
|
int change = target.GetMaxPower(powerType) - oldMaxPower;
|
||||||
@@ -3465,11 +3504,17 @@ namespace Game.Spells
|
|||||||
|
|
||||||
// Unit will keep hp% after MaxHealth being modified if unit is alive.
|
// Unit will keep hp% after MaxHealth being modified if unit is alive.
|
||||||
float percent = target.GetHealthPct();
|
float percent = target.GetHealthPct();
|
||||||
target.HandleStatModifier(UnitMods.Health, UnitModifierType.TotalPCT, GetAmount(), apply);
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.Health, UnitModifierPctType.Total, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModIncreaseHealthPercent);
|
||||||
|
target.SetStatPctModifier(UnitMods.Health, UnitModifierPctType.Total, amount);
|
||||||
|
}
|
||||||
|
|
||||||
if (target.GetHealth() > 0)
|
if (target.GetHealth() > 0)
|
||||||
{
|
{
|
||||||
uint newHealth = (uint)Math.Max(target.CountPctFromMaxHealth((int)percent), 1);
|
uint newHealth = (uint)Math.Max(MathFunctions.CalculatePct(target.GetMaxHealth(), (int)percent), 1);
|
||||||
target.SetHealth(newHealth);
|
target.SetHealth(newHealth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3482,7 +3527,13 @@ namespace Game.Spells
|
|||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.Health, UnitModifierType.BasePCT, GetAmount(), apply);
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.Health, UnitModifierPctType.Base, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModBaseHealthPct);
|
||||||
|
target.SetStatPctModifier(UnitMods.Health, UnitModifierPctType.Base, amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModBaseManaPct)]
|
[AuraEffectHandler(AuraType.ModBaseManaPct)]
|
||||||
@@ -3491,7 +3542,15 @@ namespace Game.Spells
|
|||||||
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat))
|
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
aurApp.GetTarget().HandleStatModifier(UnitMods.Mana, UnitModifierType.BasePCT, GetAmount(), apply);
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.Mana, UnitModifierPctType.Base, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModBaseManaPct);
|
||||||
|
target.SetStatPctModifier(UnitMods.Mana, UnitModifierPctType.Base, amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModPowerDisplay)]
|
[AuraEffectHandler(AuraType.ModPowerDisplay)]
|
||||||
@@ -3550,7 +3609,26 @@ namespace Game.Spells
|
|||||||
int oldMaxPower = target.GetMaxPower(powerType);
|
int oldMaxPower = target.GetMaxPower(powerType);
|
||||||
|
|
||||||
// Handle aura effect for max power
|
// Handle aura effect for max power
|
||||||
target.HandleStatModifier(unitMod, UnitModifierType.TotalPCT, (float)GetAmount(), apply);
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(unitMod, UnitModifierPctType.Total, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModMaxPowerPct, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == (int)powerType)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
amount *= target.GetTotalAuraMultiplier(AuraType.ModIncreaseEnergyPercent, aurEff =>
|
||||||
|
{
|
||||||
|
if (aurEff.GetMiscValue() == (int)powerType)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
target.SetStatPctModifier(unitMod, UnitModifierPctType.Total, amount);
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the current power change
|
// Calculate the current power change
|
||||||
int change = target.GetMaxPower(powerType) - oldMaxPower;
|
int change = target.GetMaxPower(powerType) - oldMaxPower;
|
||||||
@@ -3616,13 +3694,10 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Player target = aurApp.GetTarget().ToPlayer();
|
Player target = aurApp.GetTarget().ToPlayer();
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
target.HandleBaseModValue(BaseModGroup.CritPercentage, BaseModType.FlatMod, GetAmount(), apply);
|
target.UpdateAllWeaponDependentCritAuras();
|
||||||
target.HandleBaseModValue(BaseModGroup.OffhandCritPercentage, BaseModType.FlatMod, GetAmount(), apply);
|
|
||||||
target.HandleBaseModValue(BaseModGroup.RangedCritPercentage, BaseModType.FlatMod, GetAmount(), apply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModHitChance)]
|
[AuraEffectHandler(AuraType.ModHitChance)]
|
||||||
@@ -3687,9 +3762,7 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.ToPlayer().HandleBaseModValue(BaseModGroup.CritPercentage, BaseModType.FlatMod, GetAmount(), apply);
|
target.ToPlayer().UpdateAllWeaponDependentCritAuras();
|
||||||
target.ToPlayer().HandleBaseModValue(BaseModGroup.OffhandCritPercentage, BaseModType.FlatMod, GetAmount(), apply);
|
|
||||||
target.ToPlayer().HandleBaseModValue(BaseModGroup.RangedCritPercentage, BaseModType.FlatMod, GetAmount(), apply);
|
|
||||||
|
|
||||||
// included in Player.UpdateSpellCritChance calculation
|
// included in Player.UpdateSpellCritChance calculation
|
||||||
target.ToPlayer().UpdateSpellCritChance();
|
target.ToPlayer().UpdateSpellCritChance();
|
||||||
@@ -3863,7 +3936,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.AttackPower, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.AttackPower, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModRangedAttackPower)]
|
[AuraEffectHandler(AuraType.ModRangedAttackPower)]
|
||||||
@@ -3877,7 +3950,7 @@ namespace Game.Spells
|
|||||||
if ((target.GetClassMask() & (uint)Class.ClassMaskWandUsers) != 0)
|
if ((target.GetClassMask() & (uint)Class.ClassMaskWandUsers) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalValue, GetAmount(), apply);
|
target.HandleStatFlatModifier(UnitMods.AttackPowerRanged, UnitModifierFlatType.Total, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModAttackPowerPct)]
|
[AuraEffectHandler(AuraType.ModAttackPowerPct)]
|
||||||
@@ -3889,7 +3962,13 @@ namespace Game.Spells
|
|||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
|
//UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
|
||||||
target.HandleStatModifier(UnitMods.AttackPower, UnitModifierType.TotalPCT, GetAmount(), apply);
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.AttackPower, UnitModifierPctType.Total, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModAttackPowerPct);
|
||||||
|
target.SetStatPctModifier(UnitMods.AttackPower, UnitModifierPctType.Total, amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModRangedAttackPowerPct)]
|
[AuraEffectHandler(AuraType.ModRangedAttackPowerPct)]
|
||||||
@@ -3904,7 +3983,13 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
|
//UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
|
||||||
target.HandleStatModifier(UnitMods.AttackPowerRanged, UnitModifierType.TotalPCT, GetAmount(), apply);
|
if (apply)
|
||||||
|
target.ApplyStatPctModifier(UnitMods.AttackPowerRanged, UnitModifierPctType.Total, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModRangedAttackPowerPct);
|
||||||
|
target.SetStatPctModifier(UnitMods.AttackPowerRanged, UnitModifierPctType.Total, amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
@@ -3919,11 +4004,7 @@ namespace Game.Spells
|
|||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
if ((GetMiscValue() & (int)SpellSchoolMask.Normal) != 0)
|
if ((GetMiscValue() & (int)SpellSchoolMask.Normal) != 0)
|
||||||
{
|
target.UpdateAllDamageDoneMods();
|
||||||
target.HandleStatModifier(UnitMods.DamageMainHand, UnitModifierType.TotalValue, GetAmount(), apply);
|
|
||||||
target.HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalValue, GetAmount(), apply);
|
|
||||||
target.HandleStatModifier(UnitMods.DamageRanged, UnitModifierType.TotalValue, GetAmount(), apply);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Magic damage modifiers implemented in Unit::SpellBaseDamageBonusDone
|
// Magic damage modifiers implemented in Unit::SpellBaseDamageBonusDone
|
||||||
// This information for client side use only
|
// This information for client side use only
|
||||||
@@ -3954,35 +4035,21 @@ namespace Game.Spells
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
int spellGroupVal = target.GetHighestExclusiveSameEffectSpellGroupValue(this, AuraType.ModDamagePercentDone);
|
|
||||||
if (Math.Abs(spellGroupVal) >= Math.Abs(GetAmount()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
// also handles spell group stacks
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
if (Convert.ToBoolean(GetMiscValue() & (int)SpellSchoolMask.Normal))
|
||||||
{
|
target.UpdateAllDamagePctDoneMods();
|
||||||
if (spellGroupVal != 0)
|
|
||||||
{
|
|
||||||
target.HandleStatModifier(UnitMods.DamageMainHand, UnitModifierType.TotalPCT, spellGroupVal, !apply);
|
|
||||||
target.HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalPCT, spellGroupVal, !apply);
|
|
||||||
target.HandleStatModifier(UnitMods.DamageRanged, UnitModifierType.TotalPCT, spellGroupVal, !apply);
|
|
||||||
}
|
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.DamageMainHand, UnitModifierType.TotalPCT, GetAmount(), apply);
|
|
||||||
target.HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalPCT, GetAmount(), apply);
|
|
||||||
target.HandleStatModifier(UnitMods.DamageRanged, UnitModifierType.TotalPCT, GetAmount(), apply);
|
|
||||||
}
|
|
||||||
|
|
||||||
Player thisPlayer = target.ToPlayer();
|
Player thisPlayer = target.ToPlayer();
|
||||||
if (thisPlayer != null)
|
if (thisPlayer != null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)SpellSchools.Max; ++i)
|
for (var i = SpellSchools.Normal; i < SpellSchools.Max; ++i)
|
||||||
{
|
{
|
||||||
if (Convert.ToBoolean(GetMiscValue() & (1 << i)))
|
if (Convert.ToBoolean(GetMiscValue() & (1 << (int)i)))
|
||||||
{
|
{
|
||||||
if (spellGroupVal != 0)
|
// only aura type modifying PLAYER_FIELD_MOD_DAMAGE_DONE_PCT
|
||||||
thisPlayer.ApplyModDamageDonePercent((SpellSchools)i, spellGroupVal, !apply);
|
float amount = thisPlayer.GetTotalAuraMultiplierByMiscMask(AuraType.ModDamagePercentDone, 1u << (int)i);
|
||||||
|
thisPlayer.SetModDamageDonePercent(i, amount);
|
||||||
thisPlayer.ApplyModDamageDonePercent((SpellSchools)i, GetAmount(), apply);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3996,18 +4063,37 @@ namespace Game.Spells
|
|||||||
|
|
||||||
Unit target = aurApp.GetTarget();
|
Unit target = aurApp.GetTarget();
|
||||||
|
|
||||||
target.HandleStatModifier(UnitMods.DamageOffHand, UnitModifierType.TotalPCT, GetAmount(), apply);
|
// also handles spell group stacks
|
||||||
|
target.UpdateDamagePctDoneMods(WeaponAttackType.OffAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleShieldBlockValue(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||||
|
{
|
||||||
|
if (!mode.HasAnyFlag(AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Player player = aurApp.GetTarget().ToPlayer();
|
||||||
|
if (player != null)
|
||||||
|
player.HandleBaseModFlatValue(BaseModGroup.ShieldBlockValue, GetAmount(), apply);
|
||||||
}
|
}
|
||||||
|
|
||||||
[AuraEffectHandler(AuraType.ModShieldBlockvaluePct)]
|
[AuraEffectHandler(AuraType.ModShieldBlockvaluePct)]
|
||||||
void HandleShieldBlockValue(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
void HandleShieldBlockValuePercent(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply)
|
||||||
{
|
{
|
||||||
if (!mode.HasAnyFlag((AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat)))
|
if (!mode.HasAnyFlag((AuraEffectHandleModes.ChangeAmountMask | AuraEffectHandleModes.Stat)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Player player = aurApp.GetTarget().ToPlayer();
|
Player target = aurApp.GetTarget().ToPlayer();
|
||||||
if (player)
|
if (!target)
|
||||||
player.HandleBaseModValue(BaseModGroup.ShieldBlockValue, BaseModType.PCTmod, GetAmount(), apply);
|
return;
|
||||||
|
|
||||||
|
if (apply)
|
||||||
|
target.ApplyBaseModPctValue(BaseModGroup.ShieldBlockValue, GetAmount());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float amount = target.GetTotalAuraMultiplier(AuraType.ModShieldBlockvaluePct);
|
||||||
|
target.SetBaseModPctValue(BaseModGroup.ShieldBlockValue, amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************/
|
/********************************/
|
||||||
@@ -4478,7 +4564,7 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Adding items
|
//Adding items
|
||||||
uint noSpaceForCount = 0;
|
uint noSpaceForCount;
|
||||||
uint count = (uint)m_amount;
|
uint count = (uint)m_amount;
|
||||||
|
|
||||||
List<ItemPosCount> dest = new List<ItemPosCount>();
|
List<ItemPosCount> dest = new List<ItemPosCount>();
|
||||||
|
|||||||
@@ -1388,8 +1388,8 @@ namespace Game.Spells
|
|||||||
|
|
||||||
Player player = m_caster.ToPlayer();
|
Player player = m_caster.ToPlayer();
|
||||||
|
|
||||||
uint lockId = 0;
|
uint lockId;
|
||||||
ObjectGuid guid = ObjectGuid.Empty;
|
ObjectGuid guid;
|
||||||
|
|
||||||
// Get lockId
|
// Get lockId
|
||||||
if (gameObjTarget != null)
|
if (gameObjTarget != null)
|
||||||
@@ -1741,7 +1741,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
for (uint count = 0; count < numSummons; ++count)
|
for (uint count = 0; count < numSummons; ++count)
|
||||||
{
|
{
|
||||||
Position pos = new Position();
|
Position pos;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
pos = destTarget;
|
pos = destTarget;
|
||||||
else
|
else
|
||||||
@@ -2657,7 +2657,7 @@ namespace Game.Spells
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float weapon_total_pct = m_caster.GetModifierValue(unitMod, UnitModifierType.TotalPCT);
|
float weapon_total_pct = m_caster.GetPctModifierValue(unitMod, UnitModifierPctType.Total);
|
||||||
if (fixed_bonus != 0)
|
if (fixed_bonus != 0)
|
||||||
fixed_bonus = (int)(fixed_bonus * weapon_total_pct);
|
fixed_bonus = (int)(fixed_bonus * weapon_total_pct);
|
||||||
if (spell_bonus != 0)
|
if (spell_bonus != 0)
|
||||||
@@ -2725,7 +2725,7 @@ namespace Game.Spells
|
|||||||
if (unitTarget == null || !unitTarget.IsAlive())
|
if (unitTarget == null || !unitTarget.IsAlive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int addhealth = 0;
|
int addhealth;
|
||||||
|
|
||||||
// damage == 0 - heal for caster max health
|
// damage == 0 - heal for caster max health
|
||||||
if (damage == 0)
|
if (damage == 0)
|
||||||
@@ -2951,7 +2951,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
byte bag = 19;
|
byte bag = 19;
|
||||||
byte slot = 0;
|
byte slot = 0;
|
||||||
Item item = null;
|
Item item;
|
||||||
|
|
||||||
while (bag != 0) // 256 = 0 due to var type
|
while (bag != 0) // 256 = 0 due to var type
|
||||||
{
|
{
|
||||||
@@ -3020,7 +3020,7 @@ namespace Game.Spells
|
|||||||
if (unitTarget == null || !unitTarget.IsTypeId(TypeId.Unit))
|
if (unitTarget == null || !unitTarget.IsTypeId(TypeId.Unit))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint iTmpSpellId = 0;
|
uint iTmpSpellId;
|
||||||
switch (unitTarget.GetDisplayId())
|
switch (unitTarget.GetDisplayId())
|
||||||
{
|
{
|
||||||
case 25369: iTmpSpellId = 51552; break; // bloodelf female
|
case 25369: iTmpSpellId = 51552; break; // bloodelf female
|
||||||
@@ -3304,7 +3304,7 @@ namespace Game.Spells
|
|||||||
{
|
{
|
||||||
if (unitTarget == null || !unitTarget.IsAlive())
|
if (unitTarget == null || !unitTarget.IsAlive())
|
||||||
return;
|
return;
|
||||||
uint spellId1 = 0;
|
uint spellId1;
|
||||||
uint spellId2 = 0;
|
uint spellId2 = 0;
|
||||||
|
|
||||||
// Judgement self add switch
|
// Judgement self add switch
|
||||||
@@ -3985,7 +3985,7 @@ namespace Game.Spells
|
|||||||
if (!m_caster.IsInWorld)
|
if (!m_caster.IsInWorld)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint health = 0;
|
uint health;
|
||||||
int mana = 0;
|
int mana = 0;
|
||||||
|
|
||||||
// flat case
|
// flat case
|
||||||
@@ -5065,7 +5065,7 @@ namespace Game.Spells
|
|||||||
|
|
||||||
for (uint count = 0; count < numGuardians; ++count)
|
for (uint count = 0; count < numGuardians; ++count)
|
||||||
{
|
{
|
||||||
Position pos = new Position();
|
Position pos;
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
pos = destTarget;
|
pos = destTarget;
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user