aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlιAѕѕaѕѕιN <AilSynthax@gmail.com>2019-08-28 10:33:41 +0430
committerGiacomo Pozzoni <giacomopoz@gmail.com>2019-08-28 08:03:41 +0200
commit92d83c3c2eaba3f5b58dc98472318872f3a54706 (patch)
treecb635a573647b94046a9a073ab83f9d3b6f7e932 /src
parent07e2264964ef728050e55e5ec5217c4fb4fe1af2 (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.cpp45
-rw-r--r--src/server/game/Spells/SpellMgr.cpp28
-rw-r--r--src/server/game/Spells/SpellMgr.h4
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