mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-24 16:10:14 +00:00
feat: track UNIT_FIELD_STAT0-4 from server update fields for accurate character stats
Add UNIT_FIELD_STAT0-4 (STR/AGI/STA/INT/SPI) to the UF enum and wire up per-expansion indices in all four expansion JSON files (WotLK: 84-88, Classic/Turtle: 138-142, TBC: 159-163). Read the values in both CREATE and VALUES player update handlers and store in playerStats_[5]. renderStatsPanel now uses the server-authoritative totals when available, falling back to the previous 20+level estimate only if the server hasn't sent UNIT_FIELD_STAT* yet. Item-query bonuses are still shown as (+N) alongside the server total for both paths.
This commit is contained in:
parent
d95abfb607
commit
99de1fa3e5
10 changed files with 115 additions and 30 deletions
|
|
@ -6098,6 +6098,7 @@ void GameHandler::selectCharacter(uint64_t characterGuid) {
|
|||
onlineEquipDirty_ = false;
|
||||
playerMoneyCopper_ = 0;
|
||||
playerArmorRating_ = 0;
|
||||
std::fill(std::begin(playerStats_), std::end(playerStats_), -1);
|
||||
knownSpells.clear();
|
||||
spellCooldowns.clear();
|
||||
actionBar = {};
|
||||
|
|
@ -8142,6 +8143,11 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
|||
const uint16_t ufCoinage = fieldIndex(UF::PLAYER_FIELD_COINAGE);
|
||||
const uint16_t ufArmor = fieldIndex(UF::UNIT_FIELD_RESISTANCES);
|
||||
const uint16_t ufPBytes2 = fieldIndex(UF::PLAYER_BYTES_2);
|
||||
const uint16_t ufStats[5] = {
|
||||
fieldIndex(UF::UNIT_FIELD_STAT0), fieldIndex(UF::UNIT_FIELD_STAT1),
|
||||
fieldIndex(UF::UNIT_FIELD_STAT2), fieldIndex(UF::UNIT_FIELD_STAT3),
|
||||
fieldIndex(UF::UNIT_FIELD_STAT4)
|
||||
};
|
||||
for (const auto& [key, val] : block.fields) {
|
||||
if (key == ufPlayerXp) { playerXp_ = val; }
|
||||
else if (key == ufPlayerNextXp) { playerNextLevelXp_ = val; }
|
||||
|
|
@ -8170,6 +8176,14 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
|||
uint8_t restStateByte = static_cast<uint8_t>((val >> 24) & 0xFF);
|
||||
isResting_ = (restStateByte != 0);
|
||||
}
|
||||
else {
|
||||
for (int si = 0; si < 5; ++si) {
|
||||
if (ufStats[si] != 0xFFFF && key == ufStats[si]) {
|
||||
playerStats_[si] = static_cast<int32_t>(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do not synthesize quest-log entries from raw update-field slots.
|
||||
// Slot layouts differ on some classic-family realms and can produce
|
||||
// phantom "already accepted" quests that block quest acceptance.
|
||||
|
|
@ -8454,6 +8468,11 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
|||
const uint16_t ufPlayerFlags = fieldIndex(UF::PLAYER_FLAGS);
|
||||
const uint16_t ufArmor = fieldIndex(UF::UNIT_FIELD_RESISTANCES);
|
||||
const uint16_t ufPBytes2v = fieldIndex(UF::PLAYER_BYTES_2);
|
||||
const uint16_t ufStatsV[5] = {
|
||||
fieldIndex(UF::UNIT_FIELD_STAT0), fieldIndex(UF::UNIT_FIELD_STAT1),
|
||||
fieldIndex(UF::UNIT_FIELD_STAT2), fieldIndex(UF::UNIT_FIELD_STAT3),
|
||||
fieldIndex(UF::UNIT_FIELD_STAT4)
|
||||
};
|
||||
for (const auto& [key, val] : block.fields) {
|
||||
if (key == ufPlayerXp) {
|
||||
playerXp_ = val;
|
||||
|
|
@ -8510,6 +8529,14 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
|
|||
if (ghostStateCallback_) ghostStateCallback_(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int si = 0; si < 5; ++si) {
|
||||
if (ufStatsV[si] != 0xFFFF && key == ufStatsV[si]) {
|
||||
playerStats_[si] = static_cast<int32_t>(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Do not auto-create quests from VALUES quest-log slot fields for the
|
||||
// same reason as CREATE_OBJECT2 above (can be misaligned per realm).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue