Core/Spells: Fixed value of aura effects for stat mod auras applied by items
This commit is contained in:
@@ -469,6 +469,7 @@ CREATE TABLE `character_aura` (
|
||||
`maxDuration` int(11) NOT NULL DEFAULT '0',
|
||||
`remainTime` int(11) NOT NULL DEFAULT '0',
|
||||
`remainCharges` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`castItemId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`castItemLevel` int(11) NOT NULL DEFAULT '-1',
|
||||
PRIMARY KEY (`guid`,`casterGuid`,`itemGuid`,`spell`,`effectMask`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player System';
|
||||
@@ -3660,7 +3661,8 @@ INSERT INTO `updates` VALUES
|
||||
('2019_10_26_01_characters.sql','59D5860930D02AB77D2AAA704C564957A9143760','RELEASED','2019-10-26 22:04:46',0),
|
||||
('2019_11_03_00_characters.sql','DC789597F85B890E9A7901B4443DAD9CAEE2A02A','RELEASED','2019-11-03 14:13:27',0),
|
||||
('2019_11_12_00_characters.sql','D4C642B4D48DAE9F56329BDE51C258323A132A91','RELEASED','2019-11-12 16:31:29',0),
|
||||
('2019_11_22_00_characters.sql','95DFA71DBD75542C098CD86E9C0051C9690902F0','RELEASED','2019-11-20 15:10:12',0);
|
||||
('2019_11_22_00_characters.sql','95DFA71DBD75542C098CD86E9C0051C9690902F0','RELEASED','2019-11-20 15:10:12',0),
|
||||
('2019_11_30_00_characters.sql','D0678E62B651AECA60C2DD6989BF80BD999AD12B','RELEASED','2019-11-29 22:42:01',0);
|
||||
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `character_aura` ADD `castItemId` int(10) unsigned NOT NULL DEFAULT '0' AFTER `remainCharges`;
|
||||
@@ -86,7 +86,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
|
||||
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, extendState, resettime, entranceId FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemLevel FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_AURA_EFFECTS, "SELECT casterGuid, itemGuid, spell, effectMask, effectIndex, amount, baseAmount FROM character_aura_effect WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, timer FROM character_queststatus WHERE guid = ? AND status <> 0", CONNECTION_ASYNC);
|
||||
@@ -326,8 +326,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(CHAR_DEL_TRANSMOG_OUTFIT, "DELETE FROM character_transmog_outfits WHERE setguid=?", CONNECTION_ASYNC);
|
||||
|
||||
// Auras
|
||||
PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemLevel) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(CHAR_INS_AURA_EFFECT, "INSERT INTO character_aura_effect (guid, casterGuid, itemGuid, spell, effectMask, effectIndex, amount, baseAmount) "
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "GameTables.h"
|
||||
#include "ItemTemplate.h"
|
||||
#include "Timer.h"
|
||||
#include "Log.h"
|
||||
#include "Util.h"
|
||||
@@ -35,6 +36,7 @@ GameTable<GtNpcDamageByClassEntry> sNpcDamageByClassGameTable[MAX_E
|
||||
GameTable<GtNpcManaCostScalerEntry> sNpcManaCostScalerGameTable;
|
||||
GameTable<GtNpcTotalHpEntry> sNpcTotalHpGameTable[MAX_EXPANSIONS];
|
||||
GameTable<GtSpellScalingEntry> sSpellScalingGameTable;
|
||||
GameTable<GtStaminaMultByILvl> sStaminaMultByILvlGameTable;
|
||||
GameTable<GtXpEntry> sXpGameTable;
|
||||
|
||||
template<class T>
|
||||
@@ -136,6 +138,7 @@ void LoadGameTables(std::string const& dataPath)
|
||||
LOAD_GT(sNpcTotalHpGameTable[6], "NpcTotalHpExp6.txt");
|
||||
LOAD_GT(sNpcTotalHpGameTable[7], "NpcTotalHpExp7.txt");
|
||||
LOAD_GT(sSpellScalingGameTable, "SpellScaling.txt");
|
||||
LOAD_GT(sStaminaMultByILvlGameTable, "StaminaMultByILvl.txt");
|
||||
LOAD_GT(sXpGameTable, "xp.txt");
|
||||
|
||||
#undef LOAD_GT
|
||||
@@ -152,3 +155,34 @@ void LoadGameTables(std::string const& dataPath)
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Initialized %d GameTables in %u ms", gameTableCount, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float GetIlvlStatMultiplier(T const* row, InventoryType invType)
|
||||
{
|
||||
switch (invType)
|
||||
{
|
||||
case INVTYPE_NECK:
|
||||
case INVTYPE_FINGER:
|
||||
return row->JewelryMultiplier;
|
||||
break;
|
||||
case INVTYPE_TRINKET:
|
||||
return row->TrinketMultiplier;
|
||||
break;
|
||||
case INVTYPE_WEAPON:
|
||||
case INVTYPE_SHIELD:
|
||||
case INVTYPE_RANGED:
|
||||
case INVTYPE_2HWEAPON:
|
||||
case INVTYPE_WEAPONMAINHAND:
|
||||
case INVTYPE_WEAPONOFFHAND:
|
||||
case INVTYPE_HOLDABLE:
|
||||
case INVTYPE_RANGEDRIGHT:
|
||||
return row->WeaponMultiplier;
|
||||
break;
|
||||
default:
|
||||
return row->ArmorMultiplier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template float GetIlvlStatMultiplier(GtCombatRatingsMultByILvl const* row, InventoryType invType);
|
||||
template float GetIlvlStatMultiplier(GtStaminaMultByILvl const* row, InventoryType invType);
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "Common.h"
|
||||
#include <vector>
|
||||
|
||||
enum InventoryType : uint8;
|
||||
|
||||
struct GtArmorMitigationByLvlEntry
|
||||
{
|
||||
float Mitigation = 0.0f;
|
||||
@@ -174,6 +176,14 @@ struct GtSpellScalingEntry
|
||||
float DamageSecondary = 0.0f;
|
||||
};
|
||||
|
||||
struct GtStaminaMultByILvl
|
||||
{
|
||||
float ArmorMultiplier = 0.0f;
|
||||
float WeaponMultiplier = 0.0f;
|
||||
float TrinketMultiplier = 0.0f;
|
||||
float JewelryMultiplier = 0.0f;
|
||||
};
|
||||
|
||||
struct GtXpEntry
|
||||
{
|
||||
float Total = 0.0f;
|
||||
@@ -216,6 +226,7 @@ TC_GAME_API extern GameTable<GtNpcDamageByClassEntry> sNpcDamageBy
|
||||
TC_GAME_API extern GameTable<GtNpcManaCostScalerEntry> sNpcManaCostScalerGameTable;
|
||||
TC_GAME_API extern GameTable<GtNpcTotalHpEntry> sNpcTotalHpGameTable[MAX_EXPANSIONS];
|
||||
TC_GAME_API extern GameTable<GtSpellScalingEntry> sSpellScalingGameTable;
|
||||
TC_GAME_API extern GameTable<GtStaminaMultByILvl> sStaminaMultByILvlGameTable;
|
||||
TC_GAME_API extern GameTable<GtXpEntry> sXpGameTable;
|
||||
|
||||
TC_GAME_API void LoadGameTables(std::string const& dataPath);
|
||||
@@ -308,4 +319,7 @@ inline float GetSpellScalingColumnForClass(GtSpellScalingEntry const* row, int32
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
float GetIlvlStatMultiplier(T const* row, InventoryType invType);
|
||||
|
||||
#endif // GameTables_h__
|
||||
|
||||
@@ -7350,31 +7350,7 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
|
||||
uint32 itemLevel = item->GetItemLevel(this);
|
||||
float combatRatingMultiplier = 1.0f;
|
||||
if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(itemLevel))
|
||||
{
|
||||
switch (proto->GetInventoryType())
|
||||
{
|
||||
case INVTYPE_WEAPON:
|
||||
case INVTYPE_SHIELD:
|
||||
case INVTYPE_RANGED:
|
||||
case INVTYPE_2HWEAPON:
|
||||
case INVTYPE_WEAPONMAINHAND:
|
||||
case INVTYPE_WEAPONOFFHAND:
|
||||
case INVTYPE_HOLDABLE:
|
||||
case INVTYPE_RANGEDRIGHT:
|
||||
combatRatingMultiplier = ratingMult->WeaponMultiplier;
|
||||
break;
|
||||
case INVTYPE_TRINKET:
|
||||
combatRatingMultiplier = ratingMult->TrinketMultiplier;
|
||||
break;
|
||||
case INVTYPE_NECK:
|
||||
case INVTYPE_FINGER:
|
||||
combatRatingMultiplier = ratingMult->JewelryMultiplier;
|
||||
break;
|
||||
default:
|
||||
combatRatingMultiplier = ratingMult->ArmorMultiplier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
combatRatingMultiplier = GetIlvlStatMultiplier(ratingMult, proto->GetInventoryType());
|
||||
|
||||
// req. check at equip, but allow use for extended range if range limit max level, set proper level
|
||||
for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
|
||||
@@ -7412,9 +7388,13 @@ void Player::_ApplyItemBonuses(Item* item, uint8 slot, bool apply)
|
||||
// ApplyStatBuffMod(STAT_SPIRIT, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_SPIRIT, BASE_PCT_EXCLUDE_CREATE)), apply);
|
||||
// break;
|
||||
case ITEM_MOD_STAMINA: //modify stamina
|
||||
{
|
||||
if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(itemLevel))
|
||||
val = int32(val * GetIlvlStatMultiplier(staminaMult, proto->GetInventoryType()));
|
||||
HandleStatModifier(UNIT_MOD_STAT_STAMINA, BASE_VALUE, float(val), apply);
|
||||
ApplyStatBuffMod(STAT_STAMINA, CalculatePct(val, GetModifierValue(UNIT_MOD_STAT_STAMINA, BASE_PCT_EXCLUDE_CREATE)), apply);
|
||||
break;
|
||||
}
|
||||
case ITEM_MOD_DEFENSE_SKILL_RATING:
|
||||
ApplyRatingMod(CR_DEFENSE_SKILL, int32(val * combatRatingMultiplier), apply);
|
||||
break;
|
||||
@@ -18621,8 +18601,8 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
|
||||
}
|
||||
|
||||
/*
|
||||
0 1 2 3 4 5 6 7 8 9
|
||||
SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemLevel FROM character_aura WHERE guid = ?
|
||||
0 1 2 3 4 5 6 7 8 9 10
|
||||
SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel FROM character_aura WHERE guid = ?
|
||||
*/
|
||||
if (auraResult)
|
||||
{
|
||||
@@ -18637,7 +18617,8 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
|
||||
int32 maxDuration = fields[6].GetInt32();
|
||||
int32 remainTime = fields[7].GetInt32();
|
||||
uint8 remainCharges = fields[8].GetUInt8();
|
||||
int32 castItemLevel = fields[9].GetInt32();
|
||||
uint32 castItemId = fields[9].GetUInt32();
|
||||
int32 castItemLevel = fields[10].GetInt32();
|
||||
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(key.SpellId);
|
||||
if (!spellInfo)
|
||||
@@ -18669,7 +18650,7 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
|
||||
|
||||
AuraLoadEffectInfo& info = effectInfo[key];
|
||||
ObjectGuid castId = ObjectGuid::Create<HighGuid::Cast>(SPELL_CAST_SOURCE_NORMAL, GetMapId(), spellInfo->Id, GetMap()->GenerateLowGuid<HighGuid::Cast>());
|
||||
if (Aura* aura = Aura::TryCreate(spellInfo, castId, key.EffectMask, this, nullptr, info.BaseAmounts.data(), nullptr, casterGuid, itemGuid, castItemLevel))
|
||||
if (Aura* aura = Aura::TryCreate(spellInfo, castId, key.EffectMask, this, nullptr, info.BaseAmounts.data(), nullptr, casterGuid, itemGuid, castItemId, castItemLevel))
|
||||
{
|
||||
if (!aura->CanBeSaved())
|
||||
{
|
||||
@@ -20574,6 +20555,7 @@ void Player::_SaveAuras(CharacterDatabaseTransaction& trans)
|
||||
stmt->setInt32(index++, aura->GetMaxDuration());
|
||||
stmt->setInt32(index++, aura->GetDuration());
|
||||
stmt->setUInt8(index++, aura->GetCharges());
|
||||
stmt->setUInt32(index++, aura->GetCastItemId());
|
||||
stmt->setInt32(index++, aura->GetCastItemLevel());
|
||||
trans->Append(stmt);
|
||||
|
||||
|
||||
@@ -3223,7 +3223,7 @@ void Unit::DeMorph()
|
||||
SetDisplayId(GetNativeDisplayId());
|
||||
}
|
||||
|
||||
Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool resetPeriodicTimer /*= true*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, int32 castItemLevel /*= -1*/)
|
||||
Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool resetPeriodicTimer /*= true*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, uint32 castItemId /*= 0*/, int32 castItemLevel /*= -1*/)
|
||||
{
|
||||
ASSERT(!casterGUID.IsEmpty() || caster);
|
||||
|
||||
@@ -3239,9 +3239,15 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
|
||||
{
|
||||
castItemGuid = castItem->GetGUID();
|
||||
if (Player* owner = castItem->GetOwner())
|
||||
{
|
||||
castItemId = castItem->GetEntry();
|
||||
castItemLevel = int32(castItem->GetItemLevel(owner));
|
||||
}
|
||||
else if (castItem->GetOwnerGUID() == caster->GetGUID())
|
||||
{
|
||||
castItemId = castItem->GetEntry();
|
||||
castItemLevel = int32(castItem->GetItemLevel(caster->ToPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
// find current aura from spell and change it's stackamount, or refresh it's duration
|
||||
@@ -3278,6 +3284,8 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
|
||||
{
|
||||
ObjectGuid* oldGUID = const_cast<ObjectGuid*>(&foundAura->m_castItemGuid);
|
||||
*oldGUID = castItemGuid;
|
||||
uint32* oldItemId = const_cast<uint32*>(&foundAura->m_castItemId);
|
||||
*oldItemId = castItemId;
|
||||
int32* oldItemLevel = const_cast<int32*>(&foundAura->m_castItemLevel);
|
||||
*oldItemLevel = castItemLevel;
|
||||
}
|
||||
@@ -8987,13 +8995,13 @@ float Unit::ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index
|
||||
}
|
||||
|
||||
// function uses real base points (typically value - 1)
|
||||
int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints /*= nullptr*/, float* variance /*= nullptr*/, int32 itemLevel /*= -1*/) const
|
||||
int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
|
||||
{
|
||||
SpellEffectInfo const* effect = spellProto->GetEffect(GetMap()->GetDifficultyID(), effect_index);
|
||||
if (variance)
|
||||
*variance = 0.0f;
|
||||
|
||||
return effect ? effect->CalcValue(this, basePoints, target, variance, itemLevel) : 0;
|
||||
return effect ? effect->CalcValue(this, basePoints, target, variance, castItemId, itemLevel) : 0;
|
||||
}
|
||||
|
||||
int32 Unit::CalcSpellDuration(SpellInfo const* spellProto)
|
||||
|
||||
@@ -1482,7 +1482,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
bool InitTamedPet(Pet* pet, uint8 level, uint32 spell_id);
|
||||
|
||||
// aura apply/remove helpers - you should better not use these
|
||||
Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = ObjectGuid::Empty, int32 castItemLevel = -1);
|
||||
Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = ObjectGuid::Empty, uint32 castItemId = 0, int32 castItemLevel = -1);
|
||||
void _AddAura(UnitAura* aura, Unit* caster);
|
||||
AuraApplication * _CreateAuraApplication(Aura* aura, uint32 effMask);
|
||||
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
|
||||
@@ -1863,7 +1863,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetSpeedRate(UnitMoveType mtype, float rate);
|
||||
|
||||
float ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index, float value) const;
|
||||
int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = nullptr, float* variance = nullptr, int32 itemLevel = -1) const;
|
||||
int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = nullptr, float* variance = nullptr, uint32 castItemId = 0, int32 itemLevel = -1) const;
|
||||
int32 CalcSpellDuration(SpellInfo const* spellProto);
|
||||
int32 ModSpellDuration(SpellInfo const* spellProto, Unit const* target, int32 duration, bool positive, uint32 effectMask);
|
||||
void ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = NULL);
|
||||
|
||||
@@ -565,7 +565,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
|
||||
AuraEffect::AuraEffect(Aura* base, uint32 effIndex, int32 *baseAmount, Unit* caster) :
|
||||
m_base(base), m_spellInfo(base->GetSpellInfo()),
|
||||
_effectInfo(base->GetSpellEffectInfo(effIndex)),
|
||||
m_baseAmount(baseAmount ? *baseAmount : _effectInfo->CalcBaseValue(caster, base->GetType() == UNIT_AURA_TYPE ? base->GetOwner()->ToUnit() : nullptr, base->GetCastItemLevel())),
|
||||
m_baseAmount(baseAmount ? *baseAmount : _effectInfo->CalcBaseValue(caster, base->GetType() == UNIT_AURA_TYPE ? base->GetOwner()->ToUnit() : nullptr, base->GetCastItemId(), base->GetCastItemLevel())),
|
||||
m_damage(0), m_critChance(0.0f), m_donePct(1.0f),
|
||||
m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex),
|
||||
m_canBeRecalculated(true), m_isPeriodic(false)
|
||||
@@ -611,7 +611,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
|
||||
int32 amount = 0;
|
||||
|
||||
if (!m_spellInfo->HasAttribute(SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(GetSpellEffectInfo()->BonusCoefficient, 0.0f))
|
||||
amount = GetSpellEffectInfo()->CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit(), nullptr, GetBase()->GetCastItemLevel());
|
||||
amount = GetSpellEffectInfo()->CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit(), nullptr, GetBase()->GetCastItemId(), GetBase()->GetCastItemLevel());
|
||||
else if (caster && caster->GetTypeId() == TYPEID_PLAYER)
|
||||
amount = int32(caster->ToPlayer()->m_activePlayerData->Mastery * GetSpellEffectInfo()->BonusCoefficient);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uin
|
||||
class TC_GAME_API AuraEffect
|
||||
{
|
||||
friend void Aura::_InitEffects(uint32 effMask, Unit* caster, int32* baseAmount);
|
||||
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, bool resetPeriodicTimer, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, bool resetPeriodicTimer, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
friend Aura::~Aura();
|
||||
|
||||
public:
|
||||
|
||||
@@ -256,7 +256,7 @@ uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 availab
|
||||
return effMask & availableEffectMask;
|
||||
}
|
||||
|
||||
Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= nullptr*/, bool resetPeriodicTimer /*= true*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, int32 castItemLevel /*= -1*/)
|
||||
Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= nullptr*/, bool resetPeriodicTimer /*= true*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, uint32 castItemId /*= 0*/, int32 castItemLevel /*= -1*/)
|
||||
{
|
||||
ASSERT(spellproto);
|
||||
ASSERT(owner);
|
||||
@@ -282,10 +282,10 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, ObjectGuid cast
|
||||
return foundAura;
|
||||
}
|
||||
else
|
||||
return Create(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemLevel);
|
||||
return Create(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
|
||||
}
|
||||
|
||||
Aura* Aura::TryCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, int32 castItemLevel /*= -1*/)
|
||||
Aura* Aura::TryCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, ObjectGuid castItemGuid /*= ObjectGuid::Empty*/, uint32 castItemId /*= 0*/, int32 castItemLevel /*= -1*/)
|
||||
{
|
||||
ASSERT(spellproto);
|
||||
ASSERT(owner);
|
||||
@@ -295,10 +295,10 @@ Aura* Aura::TryCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 try
|
||||
if (!effMask)
|
||||
return nullptr;
|
||||
|
||||
return Create(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemLevel);
|
||||
return Create(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
|
||||
}
|
||||
|
||||
Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel)
|
||||
Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel)
|
||||
{
|
||||
ASSERT(effMask);
|
||||
ASSERT(spellproto);
|
||||
@@ -328,10 +328,10 @@ Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMas
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
case TYPEID_PLAYER:
|
||||
aura = new UnitAura(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemLevel);
|
||||
aura = new UnitAura(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
|
||||
break;
|
||||
case TYPEID_DYNAMICOBJECT:
|
||||
aura = new DynObjAura(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemLevel);
|
||||
aura = new DynObjAura(spellproto, castId, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemGuid, castItemId, castItemLevel);
|
||||
break;
|
||||
default:
|
||||
ABORT();
|
||||
@@ -344,9 +344,10 @@ Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMas
|
||||
return aura;
|
||||
}
|
||||
|
||||
Aura::Aura(SpellInfo const* spellproto, ObjectGuid castId, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel) :
|
||||
Aura::Aura(SpellInfo const* spellproto, ObjectGuid castId, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel) :
|
||||
m_spellInfo(spellproto), m_castGuid(castId), m_casterGuid(!casterGUID.IsEmpty() ? casterGUID : caster->GetGUID()),
|
||||
m_castItemGuid(castItem ? castItem->GetGUID() : castItemGuid), m_castItemLevel(castItemLevel), m_spellXSpellVisualId(caster ? caster->GetCastSpellXSpellVisualId(spellproto) : spellproto->GetSpellXSpellVisualId()),
|
||||
m_castItemGuid(castItem ? castItem->GetGUID() : castItemGuid), m_castItemId(castItem ? castItem->GetEntry() : castItemId),
|
||||
m_castItemLevel(castItemLevel), m_spellXSpellVisualId(caster ? caster->GetCastSpellXSpellVisualId(spellproto) : spellproto->GetSpellXSpellVisualId()),
|
||||
m_applyTime(time(NULL)), m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0),
|
||||
m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1),
|
||||
m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr),
|
||||
@@ -2253,8 +2254,8 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraAppli
|
||||
}
|
||||
}
|
||||
|
||||
UnitAura::UnitAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel)
|
||||
: Aura(spellproto, castId, owner, caster, castItem, casterGUID, castItemGuid, castItemLevel)
|
||||
UnitAura::UnitAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel)
|
||||
: Aura(spellproto, castId, owner, caster, castItem, casterGUID, castItemGuid, castItemId, castItemLevel)
|
||||
{
|
||||
m_AuraDRGroup = DIMINISHING_NONE;
|
||||
LoadScripts();
|
||||
@@ -2357,8 +2358,8 @@ void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint32>& targets, Unit* c
|
||||
}
|
||||
}
|
||||
|
||||
DynObjAura::DynObjAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel)
|
||||
: Aura(spellproto, castId, owner, caster, castItem, casterGUID, castItemGuid, castItemLevel)
|
||||
DynObjAura::DynObjAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel)
|
||||
: Aura(spellproto, castId, owner, caster, castItem, casterGUID, castItemGuid, castItemId, castItemLevel)
|
||||
{
|
||||
LoadScripts();
|
||||
ASSERT(GetDynobjOwner());
|
||||
|
||||
@@ -115,15 +115,15 @@ struct AuraLoadEffectInfo
|
||||
|
||||
class TC_GAME_API Aura
|
||||
{
|
||||
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, bool resetPeriodicTimer, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, bool resetPeriodicTimer, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
public:
|
||||
typedef std::map<ObjectGuid, AuraApplication*> ApplicationMap;
|
||||
|
||||
static uint32 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 availableEffectMask, WorldObject* owner);
|
||||
static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = nullptr, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = ObjectGuid::Empty, int32 castItemLevel = -1);
|
||||
static Aura* TryCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid castItemGuid = ObjectGuid::Empty, int32 castItemLevel = -1);
|
||||
static Aura* Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
Aura(SpellInfo const* spellproto, ObjectGuid castId, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = nullptr, bool resetPeriodicTimer = true, ObjectGuid castItemGuid = ObjectGuid::Empty, uint32 castItemId = 0, int32 castItemLevel = -1);
|
||||
static Aura* TryCreate(SpellInfo const* spellproto, ObjectGuid castId, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid castItemGuid = ObjectGuid::Empty, uint32 castItemId = 0, int32 castItemLevel = -1);
|
||||
static Aura* Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
Aura(SpellInfo const* spellproto, ObjectGuid castId, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
void _InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount);
|
||||
virtual ~Aura();
|
||||
|
||||
@@ -133,6 +133,7 @@ class TC_GAME_API Aura
|
||||
ObjectGuid GetCastGUID() const { return m_castGuid; }
|
||||
ObjectGuid GetCasterGUID() const { return m_casterGuid; }
|
||||
ObjectGuid GetCastItemGUID() const { return m_castItemGuid; }
|
||||
uint32 GetCastItemId() const { return m_castItemId; }
|
||||
int32 GetCastItemLevel() const { return m_castItemLevel; }
|
||||
uint32 GetSpellXSpellVisualId() const { return m_spellXSpellVisualId; }
|
||||
Unit* GetCaster() const;
|
||||
@@ -302,6 +303,7 @@ class TC_GAME_API Aura
|
||||
ObjectGuid const m_castGuid;
|
||||
ObjectGuid const m_casterGuid;
|
||||
ObjectGuid const m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
|
||||
uint32 m_castItemId;
|
||||
int32 m_castItemLevel;
|
||||
uint32 const m_spellXSpellVisualId;
|
||||
time_t const m_applyTime;
|
||||
@@ -338,9 +340,9 @@ class TC_GAME_API Aura
|
||||
|
||||
class TC_GAME_API UnitAura : public Aura
|
||||
{
|
||||
friend Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
friend Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
public:
|
||||
UnitAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
UnitAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
|
||||
void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
|
||||
void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
|
||||
@@ -359,9 +361,9 @@ class TC_GAME_API UnitAura : public Aura
|
||||
|
||||
class TC_GAME_API DynObjAura : public Aura
|
||||
{
|
||||
friend Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
friend Aura* Aura::Create(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
public:
|
||||
DynObjAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, int32 castItemLevel);
|
||||
DynObjAura(SpellInfo const* spellproto, ObjectGuid castId, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid castItemGuid, uint32 castItemId, int32 castItemLevel);
|
||||
|
||||
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
|
||||
|
||||
|
||||
@@ -500,7 +500,7 @@ SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto, Unit const* cast
|
||||
memset(EffectBasePoints, 0, sizeof(EffectBasePoints));
|
||||
for (SpellEffectInfo const* effect : effects)
|
||||
if (effect)
|
||||
EffectBasePoints[effect->EffectIndex] = effect->CalcBaseValue(caster, nullptr, -1);
|
||||
EffectBasePoints[effect->EffectIndex] = effect->CalcBaseValue(caster, nullptr, 0, -1);
|
||||
|
||||
CustomBasePointsMask = 0;
|
||||
MaxAffectedTargets = proto->MaxAffectedTargets;
|
||||
@@ -2602,13 +2602,13 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask)
|
||||
if (auraSpellEffect)
|
||||
basePoints[auraSpellEffect->EffectIndex] = (m_spellValue->CustomBasePointsMask & (1 << auraSpellEffect->EffectIndex)) ?
|
||||
m_spellValue->EffectBasePoints[auraSpellEffect->EffectIndex] :
|
||||
auraSpellEffect->CalcBaseValue(m_originalCaster, unit, m_castItemLevel);
|
||||
auraSpellEffect->CalcBaseValue(m_originalCaster, unit, m_castItemEntry, m_castItemLevel);
|
||||
|
||||
bool refresh = false;
|
||||
bool const resetPeriodicTimer = !(_triggeredCastFlags & TRIGGERED_DONT_RESET_PERIODIC_TIMER);
|
||||
m_spellAura = Aura::TryRefreshStackOrCreate(m_spellInfo, m_castId, effectMask, unit,
|
||||
m_originalCaster, basePoints,
|
||||
m_CastItem, ObjectGuid::Empty, &refresh, resetPeriodicTimer, ObjectGuid::Empty, m_castItemLevel);
|
||||
m_CastItem, ObjectGuid::Empty, &refresh, resetPeriodicTimer, ObjectGuid::Empty, m_castItemEntry, m_castItemLevel);
|
||||
if (m_spellAura)
|
||||
{
|
||||
// Set aura stack amount to desired value
|
||||
@@ -6046,7 +6046,7 @@ SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules()
|
||||
int32 Spell::CalculateDamage(uint8 i, Unit const* target, float* var /*= nullptr*/) const
|
||||
{
|
||||
bool needRecalculateBasePoints = !(m_spellValue->CustomBasePointsMask & (1 << i));
|
||||
return m_caster->CalculateSpellDamage(target, m_spellInfo, i, needRecalculateBasePoints ? nullptr : &m_spellValue->EffectBasePoints[i], var, m_castItemLevel);
|
||||
return m_caster->CalculateSpellDamage(target, m_spellInfo, i, needRecalculateBasePoints ? nullptr : &m_spellValue->EffectBasePoints[i], var, m_castItemEntry, m_castItemLevel);
|
||||
}
|
||||
|
||||
bool Spell::CanAutoCast(Unit* target)
|
||||
|
||||
@@ -1510,7 +1510,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
if (Aura* aura = Aura::TryCreate(m_spellInfo, m_castId, MAX_EFFECT_MASK, dynObj, caster, &m_spellValue->EffectBasePoints[0], nullptr, ObjectGuid::Empty, ObjectGuid::Empty, m_castItemLevel))
|
||||
if (Aura* aura = Aura::TryCreate(m_spellInfo, m_castId, MAX_EFFECT_MASK, dynObj, caster, &m_spellValue->EffectBasePoints[0], nullptr, ObjectGuid::Empty, ObjectGuid::Empty, m_castItemEntry, m_castItemLevel))
|
||||
{
|
||||
m_spellAura = aura;
|
||||
m_spellAura->_RegisterForTargets();
|
||||
|
||||
@@ -457,11 +457,11 @@ bool SpellEffectInfo::IsUnitOwnedAuraEffect() const
|
||||
return IsAreaAuraEffect() || Effect == SPELL_EFFECT_APPLY_AURA;
|
||||
}
|
||||
|
||||
int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, int32 itemLevel /*= -1*/) const
|
||||
int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
|
||||
{
|
||||
float basePointsPerLevel = RealPointsPerLevel;
|
||||
// TODO: this needs to be a float, not rounded
|
||||
int32 basePoints = CalcBaseValue(caster, target, itemLevel);
|
||||
int32 basePoints = CalcBaseValue(caster, target, castItemId, itemLevel);
|
||||
float value = bp ? *bp : basePoints;
|
||||
float comboDamage = PointsPerResource;
|
||||
|
||||
@@ -509,7 +509,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
|
||||
return int32(round(value));
|
||||
}
|
||||
|
||||
int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, int32 itemLevel) const
|
||||
int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const
|
||||
{
|
||||
if (Scaling.Coefficient != 0.0f)
|
||||
{
|
||||
@@ -555,10 +555,21 @@ int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, int
|
||||
value = GetSpellScalingColumnForClass(sSpellScalingGameTable.GetRow(level), _spellInfo->Scaling.Class);
|
||||
|
||||
if (_spellInfo->Scaling.Class == -7)
|
||||
{
|
||||
// todo: get inventorytype here
|
||||
if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel))
|
||||
value *= ratingMult->ArmorMultiplier;
|
||||
if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
|
||||
value *= GetIlvlStatMultiplier(ratingMult, InventoryType(itemSparse->InventoryType));
|
||||
|
||||
if (IsAura(SPELL_AURA_MOD_RATING))
|
||||
{
|
||||
if (GtCombatRatingsMultByILvl const* ratingMult = sCombatRatingsMultByILvlGameTable.GetRow(effectiveItemLevel))
|
||||
if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
|
||||
value *= GetIlvlStatMultiplier(ratingMult, InventoryType(itemSparse->InventoryType));
|
||||
}
|
||||
else if (IsAura(SPELL_AURA_MOD_STAT) && MiscValue == STAT_STAMINA)
|
||||
{
|
||||
if (GtStaminaMultByILvl const* staminaMult = sStaminaMultByILvlGameTable.GetRow(effectiveItemLevel))
|
||||
if (ItemSparseEntry const* itemSparse = sItemSparseStore.LookupEntry(itemId))
|
||||
value *= GetIlvlStatMultiplier(staminaMult, InventoryType(itemSparse->InventoryType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,6 +723,7 @@ ExpectedStatType SpellEffectInfo::GetScalingExpectedStat() const
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
|
||||
case SPELL_EFFECT_APPLY_AURA_ON_PET:
|
||||
case SPELL_EFFECT_202:
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY_NONRANDOM:
|
||||
switch (ApplyAuraName)
|
||||
{
|
||||
case SPELL_AURA_PERIODIC_DAMAGE:
|
||||
|
||||
@@ -376,8 +376,8 @@ public:
|
||||
bool IsFarDestTargetEffect() const;
|
||||
bool IsUnitOwnedAuraEffect() const;
|
||||
|
||||
int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr, int32 itemLevel = -1) const;
|
||||
int32 CalcBaseValue(Unit const* caster, Unit const* target, int32 itemLevel) const;
|
||||
int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr, uint32 castItemId = 0, int32 itemLevel = -1) const;
|
||||
int32 CalcBaseValue(Unit const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const;
|
||||
float CalcValueMultiplier(Unit* caster, Spell* spell = NULL) const;
|
||||
float CalcDamageMultiplier(Unit* caster, Spell* spell = NULL) const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user