[3.3.5] Fix spell_area not checking for zoneID for quests (#23719)

* Fix spell_area not checking for zoneID for quests

* Addendum to bdffe0a4a6

* Fix spell_area handle same spell with the same quests

Also fix not checking for quest_end at all.

* Addendum to 2d6b0545e3

* Better commenting for 7a50189de3

* Addendum to 2d6b0545e3

(cherry picked from commit 92d83c3c2e)
This commit is contained in:
AlιAѕѕaѕѕιN
2019-08-28 10:33:41 +04:30
committed by Shauren
parent 9d3dd3db84
commit e1598fa1d6
3 changed files with 50 additions and 27 deletions

View File

@@ -16535,21 +16535,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->flags & SPELL_AREA_FLAG_AUTOREMOVE && !itr->second->IsFitToRequirements(this, zone, area))
RemoveAurasDueToSpell(itr->second->spellId);
aurasToRemove.insert(itr->second->spellId);
else if (itr->second->flags & SPELL_AREA_FLAG_AUTOCAST && !(itr->second->flags & SPELL_AREA_FLAG_IGNORE_AUTOCAST_ON_QUEST_STATUS_CHANGE))
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();

View File

@@ -685,11 +685,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));
}
SpellInfo const* SpellMgr::GetSpellInfo(uint32 spellId, Difficulty difficulty) const
{
auto itr = mSpellInfoMap.find(boost::make_tuple(spellId, difficulty));
@@ -2287,7 +2282,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, flags FROM spell_area");
@@ -2449,9 +2443,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)
@@ -2461,12 +2465,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());

View File

@@ -510,12 +510,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
@@ -704,7 +702,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, Difficulty difficulty) const;
@@ -781,7 +778,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