mirror of
https://github.com/brues-code/ClassicAPI.git
synced 2026-11-10 20:07:37 +00:00
refactor(spell): test a spell's auras through one HasAuraEffect
Six places asked the same question of a Spell.dbc record: does one of its three effects apply aura N (EffectApplyAuraName, +0x16C, int32[3])? Each had its own loop: the combat log's damage-shield lookup, crowd-control classification and its snare test, tracking-spell detection, C_SpellBook.GetPlayerSpellsByAura, and the aura-source periodic-damage gate (which also hard-coded 3 for the effect count). Spell::Lookup now has FindAuraEffect (the index of the first effect that applies the aura, or -1, for callers that read that effect's other columns) and HasAuraEffect on top of it, next to the existing HasEffect. All six call it. Code that pairs an aura with the same effect's misc value, amount or effect code (Cancel, Interruptible, BonusDamage, StatAccum, EffectInfo) keeps its own per-effect reads.
This commit is contained in:
+2
-9
@@ -1023,16 +1023,9 @@ CompressState *FindOrClaimCompressState(uint64_t targetGuid,
|
||||
// would compress it, this gate excludes it exactly as the server's does.
|
||||
// (Drain Soul passes via its effect-2 periodic damage: aura=[86,3,0].)
|
||||
bool HasPeriodicDamageOrLeech(const uint8_t *rec) {
|
||||
if (rec == nullptr)
|
||||
return false;
|
||||
constexpr int32_t kPeriodicDamage = 3, kPeriodicLeech = 53;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const int32_t aura = *reinterpret_cast<const int32_t *>(
|
||||
rec + Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME + i * 4);
|
||||
if (aura == kPeriodicDamage || aura == kPeriodicLeech)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return Spell::Lookup::HasAuraEffect(rec, kPeriodicDamage) ||
|
||||
Spell::Lookup::HasAuraEffect(rec, kPeriodicLeech);
|
||||
}
|
||||
|
||||
// Compression pairs by CASTER, mirroring the server (each warlock's Dark
|
||||
|
||||
@@ -618,17 +618,6 @@ uint32_t SpellSchoolMask(const uint8_t *spell) {
|
||||
: 0;
|
||||
}
|
||||
|
||||
bool HasAuraEffect(const uint8_t *spell, int auraName) {
|
||||
if (spell == nullptr)
|
||||
return false;
|
||||
for (int i = 0; i < Offsets::SPELL_RECORD_EFFECT_COUNT; ++i) {
|
||||
if (Game::Read<int>(spell, Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME + i * 4) ==
|
||||
auraName)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Entry Begin(uint64_t source, uint64_t dest, int event, const uint8_t *spell) {
|
||||
Entry e;
|
||||
e.event = event;
|
||||
|
||||
@@ -167,10 +167,6 @@ uint32_t SchoolMask(uint32_t school);
|
||||
// The spell's school as a mask (4.3.4's SpellRec m_schoolMask), 0 for nullptr.
|
||||
uint32_t SpellSchoolMask(const uint8_t *spell);
|
||||
|
||||
// Whether one of the spell's three effects applies the aura `auraName`
|
||||
// (EffectApplyAuraName).
|
||||
bool HasAuraEffect(const uint8_t *spell, int auraName);
|
||||
|
||||
// GetCombatLogEntry: an entry for `event` from `source` to `dest` (either may
|
||||
// be 0), with the spell prefix when `spell` is a record.
|
||||
Entry Begin(uint64_t source, uint64_t dest, int event, const uint8_t *spell);
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
#include "aura/Data.h"
|
||||
#include "net/PacketDispatch.h"
|
||||
#include "object/Resolve.h"
|
||||
#include "spell/Lookup.h"
|
||||
#include "time/Clock.h"
|
||||
|
||||
#include <cstdint>
|
||||
@@ -501,7 +502,7 @@ const uint8_t *ShieldSpell(uint64_t owner, uint32_t school) {
|
||||
const uint8_t *spell = SpellRecord(static_cast<int>(spellId));
|
||||
if (spell == nullptr ||
|
||||
Game::Read<uint32_t>(spell, Offsets::OFF_SPELL_RECORD_SCHOOL) != school ||
|
||||
!HasAuraEffect(spell, AURA_DAMAGE_SHIELD))
|
||||
!Spell::Lookup::HasAuraEffect(spell, AURA_DAMAGE_SHIELD))
|
||||
continue;
|
||||
if (found != nullptr && found != spell)
|
||||
return nullptr;
|
||||
|
||||
@@ -21,14 +21,7 @@ namespace Spell::CrowdControl {
|
||||
const char *Classify(const uint8_t *rec) {
|
||||
if (rec == nullptr)
|
||||
return nullptr;
|
||||
const int32_t *aura = reinterpret_cast<const int32_t *>(
|
||||
rec + Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME);
|
||||
auto has = [&](int type) {
|
||||
for (int i = 0; i < Offsets::SPELL_RECORD_EFFECT_COUNT; ++i)
|
||||
if (aura[i] == type)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
auto has = [rec](int type) { return Spell::Lookup::HasAuraEffect(rec, type); };
|
||||
if (has(Offsets::SPELL_AURA_MOD_POSSESS)) return "POSSESS";
|
||||
if (has(Offsets::SPELL_AURA_MOD_CHARM)) return "CHARM";
|
||||
if (has(Offsets::SPELL_AURA_MOD_STUN)) return "STUN";
|
||||
@@ -50,12 +43,7 @@ bool IsCrowdControl(uint32_t spellID) {
|
||||
// slows / snares, which `Classify` (the LoC set) deliberately excludes.
|
||||
if (Classify(rec) != nullptr)
|
||||
return true;
|
||||
const int32_t *aura = reinterpret_cast<const int32_t *>(
|
||||
rec + Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME);
|
||||
for (int i = 0; i < Offsets::SPELL_RECORD_EFFECT_COUNT; ++i)
|
||||
if (aura[i] == Offsets::SPELL_AURA_MOD_DECREASE_SPEED)
|
||||
return true;
|
||||
return false;
|
||||
return Spell::Lookup::HasAuraEffect(rec, Offsets::SPELL_AURA_MOD_DECREASE_SPEED);
|
||||
}
|
||||
|
||||
} // namespace Spell::CrowdControl
|
||||
|
||||
+5
-9
@@ -534,15 +534,11 @@ static int __fastcall Script_GetPlayerSpellsByAura(void *L) {
|
||||
|
||||
int n = 0;
|
||||
ForEachKnownSpell([&](int spellID, const uint8_t *record) {
|
||||
auto *auras = reinterpret_cast<const int32_t *>(
|
||||
record + Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME);
|
||||
for (int e = 0; e < Offsets::SPELL_RECORD_EFFECT_COUNT; ++e) {
|
||||
if (auras[e] == auraName) {
|
||||
Game::Lua::PushNumber(L, static_cast<double>(++n));
|
||||
Game::Lua::PushNumber(L, static_cast<double>(spellID));
|
||||
Game::Lua::RawSet(L, -3);
|
||||
break; // one entry per spell, however many effects match
|
||||
}
|
||||
// One entry per spell, however many effects match.
|
||||
if (Spell::Lookup::HasAuraEffect(record, auraName)) {
|
||||
Game::Lua::PushNumber(L, static_cast<double>(++n));
|
||||
Game::Lua::PushNumber(L, static_cast<double>(spellID));
|
||||
Game::Lua::RawSet(L, -3);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -62,6 +62,21 @@ bool HasEffect(const uint8_t *spellRecord, int effect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int FindAuraEffect(const uint8_t *spellRecord, int aura) {
|
||||
if (spellRecord == nullptr)
|
||||
return -1;
|
||||
for (int i = 0; i < Offsets::SPELL_RECORD_EFFECT_COUNT; ++i) {
|
||||
if (Game::Read<int>(spellRecord, Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME + i * 4) ==
|
||||
aura)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool HasAuraEffect(const uint8_t *spellRecord, int aura) {
|
||||
return FindAuraEffect(spellRecord, aura) >= 0;
|
||||
}
|
||||
|
||||
int SpellbookSlotToID(int slot1Based, int bookType) {
|
||||
const int slot = slot1Based - 1;
|
||||
if (slot < 0 || slot >= Offsets::SPELLBOOK_MAX_SLOTS)
|
||||
|
||||
@@ -35,6 +35,15 @@ bool IsFitToFamily(const uint8_t *spellRecord, uint32_t family,
|
||||
// SpellHasEffect. False for a null record.
|
||||
bool HasEffect(const uint8_t *spellRecord, int effect);
|
||||
|
||||
// The index (0..2) of the first of the spell's three effects that applies
|
||||
// the aura `aura` (EffectApplyAuraName), or -1 when none does or the record
|
||||
// is null. For reading that effect's other columns (its misc value, ...).
|
||||
int FindAuraEffect(const uint8_t *spellRecord, int aura);
|
||||
|
||||
// Whether one of the spell's three effects applies the aura `aura` —
|
||||
// 4.3.4's SpellHasAuraEffect. False for a null record.
|
||||
bool HasAuraEffect(const uint8_t *spellRecord, int aura);
|
||||
|
||||
// Resolves a 1-based Lua-facing spellbook slot to the spellID stored
|
||||
// there. `bookType` is `0` for the player spellbook, `1` for the pet
|
||||
// spellbook (matches the engine's encoding from `Script_GetSpellName`).
|
||||
|
||||
+3
-10
@@ -46,16 +46,9 @@ static constexpr int32_t AURA_TRACK_STEALTHED = 151;
|
||||
// True iff `spellID`'s record has any of the three Track* effects.
|
||||
static bool IsTrackingSpell(int spellID) {
|
||||
const uint8_t *record = Spell::Lookup::RecordForID(spellID);
|
||||
if (record == nullptr)
|
||||
return false;
|
||||
auto *aura = Game::Ptr<const int32_t>(
|
||||
record, Offsets::OFF_SPELL_RECORD_EFFECT_APPLY_AURA_NAME);
|
||||
for (int i = 0; i < Offsets::SPELL_RECORD_EFFECT_COUNT; ++i) {
|
||||
if (aura[i] == AURA_TRACK_CREATURES || aura[i] == AURA_TRACK_RESOURCES ||
|
||||
aura[i] == AURA_TRACK_STEALTHED)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return Spell::Lookup::HasAuraEffect(record, AURA_TRACK_CREATURES) ||
|
||||
Spell::Lookup::HasAuraEffect(record, AURA_TRACK_RESOURCES) ||
|
||||
Spell::Lookup::HasAuraEffect(record, AURA_TRACK_STEALTHED);
|
||||
}
|
||||
|
||||
// Walks the player spellbook in slot order counting tracking spells. If
|
||||
|
||||
Reference in New Issue
Block a user