fix(Core/Items): items with charges should not remove on item unequip its … (#7064)

- Closes #5716
This commit is contained in:
UltraNix
2021-07-25 03:36:40 +02:00
committed by GitHub
parent 592b9b069a
commit 270f7bf506
5 changed files with 43 additions and 38 deletions
@@ -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 " "health, power1, power2, power3, power4, power5, power6, power7, instance_id, talentGroupsCount, activeTalentGroup, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels "
"FROM characters WHERE guid = ?", CONNECTION_ASYNC); "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); "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_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, " PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, "
+2 -2
View File
@@ -6904,8 +6904,8 @@ void Player::ApplyItemEquipSpell(Item* item, bool apply, bool form_change)
} }
else else
{ {
// Auras activated by use should not be removed on unequip // Auras activated by use should not be removed on unequip (with no charges)
if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE) if (spellData.SpellTrigger == ITEM_SPELLTRIGGER_ON_USE && spellData.SpellCharges <= 0)
{ {
continue; continue;
} }
@@ -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()); 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 /* 0 1 2 3 4 5 6 7 8 9 10 11
QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2,
11 12 13 12 13 14
maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = '%u'", GetGUID().GetCounter()); 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 damage[3];
int32 baseDamage[3]; int32 baseDamage[3];
ObjectGuid caster_guid = ObjectGuid(fields[0].GetUInt64()); ObjectGuid caster_guid = ObjectGuid(fields[0].GetUInt64());
uint32 spellid = fields[1].GetUInt32(); ObjectGuid itemGuid = ObjectGuid(fields[1].GetUInt64());
uint8 effmask = fields[2].GetUInt8(); uint32 spellid = fields[2].GetUInt32();
uint8 recalculatemask = fields[3].GetUInt8(); uint8 effmask = fields[3].GetUInt8();
uint8 stackcount = fields[4].GetUInt8(); uint8 recalculatemask = fields[4].GetUInt8();
damage[0] = fields[5].GetInt32(); uint8 stackcount = fields[5].GetUInt8();
damage[1] = fields[6].GetInt32(); damage[0] = fields[6].GetInt32();
damage[2] = fields[7].GetInt32(); damage[1] = fields[7].GetInt32();
baseDamage[0] = fields[8].GetInt32(); damage[2] = fields[8].GetInt32();
baseDamage[1] = fields[9].GetInt32(); baseDamage[0] = fields[9].GetInt32();
baseDamage[2] = fields[10].GetInt32(); baseDamage[1] = fields[10].GetInt32();
int32 maxduration = fields[11].GetInt32(); baseDamage[2] = fields[11].GetInt32();
int32 remaintime = fields[12].GetInt32(); int32 maxduration = fields[12].GetInt32();
uint8 remaincharges = fields[13].GetUInt8(); int32 remaintime = fields[13].GetInt32();
uint8 remaincharges = fields[14].GetUInt8();
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
if (!spellInfo) if (!spellInfo)
@@ -5693,7 +5694,7 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
else else
remaincharges = 0; 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()) if (!aura->CanBeSaved())
{ {
+11 -11
View File
@@ -333,7 +333,7 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMas
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); 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(spellproto);
ASSERT(owner); ASSERT(owner);
@@ -342,10 +342,10 @@ Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject
uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner); uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
if (!effMask) if (!effMask)
return nullptr; 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(effMask);
ASSERT(spellproto); ASSERT(spellproto);
@@ -375,10 +375,10 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne
{ {
case TYPEID_UNIT: case TYPEID_UNIT:
case TYPEID_PLAYER: 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; break;
case TYPEID_DYNAMICOBJECT: 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; break;
default: default:
ABORT(); ABORT();
@@ -390,9 +390,9 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne
return aura; 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_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_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0),
m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1), m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1),
m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false) 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) 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) : Aura(spellproto, owner, caster, castItem, casterGUID, itemGUID)
{ {
m_AuraDRGroup = DIMINISHING_NONE; m_AuraDRGroup = DIMINISHING_NONE;
LoadScripts(); LoadScripts();
@@ -2693,8 +2693,8 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster)
} }
} }
DynObjAura::DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid 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) : Aura(spellproto, owner, caster, castItem, casterGUID, itemGUID)
{ {
LoadScripts(); LoadScripts();
ASSERT(GetDynobjOwner()); ASSERT(GetDynobjOwner());
+11 -7
View File
@@ -80,9 +80,9 @@ public:
static uint8 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner); 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* 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* 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); 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); 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); void _InitEffects(uint8 effMask, Unit* caster, int32* baseAmount);
virtual ~Aura(); virtual ~Aura();
@@ -256,9 +256,11 @@ private:
class UnitAura : public Aura 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: 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: public:
void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication* aurApp) override; void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication* aurApp) override;
void _UnapplyForTarget(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 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: 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: public:
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override; void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;