diff options
author | AlιAѕѕaѕѕιN <AilSynthax@gmail.com> | 2019-08-28 10:33:41 +0430 |
---|---|---|
committer | Giacomo Pozzoni <giacomopoz@gmail.com> | 2019-08-28 08:03:41 +0200 |
commit | 92d83c3c2eaba3f5b58dc98472318872f3a54706 (patch) | |
tree | cb635a573647b94046a9a073ab83f9d3b6f7e932 /src | |
parent | 07e2264964ef728050e55e5ec5217c4fb4fe1af2 (diff) |
[3.3.5] Fix spell_area not checking for zoneID for quests (#23719)
* Fix spell_area not checking for zoneID for quests
* Addendum to bdffe0a4a641414fe26c9b75b00f8e70ff0f1cb8
* Fix spell_area handle same spell with the same quests
Also fix not checking for quest_end at all.
* Addendum to 2d6b0545e3762b3a25005726d4093cf4a7945a8d
* Better commenting for 7a50189de3104f000d8b31fa6c415bb69cf1a3e7
* Addendum to 2d6b0545e3762b3a25005726d4093cf4a7945a8d
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 45 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 28 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.h | 4 |
3 files changed, 50 insertions, 27 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 336d2fa5917..8015eabf6ef 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -15952,21 +15952,50 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/) void Player::SendQuestUpdate(uint32 questId) { - uint32 zone = 0, area = 0; - GetZoneAndAreaId(zone, area); - - SpellAreaForQuestAreaMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestAreaMapBounds(area, questId); + SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(questId); if (saBounds.first != saBounds.second) { - for (SpellAreaForQuestAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) + std::set<uint32> aurasToRemove, aurasToCast; + uint32 zone = 0, area = 0; + GetZoneAndAreaId(zone, area); + + for (SpellAreaForQuestMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr) { if (!itr->second->IsFitToRequirements(this, zone, area)) - RemoveAurasDueToSpell(itr->second->spellId); + aurasToRemove.insert(itr->second->spellId); else if (itr->second->autocast) - if (!HasAura(itr->second->spellId)) - CastSpell(this, itr->second->spellId, true); + aurasToCast.insert(itr->second->spellId); + } + + // Auras matching the requirements will be inside the aurasToCast container. + // Auras not matching the requirements may prevent using auras matching the requirements. + // aurasToCast will erase conflicting auras in aurasToRemove container to handle spells used by multiple quests. + + for (auto itr = aurasToRemove.begin(); itr != aurasToRemove.end();) + { + bool auraRemoved = false; + + for (const auto i : aurasToCast) + { + if (*itr == i) + { + itr = aurasToRemove.erase(itr); + auraRemoved = true; + break; + } + } + + if (!auraRemoved) + ++itr; } + + for (auto spellId : aurasToCast) + if (!HasAura(spellId)) + CastSpell(this, spellId, true); + + for (auto spellId : aurasToRemove) + RemoveAurasDueToSpell(spellId); } UpdateVisibleGameobjectsOrSpellClicks(); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 0d1d18b66a0..2c63ee8e888 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -688,11 +688,6 @@ SpellAreaForAreaMapBounds SpellMgr::GetSpellAreaForAreaMapBounds(uint32 area_id) return mSpellAreaForAreaMap.equal_range(area_id); } -SpellAreaForQuestAreaMapBounds SpellMgr::GetSpellAreaForQuestAreaMapBounds(uint32 area_id, uint32 quest_id) const -{ - return mSpellAreaForQuestAreaMap.equal_range(std::pair<uint32, uint32>(area_id, quest_id)); -} - bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const { if (gender != GENDER_NONE) // is not expected gender @@ -2376,7 +2371,6 @@ void SpellMgr::LoadSpellAreas() mSpellAreaForQuestMap.clear(); mSpellAreaForQuestEndMap.clear(); mSpellAreaForAuraMap.clear(); - mSpellAreaForQuestAreaMap.clear(); // 0 1 2 3 4 5 6 7 8 9 QueryResult result = WorldDatabase.Query("SELECT spell, area, quest_start, quest_start_status, quest_end_status, quest_end, aura_spell, racemask, gender, autocast FROM spell_area"); @@ -2538,9 +2532,19 @@ void SpellMgr::LoadSpellAreas() if (spellArea.areaId) mSpellAreaForAreaMap.insert(SpellAreaForAreaMap::value_type(spellArea.areaId, sa)); - // for search at quest start/reward - if (spellArea.questStart) - mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa)); + // for search at quest update checks + if (spellArea.questStart || spellArea.questEnd) + { + if (spellArea.questStart == spellArea.questEnd) + mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa)); + else + { + if (spellArea.questStart) + mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questStart, sa)); + if (spellArea.questEnd) + mSpellAreaForQuestMap.insert(SpellAreaForQuestMap::value_type(spellArea.questEnd, sa)); + } + } // for search at quest start/reward if (spellArea.questEnd) @@ -2550,12 +2554,6 @@ void SpellMgr::LoadSpellAreas() if (spellArea.auraSpell) mSpellAreaForAuraMap.insert(SpellAreaForAuraMap::value_type(abs(spellArea.auraSpell), sa)); - if (spellArea.areaId && spellArea.questStart) - mSpellAreaForQuestAreaMap.insert(SpellAreaForQuestAreaMap::value_type(std::pair<uint32, uint32>(spellArea.areaId, spellArea.questStart), sa)); - - if (spellArea.areaId && spellArea.questEnd) - mSpellAreaForQuestAreaMap.insert(SpellAreaForQuestAreaMap::value_type(std::pair<uint32, uint32>(spellArea.areaId, spellArea.questEnd), sa)); - ++count; } while (result->NextRow()); diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 0521146f6e4..c0d951fd245 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -490,12 +490,10 @@ typedef std::multimap<uint32, SpellArea> SpellAreaMap; typedef std::multimap<uint32, SpellArea const*> SpellAreaForQuestMap; typedef std::multimap<uint32, SpellArea const*> SpellAreaForAuraMap; typedef std::multimap<uint32, SpellArea const*> SpellAreaForAreaMap; -typedef std::multimap<std::pair<uint32, uint32>, SpellArea const*> SpellAreaForQuestAreaMap; typedef std::pair<SpellAreaMap::const_iterator, SpellAreaMap::const_iterator> SpellAreaMapBounds; typedef std::pair<SpellAreaForQuestMap::const_iterator, SpellAreaForQuestMap::const_iterator> SpellAreaForQuestMapBounds; typedef std::pair<SpellAreaForAuraMap::const_iterator, SpellAreaForAuraMap::const_iterator> SpellAreaForAuraMapBounds; typedef std::pair<SpellAreaForAreaMap::const_iterator, SpellAreaForAreaMap::const_iterator> SpellAreaForAreaMapBounds; -typedef std::pair<SpellAreaForQuestAreaMap::const_iterator, SpellAreaForQuestAreaMap::const_iterator> SpellAreaForQuestAreaMapBounds; // Spell rank chain (accessed using SpellMgr functions) struct SpellChainNode @@ -659,7 +657,6 @@ class TC_GAME_API SpellMgr SpellAreaForQuestMapBounds GetSpellAreaForQuestEndMapBounds(uint32 quest_id) const; SpellAreaForAuraMapBounds GetSpellAreaForAuraMapBounds(uint32 spell_id) const; SpellAreaForAreaMapBounds GetSpellAreaForAreaMapBounds(uint32 area_id) const; - SpellAreaForQuestAreaMapBounds GetSpellAreaForQuestAreaMapBounds(uint32 area_id, uint32 quest_id) const; // SpellInfo object management SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : nullptr; } @@ -733,7 +730,6 @@ class TC_GAME_API SpellMgr SpellAreaForQuestMap mSpellAreaForQuestEndMap; SpellAreaForAuraMap mSpellAreaForAuraMap; SpellAreaForAreaMap mSpellAreaForAreaMap; - SpellAreaForQuestAreaMap mSpellAreaForQuestAreaMap; SkillLineAbilityMap mSkillLineAbilityMap; PetLevelupSpellMap mPetLevelupSpellMap; PetDefaultSpellsMap mPetDefaultSpellsMap; // only spells not listed in related mPetLevelupSpellMap entry |