Fix online interactions, UI, and inventory sync

This commit is contained in:
Kelsi 2026-02-06 18:34:45 -08:00
parent 7436420cd1
commit fdc614902b
14 changed files with 525 additions and 143 deletions

View file

@ -67,6 +67,9 @@ public:
// Teleport to a spawn preset location (single-player only)
void teleportTo(int presetIndex);
// Render bounds lookup (for click targeting / selection)
bool getRenderBoundsForGuid(uint64_t guid, glm::vec3& outCenter, float& outRadius) const;
// Character skin composite state (saved at spawn for re-compositing on equipment change)
const std::string& getBodySkinPath() const { return bodySkinPath_; }
const std::vector<std::string>& getUnderwearPaths() const { return underwearPaths_; }

View file

@ -110,6 +110,7 @@ public:
using CharDeleteCallback = std::function<void(bool success)>;
void setCharDeleteCallback(CharDeleteCallback cb) { charDeleteCallback_ = std::move(cb); }
uint8_t getLastCharDeleteResult() const { return lastCharDeleteResult_; }
/**
* Select and log in with a character
@ -214,6 +215,7 @@ public:
void startAutoAttack(uint64_t targetGuid);
void stopAutoAttack();
bool isAutoAttacking() const { return autoAttacking; }
bool isAggressiveTowardPlayer(uint64_t guid) const { return hostileAttackers_.count(guid) > 0; }
const std::vector<CombatTextEntry>& getCombatText() const { return combatText; }
void updateCombatText(float deltaTime);
@ -332,6 +334,7 @@ public:
void lootTarget(uint64_t guid);
void lootItem(uint8_t slotIndex);
void closeLoot();
void activateSpiritHealer(uint64_t npcGuid);
bool isLootWindowOpen() const { return lootWindowOpen; }
const LootResponseData& getCurrentLoot() const { return currentLoot; }
@ -363,6 +366,8 @@ public:
void buyItem(uint64_t vendorGuid, uint32_t itemId, uint32_t slot, uint8_t count);
void sellItem(uint64_t vendorGuid, uint64_t itemGuid, uint8_t count);
void sellItemBySlot(int backpackIndex);
void autoEquipItemBySlot(int backpackIndex);
void useItemBySlot(int backpackIndex);
bool isVendorWindowOpen() const { return vendorWindowOpen; }
const ListInventoryData& getVendorItems() const { return currentVendorItems; }
const ItemQueryResponseData* getItemInfo(uint32_t itemId) const {
@ -467,6 +472,8 @@ private:
void handleItemQueryResponse(network::Packet& packet);
void queryItemInfo(uint32_t entry, uint64_t guid);
void rebuildOnlineInventory();
void detectInventorySlotBases(const std::map<uint16_t, uint32_t>& fields);
bool applyInventoryFields(const std::map<uint16_t, uint32_t>& fields);
// ---- Phase 2 handlers ----
void handleAttackStart(network::Packet& packet);
@ -606,11 +613,16 @@ private:
std::unordered_set<uint32_t> pendingItemQueries_;
std::array<uint64_t, 23> equipSlotGuids_{};
std::array<uint64_t, 16> backpackSlotGuids_{};
int invSlotBase_ = -1;
int packSlotBase_ = -1;
std::map<uint16_t, uint32_t> lastPlayerFields_;
bool onlineEquipDirty_ = false;
// ---- Phase 2: Combat ----
bool autoAttacking = false;
uint64_t autoAttackTarget = 0;
bool autoAttackOutOfRange_ = false;
std::unordered_set<uint64_t> hostileAttackers_;
std::vector<CombatTextEntry> combatText;
// ---- Phase 3: Spells ----
@ -674,6 +686,7 @@ private:
WorldConnectFailureCallback onFailure;
CharCreateCallback charCreateCallback_;
CharDeleteCallback charDeleteCallback_;
uint8_t lastCharDeleteResult_ = 0xFF;
bool pendingCharCreateResult_ = false;
bool pendingCharCreateSuccess_ = false;
std::string pendingCharCreateMsg_;

View file

@ -162,11 +162,13 @@ enum class Opcode : uint16_t {
// ---- Phase 5: Item/Equip ----
CMSG_ITEM_QUERY_SINGLE = 0x056,
SMSG_ITEM_QUERY_SINGLE_RESPONSE = 0x058,
CMSG_USE_ITEM = 0x00AB,
CMSG_AUTOEQUIP_ITEM = 0x10A,
SMSG_INVENTORY_CHANGE_FAILURE = 0x112,
// ---- Death/Respawn ----
CMSG_REPOP_REQUEST = 0x015A,
CMSG_SPIRIT_HEALER_ACTIVATE = 0x0176,
};
} // namespace game

View file

@ -1125,6 +1125,18 @@ public:
static network::Packet build(uint8_t slotIndex);
};
/** CMSG_USE_ITEM packet builder */
class UseItemPacket {
public:
static network::Packet build(uint8_t bagIndex, uint8_t slotIndex, uint64_t itemGuid);
};
/** CMSG_AUTOEQUIP_ITEM packet builder */
class AutoEquipItemPacket {
public:
static network::Packet build(uint64_t itemGuid);
};
/** CMSG_LOOT_RELEASE packet builder */
class LootReleasePacket {
public:
@ -1274,5 +1286,11 @@ public:
static network::Packet build();
};
/** CMSG_SPIRIT_HEALER_ACTIVATE packet builder */
class SpiritHealerActivatePacket {
public:
static network::Packet build(uint64_t npcGuid);
};
} // namespace game
} // namespace wowee

View file

@ -72,6 +72,7 @@ public:
bool hasAnimation(uint32_t instanceId, uint32_t animationId) const;
bool getAnimationSequences(uint32_t instanceId, std::vector<pipeline::M2Sequence>& out) const;
bool getInstanceModelName(uint32_t instanceId, std::string& modelName) const;
bool getInstanceBounds(uint32_t instanceId, glm::vec3& outCenter, float& outRadius) const;
/** Attach a weapon model to a character instance at the given attachment point. */
bool attachWeapon(uint32_t charInstanceId, uint32_t attachmentId,

View file

@ -52,12 +52,16 @@ private:
char chatInputBuffer[512] = "";
bool chatInputActive = false;
int selectedChatType = 0; // 0=SAY, 1=YELL, 2=PARTY, etc.
bool chatInputMoveCursorToEnd = false;
// UI state
bool showEntityWindow = false;
bool showChatWindow = true;
bool showPlayerInfo = false;
bool refocusChatInput = false;
bool chatWindowLocked = true;
ImVec2 chatWindowPos_ = ImVec2(0.0f, 0.0f);
bool chatWindowPosInit_ = false;
bool showTeleporter = false;
bool showEscapeMenu = false;
bool showEscapeSettingsNotice = false;

View file

@ -38,6 +38,7 @@ public:
vendorMode_ = enabled;
gameHandler_ = handler;
}
void setGameHandler(game::GameHandler* handler) { gameHandler_ = handler; }
/// Set asset manager for icon/model loading
void setAssetManager(pipeline::AssetManager* am) { assetManager_ = am; }