diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 760776a88..ebabef2d2 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -61,7 +61,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() "health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels " "FROM characters WHERE guid = ?", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, " + PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, " "base_amount0, base_amount1, base_amount2, maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, specMask FROM character_spell WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, " diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index c477cfc0c..57835f915 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -6904,8 +6904,8 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change) } else { - // Auras activated by use should not be removed on unequip - if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE) + // Auras activated by use should not be removed on unequip (with no charges) + if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE && spellData.SpellCharges <= 0) { continue; } diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 1250c9582..0047e68d1 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -5631,9 +5631,9 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff) { LOG_DEBUG("entities.player.loading", "Loading auras for player %s", GetGUID().ToString().c_str()); - /* 0 1 2 3 4 5 6 7 8 9 10 - QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, - 11 12 13 + /* 0 1 2 3 4 5 6 7 8 9 10 11 + QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, + 12 13 14 maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = '%u'", GetGUID().GetCounter()); */ @@ -5645,19 +5645,20 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff) int32 damage[3]; int32 baseDamage[3]; ObjectGuid caster_guid = ObjectGuid(fields[0].GetUInt64()); - uint32 spellid = fields[1].GetUInt32(); - uint8 effmask = fields[2].GetUInt8(); - uint8 recalculatemask = fields[3].GetUInt8(); - uint8 stackcount = fields[4].GetUInt8(); - damage[0] = fields[5].GetInt32(); - damage[1] = fields[6].GetInt32(); - damage[2] = fields[7].GetInt32(); - baseDamage[0] = fields[8].GetInt32(); - baseDamage[1] = fields[9].GetInt32(); - baseDamage[2] = fields[10].GetInt32(); - int32 maxduration = fields[11].GetInt32(); - int32 remaintime = fields[12].GetInt32(); - uint8 remaincharges = fields[13].GetUInt8(); + ObjectGuid itemGuid = ObjectGuid(fields[1].GetUInt64()); + uint32 spellid = fields[2].GetUInt32(); + uint8 effmask = fields[3].GetUInt8(); + uint8 recalculatemask = fields[4].GetUInt8(); + uint8 stackcount = fields[5].GetUInt8(); + damage[0] = fields[6].GetInt32(); + damage[1] = fields[7].GetInt32(); + damage[2] = fields[8].GetInt32(); + baseDamage[0] = fields[9].GetInt32(); + baseDamage[1] = fields[10].GetInt32(); + baseDamage[2] = fields[11].GetInt32(); + int32 maxduration = fields[12].GetInt32(); + int32 remaintime = fields[13].GetInt32(); + uint8 remaincharges = fields[14].GetUInt8(); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); if (!spellInfo) @@ -5693,7 +5694,7 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff) else remaincharges = 0; - if (Aura* aura = Aura::TryCreate(spellInfo, effmask, this, nullptr, &baseDamage[0], nullptr, caster_guid)) + if (Aura* aura = Aura::TryCreate(spellInfo, effmask, this, nullptr, &baseDamage[0], nullptr, caster_guid, itemGuid)) { if (!aura->CanBeSaved()) { diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index a246b0d19..6c5e2bb9f 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -333,7 +333,7 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMas return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); } -Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/) +Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= nullptr*/, Item* castItem /*= nullptr*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, ObjectGuid itemGUID /*= ObjectGuid::Empty*/) { ASSERT(spellproto); ASSERT(owner); @@ -342,10 +342,10 @@ Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner); if (!effMask) return nullptr; - return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); + return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID, itemGUID); } -Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID) +Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID /*= ObjectGuid::Empty*/) { ASSERT(effMask); ASSERT(spellproto); @@ -375,10 +375,10 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne { 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, itemGUID); break; case TYPEID_DYNAMICOBJECT: - aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); + aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID, itemGUID); break; default: ABORT(); @@ -390,9 +390,9 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne 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, ObjectGuid itemGUID /*= ObjectGuid::Empty*/) : m_spellInfo(spellproto), m_casterGuid(casterGUID ? casterGUID : caster->GetGUID()), - m_castItemGuid(castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_castItemEntry(castItem ? castItem->GetEntry() : 0), m_applyTime(time(nullptr)), + m_castItemGuid(itemGUID ? itemGUID : castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_castItemEntry(castItem ? castItem->GetEntry() : 0), m_applyTime(time(nullptr)), 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) @@ -2590,8 +2590,8 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraAppli } } -UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID) - : Aura(spellproto, owner, caster, castItem, casterGUID) +UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID /*= ObjectGuid::Empty*/) + : Aura(spellproto, owner, caster, castItem, casterGUID, itemGUID) { m_AuraDRGroup = DIMINISHING_NONE; LoadScripts(); @@ -2693,8 +2693,8 @@ void UnitAura::FillTargetMap(std::map& targets, Unit* caster) } } -DynObjAura::DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID) - : Aura(spellproto, owner, caster, castItem, casterGUID) +DynObjAura::DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID /*= ObjectGuid::Empty*/) + : Aura(spellproto, owner, caster, castItem, casterGUID, itemGUID) { LoadScripts(); ASSERT(GetDynobjOwner()); diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 23e336d77..7ff14716f 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -80,9 +80,9 @@ public: static uint8 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner); static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = nullptr, bool periodicReset = false); - static Aura* TryCreate(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty); - static Aura* Create(SpellInfo const* spellproto, uint8 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* TryCreate(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount = nullptr, Item* castItem = nullptr, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemGUID = ObjectGuid::Empty); + static Aura* Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID = ObjectGuid::Empty); + explicit Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID = ObjectGuid::Empty); void _InitEffects(uint8 effMask, Unit* caster, int32* baseAmount); virtual ~Aura(); @@ -256,9 +256,11 @@ private: class UnitAura : public Aura { - friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID); + friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID); + protected: - explicit UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID); + explicit UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID = ObjectGuid::Empty); + public: void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication* aurApp) override; void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication* aurApp) override; @@ -277,9 +279,11 @@ private: class DynObjAura : public Aura { - friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID); + friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID); + protected: - explicit DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID); + explicit DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID, ObjectGuid itemGUID = ObjectGuid::Empty); + public: void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;