Add separate draggable bag windows, fix dismount and player equipment

Bags are now individual draggable ImGui windows (backpack + each equipped
bag) with per-bag toggle from the bag bar. B key opens/closes all. A
settings toggle under Gameplay lets users switch back to the original
aggregate single-window mode. Window width adapts to bag item name length.

Fix dismount by clearing local mount state immediately (optimistic) instead
of waiting for server confirmation, and allow buff bar right-click dismount
regardless of the aura's buff flag.

Fix other players appearing naked by queuing them for auto-inspect when
the visible item field layout hasn't been detected yet.
This commit is contained in:
Kelsi 2026-02-13 22:51:49 -08:00
parent 89ccb0720a
commit 85864ab05b
5 changed files with 264 additions and 62 deletions

View file

@ -5539,7 +5539,13 @@ void GameHandler::maybeDetectVisibleItemLayout() {
void GameHandler::updateOtherPlayerVisibleItems(uint64_t guid, const std::map<uint16_t, uint32_t>& fields) {
if (guid == 0 || guid == playerGuid) return;
if (visibleItemEntryBase_ < 0 || visibleItemStride_ <= 0) return;
if (visibleItemEntryBase_ < 0 || visibleItemStride_ <= 0) {
// Layout not detected yet — queue this player for inspect as fallback.
if (socket && state == WorldState::IN_WORLD) {
pendingAutoInspect_.insert(guid);
}
return;
}
std::array<uint32_t, 19> newEntries{};
for (int s = 0; s < 19; s++) {
@ -5713,18 +5719,16 @@ void GameHandler::handleAttackStop(network::Packet& packet) {
void GameHandler::dismount() {
if (!socket) return;
if (!isMounted()) {
// Local/server desync guard: clear visual mount even when server says unmounted.
// Clear local mount state immediately (optimistic dismount).
// Server will confirm via SMSG_UPDATE_OBJECT with mountDisplayId=0.
if (currentMountDisplayId_ != 0 || taxiMountActive_) {
if (mountCallback_) {
mountCallback_(0);
}
currentMountDisplayId_ = 0;
taxiMountActive_ = false;
taxiMountDisplayId_ = 0;
onTaxiFlight_ = false;
taxiActivatePending_ = false;
taxiClientActive_ = false;
LOG_INFO("Dismount desync recovery: force-cleared local mount state");
LOG_INFO("Dismount: cleared local mount state");
}
network::Packet pkt(wireOpcode(Opcode::CMSG_CANCEL_MOUNT_AURA));
socket->send(pkt);