aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp6
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp1
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp18
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp11
-rw-r--r--src/server/game/Entities/Unit/Unit.h4
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h4
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp8
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp39
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h20
-rw-r--r--src/server/game/Spells/Spell.cpp13
-rw-r--r--src/server/game/Spells/Spell.h3
-rw-r--r--src/server/game/Spells/SpellEffects.cpp5
-rw-r--r--src/server/game/Spells/SpellInfo.cpp10
-rw-r--r--src/server/game/Spells/SpellInfo.h2
16 files changed, 88 insertions, 60 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 3ecc3975611..7a89d3d217e 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -84,7 +84,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, resettime 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 FROM character_aura 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_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);
@@ -263,8 +263,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC);
// Auras
- PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges) "
- "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ 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_EFFECT, "INSERT INTO character_aura_effect (guid, casterGuid, itemGuid, spell, effectMask, effectIndex, amount, baseAmount) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp
index 00c5ef2404b..8a888715500 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp
@@ -4065,3 +4065,4 @@ uint32 ConversationDynamicUpdateFieldFlags[CONVERSATION_DYNAMIC_END] =
UF_FLAG_PUBLIC, // CONVERSATION_DYNAMIC_FIELD_ACTORS
UF_FLAG_0x100, // CONVERSATION_DYNAMIC_FIELD_LINES
};
+
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index f7c563f3f92..3715d622fcf 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -19,7 +19,7 @@
#ifndef _UPDATEFIELDS_H
#define _UPDATEFIELDS_H
-// Auto generated for version 6, 2, 2, 20444
+// Auto generated for version 6, 2, 3, 20726
enum ObjectFields
{
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 1bad5c699e4..d030b278bce 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -5198,7 +5198,7 @@ bool Player::UpdateCraftSkill(uint32 spellid)
bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator)
{
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateGatherSkill: Player '%s' (%s), SkillID: %u, SkillLevel: %u, RedLevel: %u)",
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateGatherSkill: Player '%s' (%s), SkillID: %u, SkillLevel: %u, RedLevel: %u)",
GetName().c_str(), GetGUID().ToString().c_str(), SkillId, SkillValue, RedLevel);
uint32 gathering_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_GATHERING);
@@ -5472,7 +5472,7 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(id);
if (!skillEntry)
{
- TC_LOG_ERROR("misc", "Player::SetSkill: Skill (SkillID: %u) not found in SkillLineStore for player '%s' (%s)",
+ TC_LOG_ERROR("misc", "Player::SetSkill: Skill (SkillID: %u) not found in SkillLineStore for player '%s' (%s)",
id, GetName().c_str(), GetGUID().ToString().c_str());
return;
}
@@ -11632,7 +11632,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update)
void Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, bool unequip_check)
{
- TC_LOG_DEBUG("entities.player.items", "Player::DestroyItemCount: Player '%s' (%s), Item: %u, Count: %u",
+ TC_LOG_DEBUG("entities.player.items", "Player::DestroyItemCount: Player '%s' (%s), Item: %u, Count: %u",
GetName().c_str(), GetGUID().ToString().c_str(), itemEntry, count);
uint32 remcount = 0;
@@ -12422,7 +12422,7 @@ void Player::AddItemToBuyBackSlot(Item* pItem)
RemoveItemFromBuyBackSlot(slot, true);
TC_LOG_DEBUG("entities.player.items", "Player::AddItemToBuyBackSlot: Player '%s' (%s), Item: %u, Slot: %u",
GetName().c_str(), GetGUID().ToString().c_str(), pItem->GetEntry(), slot);
-
+
m_items[slot] = pItem;
time_t base = time(nullptr);
uint32 etime = uint32(base - m_logintime + (30 * 3600));
@@ -17102,8 +17102,8 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
}
/*
- 0 1 2 3 4 5 6 7 8
- SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = ?
+ 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 = ?
*/
if (auraResult)
{
@@ -17118,6 +17118,7 @@ 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();
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(key.SpellId);
if (!spellInfo)
@@ -17148,7 +17149,7 @@ void Player::_LoadAuras(PreparedQueryResult auraResult, PreparedQueryResult effe
remainCharges = 0;
AuraLoadEffectInfo& info = effectInfo[key];
- if (Aura* aura = Aura::TryCreate(spellInfo, key.EffectMask, this, nullptr, info.BaseAmounts.data(), nullptr, casterGuid))
+ if (Aura* aura = Aura::TryCreate(spellInfo, key.EffectMask, this, nullptr, info.BaseAmounts.data(), nullptr, casterGuid, castItemLevel))
{
if (!aura->CanBeSaved())
{
@@ -18861,7 +18862,8 @@ void Player::_SaveAuras(SQLTransaction& trans)
stmt->setUInt8(index++, aura->GetStackAmount());
stmt->setInt32(index++, aura->GetMaxDuration());
stmt->setInt32(index++, aura->GetDuration());
- stmt->setUInt8(index, aura->GetCharges());
+ stmt->setUInt8(index++, aura->GetCharges());
+ stmt->setInt32(index++, aura->GetCastItemLevel());
trans->Append(stmt);
for (AuraEffect const* effect : aura->GetAuraEffects())
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index bd928270f14..2185370ee07 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3017,7 +3017,7 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
-Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/)
+Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/, int32 castItemLevel /*= -1*/)
{
ASSERT(!casterGUID.IsEmpty() || caster);
@@ -3031,7 +3031,10 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
// check if cast item changed
ObjectGuid castItemGUID;
if (castItem)
+ {
castItemGUID = castItem->GetGUID();
+ castItemLevel = castItem->GetItemLevel(castItem->GetOwner());
+ }
// find current aura from spell and change it's stackamount, or refresh it's duration
if (Aura* foundAura = GetOwnedAura(newAura->Id, casterGUID, (newAura->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC)) ? castItemGUID : ObjectGuid::Empty, 0))
@@ -3067,6 +3070,8 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint3
{
ObjectGuid* oldGUID = const_cast<ObjectGuid*>(&foundAura->m_castItemGuid);
*oldGUID = castItemGUID;
+ int32* oldItemLevel = const_cast<int32*>(&foundAura->m_castItemLevel);
+ *oldItemLevel = castItemLevel;
}
// try to increase stack amount
@@ -10920,13 +10925,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*/) const
+int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints /*= nullptr*/, float* variance /*= nullptr*/, 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) : 0;
+ return effect ? effect->CalcValue(this, basePoints, target, variance, itemLevel) : 0;
}
int32 Unit::CalcSpellDuration(SpellInfo const* spellProto)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 1a799163256..606e00d4474 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1753,7 +1753,7 @@ class 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 = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
+ Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, int32 castItemLevel = -1);
void _AddAura(UnitAura* aura, Unit* caster);
AuraApplication * _CreateAuraApplication(Aura* aura, uint32 effMask);
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
@@ -2078,7 +2078,7 @@ class Unit : public WorldObject
void SetSpeed(UnitMoveType mtype, float rate, bool forced = false);
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) const;
+ int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = nullptr, float* variance = nullptr, 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);
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index fa53e28f749..2cfdbcd4918 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -751,12 +751,12 @@ enum SpellAttr11
{
SPELL_ATTR11_UNK0 = 0x00000001, // 0
SPELL_ATTR11_UNK1 = 0x00000002, // 1
- SPELL_ATTR11_UNK2 = 0x00000004, // 2
+ SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL = 0x00000004, // 2
SPELL_ATTR11_UNK3 = 0x00000008, // 3
SPELL_ATTR11_UNK4 = 0x00000010, // 4
SPELL_ATTR11_UNK5 = 0x00000020, // 5
SPELL_ATTR11_UNK6 = 0x00000040, // 6
- SPELL_ATTR11_UNK7 = 0x00000080, // 7
+ SPELL_ATTR11_NO_RANK = 0x00000080, // 7 Spell_C_GetSpellRank returns 0 instead of 5 * std::min(SpellLevels->MaxLevel, caster->Level)
SPELL_ATTR11_UNK8 = 0x00000100, // 8
SPELL_ATTR11_UNK9 = 0x00000200, // 9
SPELL_ATTR11_UNK10 = 0x00000400, // 10
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 077371280f9..19b7f320ff7 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -592,7 +592,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());
+ amount = GetSpellEffectInfo()->CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit(), nullptr, GetBase()->GetCastItemLevel());
else if (caster && caster->GetTypeId() == TYPEID_PLAYER)
amount = int32(caster->GetFloatValue(PLAYER_MASTERY) * GetSpellEffectInfo()->BonusCoefficient);
@@ -617,11 +617,13 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
if (pEnchant)
{
for (int t = 0; t < MAX_ITEM_ENCHANTMENT_EFFECTS; t++)
+ {
if (pEnchant->EffectSpellID[t] == m_spellInfo->Id)
{
- amount = uint32((item_rand_suffix->AllocationPct[k] * castItem->GetItemSuffixFactor()) / 10000);
- break;
+ amount = uint32((item_rand_suffix->AllocationPct[k] * castItem->GetItemSuffixFactor()) / 10000);
+ break;
}
+ }
}
if (amount)
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 91cf75dbe87..952e72b23bb 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -30,7 +30,7 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uin
class 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);
+ friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
friend Aura::~Aura();
public:
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index dd5519dc7b1..6fdcfd5b722 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -151,7 +151,7 @@ void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
_flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
}
- if (GetBase()->GetSpellInfo()->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT ||
+ if (GetBase()->GetSpellInfo()->HasAttribute(SPELL_ATTR8_AURA_SEND_AMOUNT) ||
GetBase()->HasEffectType(SPELL_AURA_MOD_MAX_CHARGES) ||
GetBase()->HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MOD) ||
GetBase()->HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER))
@@ -208,7 +208,10 @@ void AuraApplication::BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo
auraData.Flags |= AFLAG_DURATION;
auraData.ActiveFlags = GetEffectMask();
- auraData.CastLevel = aura->GetCasterLevel();
+ if (!aura->GetSpellInfo()->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL))
+ auraData.CastLevel = aura->GetCasterLevel();
+ else
+ auraData.CastLevel = uint16(aura->GetCastItemLevel());
// send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges
// stack amount has priority over charges (checked on retail with spell 50262)
@@ -276,7 +279,7 @@ uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibl
return effMask & avalibleEffectMask;
}
-Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/)
+Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/, int32 castItemLevel /*= -1*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -288,7 +291,7 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMa
if (!effMask)
return NULL;
- if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID))
+ if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID, castItemLevel))
{
// we've here aura, which script triggered removal after modding stack amount
// check the state here, so we won't create new Aura object
@@ -300,22 +303,22 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMa
return foundAura;
}
else
- return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
+ return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemLevel);
}
-Aura* Aura::TryCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
+Aura* Aura::TryCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, int32 castItemLevel /*= -1*/)
{
ASSERT(spellproto);
ASSERT(owner);
ASSERT(caster || !casterGUID.IsEmpty());
ASSERT(tryEffMask <= MAX_EFFECT_MASK);
- uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
+ uint32 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
if (!effMask)
return NULL;
- return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
+ return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemLevel);
}
-Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
+Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel)
{
ASSERT(effMask);
ASSERT(spellproto);
@@ -345,10 +348,10 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* own
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
- aura = new UnitAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
+ aura = new UnitAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemLevel);
break;
case TYPEID_DYNAMICOBJECT:
- aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
+ aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID, castItemLevel);
break;
default:
ABORT();
@@ -360,10 +363,10 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* own
return aura;
}
-Aura::Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID) :
+Aura::Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel) :
m_spellInfo(spellproto), m_casterGuid(!casterGUID.IsEmpty() ? casterGUID : caster->GetGUID()),
-m_castItemGuid(castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_applyTime(time(NULL)),
-m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0),
+m_castItemGuid(castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_castItemLevel(castItemLevel),
+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)
{
@@ -2324,8 +2327,8 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraAppli
}
}
-UnitAura::UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
- : Aura(spellproto, owner, caster, castItem, casterGUID)
+UnitAura::UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel)
+ : Aura(spellproto, owner, caster, castItem, casterGUID, castItemLevel)
{
m_AuraDRGroup = DIMINISHING_NONE;
LoadScripts();
@@ -2427,8 +2430,8 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster)
}
}
-DynObjAura::DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
- : Aura(spellproto, owner, caster, castItem, casterGUID)
+DynObjAura::DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel)
+ : Aura(spellproto, owner, caster, castItem, casterGUID, castItemLevel)
{
LoadScripts();
ASSERT(GetDynobjOwner());
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 0d06e1a962c..a074346a4a2 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -115,15 +115,15 @@ struct AuraLoadEffectInfo
class Aura
{
- friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
public:
typedef std::map<ObjectGuid, AuraApplication*> ApplicationMap;
static uint32 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner);
- static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL);
- static Aura* TryCreate(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
- static Aura* Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
- explicit Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID);
+ static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL, int32 castItemLevel = -1);
+ static Aura* TryCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, int32 castItemLevel = -1);
+ static Aura* Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
+ Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
void _InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount);
virtual ~Aura();
@@ -131,6 +131,7 @@ class Aura
uint32 GetId() const{ return GetSpellInfo()->Id; }
ObjectGuid GetCastItemGUID() const { return m_castItemGuid; }
+ int32 GetCastItemLevel() const { return m_castItemLevel; }
ObjectGuid GetCasterGUID() const { return m_casterGuid; }
Unit* GetCaster() const;
WorldObject* GetOwner() const { return m_owner; }
@@ -295,6 +296,7 @@ class Aura
SpellInfo const* const m_spellInfo;
ObjectGuid const m_casterGuid;
ObjectGuid const m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
+ int32 m_castItemLevel;
time_t const m_applyTime;
WorldObject* const m_owner;
@@ -326,9 +328,9 @@ class Aura
class UnitAura : public Aura
{
- friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
public:
- explicit UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
@@ -347,9 +349,9 @@ class UnitAura : public Aura
class DynObjAura : public Aura
{
- friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
public:
- explicit DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID, int32 castItemLevel);
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index d5b6baaf056..69bb1d19b73 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -570,6 +570,7 @@ m_spellValue(new SpellValue(caster->GetMap()->GetDifficultyID(), m_spellInfo)),
m_CastItem = NULL;
m_castItemGUID.Clear();
m_castItemEntry = 0;
+ m_castItemLevel = -1;
m_castFlagsEx = 0;
unitTarget = NULL;
@@ -2604,7 +2605,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
{
bool refresh = false;
m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit,
- m_originalCaster, (aurSpellInfo == m_spellInfo) ? m_spellValue->EffectBasePoints : basePoints, m_CastItem, ObjectGuid::Empty, &refresh);
+ m_originalCaster, (aurSpellInfo == m_spellInfo) ? m_spellValue->EffectBasePoints : basePoints,
+ m_CastItem, ObjectGuid::Empty, &refresh, m_castItemLevel);
if (m_spellAura)
{
// Set aura stack amount to desired value
@@ -2859,6 +2861,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
{
m_castItemGUID = m_CastItem->GetGUID();
m_castItemEntry = m_CastItem->GetEntry();
+ m_castItemLevel = int32(m_CastItem->GetItemLevel(m_CastItem->GetOwner()));
}
InitExplicitTargets(*targets);
@@ -2887,7 +2890,10 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
m_spellState = SPELL_STATE_PREPARING;
if (triggeredByAura)
- m_triggeredByAuraSpell = triggeredByAura->GetSpellInfo();
+ {
+ m_triggeredByAuraSpell = triggeredByAura->GetSpellInfo();
+ m_castItemLevel = triggeredByAura->GetBase()->GetCastItemLevel();
+ }
// create and add update event for this spell
SpellEvent* Event = new SpellEvent(this);
@@ -6462,6 +6468,7 @@ bool Spell::UpdatePointers()
if (!m_castItemGUID.IsEmpty() && m_caster->GetTypeId() == TYPEID_PLAYER)
{
m_CastItem = m_caster->ToPlayer()->GetItemByGuid(m_castItemGUID);
+ m_castItemLevel = -1;
// cast item not found, somehow the item is no longer where we expected
if (!m_CastItem)
return false;
@@ -6469,6 +6476,8 @@ bool Spell::UpdatePointers()
// check if the item is really the same, in case it has been wrapped for example
if (m_castItemEntry != m_CastItem->GetEntry())
return false;
+
+ m_castItemLevel = int32(m_CastItem->GetItemLevel(m_caster->ToPlayer()));
}
m_targets.Update(m_caster);
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 96136374dd4..1ae5c75a66d 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -501,7 +501,7 @@ class Spell
SpellCastResult CheckCasterAuras() const;
SpellCastResult CheckArenaAndRatedBattlegroundCastRules();
- int32 CalculateDamage(uint8 i, Unit const* target, float* var = nullptr) const { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i], var); }
+ int32 CalculateDamage(uint8 i, Unit const* target, float* var = nullptr) const { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i], var, m_castItemLevel); }
bool HaveTargetsForEffect(uint8 effect) const;
void Delayed();
@@ -548,6 +548,7 @@ class Spell
Item* m_CastItem;
ObjectGuid m_castItemGUID;
uint32 m_castItemEntry;
+ int32 m_castItemLevel;
uint8 m_cast_count;
uint32 m_castFlagsEx;
union
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 3431eb71898..fca953aa179 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1625,7 +1625,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
return;
}
- if (Aura* aura = Aura::TryCreate(m_spellInfo, MAX_EFFECT_MASK, dynObj, caster, &m_spellValue->EffectBasePoints[0]))
+ if (Aura* aura = Aura::TryCreate(m_spellInfo, MAX_EFFECT_MASK, dynObj, caster, &m_spellValue->EffectBasePoints[0], nullptr, ObjectGuid::Empty, m_castItemLevel))
{
m_spellAura = aura;
m_spellAura->_RegisterForTargets();
@@ -2000,6 +2000,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex /*effIndex*/)
m_CastItem = NULL;
m_castItemGUID.Clear();
m_castItemEntry = 0;
+ m_castItemLevel = -1;
player->StoreItem(dest, pNewItem, true);
return;
@@ -2020,6 +2021,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex /*effIndex*/)
m_CastItem = NULL;
m_castItemGUID.Clear();
m_castItemEntry = 0;
+ m_castItemLevel = -1;
player->BankItem(dest, pNewItem, true);
return;
@@ -2044,6 +2046,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex /*effIndex*/)
m_CastItem = NULL;
m_castItemGUID.Clear();
m_castItemEntry = 0;
+ m_castItemLevel = -1;
player->EquipItem(dest, pNewItem, true);
player->AutoUnequipOffhandIfNeed();
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index e91dadca57e..ee5f1ba471f 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -452,7 +452,7 @@ 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*/) const
+int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, int32 itemLevel /*= -1*/) const
{
float basePointsPerLevel = RealPointsPerLevel;
int32 basePoints = bp ? *bp : BasePoints;
@@ -467,7 +467,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
else if (caster)
level = caster->getLevel();
- if (!_spellInfo->HasAttribute(SPELL_ATTR11_UNK2) && _spellInfo->HasAttribute(SPELL_ATTR10_UNK12))
+ if (!_spellInfo->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL) && _spellInfo->HasAttribute(SPELL_ATTR10_UNK12))
level = _spellInfo->BaseLevel;
if (_spellInfo->Scaling.MaxScalingLevel && _spellInfo->Scaling.MaxScalingLevel > level)
@@ -481,13 +481,13 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
if (!_spellInfo->Scaling.ScalesFromItemLevel)
{
- if (!_spellInfo->HasAttribute(SPELL_ATTR11_UNK2))
+ if (!_spellInfo->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL))
{
if (GtSpellScalingEntry const* gtScaling = sGtSpellScalingStore.EvaluateTable(level - 1, (_spellInfo->Scaling.Class > 0 ? _spellInfo->Scaling.Class : ((MAX_CLASSES - 1 /*last class*/) - _spellInfo->Scaling.Class)) - 1))
value = gtScaling->value;
}
else
- value = GetRandomPropertyPoints(level, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
+ value = GetRandomPropertyPoints(itemLevel != -1 ? uint32(itemLevel) : 1u, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
}
else
value = GetRandomPropertyPoints(_spellInfo->Scaling.ScalesFromItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
@@ -496,7 +496,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
value *= float(_spellInfo->Scaling.CastTimeMin + (level - 1) * (_spellInfo->Scaling.CastTimeMax - _spellInfo->Scaling.CastTimeMin) / (_spellInfo->Scaling.CastTimeMaxLevel - 1)) / float(_spellInfo->Scaling.CastTimeMax);
if (level < _spellInfo->Scaling.NerfMaxLevel)
- value *= ((((1.0 - _spellInfo->Scaling.NerfFactor) * (level - 1)) / (_spellInfo->Scaling.NerfMaxLevel - 1)) + _spellInfo->Scaling.NerfFactor);
+ value *= ((((1.0f - _spellInfo->Scaling.NerfFactor) * (level - 1)) / (_spellInfo->Scaling.NerfMaxLevel - 1)) + _spellInfo->Scaling.NerfFactor);
}
value *= Scaling.Coefficient;
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 6a56b876ccc..bc7a693d770 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -288,7 +288,7 @@ public:
bool IsFarDestTargetEffect() const;
bool IsUnitOwnedAuraEffect() const;
- int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr) const;
+ int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr, int32 itemLevel = -1) const;
int32 CalcBaseValue(int32 value) const;
float CalcValueMultiplier(Unit* caster, Spell* spell = NULL) const;
float CalcDamageMultiplier(Unit* caster, Spell* spell = NULL) const;