diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 589aa438581..ccac149d0f2 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -640,6 +640,7 @@ DROP TABLE IF EXISTS `character_aura`; CREATE TABLE `character_aura` ( `guid` int unsigned NOT NULL DEFAULT '0' COMMENT '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', `effectMask` 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', `critChance` float 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'; /*!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_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_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_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), diff --git a/sql/updates/characters/4.3.4/2022_09_03_00_characters.sql b/sql/updates/characters/4.3.4/2022_09_03_00_characters.sql new file mode 100644 index 00000000000..53de0b528b6 --- /dev/null +++ b/sql/updates/characters/4.3.4/2022_09_03_00_characters.sql @@ -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`); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index 36a2be785af..8e71ec55ab7 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -70,7 +70,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, 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); 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, " @@ -273,8 +273,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, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges, critChance, applyResilience) " - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + 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); // Currency PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT Currency, Quantity, WeeklyQuantity, TrackedQuantity, Flags FROM character_currency WHERE CharacterGuid = ?", CONNECTION_ASYNC); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e83c345702d..3379a8f1e59 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -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()); - /* 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 14 15 + /* 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 15 16 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 baseDamage[3]; ObjectGuid caster_guid(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(); - float critChance = fields[14].GetFloat(); - bool applyResilience = fields[15].GetBool(); + ObjectGuid itemGuid(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(); + float critChance = fields[15].GetFloat(); + bool applyResilience = fields[16].GetBool(); SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid); if (!spellInfo) @@ -18016,6 +18017,7 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff) AuraCreateInfo createInfo(spellInfo, effmask, this); createInfo .SetCasterGUID(caster_guid) + .SetCastItemGUID(itemGuid) .SetBaseAmount(baseDamage); if (Aura* aura = Aura::TryCreate(createInfo)) @@ -19934,6 +19936,7 @@ void Player::_SaveAuras(CharacterDatabaseTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA); stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt64(index++, itr->second->GetCasterGUID().GetRawValue()); + stmt->setUInt64(index++, itr->second->GetCastItemGUID().GetRawValue()); stmt->setUInt32(index++, itr->second->GetId()); stmt->setUInt8(index++, effMask); stmt->setUInt8(index++, recalculateMask); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f9582b20ba9..faeec7d3d94 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3041,9 +3041,7 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(AuraCreateInfo& createInfo) if (!createInfo.GetSpellInfo()->IsMultiSlotAura()) { // check if cast item changed - ObjectGuid castItemGUID; - if (createInfo.CastItem) - castItemGUID = createInfo.CastItem->GetGUID(); + ObjectGuid castItemGUID = createInfo.CastItemGUID; // 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)) diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 08c41ff15d8..80aabce89de 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -508,7 +508,7 @@ struct TC_GAME_API AuraCreateInfo AuraCreateInfo& SetCasterGUID(ObjectGuid const& guid) { CasterGUID = guid; return *this; } AuraCreateInfo& SetCaster(Unit* caster) { Caster = caster; 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; } SpellInfo const* GetSpellInfo() const { return _spellInfo; } @@ -517,7 +517,7 @@ struct TC_GAME_API AuraCreateInfo ObjectGuid CasterGUID; Unit* Caster = nullptr; int32 const* BaseAmount = nullptr; - Item* CastItem = nullptr; + ObjectGuid CastItemGUID; bool* IsRefresh = nullptr; private: diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 786c16b3e8c..b7ac87db55b 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -432,7 +432,7 @@ Aura* Aura::Create(AuraCreateInfo& createInfo) Aura::Aura(AuraCreateInfo const& createInfo) : 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), _casterInfo(), m_procCharges(0), m_stackAmount(1), m_isRemoved(false), m_isLimitedTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr), diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 52656a7994a..9d4a1da355d 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2970,7 +2970,7 @@ void Spell::DoSpellEffectHit(Unit* unit, uint8 effIndex, TargetInfo& hitInfo) createInfo .SetCasterGUID(caster->GetGUID()) .SetBaseAmount(bp) - .SetCastItem(m_CastItem) + .SetCastItemGUID(m_CastItem ? m_CastItem->GetGUID() : ObjectGuid::Empty) .SetOwnerEffectMask(aura_effmask) .IsRefresh = &refresh;