fix: derive rest state from PLAYER_BYTES_2 and add action bar 2 settings

XP bar rest state:
- isResting_ now set from PLAYER_BYTES_2 byte 3 bit 0 (rest state flag)
  on both CREATE and VALUES update object handlers
- playerRestedXp_ was missing from VALUES handler — now tracked there too
- Eliminates dependency on SMSG_SET_REST_START (wrong in WotLK opcodes.json)

Interface settings:
- New "Interface" tab in Settings window
- "Show Second Action Bar" toggle (default: on)
- Horizontal/vertical position offset sliders for bar 2
- Settings persisted to/from save file
This commit is contained in:
Kelsi 2026-03-10 15:45:35 -07:00
parent 1a370fef76
commit ec5e7c66c3
3 changed files with 64 additions and 3 deletions

View file

@ -8086,6 +8086,9 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
LOG_WARNING("PLAYER_BYTES_2 (CREATE): raw=0x", std::hex, val, std::dec,
" bankBagSlots=", static_cast<int>(bankBagSlots));
inventory.setPurchasedBankBagSlots(bankBagSlots);
// Byte 3 (bits 24-31): REST_STATE — bit 0 set means in inn/city
uint8_t restStateByte = static_cast<uint8_t>((val >> 24) & 0xFF);
isResting_ = (restStateByte & 0x01) != 0;
}
// Do not synthesize quest-log entries from raw update-field slots.
// Slot layouts differ on some classic-family realms and can produce
@ -8354,6 +8357,7 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
bool slotsChanged = false;
const uint16_t ufPlayerXp = fieldIndex(UF::PLAYER_XP);
const uint16_t ufPlayerNextXp = fieldIndex(UF::PLAYER_NEXT_LEVEL_XP);
const uint16_t ufPlayerRestedXpV = fieldIndex(UF::PLAYER_REST_STATE_EXPERIENCE);
const uint16_t ufPlayerLevel = fieldIndex(UF::UNIT_FIELD_LEVEL);
const uint16_t ufCoinage = fieldIndex(UF::PLAYER_FIELD_COINAGE);
const uint16_t ufPlayerFlags = fieldIndex(UF::PLAYER_FLAGS);
@ -8368,6 +8372,9 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
playerNextLevelXp_ = val;
LOG_DEBUG("Next level XP updated: ", val);
}
else if (ufPlayerRestedXpV != 0xFFFF && key == ufPlayerRestedXpV) {
playerRestedXp_ = val;
}
else if (key == ufPlayerLevel) {
serverPlayerLevel_ = val;
LOG_DEBUG("Level updated: ", val);
@ -8390,6 +8397,9 @@ void GameHandler::handleUpdateObject(network::Packet& packet) {
LOG_WARNING("PLAYER_BYTES_2 (VALUES): raw=0x", std::hex, val, std::dec,
" bankBagSlots=", static_cast<int>(bankBagSlots));
inventory.setPurchasedBankBagSlots(bankBagSlots);
// Byte 3 (bits 24-31): REST_STATE — bit 0 set means in inn/city
uint8_t restStateByte = static_cast<uint8_t>((val >> 24) & 0xFF);
isResting_ = (restStateByte & 0x01) != 0;
}
else if (key == ufPlayerFlags) {
constexpr uint32_t PLAYER_FLAGS_GHOST = 0x00000010;