diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 18 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 4 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 4 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 39 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 20 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 13 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 3 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Spells/SpellInfo.h | 2 |
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; |