Core/Auras: Fixed saving auras with same spell id but different item source

This commit is contained in:
Shauren authored and Ovahlord committed 2022-09-12 09:15:21 +02:00
1 parent b4b8fffa22
commit dc8bf301bb
8 files changed
+36 -29

No files matched your search

+3 -1
View File
@@ -640,6 +640,7 @@ DROP TABLE IF EXISTS `character_aura`;
CREATE TABLE `character_aura` ( CREATE TABLE `character_aura` (
`guid` int unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier', `guid` int unsigned NOT NULL DEFAULT '0' COMMENT 'Global Unique Identifier',
`casterGuid` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier', `casterGuid` bigint unsigned NOT NULL DEFAULT '0' COMMENT 'Full Global Unique Identifier',
`itemGuid` bigint unsigned NOT NULL DEFAULT '0',
`spell` int unsigned NOT NULL DEFAULT '0', `spell` int unsigned NOT NULL DEFAULT '0',
`effectMask` tinyint unsigned NOT NULL DEFAULT '0', `effectMask` tinyint unsigned NOT NULL DEFAULT '0',
`recalculateMask` tinyint unsigned NOT NULL DEFAULT '0', `recalculateMask` tinyint unsigned NOT NULL DEFAULT '0',
@@ -655,7 +656,7 @@ CREATE TABLE `character_aura` (
`remainCharges` tinyint unsigned NOT NULL DEFAULT '0', `remainCharges` tinyint unsigned NOT NULL DEFAULT '0',
`critChance` float NOT NULL DEFAULT '0', `critChance` float NOT NULL DEFAULT '0',
`applyResilience` tinyint(3) NOT NULL DEFAULT '0', `applyResilience` tinyint(3) NOT NULL DEFAULT '0',
PRIMARY KEY (`guid`,`casterGuid`,`spell`,`effectMask`) PRIMARY KEY (`guid`,`casterGuid`,`itemGuid`,`spell`,`effectMask`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Player System'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Player System';
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
@@ -3056,6 +3057,7 @@ INSERT INTO `updates` VALUES
('2022_01_01_00_characters.sql','336E62A8850A3E78A1D0BD3E81FFD5769184BDF8','ARCHIVED','2022-01-01 11:04:58',0), ('2022_01_01_00_characters.sql','336E62A8850A3E78A1D0BD3E81FFD5769184BDF8','ARCHIVED','2022-01-01 11:04:58',0),
('2022_01_09_00_characters.sql','1420602F3A6F5AAE1CB59045C47E33A3CE8809A4','ARCHIVED','2022-01-09 00:12:22',0), ('2022_01_09_00_characters.sql','1420602F3A6F5AAE1CB59045C47E33A3CE8809A4','ARCHIVED','2022-01-09 00:12:22',0),
('2022_09_01_00_characters.sql','E3C0DA9995BA71ED5A267294470CD03DC51862DD','RELEASED','2022-09-01 14:51:33',0), ('2022_09_01_00_characters.sql','E3C0DA9995BA71ED5A267294470CD03DC51862DD','RELEASED','2022-09-01 14:51:33',0),
('2022_09_03_00_characters.sql','50429D68E6EBD1149CDA14A9EA642BC06A1FAE3D','RELEASED','2022-09-03 11:03:06',0),
('custom_2017_12_21_00_characters.sql','2D5B3830D47E4BC717EC468E18E477A32B9A21BF','ARCHIVED','2019-11-06 00:17:44',0), ('custom_2017_12_21_00_characters.sql','2D5B3830D47E4BC717EC468E18E477A32B9A21BF','ARCHIVED','2019-11-06 00:17:44',0),
('custom_2018_01_07_00_characters.sql','7437B6243B3CB6FA08F6A37BB39E38930B0DCFD3','ARCHIVED','2019-11-06 00:17:44',0), ('custom_2018_01_07_00_characters.sql','7437B6243B3CB6FA08F6A37BB39E38930B0DCFD3','ARCHIVED','2019-11-06 00:17:44',0),
('custom_2018_03_18_00_characters.sql','8D1E81A7272F643687C67443C270D17255A9AA84','ARCHIVED','2019-11-06 00:17:44',0), ('custom_2018_03_18_00_characters.sql','8D1E81A7272F643687C67443C270D17255A9AA84','ARCHIVED','2019-11-06 00:17:44',0),
@@ -0,0 +1,4 @@
ALTER TABLE `character_aura`
DROP PRIMARY KEY,
ADD `itemGuid` bigint(20) unsigned NOT NULL DEFAULT '0' AFTER `casterGuid`,
ADD PRIMARY KEY(`guid`,`casterGuid`,`itemGuid`,`spell`,`effectMask`);
@@ -70,7 +70,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, extendState, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_CHARACTER_INSTANCE, "SELECT id, permanent, map, difficulty, extendState, resettime FROM character_instance LEFT JOIN instance ON instance = id 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, critChance, applyResilience FROM character_aura WHERE guid = ?", CONNECTION_ASYNC); "base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges, critChance, applyResilience FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_BOTH); PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_BOTH);
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, "
@@ -273,8 +273,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC); PrepareStatement(CHAR_DEL_EQUIP_SET, "DELETE FROM character_equipmentsets WHERE setguid=?", CONNECTION_ASYNC);
// Auras // Auras
PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges, critChance, applyResilience) " PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, casterGuid, itemGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges, critChance, applyResilience) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
// Currency // Currency
PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT Currency, Quantity, WeeklyQuantity, TrackedQuantity, Flags FROM character_currency WHERE CharacterGuid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT Currency, Quantity, WeeklyQuantity, TrackedQuantity, Flags FROM character_currency WHERE CharacterGuid = ?", CONNECTION_ASYNC);
+21 -18
View File
@@ -17955,9 +17955,9 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
{ {
TC_LOG_DEBUG("entities.player.loading", "Player::_LoadAuras: Loading auras for %s", GetGUID().ToString().c_str()); TC_LOG_DEBUG("entities.player.loading", "Player::_LoadAuras: Loading auras for %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 14 15 12 13 14 15 16
maxDuration, remainTime, remainCharges, critChance, applyResilience FROM character_aura WHERE guid = '%u'", GetGUID().GetCounter()); maxDuration, remainTime, remainCharges, critChance, applyResilience FROM character_aura WHERE guid = '%u'", GetGUID().GetCounter());
*/ */
@@ -17969,21 +17969,22 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
int32 damage[3]; int32 damage[3];
int32 baseDamage[3]; int32 baseDamage[3];
ObjectGuid caster_guid(fields[0].GetUInt64()); ObjectGuid caster_guid(fields[0].GetUInt64());
uint32 spellid = fields[1].GetUInt32(); ObjectGuid itemGuid(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();
float critChance = fields[14].GetFloat(); uint8 remaincharges = fields[14].GetUInt8();
bool applyResilience = fields[15].GetBool(); float critChance = fields[15].GetFloat();
bool applyResilience = fields[16].GetBool();
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
if (!spellInfo) if (!spellInfo)
@@ -18016,6 +18017,7 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
AuraCreateInfo createInfo(spellInfo, effmask, this); AuraCreateInfo createInfo(spellInfo, effmask, this);
createInfo createInfo
.SetCasterGUID(caster_guid) .SetCasterGUID(caster_guid)
.SetCastItemGUID(itemGuid)
.SetBaseAmount(baseDamage); .SetBaseAmount(baseDamage);
if (Aura* aura = Aura::TryCreate(createInfo)) if (Aura* aura = Aura::TryCreate(createInfo))
@@ -19934,6 +19936,7 @@ void Player::_SaveAuras(CharacterDatabaseTransaction& trans)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA);
stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt32(index++, GetGUID().GetCounter());
stmt->setUInt64(index++, itr->second->GetCasterGUID().GetRawValue()); stmt->setUInt64(index++, itr->second->GetCasterGUID().GetRawValue());
stmt->setUInt64(index++, itr->second->GetCastItemGUID().GetRawValue());
stmt->setUInt32(index++, itr->second->GetId()); stmt->setUInt32(index++, itr->second->GetId());
stmt->setUInt8(index++, effMask); stmt->setUInt8(index++, effMask);
stmt->setUInt8(index++, recalculateMask); stmt->setUInt8(index++, recalculateMask);
+1 -3
View File
@@ -3041,9 +3041,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo)
if (!createInfo.GetSpellInfo()->IsMultiSlotAura()) if (!createInfo.GetSpellInfo()->IsMultiSlotAura())
{ {
// check if cast item changed // check if cast item changed
ObjectGuid castItemGUID; ObjectGuid castItemGUID = createInfo.CastItemGUID;
if (createInfo.CastItem)
castItemGUID = createInfo.CastItem->GetGUID();
// find current aura from spell and change it's stackamount, or refresh it's duration // find current aura from spell and change it's stackamount, or refresh it's duration
if (Aura* foundAura = GetOwnedAura(createInfo.GetSpellInfo()->Id, createInfo.CasterGUID, createInfo.GetSpellInfo()->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty)) if (Aura* foundAura = GetOwnedAura(createInfo.GetSpellInfo()->Id, createInfo.CasterGUID, createInfo.GetSpellInfo()->HasAttribute(SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : ObjectGuid::Empty))
@@ -508,7 +508,7 @@ struct TC_GAME_API AuraCreateInfo
AuraCreateInfo& SetCasterGUID(ObjectGuid const& guid) { CasterGUID = guid; return *this; } AuraCreateInfo& SetCasterGUID(ObjectGuid const& guid) { CasterGUID = guid; return *this; }
AuraCreateInfo& SetCaster(Unit* caster) { Caster = caster; return *this; } AuraCreateInfo& SetCaster(Unit* caster) { Caster = caster; return *this; }
AuraCreateInfo& SetBaseAmount(int32 const* bp) { BaseAmount = bp; return *this; } AuraCreateInfo& SetBaseAmount(int32 const* bp) { BaseAmount = bp; return *this; }
AuraCreateInfo& SetCastItem(Item* item) { CastItem = item; return *this; } AuraCreateInfo& SetCastItemGUID(ObjectGuid const& guid) { CastItemGUID = guid; return *this; }
AuraCreateInfo& SetOwnerEffectMask(uint8 effMask) { _targetEffectMask = effMask; return *this; } AuraCreateInfo& SetOwnerEffectMask(uint8 effMask) { _targetEffectMask = effMask; return *this; }
SpellInfo const* GetSpellInfo() const { return _spellInfo; } SpellInfo const* GetSpellInfo() const { return _spellInfo; }
@@ -517,7 +517,7 @@ struct TC_GAME_API AuraCreateInfo
ObjectGuid CasterGUID; ObjectGuid CasterGUID;
Unit* Caster = nullptr; Unit* Caster = nullptr;
int32 const* BaseAmount = nullptr; int32 const* BaseAmount = nullptr;
Item* CastItem = nullptr; ObjectGuid CastItemGUID;
bool* IsRefresh = nullptr; bool* IsRefresh = nullptr;
private: private:
+1 -1
View File
@@ -432,7 +432,7 @@ Aura* Aura::Create(AuraCreateInfo& createInfo)
Aura::Aura(AuraCreateInfo const& createInfo) : Aura::Aura(AuraCreateInfo const& createInfo) :
m_spellInfo(createInfo._spellInfo), m_casterGuid(createInfo.CasterGUID), m_spellInfo(createInfo._spellInfo), m_casterGuid(createInfo.CasterGUID),
m_castItemGuid(createInfo.CastItem ? createInfo.CastItem->GetGUID() : ObjectGuid::Empty), m_applyTime(GameTime::GetGameTime()), m_castItemGuid(createInfo.CastItemGUID), m_applyTime(GameTime::GetGameTime()),
m_owner(createInfo._owner), m_timeCla(0), m_updateTargetMapInterval(0), m_owner(createInfo._owner), m_timeCla(0), m_updateTargetMapInterval(0),
_casterInfo(), m_procCharges(0), m_stackAmount(1), _casterInfo(), m_procCharges(0), m_stackAmount(1),
m_isRemoved(false), m_isLimitedTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr), m_isRemoved(false), m_isLimitedTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr),
+1 -1
View File
@@ -2970,7 +2970,7 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo)
createInfo createInfo
.SetCasterGUID(caster->GetGUID()) .SetCasterGUID(caster->GetGUID())
.SetBaseAmount(bp) .SetBaseAmount(bp)
.SetCastItem(m_CastItem) .SetCastItemGUID(m_CastItem ? m_CastItem->GetGUID() : ObjectGuid::Empty)
.SetOwnerEffectMask(aura_effmask) .SetOwnerEffectMask(aura_effmask)
.IsRefresh = &refresh; .IsRefresh = &refresh;