From 779e40d5ffb5c378759bae81455c2ae6aff84e27 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 9 Aug 2010 04:36:33 +0400 Subject: [PATCH] [10332] Save cast item guid for auras also. This must fix another way duplicate aura adding to DB error. It also prevent wrong stacking work for weapon equip bufs in cases when its allowed for both wepoan indepndently apply. --- sql/characters.sql | 8 +++-- .../10332_01_characters_character_aura.sql | 7 +++++ sql/updates/10332_02_characters_pet_aura.sql | 7 +++++ sql/updates/Makefile.am | 4 +++ src/game/CharacterHandler.cpp | 2 +- src/game/Pet.cpp | 27 ++++++++++------- src/game/Player.cpp | 29 ++++++++++++------- src/game/SpellAuras.cpp | 6 +++- src/game/SpellAuras.h | 3 +- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 11 files changed, 68 insertions(+), 29 deletions(-) create mode 100644 sql/updates/10332_01_characters_character_aura.sql create mode 100644 sql/updates/10332_02_characters_pet_aura.sql diff --git a/sql/characters.sql b/sql/characters.sql index 880a8b80a..a5b4d2e0d 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_10312_02_characters_pet_aura` bit(1) default NULL + `required_10332_02_characters_pet_aura` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- @@ -370,6 +370,7 @@ DROP TABLE IF EXISTS `character_aura`; CREATE TABLE `character_aura` ( `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', + `item_guid` int(11) unsigned NOT NULL default '0', `spell` int(11) unsigned NOT NULL default '0', `stackcount` int(11) NOT NULL default '1', `remaincharges` int(11) NOT NULL default '0', @@ -383,7 +384,7 @@ CREATE TABLE `character_aura` ( `remaintime1` INT(11) NOT NULL DEFAULT '0', `remaintime2` INT(11) NOT NULL DEFAULT '0', `effIndexMask` INT(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`guid`,`caster_guid`,`spell`) + PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; -- @@ -1455,6 +1456,7 @@ DROP TABLE IF EXISTS `pet_aura`; CREATE TABLE `pet_aura` ( `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', `caster_guid` bigint(20) unsigned NOT NULL default '0' COMMENT 'Full Global Unique Identifier', + `item_guid` int(11) unsigned NOT NULL default '0', `spell` int(11) unsigned NOT NULL default '0', `stackcount` int(11) NOT NULL default '1', `remaincharges` int(11) NOT NULL default '0', @@ -1468,7 +1470,7 @@ CREATE TABLE `pet_aura` ( `remaintime1` INT(11) NOT NULL DEFAULT '0', `remaintime2` INT(11) NOT NULL DEFAULT '0', `effIndexMask` INT(11) NOT NULL DEFAULT '0', - PRIMARY KEY (`guid`,`caster_guid`,`spell`) + PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Pet System'; -- diff --git a/sql/updates/10332_01_characters_character_aura.sql b/sql/updates/10332_01_characters_character_aura.sql new file mode 100644 index 000000000..f1157a4e1 --- /dev/null +++ b/sql/updates/10332_01_characters_character_aura.sql @@ -0,0 +1,7 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_10312_02_characters_pet_aura required_10332_01_characters_character_aura bit; + +ALTER TABLE `character_aura` + ADD COLUMN `item_guid` int(11) unsigned NOT NULL default '0' AFTER `caster_guid`, + DROP PRIMARY KEY, + ADD PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`); + diff --git a/sql/updates/10332_02_characters_pet_aura.sql b/sql/updates/10332_02_characters_pet_aura.sql new file mode 100644 index 000000000..e84afb8af --- /dev/null +++ b/sql/updates/10332_02_characters_pet_aura.sql @@ -0,0 +1,7 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_10332_01_characters_character_aura required_10332_02_characters_pet_aura bit; + +ALTER TABLE `pet_aura` + ADD COLUMN `item_guid` int(11) unsigned NOT NULL default '0' AFTER `caster_guid`, + DROP PRIMARY KEY, + ADD PRIMARY KEY (`guid`,`caster_guid`,`item_guid`,`spell`); + diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 0bd83b90f..dfb81f1a1 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -72,6 +72,8 @@ pkgdata_DATA = \ 10323_02_mangos_command.sql \ 10331_01_mangos_mangos_string.sql \ 10331_02_mangos_command.sql \ + 10332_01_characters_character_aura.sql \ + 10332_02_characters_pet_aura.sql \ README ## Additional files to include when running 'make dist' @@ -124,4 +126,6 @@ EXTRA_DIST = \ 10323_02_mangos_command.sql \ 10331_01_mangos_mangos_string.sql \ 10331_02_mangos_command.sql \ + 10332_01_characters_character_aura.sql \ + 10332_02_characters_pet_aura.sql \ README diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index cc7b0623f..eca8253af 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -75,7 +75,7 @@ bool LoginQueryHolder::Initialize() "health, power1, power2, power3, power4, power5, power6, power7, specCount, activeSpec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT groupId FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid)); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index fdf93cd2f..895b36b51 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1144,7 +1144,7 @@ void Pet::_LoadAuras(uint32 timediff) { RemoveAllAuras(); - QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); + QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber()); if(result) { @@ -1152,19 +1152,20 @@ void Pet::_LoadAuras(uint32 timediff) { Field *fields = result->Fetch(); uint64 caster_guid = fields[0].GetUInt64(); - uint32 spellid = fields[1].GetUInt32(); - uint32 stackcount= fields[2].GetUInt32(); - int32 remaincharges = (int32)fields[3].GetUInt32(); + uint32 item_lowguid = fields[1].GetUInt32(); + uint32 spellid = fields[2].GetUInt32(); + uint32 stackcount= fields[3].GetUInt32(); + int32 remaincharges = (int32)fields[4].GetUInt32(); int32 damage[MAX_EFFECT_INDEX]; int32 maxduration[MAX_EFFECT_INDEX]; int32 remaintime[MAX_EFFECT_INDEX]; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - damage[i] = (int32)fields[i+4].GetUInt32(); - maxduration[i] = (int32)fields[i+7].GetUInt32(); - remaintime[i] = (int32)fields[i+10].GetUInt32(); + damage[i] = (int32)fields[i+5].GetUInt32(); + maxduration[i] = (int32)fields[i+8].GetUInt32(); + remaintime[i] = (int32)fields[i+11].GetUInt32(); } - uint32 effIndexMask = (int32)fields[13].GetUInt32(); + uint32 effIndexMask = (int32)fields[14].GetUInt32(); SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); if(!spellproto) @@ -1213,7 +1214,7 @@ void Pet::_LoadAuras(uint32 timediff) if (!holder->IsEmptyHolder()) { - holder->SetLoadedState(caster_guid, stackcount, remaincharges); + holder->SetLoadedState(caster_guid, item_lowguid ? MAKE_NEW_GUID(HIGHGUID_ITEM, 0, item_lowguid) : 0, stackcount, remaincharges); AddSpellAuraHolder(holder); } else @@ -1282,7 +1283,13 @@ void Pet::_SaveAuras() if (!effIndexMask) continue; - CharacterDatabase.PExecute("INSERT INTO pet_aura (guid, caster_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", m_charmInfo->GetPetNumber(), holder->GetCasterGUID(), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], effIndexMask); + CharacterDatabase.PExecute("INSERT INTO pet_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES " + "('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", + m_charmInfo->GetPetNumber(), holder->GetCasterGUID(), GUID_LOPART(holder->GetCastItemGUID()), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), + damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], + maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], + remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], + effIndexMask); } } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index c316720fc..5d64ad0a0 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -15661,9 +15661,9 @@ void Player::_LoadActions(QueryResult *result) void Player::_LoadAuras(QueryResult *result, uint32 timediff) { - //RemoveAllAuras(); -- some spells casted before aura load, for example in LoadSkills, aura list explcitly cleaned early + //RemoveAllAuras(); -- some spells casted before aura load, for example in LoadSkills, aura list explicitly cleaned early - //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'",GetGUIDLow()); + //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,item_guid,spell,stackcount,remaincharges,basepoints0,basepoints1,basepoints2,maxduration0,maxduration1,maxduration2,remaintime0,remaintime1,remaintime2,effIndexMask FROM character_aura WHERE guid = '%u'",GetGUIDLow()); if(result) { @@ -15671,19 +15671,20 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) { Field *fields = result->Fetch(); uint64 caster_guid = fields[0].GetUInt64(); - uint32 spellid = fields[1].GetUInt32(); - uint32 stackcount = fields[2].GetUInt32(); - int32 remaincharges = (int32)fields[3].GetUInt32(); + uint32 item_lowguid = fields[1].GetUInt64(); + uint32 spellid = fields[2].GetUInt32(); + uint32 stackcount = fields[3].GetUInt32(); + int32 remaincharges = (int32)fields[4].GetUInt32(); int32 damage[MAX_EFFECT_INDEX]; int32 maxduration[MAX_EFFECT_INDEX]; int32 remaintime[MAX_EFFECT_INDEX]; for (int32 i = 0; i < MAX_EFFECT_INDEX; ++i) { - damage[i] = (int32)fields[i+4].GetUInt32(); - maxduration[i] = (int32)fields[i+7].GetUInt32(); - remaintime[i] = (int32)fields[i+10].GetUInt32(); + damage[i] = (int32)fields[i+5].GetUInt32(); + maxduration[i] = (int32)fields[i+8].GetUInt32(); + remaintime[i] = (int32)fields[i+11].GetUInt32(); } - uint32 effIndexMask = (int32)fields[13].GetUInt32(); + uint32 effIndexMask = (int32)fields[14].GetUInt32(); SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid); if(!spellproto) @@ -15732,7 +15733,7 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff) if (caster_guid != GetGUID() && holder->IsSingleTarget()) holder->SetIsSingleTarget(false); - holder->SetLoadedState(caster_guid, stackcount, remaincharges); + holder->SetLoadedState(caster_guid, item_lowguid ? MAKE_NEW_GUID(item_lowguid, 0, HIGHGUID_ITEM) : 0, stackcount, remaincharges); AddSpellAuraHolder(holder); DETAIL_LOG("Added auras from spellid %u", spellproto->Id); } @@ -16979,7 +16980,13 @@ void Player::_SaveAuras() if (!effIndexMask) continue; - CharacterDatabase.PExecute("INSERT INTO character_aura (guid, caster_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", GetGUIDLow(), holder->GetCasterGUID(), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], effIndexMask); + CharacterDatabase.PExecute("INSERT INTO character_aura (guid, caster_guid, item_guid, spell, stackcount, remaincharges, basepoints0, basepoints1, basepoints2, maxduration0, maxduration1, maxduration2, remaintime0, remaintime1, remaintime2, effIndexMask) VALUES " + "('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')", + GetGUIDLow(), holder->GetCasterGUID(), GUID_LOPART(holder->GetCastItemGUID()), holder->GetId(), holder->GetStackAmount(), holder->GetAuraCharges(), + damage[EFFECT_INDEX_0], damage[EFFECT_INDEX_1], damage[EFFECT_INDEX_2], + maxduration[EFFECT_INDEX_0], maxduration[EFFECT_INDEX_1], maxduration[EFFECT_INDEX_2], + remaintime[EFFECT_INDEX_0], remaintime[EFFECT_INDEX_1], remaintime[EFFECT_INDEX_2], + effIndexMask); } } } diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 9c9ccc3af..418ad9b72 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -8092,6 +8092,10 @@ Unit* SpellAuraHolder::GetCaster() const bool SpellAuraHolder::IsWeaponBuffCoexistableWith(SpellAuraHolder* ref) { + // only item casted spells + if (!GetCastItemGUID()) + return false; + // Exclude Debuffs if (!IsPositive()) return false; @@ -8118,7 +8122,7 @@ bool SpellAuraHolder::IsWeaponBuffCoexistableWith(SpellAuraHolder* ref) return false; // form different weapons - return ref->GetCastItemGUID() != GetCastItemGUID(); + return ref->GetCastItemGUID() && ref->GetCastItemGUID() != GetCastItemGUID(); } bool SpellAuraHolder::IsNeedVisibleSlot(Unit const* caster) const diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index be77732d9..68c68f134 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -142,9 +142,10 @@ class MANGOS_DLL_SPEC SpellAuraHolder void SetVisibleAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); } void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; } - void SetLoadedState(uint64 casterGUID, int32 stackAmount, int32 charges) + void SetLoadedState(uint64 casterGUID, uint64 itemGUID, int32 stackAmount, int32 charges) { m_caster_guid = casterGUID; + m_castItemGuid = itemGUID; m_procCharges = charges; m_stackAmount = stackAmount; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 19490b69f..65d27f0c1 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "10331" + #define REVISION_NR "10332" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 2f78ae128..9d09ac49d 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ - #define REVISION_DB_CHARACTERS "required_10312_02_characters_pet_aura" + #define REVISION_DB_CHARACTERS "required_10332_02_characters_pet_aura" #define REVISION_DB_MANGOS "required_10331_02_mangos_command" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #endif // __REVISION_SQL_H__