2026-02-02 12:24:50 -08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "game/world_packets.hpp"
|
|
|
|
|
#include "game/character.hpp"
|
|
|
|
|
#include "game/inventory.hpp"
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
#include "game/spell_defines.hpp"
|
|
|
|
|
#include "game/group_defines.hpp"
|
2026-02-02 12:24:50 -08:00
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <vector>
|
2026-02-04 11:31:08 -08:00
|
|
|
#include <deque>
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
#include <array>
|
2026-02-02 12:24:50 -08:00
|
|
|
#include <functional>
|
|
|
|
|
#include <cstdint>
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
#include <unordered_map>
|
|
|
|
|
#include <unordered_set>
|
2026-02-02 12:24:50 -08:00
|
|
|
|
|
|
|
|
namespace wowee {
|
|
|
|
|
namespace network { class WorldSocket; class Packet; }
|
|
|
|
|
|
|
|
|
|
namespace game {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* World connection state
|
|
|
|
|
*/
|
|
|
|
|
enum class WorldState {
|
|
|
|
|
DISCONNECTED, // Not connected
|
|
|
|
|
CONNECTING, // TCP connection in progress
|
|
|
|
|
CONNECTED, // Connected, waiting for challenge
|
|
|
|
|
CHALLENGE_RECEIVED, // Received SMSG_AUTH_CHALLENGE
|
|
|
|
|
AUTH_SENT, // Sent CMSG_AUTH_SESSION, encryption initialized
|
|
|
|
|
AUTHENTICATED, // Received SMSG_AUTH_RESPONSE success
|
|
|
|
|
READY, // Ready for character/world operations
|
|
|
|
|
CHAR_LIST_REQUESTED, // CMSG_CHAR_ENUM sent
|
|
|
|
|
CHAR_LIST_RECEIVED, // SMSG_CHAR_ENUM received
|
|
|
|
|
ENTERING_WORLD, // CMSG_PLAYER_LOGIN sent
|
|
|
|
|
IN_WORLD, // In game world
|
|
|
|
|
FAILED // Connection or authentication failed
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* World connection callbacks
|
|
|
|
|
*/
|
|
|
|
|
using WorldConnectSuccessCallback = std::function<void()>;
|
|
|
|
|
using WorldConnectFailureCallback = std::function<void(const std::string& reason)>;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* GameHandler - Manages world server connection and game protocol
|
|
|
|
|
*
|
|
|
|
|
* Handles:
|
|
|
|
|
* - Connection to world server
|
|
|
|
|
* - Authentication with session key from auth server
|
|
|
|
|
* - RC4 header encryption
|
|
|
|
|
* - Character enumeration
|
|
|
|
|
* - World entry
|
|
|
|
|
* - Game packets
|
|
|
|
|
*/
|
|
|
|
|
class GameHandler {
|
|
|
|
|
public:
|
|
|
|
|
GameHandler();
|
|
|
|
|
~GameHandler();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Connect to world server
|
|
|
|
|
*
|
|
|
|
|
* @param host World server hostname/IP
|
|
|
|
|
* @param port World server port (default 8085)
|
|
|
|
|
* @param sessionKey 40-byte session key from auth server
|
|
|
|
|
* @param accountName Account name (will be uppercased)
|
|
|
|
|
* @param build Client build number (default 12340 for 3.3.5a)
|
|
|
|
|
* @return true if connection initiated
|
|
|
|
|
*/
|
|
|
|
|
bool connect(const std::string& host,
|
|
|
|
|
uint16_t port,
|
|
|
|
|
const std::vector<uint8_t>& sessionKey,
|
|
|
|
|
const std::string& accountName,
|
|
|
|
|
uint32_t build = 12340);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Disconnect from world server
|
|
|
|
|
*/
|
|
|
|
|
void disconnect();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if connected to world server
|
|
|
|
|
*/
|
|
|
|
|
bool isConnected() const;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get current connection state
|
|
|
|
|
*/
|
|
|
|
|
WorldState getState() const { return state; }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Request character list from server
|
|
|
|
|
* Must be called when state is READY or AUTHENTICATED
|
|
|
|
|
*/
|
|
|
|
|
void requestCharacterList();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get list of characters (available after CHAR_LIST_RECEIVED state)
|
|
|
|
|
*/
|
|
|
|
|
const std::vector<Character>& getCharacters() const { return characters; }
|
|
|
|
|
|
2026-02-05 14:13:48 -08:00
|
|
|
void createCharacter(const CharCreateData& data);
|
2026-02-06 03:24:46 -08:00
|
|
|
void deleteCharacter(uint64_t characterGuid);
|
2026-02-05 14:13:48 -08:00
|
|
|
|
|
|
|
|
using CharCreateCallback = std::function<void(bool success, const std::string& message)>;
|
|
|
|
|
void setCharCreateCallback(CharCreateCallback cb) { charCreateCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-06 03:24:46 -08:00
|
|
|
using CharDeleteCallback = std::function<void(bool success)>;
|
|
|
|
|
void setCharDeleteCallback(CharDeleteCallback cb) { charDeleteCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
/**
|
|
|
|
|
* Select and log in with a character
|
|
|
|
|
* @param characterGuid GUID of character to log in with
|
|
|
|
|
*/
|
|
|
|
|
void selectCharacter(uint64_t characterGuid);
|
2026-02-05 14:35:12 -08:00
|
|
|
void setActiveCharacterGuid(uint64_t guid) { activeCharacterGuid_ = guid; }
|
|
|
|
|
uint64_t getActiveCharacterGuid() const { return activeCharacterGuid_; }
|
|
|
|
|
const Character* getActiveCharacter() const;
|
|
|
|
|
const Character* getFirstCharacter() const;
|
2026-02-02 12:24:50 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get current player movement info
|
|
|
|
|
*/
|
|
|
|
|
const MovementInfo& getMovementInfo() const { return movementInfo; }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Send a movement packet
|
|
|
|
|
* @param opcode Movement opcode (CMSG_MOVE_START_FORWARD, etc.)
|
|
|
|
|
*/
|
|
|
|
|
void sendMovement(Opcode opcode);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update player position
|
|
|
|
|
* @param x X coordinate
|
|
|
|
|
* @param y Y coordinate
|
|
|
|
|
* @param z Z coordinate
|
|
|
|
|
*/
|
|
|
|
|
void setPosition(float x, float y, float z);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update player orientation
|
|
|
|
|
* @param orientation Facing direction in radians
|
|
|
|
|
*/
|
|
|
|
|
void setOrientation(float orientation);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get entity manager (for accessing entities in view)
|
|
|
|
|
*/
|
|
|
|
|
EntityManager& getEntityManager() { return entityManager; }
|
|
|
|
|
const EntityManager& getEntityManager() const { return entityManager; }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Send a chat message
|
|
|
|
|
* @param type Chat type (SAY, YELL, WHISPER, etc.)
|
|
|
|
|
* @param message Message text
|
|
|
|
|
* @param target Target name (for whispers, empty otherwise)
|
|
|
|
|
*/
|
|
|
|
|
void sendChatMessage(ChatType type, const std::string& message, const std::string& target = "");
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get chat history (recent messages)
|
|
|
|
|
* @param maxMessages Maximum number of messages to return (0 = all)
|
|
|
|
|
* @return Vector of chat messages
|
|
|
|
|
*/
|
2026-02-04 11:31:08 -08:00
|
|
|
const std::deque<MessageChatData>& getChatHistory() const { return chatHistory; }
|
2026-02-02 12:24:50 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a locally-generated chat message (e.g., emote feedback)
|
|
|
|
|
*/
|
|
|
|
|
void addLocalChatMessage(const MessageChatData& msg);
|
|
|
|
|
|
2026-02-05 14:01:26 -08:00
|
|
|
// Money (copper)
|
|
|
|
|
uint64_t getMoneyCopper() const { return playerMoneyCopper_; }
|
|
|
|
|
|
2026-02-05 14:35:12 -08:00
|
|
|
// Single-player: mark character list ready for selection UI
|
|
|
|
|
void setSinglePlayerCharListReady();
|
2026-02-05 17:40:15 -08:00
|
|
|
struct SinglePlayerSettings {
|
|
|
|
|
bool fullscreen = false;
|
|
|
|
|
bool vsync = true;
|
|
|
|
|
bool shadows = true;
|
|
|
|
|
int resWidth = 1920;
|
|
|
|
|
int resHeight = 1080;
|
|
|
|
|
int musicVolume = 30;
|
|
|
|
|
int sfxVolume = 100;
|
|
|
|
|
float mouseSensitivity = 0.2f;
|
|
|
|
|
bool invertMouse = false;
|
|
|
|
|
};
|
|
|
|
|
bool getSinglePlayerSettings(SinglePlayerSettings& out) const;
|
|
|
|
|
void setSinglePlayerSettings(const SinglePlayerSettings& settings);
|
2026-02-05 14:35:12 -08:00
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
// Inventory
|
|
|
|
|
Inventory& getInventory() { return inventory; }
|
|
|
|
|
const Inventory& getInventory() const { return inventory; }
|
2026-02-06 03:13:42 -08:00
|
|
|
bool consumeOnlineEquipmentDirty() { bool d = onlineEquipDirty_; onlineEquipDirty_ = false; return d; }
|
2026-02-02 12:24:50 -08:00
|
|
|
|
|
|
|
|
// Targeting
|
|
|
|
|
void setTarget(uint64_t guid);
|
|
|
|
|
void clearTarget();
|
|
|
|
|
uint64_t getTargetGuid() const { return targetGuid; }
|
|
|
|
|
std::shared_ptr<Entity> getTarget() const;
|
|
|
|
|
bool hasTarget() const { return targetGuid != 0; }
|
|
|
|
|
void tabTarget(float playerX, float playerY, float playerZ);
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// ---- Phase 1: Name queries ----
|
|
|
|
|
void queryPlayerName(uint64_t guid);
|
|
|
|
|
void queryCreatureInfo(uint32_t entry, uint64_t guid);
|
|
|
|
|
std::string getCachedPlayerName(uint64_t guid) const;
|
|
|
|
|
std::string getCachedCreatureName(uint32_t entry) const;
|
|
|
|
|
|
|
|
|
|
// ---- Phase 2: Combat ----
|
|
|
|
|
void startAutoAttack(uint64_t targetGuid);
|
|
|
|
|
void stopAutoAttack();
|
|
|
|
|
bool isAutoAttacking() const { return autoAttacking; }
|
|
|
|
|
const std::vector<CombatTextEntry>& getCombatText() const { return combatText; }
|
|
|
|
|
void updateCombatText(float deltaTime);
|
|
|
|
|
|
|
|
|
|
// ---- Phase 3: Spells ----
|
|
|
|
|
void castSpell(uint32_t spellId, uint64_t targetGuid = 0);
|
|
|
|
|
void cancelCast();
|
|
|
|
|
void cancelAura(uint32_t spellId);
|
|
|
|
|
const std::vector<uint32_t>& getKnownSpells() const { return knownSpells; }
|
|
|
|
|
bool isCasting() const { return casting; }
|
|
|
|
|
uint32_t getCurrentCastSpellId() const { return currentCastSpellId; }
|
|
|
|
|
float getCastProgress() const { return castTimeTotal > 0 ? (castTimeTotal - castTimeRemaining) / castTimeTotal : 0.0f; }
|
|
|
|
|
float getCastTimeRemaining() const { return castTimeRemaining; }
|
|
|
|
|
|
|
|
|
|
// Action bar
|
|
|
|
|
static constexpr int ACTION_BAR_SLOTS = 12;
|
|
|
|
|
std::array<ActionBarSlot, ACTION_BAR_SLOTS>& getActionBar() { return actionBar; }
|
|
|
|
|
const std::array<ActionBarSlot, ACTION_BAR_SLOTS>& getActionBar() const { return actionBar; }
|
|
|
|
|
void setActionBarSlot(int slot, ActionBarSlot::Type type, uint32_t id);
|
|
|
|
|
|
|
|
|
|
// Auras
|
|
|
|
|
const std::vector<AuraSlot>& getPlayerAuras() const { return playerAuras; }
|
|
|
|
|
const std::vector<AuraSlot>& getTargetAuras() const { return targetAuras; }
|
|
|
|
|
|
2026-02-05 12:01:03 -08:00
|
|
|
// Single-player mode
|
|
|
|
|
void setSinglePlayerMode(bool sp) { singlePlayerMode_ = sp; }
|
|
|
|
|
bool isSinglePlayerMode() const { return singlePlayerMode_; }
|
2026-02-05 14:13:48 -08:00
|
|
|
void simulateMotd(const std::vector<std::string>& lines);
|
2026-02-05 14:35:12 -08:00
|
|
|
void applySinglePlayerStartData(Race race, Class cls);
|
2026-02-05 14:55:42 -08:00
|
|
|
bool loadSinglePlayerCharacterState(uint64_t guid);
|
|
|
|
|
void notifyInventoryChanged();
|
|
|
|
|
void notifyEquipmentChanged();
|
|
|
|
|
void notifyQuestStateChanged();
|
|
|
|
|
void flushSinglePlayerSave();
|
2026-02-05 12:01:03 -08:00
|
|
|
|
|
|
|
|
// NPC death callback (single-player)
|
|
|
|
|
using NpcDeathCallback = std::function<void(uint64_t guid)>;
|
|
|
|
|
void setNpcDeathCallback(NpcDeathCallback cb) { npcDeathCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-06 16:47:07 -08:00
|
|
|
// NPC respawn callback (health 0 → >0, resets animation to idle)
|
|
|
|
|
using NpcRespawnCallback = std::function<void(uint64_t guid)>;
|
|
|
|
|
void setNpcRespawnCallback(NpcRespawnCallback cb) { npcRespawnCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-05 14:01:26 -08:00
|
|
|
// Melee swing callback (for driving animation/SFX)
|
|
|
|
|
using MeleeSwingCallback = std::function<void()>;
|
|
|
|
|
void setMeleeSwingCallback(MeleeSwingCallback cb) { meleeSwingCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-06 03:39:36 -08:00
|
|
|
// NPC swing callback (single-player combat: plays attack animation on NPC)
|
|
|
|
|
using NpcSwingCallback = std::function<void(uint64_t guid)>;
|
|
|
|
|
void setNpcSwingCallback(NpcSwingCallback cb) { npcSwingCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-05 12:01:03 -08:00
|
|
|
// Local player stats (single-player)
|
|
|
|
|
uint32_t getLocalPlayerHealth() const { return localPlayerHealth_; }
|
|
|
|
|
uint32_t getLocalPlayerMaxHealth() const { return localPlayerMaxHealth_; }
|
|
|
|
|
void initLocalPlayerStats(uint32_t level, uint32_t hp, uint32_t maxHp) {
|
|
|
|
|
localPlayerLevel_ = level;
|
|
|
|
|
localPlayerHealth_ = hp;
|
|
|
|
|
localPlayerMaxHealth_ = maxHp;
|
2026-02-05 12:07:58 -08:00
|
|
|
playerNextLevelXp_ = xpForLevel(level);
|
|
|
|
|
playerXp_ = 0;
|
2026-02-05 12:01:03 -08:00
|
|
|
}
|
|
|
|
|
|
2026-02-05 12:07:58 -08:00
|
|
|
// XP tracking (works in both single-player and server modes)
|
|
|
|
|
uint32_t getPlayerXp() const { return playerXp_; }
|
|
|
|
|
uint32_t getPlayerNextLevelXp() const { return playerNextLevelXp_; }
|
|
|
|
|
uint32_t getPlayerLevel() const { return singlePlayerMode_ ? localPlayerLevel_ : serverPlayerLevel_; }
|
2026-02-06 16:53:09 -08:00
|
|
|
static uint32_t killXp(uint32_t playerLevel, uint32_t victimLevel);
|
2026-02-05 12:07:58 -08:00
|
|
|
|
2026-02-04 13:29:27 -08:00
|
|
|
// Hearthstone callback (single-player teleport)
|
|
|
|
|
using HearthstoneCallback = std::function<void()>;
|
|
|
|
|
void setHearthstoneCallback(HearthstoneCallback cb) { hearthstoneCallback = std::move(cb); }
|
|
|
|
|
|
2026-02-05 21:28:21 -08:00
|
|
|
// World entry callback (online mode - triggered when entering world)
|
|
|
|
|
// Parameters: mapId, x, y, z (canonical WoW coordinates)
|
|
|
|
|
using WorldEntryCallback = std::function<void(uint32_t mapId, float x, float y, float z)>;
|
|
|
|
|
void setWorldEntryCallback(WorldEntryCallback cb) { worldEntryCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-05 21:55:52 -08:00
|
|
|
// Creature spawn callback (online mode - triggered when creature enters view)
|
|
|
|
|
// Parameters: guid, displayId, x, y, z (canonical), orientation
|
|
|
|
|
using CreatureSpawnCallback = std::function<void(uint64_t guid, uint32_t displayId, float x, float y, float z, float orientation)>;
|
|
|
|
|
void setCreatureSpawnCallback(CreatureSpawnCallback cb) { creatureSpawnCallback_ = std::move(cb); }
|
|
|
|
|
|
|
|
|
|
// Creature despawn callback (online mode - triggered when creature leaves view)
|
|
|
|
|
using CreatureDespawnCallback = std::function<void(uint64_t guid)>;
|
|
|
|
|
void setCreatureDespawnCallback(CreatureDespawnCallback cb) { creatureDespawnCallback_ = std::move(cb); }
|
|
|
|
|
|
2026-02-06 14:24:38 -08:00
|
|
|
// Faction hostility map (populated from FactionTemplate.dbc by Application)
|
|
|
|
|
void setFactionHostileMap(std::unordered_map<uint32_t, bool> map) { factionHostileMap_ = std::move(map); }
|
|
|
|
|
|
2026-02-06 13:47:03 -08:00
|
|
|
// Creature move callback (online mode - triggered by SMSG_MONSTER_MOVE)
|
|
|
|
|
// Parameters: guid, x, y, z (canonical), duration_ms (0 = instant)
|
|
|
|
|
using CreatureMoveCallback = std::function<void(uint64_t guid, float x, float y, float z, uint32_t durationMs)>;
|
|
|
|
|
void setCreatureMoveCallback(CreatureMoveCallback cb) { creatureMoveCallback_ = std::move(cb); }
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// Cooldowns
|
|
|
|
|
float getSpellCooldown(uint32_t spellId) const;
|
|
|
|
|
|
|
|
|
|
// Player GUID
|
|
|
|
|
uint64_t getPlayerGuid() const { return playerGuid; }
|
|
|
|
|
void setPlayerGuid(uint64_t guid) { playerGuid = guid; }
|
|
|
|
|
|
|
|
|
|
// ---- Phase 4: Group ----
|
|
|
|
|
void inviteToGroup(const std::string& playerName);
|
|
|
|
|
void acceptGroupInvite();
|
|
|
|
|
void declineGroupInvite();
|
|
|
|
|
void leaveGroup();
|
|
|
|
|
bool isInGroup() const { return !partyData.isEmpty(); }
|
|
|
|
|
const GroupListData& getPartyData() const { return partyData; }
|
|
|
|
|
bool hasPendingGroupInvite() const { return pendingGroupInvite; }
|
|
|
|
|
const std::string& getPendingInviterName() const { return pendingInviterName; }
|
|
|
|
|
|
|
|
|
|
// ---- Phase 5: Loot ----
|
|
|
|
|
void lootTarget(uint64_t guid);
|
|
|
|
|
void lootItem(uint8_t slotIndex);
|
|
|
|
|
void closeLoot();
|
|
|
|
|
bool isLootWindowOpen() const { return lootWindowOpen; }
|
|
|
|
|
const LootResponseData& getCurrentLoot() const { return currentLoot; }
|
|
|
|
|
|
|
|
|
|
// NPC Gossip
|
|
|
|
|
void interactWithNpc(uint64_t guid);
|
|
|
|
|
void selectGossipOption(uint32_t optionId);
|
2026-02-06 11:45:35 -08:00
|
|
|
void selectGossipQuest(uint32_t questId);
|
2026-02-06 11:59:51 -08:00
|
|
|
void acceptQuest();
|
|
|
|
|
void declineQuest();
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
void closeGossip();
|
|
|
|
|
bool isGossipWindowOpen() const { return gossipWindowOpen; }
|
|
|
|
|
const GossipMessageData& getCurrentGossip() const { return currentGossip; }
|
2026-02-06 11:59:51 -08:00
|
|
|
bool isQuestDetailsOpen() const { return questDetailsOpen; }
|
|
|
|
|
const QuestDetailsData& getQuestDetails() const { return currentQuestDetails; }
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
|
2026-02-06 13:47:03 -08:00
|
|
|
// Quest log
|
|
|
|
|
struct QuestLogEntry {
|
|
|
|
|
uint32_t questId = 0;
|
|
|
|
|
std::string title;
|
|
|
|
|
std::string objectives;
|
|
|
|
|
bool complete = false;
|
|
|
|
|
};
|
|
|
|
|
const std::vector<QuestLogEntry>& getQuestLog() const { return questLog_; }
|
|
|
|
|
void abandonQuest(uint32_t questId);
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// Vendor
|
|
|
|
|
void openVendor(uint64_t npcGuid);
|
2026-02-06 11:59:51 -08:00
|
|
|
void closeVendor();
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
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);
|
2026-02-06 13:47:03 -08:00
|
|
|
void sellItemBySlot(int backpackIndex);
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
bool isVendorWindowOpen() const { return vendorWindowOpen; }
|
|
|
|
|
const ListInventoryData& getVendorItems() const { return currentVendorItems; }
|
2026-02-06 11:59:51 -08:00
|
|
|
const ItemQueryResponseData* getItemInfo(uint32_t itemId) const {
|
|
|
|
|
auto it = itemInfoCache_.find(itemId);
|
|
|
|
|
return (it != itemInfoCache_.end()) ? &it->second : nullptr;
|
|
|
|
|
}
|
Fix camera orbit, deselect, chat formatting, loot/vendor bugs, critter hostility, and character screen
Smooth idle camera orbit without jump at loop boundary, click empty space to
deselect target, auto-target when attacked, fix critter hostility so neutral
factions aren't flagged red, add armor/stats to item templates, fix loot
iterator invalidation, show item template names as fallback, position drop
confirmation at cursor, remove [SYSTEM] chat prefix, show NPC names in monster
say/yell, and prevent auto-login on character select screen.
2026-02-06 16:40:44 -08:00
|
|
|
std::string getItemTemplateName(uint32_t itemId) const;
|
|
|
|
|
ItemQuality getItemTemplateQuality(uint32_t itemId) const;
|
2026-02-06 13:47:03 -08:00
|
|
|
uint64_t getBackpackItemGuid(int index) const {
|
|
|
|
|
if (index < 0 || index >= static_cast<int>(backpackSlotGuids_.size())) return 0;
|
|
|
|
|
return backpackSlotGuids_[index];
|
|
|
|
|
}
|
|
|
|
|
uint64_t getVendorGuid() const { return currentVendorItems.vendorGuid; }
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
/**
|
|
|
|
|
* Set callbacks
|
|
|
|
|
*/
|
|
|
|
|
void setOnSuccess(WorldConnectSuccessCallback callback) { onSuccess = callback; }
|
|
|
|
|
void setOnFailure(WorldConnectFailureCallback callback) { onFailure = callback; }
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Update - call regularly (e.g., each frame)
|
|
|
|
|
*
|
|
|
|
|
* @param deltaTime Time since last update in seconds
|
|
|
|
|
*/
|
|
|
|
|
void update(float deltaTime);
|
|
|
|
|
|
2026-02-05 14:35:12 -08:00
|
|
|
struct SinglePlayerCreateInfo {
|
|
|
|
|
uint32_t mapId = 0;
|
|
|
|
|
uint32_t zoneId = 0;
|
|
|
|
|
float x = 0.0f;
|
|
|
|
|
float y = 0.0f;
|
|
|
|
|
float z = 0.0f;
|
|
|
|
|
float orientation = 0.0f;
|
|
|
|
|
};
|
|
|
|
|
bool getSinglePlayerCreateInfo(Race race, Class cls, SinglePlayerCreateInfo& out) const;
|
|
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
private:
|
|
|
|
|
/**
|
|
|
|
|
* Handle incoming packet from world server
|
|
|
|
|
*/
|
|
|
|
|
void handlePacket(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_AUTH_CHALLENGE from server
|
|
|
|
|
*/
|
|
|
|
|
void handleAuthChallenge(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_AUTH_RESPONSE from server
|
|
|
|
|
*/
|
|
|
|
|
void handleAuthResponse(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_CHAR_ENUM from server
|
|
|
|
|
*/
|
|
|
|
|
void handleCharEnum(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_LOGIN_VERIFY_WORLD from server
|
|
|
|
|
*/
|
|
|
|
|
void handleLoginVerifyWorld(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_ACCOUNT_DATA_TIMES from server
|
|
|
|
|
*/
|
|
|
|
|
void handleAccountDataTimes(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_MOTD from server
|
|
|
|
|
*/
|
|
|
|
|
void handleMotd(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_PONG from server
|
|
|
|
|
*/
|
|
|
|
|
void handlePong(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_UPDATE_OBJECT from server
|
|
|
|
|
*/
|
|
|
|
|
void handleUpdateObject(network::Packet& packet);
|
|
|
|
|
|
2026-02-05 21:55:52 -08:00
|
|
|
/**
|
|
|
|
|
* Handle SMSG_COMPRESSED_UPDATE_OBJECT from server
|
|
|
|
|
*/
|
|
|
|
|
void handleCompressedUpdateObject(network::Packet& packet);
|
|
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
/**
|
|
|
|
|
* Handle SMSG_DESTROY_OBJECT from server
|
|
|
|
|
*/
|
|
|
|
|
void handleDestroyObject(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle SMSG_MESSAGECHAT from server
|
|
|
|
|
*/
|
|
|
|
|
void handleMessageChat(network::Packet& packet);
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// ---- Phase 1 handlers ----
|
|
|
|
|
void handleNameQueryResponse(network::Packet& packet);
|
|
|
|
|
void handleCreatureQueryResponse(network::Packet& packet);
|
2026-02-06 03:11:43 -08:00
|
|
|
void handleItemQueryResponse(network::Packet& packet);
|
|
|
|
|
void queryItemInfo(uint32_t entry, uint64_t guid);
|
|
|
|
|
void rebuildOnlineInventory();
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
|
|
|
|
|
// ---- Phase 2 handlers ----
|
|
|
|
|
void handleAttackStart(network::Packet& packet);
|
|
|
|
|
void handleAttackStop(network::Packet& packet);
|
|
|
|
|
void handleAttackerStateUpdate(network::Packet& packet);
|
|
|
|
|
void handleSpellDamageLog(network::Packet& packet);
|
|
|
|
|
void handleSpellHealLog(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
// ---- Phase 3 handlers ----
|
|
|
|
|
void handleInitialSpells(network::Packet& packet);
|
|
|
|
|
void handleCastFailed(network::Packet& packet);
|
|
|
|
|
void handleSpellStart(network::Packet& packet);
|
|
|
|
|
void handleSpellGo(network::Packet& packet);
|
|
|
|
|
void handleSpellCooldown(network::Packet& packet);
|
|
|
|
|
void handleCooldownEvent(network::Packet& packet);
|
|
|
|
|
void handleAuraUpdate(network::Packet& packet, bool isAll);
|
|
|
|
|
void handleLearnedSpell(network::Packet& packet);
|
|
|
|
|
void handleRemovedSpell(network::Packet& packet);
|
|
|
|
|
|
|
|
|
|
// ---- Phase 4 handlers ----
|
|
|
|
|
void handleGroupInvite(network::Packet& packet);
|
|
|
|
|
void handleGroupDecline(network::Packet& packet);
|
|
|
|
|
void handleGroupList(network::Packet& packet);
|
|
|
|
|
void handleGroupUninvite(network::Packet& packet);
|
|
|
|
|
void handlePartyCommandResult(network::Packet& packet);
|
|
|
|
|
|
2026-02-05 14:13:48 -08:00
|
|
|
// ---- Character creation handler ----
|
|
|
|
|
void handleCharCreateResponse(network::Packet& packet);
|
|
|
|
|
|
2026-02-05 12:07:58 -08:00
|
|
|
// ---- XP handler ----
|
|
|
|
|
void handleXpGain(network::Packet& packet);
|
|
|
|
|
|
2026-02-06 13:47:03 -08:00
|
|
|
// ---- Creature movement handler ----
|
|
|
|
|
void handleMonsterMove(network::Packet& packet);
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// ---- Phase 5 handlers ----
|
|
|
|
|
void handleLootResponse(network::Packet& packet);
|
|
|
|
|
void handleLootReleaseResponse(network::Packet& packet);
|
|
|
|
|
void handleLootRemoved(network::Packet& packet);
|
|
|
|
|
void handleGossipMessage(network::Packet& packet);
|
|
|
|
|
void handleGossipComplete(network::Packet& packet);
|
2026-02-06 11:59:51 -08:00
|
|
|
void handleQuestDetails(network::Packet& packet);
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
void handleListInventory(network::Packet& packet);
|
2026-02-05 14:01:26 -08:00
|
|
|
LootResponseData generateLocalLoot(uint64_t guid);
|
|
|
|
|
void simulateLootResponse(const LootResponseData& data);
|
|
|
|
|
void simulateLootRelease();
|
|
|
|
|
void simulateLootRemove(uint8_t slotIndex);
|
|
|
|
|
void simulateXpGain(uint64_t victimGuid, uint32_t totalXp);
|
|
|
|
|
void addMoneyCopper(uint32_t amount);
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
|
|
|
|
|
void addCombatText(CombatTextEntry::Type type, int32_t amount, uint32_t spellId, bool isPlayerSource);
|
2026-02-05 13:22:15 -08:00
|
|
|
void addSystemChatMessage(const std::string& message);
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
/**
|
|
|
|
|
* Send CMSG_PING to server (heartbeat)
|
|
|
|
|
*/
|
|
|
|
|
void sendPing();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Send CMSG_AUTH_SESSION to server
|
|
|
|
|
*/
|
|
|
|
|
void sendAuthSession();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Generate random client seed
|
|
|
|
|
*/
|
|
|
|
|
uint32_t generateClientSeed();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Change state with logging
|
|
|
|
|
*/
|
|
|
|
|
void setState(WorldState newState);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fail connection with reason
|
|
|
|
|
*/
|
|
|
|
|
void fail(const std::string& reason);
|
|
|
|
|
|
|
|
|
|
// Network
|
|
|
|
|
std::unique_ptr<network::WorldSocket> socket;
|
|
|
|
|
|
|
|
|
|
// State
|
|
|
|
|
WorldState state = WorldState::DISCONNECTED;
|
|
|
|
|
|
|
|
|
|
// Authentication data
|
|
|
|
|
std::vector<uint8_t> sessionKey; // 40-byte session key from auth server
|
|
|
|
|
std::string accountName; // Account name
|
|
|
|
|
uint32_t build = 12340; // Client build (3.3.5a)
|
|
|
|
|
uint32_t clientSeed = 0; // Random seed generated by client
|
|
|
|
|
uint32_t serverSeed = 0; // Seed from SMSG_AUTH_CHALLENGE
|
|
|
|
|
|
|
|
|
|
// Characters
|
|
|
|
|
std::vector<Character> characters; // Character list from SMSG_CHAR_ENUM
|
|
|
|
|
|
|
|
|
|
// Movement
|
|
|
|
|
MovementInfo movementInfo; // Current player movement state
|
|
|
|
|
uint32_t movementTime = 0; // Movement timestamp counter
|
|
|
|
|
|
|
|
|
|
// Inventory
|
|
|
|
|
Inventory inventory;
|
|
|
|
|
|
|
|
|
|
// Entity tracking
|
|
|
|
|
EntityManager entityManager; // Manages all entities in view
|
|
|
|
|
|
|
|
|
|
// Chat
|
2026-02-04 11:31:08 -08:00
|
|
|
std::deque<MessageChatData> chatHistory; // Recent chat messages
|
2026-02-02 12:24:50 -08:00
|
|
|
size_t maxChatHistory = 100; // Maximum chat messages to keep
|
|
|
|
|
|
|
|
|
|
// Targeting
|
|
|
|
|
uint64_t targetGuid = 0;
|
|
|
|
|
std::vector<uint64_t> tabCycleList;
|
|
|
|
|
int tabCycleIndex = -1;
|
|
|
|
|
bool tabCycleStale = true;
|
|
|
|
|
|
|
|
|
|
// Heartbeat
|
|
|
|
|
uint32_t pingSequence = 0; // Ping sequence number (increments)
|
|
|
|
|
float timeSinceLastPing = 0.0f; // Time since last ping sent (seconds)
|
|
|
|
|
float pingInterval = 30.0f; // Ping interval (30 seconds)
|
|
|
|
|
uint32_t lastLatency = 0; // Last measured latency (milliseconds)
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// Player GUID
|
|
|
|
|
uint64_t playerGuid = 0;
|
|
|
|
|
|
|
|
|
|
// ---- Phase 1: Name caches ----
|
|
|
|
|
std::unordered_map<uint64_t, std::string> playerNameCache;
|
|
|
|
|
std::unordered_set<uint64_t> pendingNameQueries;
|
|
|
|
|
std::unordered_map<uint32_t, CreatureQueryResponseData> creatureInfoCache;
|
|
|
|
|
std::unordered_set<uint32_t> pendingCreatureQueries;
|
|
|
|
|
|
2026-02-06 03:11:43 -08:00
|
|
|
// ---- Online item tracking ----
|
|
|
|
|
struct OnlineItemInfo {
|
|
|
|
|
uint32_t entry = 0;
|
|
|
|
|
uint32_t stackCount = 1;
|
|
|
|
|
};
|
|
|
|
|
std::unordered_map<uint64_t, OnlineItemInfo> onlineItems_;
|
|
|
|
|
std::unordered_map<uint32_t, ItemQueryResponseData> itemInfoCache_;
|
|
|
|
|
std::unordered_set<uint32_t> pendingItemQueries_;
|
|
|
|
|
std::array<uint64_t, 23> equipSlotGuids_{};
|
|
|
|
|
std::array<uint64_t, 16> backpackSlotGuids_{};
|
2026-02-06 03:13:42 -08:00
|
|
|
bool onlineEquipDirty_ = false;
|
2026-02-06 03:11:43 -08:00
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// ---- Phase 2: Combat ----
|
|
|
|
|
bool autoAttacking = false;
|
|
|
|
|
uint64_t autoAttackTarget = 0;
|
|
|
|
|
std::vector<CombatTextEntry> combatText;
|
|
|
|
|
|
|
|
|
|
// ---- Phase 3: Spells ----
|
2026-02-04 13:29:27 -08:00
|
|
|
HearthstoneCallback hearthstoneCallback;
|
2026-02-05 21:28:21 -08:00
|
|
|
WorldEntryCallback worldEntryCallback_;
|
2026-02-05 21:55:52 -08:00
|
|
|
CreatureSpawnCallback creatureSpawnCallback_;
|
|
|
|
|
CreatureDespawnCallback creatureDespawnCallback_;
|
2026-02-06 13:47:03 -08:00
|
|
|
CreatureMoveCallback creatureMoveCallback_;
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
std::vector<uint32_t> knownSpells;
|
|
|
|
|
std::unordered_map<uint32_t, float> spellCooldowns; // spellId -> remaining seconds
|
|
|
|
|
uint8_t castCount = 0;
|
|
|
|
|
bool casting = false;
|
|
|
|
|
uint32_t currentCastSpellId = 0;
|
|
|
|
|
float castTimeRemaining = 0.0f;
|
|
|
|
|
float castTimeTotal = 0.0f;
|
|
|
|
|
std::array<ActionBarSlot, 12> actionBar{};
|
|
|
|
|
std::vector<AuraSlot> playerAuras;
|
|
|
|
|
std::vector<AuraSlot> targetAuras;
|
|
|
|
|
|
|
|
|
|
// ---- Phase 4: Group ----
|
|
|
|
|
GroupListData partyData;
|
|
|
|
|
bool pendingGroupInvite = false;
|
|
|
|
|
std::string pendingInviterName;
|
|
|
|
|
|
2026-02-05 14:35:12 -08:00
|
|
|
uint64_t activeCharacterGuid_ = 0;
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// ---- Phase 5: Loot ----
|
|
|
|
|
bool lootWindowOpen = false;
|
|
|
|
|
LootResponseData currentLoot;
|
2026-02-05 14:01:26 -08:00
|
|
|
struct LocalLootState {
|
|
|
|
|
LootResponseData data;
|
|
|
|
|
bool moneyTaken = false;
|
|
|
|
|
};
|
|
|
|
|
std::unordered_map<uint64_t, LocalLootState> localLootState_;
|
|
|
|
|
uint64_t playerMoneyCopper_ = 0;
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
|
|
|
|
|
// Gossip
|
|
|
|
|
bool gossipWindowOpen = false;
|
|
|
|
|
GossipMessageData currentGossip;
|
|
|
|
|
|
2026-02-06 11:59:51 -08:00
|
|
|
// Quest details
|
|
|
|
|
bool questDetailsOpen = false;
|
|
|
|
|
QuestDetailsData currentQuestDetails;
|
|
|
|
|
|
2026-02-06 13:47:03 -08:00
|
|
|
// Quest log
|
|
|
|
|
std::vector<QuestLogEntry> questLog_;
|
|
|
|
|
|
2026-02-06 14:24:38 -08:00
|
|
|
// Faction hostility lookup (populated from FactionTemplate.dbc)
|
|
|
|
|
std::unordered_map<uint32_t, bool> factionHostileMap_;
|
|
|
|
|
bool isHostileFaction(uint32_t factionTemplateId) const {
|
|
|
|
|
auto it = factionHostileMap_.find(factionTemplateId);
|
|
|
|
|
return it != factionHostileMap_.end() ? it->second : true; // default hostile if unknown
|
|
|
|
|
}
|
|
|
|
|
|
Add gameplay systems: combat, spells, groups, loot, vendors, and UI
Implement ~70 new protocol opcodes across 5 phases while maintaining
full 3.3.5a private server compatibility:
- Phase 1: Server-aware targeting (CMSG_SET_SELECTION), player/creature
name queries, CMSG_SET_ACTIVE_MOVER after login
- Phase 2: Auto-attack, melee/spell damage parsing, health/mana/power
tracking from UPDATE_OBJECT fields, floating combat text
- Phase 3: Spell casting, action bar (12 slots, keys 1-=), cast bar,
cooldown tracking, aura/buff system with cancellation
- Phase 4: Group invite/accept/decline/leave, party frames UI,
/invite chat command
- Phase 5: Loot window, NPC gossip dialog, vendor buy/sell interface
Also: disable debug HUD/panels by default, gate 3D rendering to
IN_GAME state only, fix window resize not updating UI positions.
2026-02-04 10:30:52 -08:00
|
|
|
// Vendor
|
|
|
|
|
bool vendorWindowOpen = false;
|
|
|
|
|
ListInventoryData currentVendorItems;
|
|
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
// Callbacks
|
|
|
|
|
WorldConnectSuccessCallback onSuccess;
|
|
|
|
|
WorldConnectFailureCallback onFailure;
|
2026-02-05 14:13:48 -08:00
|
|
|
CharCreateCallback charCreateCallback_;
|
2026-02-06 03:24:46 -08:00
|
|
|
CharDeleteCallback charDeleteCallback_;
|
2026-02-05 14:18:41 -08:00
|
|
|
bool pendingCharCreateResult_ = false;
|
|
|
|
|
bool pendingCharCreateSuccess_ = false;
|
|
|
|
|
std::string pendingCharCreateMsg_;
|
2026-02-05 12:01:03 -08:00
|
|
|
|
2026-02-05 12:07:58 -08:00
|
|
|
// ---- XP tracking ----
|
|
|
|
|
uint32_t playerXp_ = 0;
|
|
|
|
|
uint32_t playerNextLevelXp_ = 0;
|
|
|
|
|
uint32_t serverPlayerLevel_ = 1;
|
2026-02-05 14:01:26 -08:00
|
|
|
void awardLocalXp(uint64_t victimGuid, uint32_t victimLevel);
|
2026-02-05 12:07:58 -08:00
|
|
|
void levelUp();
|
|
|
|
|
static uint32_t xpForLevel(uint32_t level);
|
|
|
|
|
|
2026-02-05 12:01:03 -08:00
|
|
|
// ---- Single-player combat ----
|
|
|
|
|
bool singlePlayerMode_ = false;
|
|
|
|
|
float swingTimer_ = 0.0f;
|
|
|
|
|
static constexpr float SWING_SPEED = 2.0f;
|
|
|
|
|
NpcDeathCallback npcDeathCallback_;
|
2026-02-06 16:47:07 -08:00
|
|
|
NpcRespawnCallback npcRespawnCallback_;
|
2026-02-05 14:01:26 -08:00
|
|
|
MeleeSwingCallback meleeSwingCallback_;
|
2026-02-06 03:39:36 -08:00
|
|
|
NpcSwingCallback npcSwingCallback_;
|
2026-02-05 12:01:03 -08:00
|
|
|
uint32_t localPlayerHealth_ = 0;
|
|
|
|
|
uint32_t localPlayerMaxHealth_ = 0;
|
|
|
|
|
uint32_t localPlayerLevel_ = 1;
|
|
|
|
|
|
|
|
|
|
struct NpcAggroEntry {
|
|
|
|
|
uint64_t guid;
|
|
|
|
|
float swingTimer;
|
|
|
|
|
};
|
|
|
|
|
std::vector<NpcAggroEntry> aggroList_;
|
|
|
|
|
|
|
|
|
|
void updateLocalCombat(float deltaTime);
|
|
|
|
|
void updateNpcAggro(float deltaTime);
|
|
|
|
|
void performPlayerSwing();
|
|
|
|
|
void performNpcSwing(uint64_t guid);
|
|
|
|
|
void handleNpcDeath(uint64_t guid);
|
|
|
|
|
void aggroNpc(uint64_t guid);
|
|
|
|
|
bool isNpcAggroed(uint64_t guid) const;
|
2026-02-05 14:55:42 -08:00
|
|
|
|
|
|
|
|
// ---- Single-player persistence ----
|
|
|
|
|
enum SinglePlayerDirty : uint32_t {
|
|
|
|
|
SP_DIRTY_NONE = 0,
|
|
|
|
|
SP_DIRTY_CHAR = 1 << 0,
|
|
|
|
|
SP_DIRTY_INVENTORY = 1 << 1,
|
|
|
|
|
SP_DIRTY_SPELLS = 1 << 2,
|
|
|
|
|
SP_DIRTY_ACTIONBAR = 1 << 3,
|
|
|
|
|
SP_DIRTY_AURAS = 1 << 4,
|
|
|
|
|
SP_DIRTY_QUESTS = 1 << 5,
|
|
|
|
|
SP_DIRTY_MONEY = 1 << 6,
|
|
|
|
|
SP_DIRTY_XP = 1 << 7,
|
|
|
|
|
SP_DIRTY_POSITION = 1 << 8,
|
|
|
|
|
SP_DIRTY_STATS = 1 << 9,
|
2026-02-05 17:40:15 -08:00
|
|
|
SP_DIRTY_SETTINGS = 1 << 10,
|
2026-02-05 14:55:42 -08:00
|
|
|
SP_DIRTY_ALL = 0xFFFFFFFFu
|
|
|
|
|
};
|
|
|
|
|
void markSinglePlayerDirty(uint32_t flags, bool highPriority);
|
|
|
|
|
void loadSinglePlayerCharacters();
|
|
|
|
|
void saveSinglePlayerCharacterState(bool force);
|
|
|
|
|
|
|
|
|
|
uint32_t spDirtyFlags_ = SP_DIRTY_NONE;
|
|
|
|
|
bool spDirtyHighPriority_ = false;
|
|
|
|
|
float spDirtyTimer_ = 0.0f;
|
|
|
|
|
float spPeriodicTimer_ = 0.0f;
|
|
|
|
|
float spLastDirtyX_ = 0.0f;
|
|
|
|
|
float spLastDirtyY_ = 0.0f;
|
|
|
|
|
float spLastDirtyZ_ = 0.0f;
|
|
|
|
|
float spLastDirtyOrientation_ = 0.0f;
|
|
|
|
|
std::unordered_map<uint64_t, bool> spHasState_;
|
|
|
|
|
std::unordered_map<uint64_t, float> spSavedOrientation_;
|
2026-02-05 17:40:15 -08:00
|
|
|
SinglePlayerSettings spSettings_{};
|
|
|
|
|
bool spSettingsLoaded_ = false;
|
2026-02-02 12:24:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace game
|
|
|
|
|
} // namespace wowee
|