Skip to content

Commit 84da9c2

Browse files
committed
Consolidate the duplicated Spell.dbc attribute flag bits
The remaining flag-bit duplicates -- the same drift risk that caused the AttributesEx2/Ex3 mix-up -- now live once in Offsets.h: - SPELL_ATTR_PASSIVE (0x40): was already in Offsets.h yet copied in Info.cpp and Level.cpp; drop both locals. - SPELL_ATTR_EX_CHANNELED (0x4|0x40): identical local in Cast.cpp and CastEvents.cpp; add to Offsets.h and repoint. - SPELL_ATTR_EX2_AUTOREPEAT_FLAG (0x20): the same bit under two names (Cast's _AUTOREPEAT, AutoAttack's _FLAG); unify in Offsets.h. Single-use flag bits (TRADESPELL, RANGED, HEALTH_FUNNEL, HIDDEN_CLIENTSIDE, ON_NEXT_SWING, NOT_RESET_AUTO_ACTIONS) and per-module effect/target enum codes stay local -- they are not duplicated and read clearer at the use site.
1 parent 6e58cb8 commit 84da9c2

6 files changed

Lines changed: 11 additions & 17 deletions

File tree

src/Offsets.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5774,6 +5774,11 @@ enum Offsets {
57745774
// SPELL_ATTR_EX3_IGNORE_CASTER_MODIFIERS (verified via disassembly; the
57755775
// server enum agrees). NOT AttributesEx2's bit 29 (that's CANT_CRIT).
57765776
SPELL_ATTR_EX3_IGNORE_CASTER_MODIFIERS = 0x20000000,
5777+
// AttributesEx channel bits (CHANNELED_1 0x4 | CHANNELED_2 0x40) and the
5778+
// AttributesEx2 autorepeat flag (bit 5, Auto Shot / Shoot) — each shared
5779+
// by more than one module, so kept here rather than redefined locally.
5780+
SPELL_ATTR_EX_CHANNELED = 0x4 | 0x40,
5781+
SPELL_ATTR_EX2_AUTOREPEAT_FLAG = 0x20,
57775782
OFF_SPELL_RECORD_INTERRUPT_FLAGS = 0x54, // u32 (column 21)
57785783

57795784
// Remaining Spell.dbc record fields — the single source of truth for the

src/spell/AutoAttack.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ namespace Spell::AutoAttack {
4242
namespace {
4343

4444
constexpr int SPELL_AUTO_ATTACK = 6603;
45-
constexpr uint32_t SPELL_ATTR_EX2_AUTOREPEAT_FLAG = 0x00000020;
4645

4746
bool IsMelee(int spellID) {
4847
return spellID == SPELL_AUTO_ATTACK;
@@ -58,7 +57,7 @@ bool IsRanged(int spellID) {
5857
return false;
5958
const uint32_t attrEx2 = *reinterpret_cast<const uint32_t *>(
6059
rec + Offsets::OFF_SPELL_RECORD_ATTRIBUTES_EX2);
61-
return (attrEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG) != 0;
60+
return (attrEx2 & Offsets::SPELL_ATTR_EX2_AUTOREPEAT_FLAG) != 0;
6261
}
6362

6463
int ReadSpellID(void *L) {

src/spell/Cast.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ constexpr uint32_t SPELL_ATTR_TRADESPELL = 0x20;
9999
// flat +500ms "aim time" to these (SpellEntry::GetCastTime). Auto-repeat
100100
// shots (Auto Shot / Shoot, AttributesEx2 bit 0x20) are the one exclusion.
101101
constexpr uint32_t SPELL_ATTR_RANGED = 0x2;
102-
constexpr uint32_t SPELL_ATTR_EX2_AUTOREPEAT = 0x20;
103102

104103
struct TrackedSpell {
105104
int spellID; // 0 = not casting / channeling
@@ -184,7 +183,7 @@ int CastTimeMs(int spellID) {
184183
*reinterpret_cast<const uint32_t *>(rec + Offsets::OFF_SPELL_RECORD_ATTRIBUTES);
185184
const uint32_t attrEx2 =
186185
*reinterpret_cast<const uint32_t *>(rec + Offsets::OFF_SPELL_RECORD_ATTRIBUTES_EX2);
187-
if ((attr & SPELL_ATTR_RANGED) && !(attrEx2 & SPELL_ATTR_EX2_AUTOREPEAT))
186+
if ((attr & SPELL_ATTR_RANGED) && !(attrEx2 & Offsets::SPELL_ATTR_EX2_AUTOREPEAT_FLAG))
188187
ms += 500;
189188
}
190189
}
@@ -334,11 +333,9 @@ const Game::HookAutoRegister _castStartHook{
334333
// thing at a time). Regular casts back `UnitCastingInfo`; channels add real
335334
// times to `UnitChannelInfo` (validated against the live +0x228 field).
336335

337-
constexpr uint32_t SPELL_ATTR_EX_CHANNELED = 0x4 | 0x40; // IS_CHANNELED | SELF
338-
339336
bool IsChannelSpell(const uint8_t *rec) {
340337
return (*reinterpret_cast<const uint32_t *>(rec + Offsets::OFF_SPELL_RECORD_ATTRIBUTES_EX) &
341-
SPELL_ATTR_EX_CHANNELED) != 0;
338+
Offsets::SPELL_ATTR_EX_CHANNELED) != 0;
342339
}
343340

344341
// Channel duration for a non-player caster — base (skipMod=1), since we

src/spell/CastEvents.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,11 @@ int g_pendingChanSuccSpell = 0;
254254
int g_pendingChanSuccTMs = 0;
255255
constexpr int kChanSuccDeferMs = 500;
256256

257-
// Spell.dbc AttributesEx channel bits — same test Spell::Cast uses.
258-
constexpr uint32_t SPELL_ATTR_EX_CHANNELED = 0x4 | 0x40; // IS_CHANNELED | SELF
259-
260257
bool IsChanneledSpell(int spellID) {
261258
const uint8_t *rec = Spell::Lookup::RecordForID(spellID);
262259
return rec != nullptr &&
263260
(*reinterpret_cast<const uint32_t *>(rec + Offsets::OFF_SPELL_RECORD_ATTRIBUTES_EX) &
264-
SPELL_ATTR_EX_CHANNELED) != 0;
261+
Offsets::SPELL_ATTR_EX_CHANNELED) != 0;
265262
}
266263

267264
int NowMs() {

src/spell/Info.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222

2323
namespace Spell::Info {
2424

25-
// Attributes (+0x18) bit 6 = SPELL_ATTR_PASSIVE — passive spell (no cast
26-
// bar, applies its effect as soon as learned/equipped).
27-
static constexpr uint32_t SPELL_ATTR_PASSIVE = 0x40;
2825
// GetSpellInfo's isFunnel means a health-funnel spell — AttributesEx2 (+0x20)
2926
// bit 11 = SPELL_ATTR_EX2_HEALTH_FUNNEL. Verified from Spell.dbc: Health
3027
// Funnel (755) Ex2=0x808 and Hellfire (1949) Ex2=0x800 carry it, while
@@ -397,7 +394,7 @@ static int PushIsPassive(void *L, int spellID) {
397394
return 0;
398395
const uint32_t attr = *reinterpret_cast<const uint32_t *>(
399396
record + Offsets::OFF_SPELL_RECORD_ATTRIBUTES);
400-
Game::Lua::PushBool(L, (attr & SPELL_ATTR_PASSIVE) != 0);
397+
Game::Lua::PushBool(L, (attr & Offsets::SPELL_ATTR_PASSIVE) != 0);
401398
return 1;
402399
}
403400

src/spell/Level.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ bool SpellHiddenFromSpellbook(int spellID) {
130130
// checks are NOT in the 1.12 client's Spell.dbc — server-only columns — so
131131
// the spellLevel rule is the only client-readable target-level mechanism.)
132132

133-
constexpr uint32_t SPELL_ATTR_PASSIVE = 0x40; // Attributes bit
134133
constexpr uint32_t SPELL_EFFECT_APPLY_AURA = 6;
135134
constexpr uint32_t SPELL_EFFECT_APPLY_AREA_AURA_PARTY = 35;
136135

@@ -184,7 +183,7 @@ int RequiredTargetLevel(const uint8_t *record) {
184183
return 0;
185184
const uint32_t attr =
186185
*reinterpret_cast<const uint32_t *>(record + Offsets::OFF_SPELL_RECORD_ATTRIBUTES);
187-
if (attr & SPELL_ATTR_PASSIVE)
186+
if (attr & Offsets::SPELL_ATTR_PASSIVE)
188187
return 0;
189188
if (!HasRankString(record)) // single-rank spell → not gated
190189
return 0;

0 commit comments

Comments
 (0)