mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: use UNIT_FIELD_AURAFLAGS to correctly classify Classic buffs vs debuffs
Classic WoW stores aura flags in UNIT_FIELD_AURAFLAGS (12 uint32 fields packed 4 bytes per uint32, one byte per aura slot). Flag bit 0x02 = harmful (debuff), 0x04 = helpful (buff). - Add UNIT_FIELD_AURAFLAGS to update_field_table.hpp (Classic wire index 98) - Add wire index 98 to Classic and Turtle WoW JSON update field tables - Both Classic aura rebuild paths (CREATE_OBJECT and VALUES) now read the flag byte for each aura slot to populate AuraSlot.flags, enabling the buff/debuff bar to correctly separate buffs from debuffs on Classic
This commit is contained in:
parent
fb8c251a82
commit
18d0e6a252
4 changed files with 23 additions and 4 deletions
|
|
@ -14,6 +14,7 @@
|
||||||
"UNIT_FIELD_DISPLAYID": 131,
|
"UNIT_FIELD_DISPLAYID": 131,
|
||||||
"UNIT_FIELD_MOUNTDISPLAYID": 133,
|
"UNIT_FIELD_MOUNTDISPLAYID": 133,
|
||||||
"UNIT_FIELD_AURAS": 50,
|
"UNIT_FIELD_AURAS": 50,
|
||||||
|
"UNIT_FIELD_AURAFLAGS": 98,
|
||||||
"UNIT_NPC_FLAGS": 147,
|
"UNIT_NPC_FLAGS": 147,
|
||||||
"UNIT_DYNAMIC_FLAGS": 143,
|
"UNIT_DYNAMIC_FLAGS": 143,
|
||||||
"UNIT_FIELD_RESISTANCES": 154,
|
"UNIT_FIELD_RESISTANCES": 154,
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"UNIT_FIELD_DISPLAYID": 131,
|
"UNIT_FIELD_DISPLAYID": 131,
|
||||||
"UNIT_FIELD_MOUNTDISPLAYID": 133,
|
"UNIT_FIELD_MOUNTDISPLAYID": 133,
|
||||||
"UNIT_FIELD_AURAS": 50,
|
"UNIT_FIELD_AURAS": 50,
|
||||||
|
"UNIT_FIELD_AURAFLAGS": 98,
|
||||||
"UNIT_NPC_FLAGS": 147,
|
"UNIT_NPC_FLAGS": 147,
|
||||||
"UNIT_DYNAMIC_FLAGS": 143,
|
"UNIT_DYNAMIC_FLAGS": 143,
|
||||||
"UNIT_FIELD_RESISTANCES": 154,
|
"UNIT_FIELD_RESISTANCES": 154,
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ enum class UF : uint16_t {
|
||||||
UNIT_FIELD_DISPLAYID,
|
UNIT_FIELD_DISPLAYID,
|
||||||
UNIT_FIELD_MOUNTDISPLAYID,
|
UNIT_FIELD_MOUNTDISPLAYID,
|
||||||
UNIT_FIELD_AURAS, // Start of aura spell ID array (48 consecutive uint32 slots, classic/vanilla only)
|
UNIT_FIELD_AURAS, // Start of aura spell ID array (48 consecutive uint32 slots, classic/vanilla only)
|
||||||
|
UNIT_FIELD_AURAFLAGS, // Aura flags packed 4-per-uint32 (12 uint32 slots); 0x01=cancelable,0x02=harmful,0x04=helpful
|
||||||
UNIT_NPC_FLAGS,
|
UNIT_NPC_FLAGS,
|
||||||
UNIT_DYNAMIC_FLAGS,
|
UNIT_DYNAMIC_FLAGS,
|
||||||
UNIT_FIELD_RESISTANCES, // Physical armor (index 0 of the resistance array)
|
UNIT_FIELD_RESISTANCES, // Physical armor (index 0 of the resistance array)
|
||||||
|
|
|
||||||
|
|
@ -8991,7 +8991,8 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
}
|
}
|
||||||
// Classic: rebuild playerAuras from UNIT_FIELD_AURAS on initial object create
|
// Classic: rebuild playerAuras from UNIT_FIELD_AURAS on initial object create
|
||||||
if (block.guid == playerGuid && isClassicLikeExpansion()) {
|
if (block.guid == playerGuid && isClassicLikeExpansion()) {
|
||||||
const uint16_t ufAuras = fieldIndex(UF::UNIT_FIELD_AURAS);
|
const uint16_t ufAuras = fieldIndex(UF::UNIT_FIELD_AURAS);
|
||||||
|
const uint16_t ufAuraFlags = fieldIndex(UF::UNIT_FIELD_AURAFLAGS);
|
||||||
if (ufAuras != 0xFFFF) {
|
if (ufAuras != 0xFFFF) {
|
||||||
bool hasAuraField = false;
|
bool hasAuraField = false;
|
||||||
for (const auto& [fk, fv] : block.fields) {
|
for (const auto& [fk, fv] : block.fields) {
|
||||||
|
|
@ -9009,7 +9010,14 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
if (it != allFields.end() && it->second != 0) {
|
if (it != allFields.end() && it->second != 0) {
|
||||||
AuraSlot& a = playerAuras[slot];
|
AuraSlot& a = playerAuras[slot];
|
||||||
a.spellId = it->second;
|
a.spellId = it->second;
|
||||||
a.flags = 0;
|
// Read aura flag byte: packed 4-per-uint32 at ufAuraFlags
|
||||||
|
uint8_t aFlag = 0;
|
||||||
|
if (ufAuraFlags != 0xFFFF) {
|
||||||
|
auto fit = allFields.find(static_cast<uint16_t>(ufAuraFlags + slot / 4));
|
||||||
|
if (fit != allFields.end())
|
||||||
|
aFlag = static_cast<uint8_t>((fit->second >> ((slot % 4) * 8)) & 0xFF);
|
||||||
|
}
|
||||||
|
a.flags = aFlag;
|
||||||
a.durationMs = -1;
|
a.durationMs = -1;
|
||||||
a.maxDurationMs = -1;
|
a.maxDurationMs = -1;
|
||||||
a.casterGuid = playerGuid;
|
a.casterGuid = playerGuid;
|
||||||
|
|
@ -9435,7 +9443,8 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
|
|
||||||
// Classic: sync playerAuras from UNIT_FIELD_AURAS when those fields are updated
|
// Classic: sync playerAuras from UNIT_FIELD_AURAS when those fields are updated
|
||||||
if (block.guid == playerGuid && isClassicLikeExpansion()) {
|
if (block.guid == playerGuid && isClassicLikeExpansion()) {
|
||||||
const uint16_t ufAuras = fieldIndex(UF::UNIT_FIELD_AURAS);
|
const uint16_t ufAuras = fieldIndex(UF::UNIT_FIELD_AURAS);
|
||||||
|
const uint16_t ufAuraFlags = fieldIndex(UF::UNIT_FIELD_AURAFLAGS);
|
||||||
if (ufAuras != 0xFFFF) {
|
if (ufAuras != 0xFFFF) {
|
||||||
bool hasAuraUpdate = false;
|
bool hasAuraUpdate = false;
|
||||||
for (const auto& [fk, fv] : block.fields) {
|
for (const auto& [fk, fv] : block.fields) {
|
||||||
|
|
@ -9453,7 +9462,14 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
||||||
if (it != allFields.end() && it->second != 0) {
|
if (it != allFields.end() && it->second != 0) {
|
||||||
AuraSlot& a = playerAuras[slot];
|
AuraSlot& a = playerAuras[slot];
|
||||||
a.spellId = it->second;
|
a.spellId = it->second;
|
||||||
a.flags = 0;
|
// Read aura flag byte: packed 4-per-uint32 at ufAuraFlags
|
||||||
|
uint8_t aFlag = 0;
|
||||||
|
if (ufAuraFlags != 0xFFFF) {
|
||||||
|
auto fit = allFields.find(static_cast<uint16_t>(ufAuraFlags + slot / 4));
|
||||||
|
if (fit != allFields.end())
|
||||||
|
aFlag = static_cast<uint8_t>((fit->second >> ((slot % 4) * 8)) & 0xFF);
|
||||||
|
}
|
||||||
|
a.flags = aFlag;
|
||||||
a.durationMs = -1;
|
a.durationMs = -1;
|
||||||
a.maxDurationMs = -1;
|
a.maxDurationMs = -1;
|
||||||
a.casterGuid = playerGuid;
|
a.casterGuid = playerGuid;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue