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

View File

@@ -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, "

View File

@@ -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;
}

View File

@@ -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())
{

View File

@@ -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<Unit*, uint8>& 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());

View File

@@ -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;