mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
feat(Core/Spells): implement two new custom attributes to handle aura saving rule (#8377)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1633787767742446400');
|
||||
|
||||
-- Raise Ally control aura should not be saved
|
||||
DELETE FROM `spell_custom_attr` WHERE `spell_id` = '46619';
|
||||
INSERT INTO `spell_custom_attr` (`spell_id`, `attributes`) VALUES
|
||||
('46619', '268435456');
|
||||
@@ -1048,49 +1048,76 @@ bool Aura::IsRemovedOnShapeLost(Unit* target) const
|
||||
|
||||
bool Aura::CanBeSaved() const
|
||||
{
|
||||
if (IsPassive() || (GetSpellInfo()->HasAttribute(SPELL_ATTR0_DO_NOT_DISPLAY) && GetSpellInfo()->Stances))
|
||||
SpellInfo const* spellInfo = GetSpellInfo();
|
||||
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_CU_FORCE_AURA_SAVING))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (spellInfo->HasAttribute(SPELL_ATTR0_CU_REJECT_AURA_SAVING))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsPassive() || (spellInfo->HasAttribute(SPELL_ATTR0_DO_NOT_DISPLAY) && spellInfo->Stances))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Xinef: do not save channel auras
|
||||
if (GetSpellInfo()->IsChanneled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Xinef: Check if aura is single target, not only spell info
|
||||
if (GetCasterGUID() != GetOwner()->GetGUID())
|
||||
if (GetSpellInfo()->IsSingleTarget() || IsSingleTarget())
|
||||
return false;
|
||||
if (GetCasterGUID() != GetOwner()->GetGUID() && (GetSpellInfo()->IsSingleTarget() || IsSingleTarget()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Xinef: Dont save control vehicle auras - caster may not exist
|
||||
if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Can't be saved - aura handler relies on calculated amount and changes it
|
||||
if (HasEffectType(SPELL_AURA_CONVERT_RUNE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// No point in saving this, since the stable dialog can't be open on aura load anyway.
|
||||
if (HasEffectType(SPELL_AURA_OPEN_STABLE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// xinef: do not save bind sight auras!
|
||||
if (HasEffectType(SPELL_AURA_BIND_SIGHT))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// xinef: no charming auras (taking direct control)
|
||||
if (HasEffectType(SPELL_AURA_MOD_POSSESS) || HasEffectType(SPELL_AURA_MOD_POSSESS_PET))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// xinef: no charming auras can be saved
|
||||
if (HasEffectType(SPELL_AURA_MOD_CHARM) || HasEffectType(SPELL_AURA_AOE_CHARM))
|
||||
{
|
||||
return false;
|
||||
|
||||
// Xinef: Raise Ally control aura
|
||||
if (GetId() == 46619)
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't save auras removed by proc system
|
||||
if (IsUsingCharges() && !GetCharges())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -201,6 +201,8 @@ enum SpellCustomAttributes
|
||||
SPELL_ATTR0_CU_POSITIVE_EFF0 = 0x02000000,
|
||||
SPELL_ATTR0_CU_POSITIVE_EFF1 = 0x04000000,
|
||||
SPELL_ATTR0_CU_POSITIVE_EFF2 = 0x08000000,
|
||||
SPELL_ATTR0_CU_REJECT_AURA_SAVING = 0x10000000,
|
||||
SPELL_ATTR0_CU_FORCE_AURA_SAVING = 0x20000800,
|
||||
|
||||
SPELL_ATTR0_CU_NEGATIVE = SPELL_ATTR0_CU_NEGATIVE_EFF0 | SPELL_ATTR0_CU_NEGATIVE_EFF1 | SPELL_ATTR0_CU_NEGATIVE_EFF2,
|
||||
SPELL_ATTR0_CU_POSITIVE = SPELL_ATTR0_CU_POSITIVE_EFF0 | SPELL_ATTR0_CU_POSITIVE_EFF1 | SPELL_ATTR0_CU_POSITIVE_EFF2,
|
||||
@@ -403,15 +405,15 @@ public:
|
||||
bool HasAnyAura() const;
|
||||
bool HasAreaAuraEffect() const;
|
||||
|
||||
inline bool HasAttribute(SpellAttr0 attribute) const { return Attributes & attribute; }
|
||||
inline bool HasAttribute(SpellAttr1 attribute) const { return AttributesEx & attribute; }
|
||||
inline bool HasAttribute(SpellAttr2 attribute) const { return AttributesEx2 & attribute; }
|
||||
inline bool HasAttribute(SpellAttr3 attribute) const { return AttributesEx3 & attribute; }
|
||||
inline bool HasAttribute(SpellAttr4 attribute) const { return AttributesEx4 & attribute; }
|
||||
inline bool HasAttribute(SpellAttr5 attribute) const { return AttributesEx5 & attribute; }
|
||||
inline bool HasAttribute(SpellAttr6 attribute) const { return AttributesEx6 & attribute; }
|
||||
inline bool HasAttribute(SpellAttr7 attribute) const { return AttributesEx7 & attribute; }
|
||||
inline bool HasAttribute(SpellCustomAttributes customAttribute) const { return AttributesCu & customAttribute; }
|
||||
inline bool HasAttribute(SpellAttr0 attribute) const { return (Attributes & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr1 attribute) const { return (AttributesEx & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr2 attribute) const { return (AttributesEx2 & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr3 attribute) const { return (AttributesEx3 & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr4 attribute) const { return (AttributesEx4 & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr5 attribute) const { return (AttributesEx5 & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr6 attribute) const { return (AttributesEx6 & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellAttr7 attribute) const { return (AttributesEx7 & attribute) != 0; }
|
||||
inline bool HasAttribute(SpellCustomAttributes customAttribute) const { return (AttributesCu & customAttribute) != 0; }
|
||||
|
||||
bool IsExplicitDiscovery() const;
|
||||
bool IsLootCrafting() const;
|
||||
|
||||
@@ -2726,60 +2726,77 @@ void SpellMgr::LoadSpellSpecificAndAuraState()
|
||||
|
||||
void SpellMgr::LoadSpellCustomAttr()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
uint32 customAttrTime = getMSTime();
|
||||
uint32 const oldMSTime = getMSTime();
|
||||
uint32 const customAttrTime = getMSTime();
|
||||
uint32 count;
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT spell_id, attributes FROM spell_custom_attr");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
LOG_INFO("server.loading", ">> Loaded 0 spell custom attributes from DB. DB table `spell_custom_attr` is empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (count = 0; result->NextRow(); ++count)
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
Field const* fields = result->Fetch();
|
||||
|
||||
uint32 spellId = fields[0].GetUInt32();
|
||||
uint32 const spellId = fields[0].GetUInt32();
|
||||
uint32 attributes = fields[1].GetUInt32();
|
||||
|
||||
SpellInfo* spellInfo = _GetSpellInfo(spellId);
|
||||
if (!spellInfo)
|
||||
{
|
||||
LOG_INFO("spells", "Table `spell_custom_attr` has wrong spell (spell_id: %u), ignored.", spellId);
|
||||
LOG_INFO("sql.sql", "Table `spell_custom_attr` has wrong spell (spell_id: %u), ignored.", spellId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((attributes & SPELL_ATTR0_CU_NEGATIVE) != 0)
|
||||
if (attributes & SPELL_ATTR0_CU_NEGATIVE)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (spellInfo->Effects[i].IsEffect())
|
||||
continue;
|
||||
|
||||
if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) != 0)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_NEGATIVE_EFF%u for spell %u with no EFFECT_%u", uint32(i), spellId, uint32(i));
|
||||
if ((attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)) && (attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_NEGATIVE_EFF%u and SPELL_ATTR0_CU_POSITIVE_EFF%u attributes for spell %u which cannot stack together. Attributes will not get applied", static_cast<uint32>(i), static_cast<uint32>(i), spellId);
|
||||
attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i)|(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (attributes & (SPELL_ATTR0_CU_NEGATIVE_EFF0 << i))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_NEGATIVE_EFF%u for spell %u with no EFFECT_%u", static_cast<uint32>(i), spellId, static_cast<uint32>(i));
|
||||
attributes &= ~(SPELL_ATTR0_CU_NEGATIVE_EFF0 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((attributes & SPELL_ATTR0_CU_POSITIVE) != 0)
|
||||
if (attributes & SPELL_ATTR0_CU_POSITIVE)
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
|
||||
{
|
||||
if (spellInfo->Effects[i].IsEffect())
|
||||
continue;
|
||||
|
||||
if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)) != 0)
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_POSITIVE_EFF%u for spell %u with no EFFECT_%u", uint32(i), spellId, uint32(i));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((attributes & (SPELL_ATTR0_CU_POSITIVE_EFF0 << i)))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `spell_custom_attr` has attribute SPELL_ATTR0_CU_POSITIVE_EFF%u for spell %u with no EFFECT_%u", uint32(i), spellId, uint32(i));
|
||||
attributes &= ~(SPELL_ATTR0_CU_POSITIVE_EFF0 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((attributes & SPELL_ATTR0_CU_FORCE_AURA_SAVING) && (attributes & SPELL_ATTR0_CU_REJECT_AURA_SAVING))
|
||||
{
|
||||
LOG_ERROR("sql.sql", "Table `spell_custom_attr` attribute1 field has attributes SPELL_ATTR1_CU_FORCE_AURA_SAVING and SPELL_ATTR1_CU_REJECT_AURA_SAVING which cannot stack for spell %u. Both attributes will get applied", spellId);
|
||||
attributes &= ~(SPELL_ATTR0_CU_FORCE_AURA_SAVING | SPELL_ATTR0_CU_REJECT_AURA_SAVING);
|
||||
}
|
||||
|
||||
spellInfo->AttributesCu |= attributes;
|
||||
}
|
||||
LOG_INFO("server.loading", ">> Loaded %u spell custom attributes from DB in %u ms", count, GetMSTimeDiffToNow(customAttrTime));
|
||||
|
||||
Reference in New Issue
Block a user