diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 3af2f59a..393b739c 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -332,6 +332,10 @@ public: // Stand state void setStandState(uint8_t state); // 0=stand, 1=sit, 2=sit_chair, 3=sleep, 4=sit_low_chair, 5=sit_medium_chair, 6=sit_high_chair, 7=dead, 8=kneel, 9=submerged + uint8_t getStandState() const { return standState_; } + bool isSitting() const { return standState_ >= 1 && standState_ <= 6; } + bool isDead() const { return standState_ == 7; } + bool isKneeling() const { return standState_ == 8; } // Display toggles void toggleHelm(); @@ -1381,6 +1385,7 @@ private: // ---- Display state ---- bool helmVisible_ = true; bool cloakVisible_ = true; + uint8_t standState_ = 0; // 0=stand, 1=sit, ..., 7=dead, 8=kneel (server-confirmed) // ---- Follow state ---- uint64_t followTargetGuid_ = 0; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 3cd05d3c..edd0839c 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -1467,11 +1467,39 @@ void GameHandler::handlePacket(network::Packet& packet) { handleRandomRoll(packet); } break; - case Opcode::SMSG_ITEM_PUSH_RESULT: - // Item received notification (new item in bags, loot, quest reward, etc.) - // TODO: parse and show "item received" UI notification - packet.setReadPos(packet.getSize()); + case Opcode::SMSG_ITEM_PUSH_RESULT: { + // Item received notification (loot, quest reward, trade, etc.) + // guid(8) + received(1) + created(1) + showInChat(1) + bagSlot(1) + itemSlot(4) + // + itemId(4) + itemSuffixFactor(4) + randomPropertyId(4) + count(4) + totalCount(4) + constexpr size_t kMinSize = 8 + 1 + 1 + 1 + 1 + 4 + 4 + 4 + 4 + 4 + 4; + if (packet.getSize() - packet.getReadPos() >= kMinSize) { + /*uint64_t recipientGuid =*/ packet.readUInt64(); + /*uint8_t received =*/ packet.readUInt8(); // 0=looted/generated, 1=received from trade + /*uint8_t created =*/ packet.readUInt8(); // 0=stack added, 1=new item slot + uint8_t showInChat = packet.readUInt8(); + /*uint8_t bagSlot =*/ packet.readUInt8(); + /*uint32_t itemSlot =*/ packet.readUInt32(); + uint32_t itemId = packet.readUInt32(); + /*uint32_t suffixFactor =*/ packet.readUInt32(); + /*int32_t randomProp =*/ static_cast(packet.readUInt32()); + uint32_t count = packet.readUInt32(); + /*uint32_t totalCount =*/ packet.readUInt32(); + + queryItemInfo(itemId, 0); + if (showInChat) { + std::string itemName = "item #" + std::to_string(itemId); + if (const ItemQueryResponseData* info = getItemInfo(itemId)) { + if (!info->name.empty()) itemName = info->name; + } + std::string msg = "Received: " + itemName; + if (count > 1) msg += " x" + std::to_string(count); + addSystemChatMessage(msg); + } + LOG_INFO("Item push: itemId=", itemId, " count=", count, + " showInChat=", static_cast(showInChat)); + } break; + } case Opcode::SMSG_LOGOUT_RESPONSE: handleLogoutResponse(packet); @@ -2728,8 +2756,12 @@ void GameHandler::handlePacket(network::Packet& packet) { break; case Opcode::SMSG_STANDSTATE_UPDATE: // Server confirms stand state change (sit/stand/sleep/kneel) - // TODO: parse uint8 standState and update player entity - packet.setReadPos(packet.getSize()); + if (packet.getSize() - packet.getReadPos() >= 1) { + standState_ = packet.readUInt8(); + LOG_INFO("Stand state updated: ", static_cast(standState_), + " (", standState_ == 0 ? "stand" : standState_ == 1 ? "sit" + : standState_ == 7 ? "dead" : standState_ == 8 ? "kneel" : "other", ")"); + } break; case Opcode::SMSG_NEW_TAXI_PATH: // Empty packet - server signals a new flight path was learned