mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Core/Spells: Allow skipping automatic removal of auras from spell_area when condition is no longer met (mostly used for cosmetic cutscenes after quest completion) (#21317)
This commit is contained in:
2
sql/updates/world/master/2018_01_28_00_world.sql
Normal file
2
sql/updates/world/master/2018_01_28_00_world.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE `spell_area` CHANGE `autocast` `flags` TINYINT(3) UNSIGNED NOT NULL DEFAULT '3' AFTER `gender`;
|
||||
UPDATE `spell_area` SET `flags`=`flags`|2;
|
||||
@@ -16056,9 +16056,9 @@ void Player::SendQuestUpdate(uint32 questId)
|
||||
{
|
||||
for (SpellAreaForQuestAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
{
|
||||
if (!itr->second->IsFitToRequirements(this, zone, area))
|
||||
if (itr->second->flags & SPELL_AREA_FLAG_AUTOREMOVE && !itr->second->IsFitToRequirements(this, zone, area))
|
||||
RemoveAurasDueToSpell(itr->second->spellId);
|
||||
else if (itr->second->autocast)
|
||||
else if (itr->second->flags & SPELL_AREA_FLAG_AUTOCAST)
|
||||
if (!HasAura(itr->second->spellId))
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
@@ -24887,7 +24887,7 @@ void Player::UpdateZoneDependentAuras(uint32 newZone)
|
||||
// Some spells applied at enter into zone (with subzones), aura removed in UpdateAreaDependentAuras that called always at zone->area update
|
||||
SpellAreaForAreaMapBounds saBounds = sSpellMgr->GetSpellAreaForAreaMapBounds(newZone);
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
if (itr->second->autocast && itr->second->IsFitToRequirements(this, newZone, 0))
|
||||
if (itr->second->flags & SPELL_AREA_FLAG_AUTOCAST && itr->second->IsFitToRequirements(this, newZone, 0))
|
||||
if (!HasAura(itr->second->spellId))
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
@@ -24907,7 +24907,7 @@ void Player::UpdateAreaDependentAuras(uint32 newArea)
|
||||
// some auras applied at subzone enter
|
||||
SpellAreaForAreaMapBounds saBounds = sSpellMgr->GetSpellAreaForAreaMapBounds(newArea);
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
if (itr->second->autocast && itr->second->IsFitToRequirements(this, m_zoneUpdateId, newArea))
|
||||
if (itr->second->flags & SPELL_AREA_FLAG_AUTOCAST && itr->second->IsFitToRequirements(this, m_zoneUpdateId, newArea))
|
||||
if (!HasAura(itr->second->spellId))
|
||||
CastSpell(this, itr->second->spellId, true);
|
||||
}
|
||||
|
||||
@@ -1212,10 +1212,10 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
|
||||
for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
|
||||
{
|
||||
// some auras remove at aura remove
|
||||
if (!itr->second->IsFitToRequirements(target->ToPlayer(), zone, area))
|
||||
if (itr->second->flags & SPELL_AREA_FLAG_AUTOREMOVE && !itr->second->IsFitToRequirements(target->ToPlayer(), zone, area))
|
||||
target->RemoveAurasDueToSpell(itr->second->spellId);
|
||||
// some auras applied at aura apply
|
||||
else if (itr->second->autocast)
|
||||
else if (itr->second->flags & SPELL_AREA_FLAG_AUTOCAST)
|
||||
{
|
||||
if (!target->HasAura(itr->second->spellId))
|
||||
target->CastSpell(target, itr->second->spellId, true);
|
||||
|
||||
@@ -2008,7 +2008,7 @@ void SpellMgr::LoadSpellAreas()
|
||||
mSpellAreaForAuraMap.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");
|
||||
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");
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 spell area requirements. DB table `spell_area` is empty.");
|
||||
@@ -2032,11 +2032,11 @@ void SpellMgr::LoadSpellAreas()
|
||||
spellArea.auraSpell = fields[6].GetInt32();
|
||||
spellArea.raceMask = fields[7].GetUInt32();
|
||||
spellArea.gender = Gender(fields[8].GetUInt8());
|
||||
spellArea.autocast = fields[9].GetBool();
|
||||
spellArea.flags = fields[9].GetUInt8();
|
||||
|
||||
if (SpellInfo const* spellInfo = GetSpellInfo(spell))
|
||||
{
|
||||
if (spellArea.autocast)
|
||||
if (spellArea.flags & SPELL_AREA_FLAG_AUTOCAST)
|
||||
const_cast<SpellInfo*>(spellInfo)->Attributes |= SPELL_ATTR0_CANT_CANCEL;
|
||||
}
|
||||
else
|
||||
@@ -2112,13 +2112,13 @@ void SpellMgr::LoadSpellAreas()
|
||||
}
|
||||
|
||||
// not allow autocast chains by auraSpell field (but allow use as alternative if not present)
|
||||
if (spellArea.autocast && spellArea.auraSpell > 0)
|
||||
if (spellArea.flags & SPELL_AREA_FLAG_AUTOCAST && spellArea.auraSpell > 0)
|
||||
{
|
||||
bool chain = false;
|
||||
SpellAreaForAuraMapBounds saBound = GetSpellAreaForAuraMapBounds(spellArea.spellId);
|
||||
for (SpellAreaForAuraMap::const_iterator itr = saBound.first; itr != saBound.second; ++itr)
|
||||
{
|
||||
if (itr->second->autocast && itr->second->auraSpell > 0)
|
||||
if (itr->second->flags & SPELL_AREA_FLAG_AUTOCAST && itr->second->auraSpell > 0)
|
||||
{
|
||||
chain = true;
|
||||
break;
|
||||
@@ -2134,7 +2134,7 @@ void SpellMgr::LoadSpellAreas()
|
||||
SpellAreaMapBounds saBound2 = GetSpellAreaMapBounds(spellArea.auraSpell);
|
||||
for (SpellAreaMap::const_iterator itr2 = saBound2.first; itr2 != saBound2.second; ++itr2)
|
||||
{
|
||||
if (itr2->second.autocast && itr2->second.auraSpell > 0)
|
||||
if (itr2->second.flags & SPELL_AREA_FLAG_AUTOCAST && itr2->second.auraSpell > 0)
|
||||
{
|
||||
chain = true;
|
||||
break;
|
||||
|
||||
@@ -450,6 +450,12 @@ class TC_GAME_API PetAura
|
||||
};
|
||||
typedef std::map<uint32, PetAura> SpellPetAuraMap;
|
||||
|
||||
enum SpellAreaFlag
|
||||
{
|
||||
SPELL_AREA_FLAG_AUTOCAST = 0x1, // if has autocast, spell is applied on enter
|
||||
SPELL_AREA_FLAG_AUTOREMOVE = 0x2, // if has autoremove, spell is remove automatically inside zone/area (allways removed on leaving area or zone)
|
||||
};
|
||||
|
||||
struct TC_GAME_API SpellArea
|
||||
{
|
||||
uint32 spellId;
|
||||
@@ -461,7 +467,7 @@ struct TC_GAME_API SpellArea
|
||||
Gender gender; // can be applied only to gender
|
||||
uint32 questStartStatus; // QuestStatus that quest_start must have in order to keep the spell
|
||||
uint32 questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped)
|
||||
bool autocast; // if true then auto applied at area enter, in other case just allowed to cast
|
||||
uint8 flags; // if SPELL_AREA_FLAG_AUTOCAST then auto applied at area enter, in other case just allowed to cast || if SPELL_AREA_FLAG_AUTOREMOVE then auto removed inside area (will allways be removed on leaved even without flag)
|
||||
|
||||
// helpers
|
||||
bool IsFitToRequirements(Player const* player, uint32 newZone, uint32 newArea) const;
|
||||
|
||||
Reference in New Issue
Block a user