mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-19 17:05:44 +01:00
[3.3.5] Fix spell_area not checking for zoneID for quests (#23719)
* Fix spell_area not checking for zoneID for quests * Addendum tobdffe0a4a6* Fix spell_area handle same spell with the same quests Also fix not checking for quest_end at all. * Addendum to2d6b0545e3* Better commenting for7a50189de3* Addendum to2d6b0545e3(cherry picked from commit92d83c3c2e)
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user