2026-02-02 12:24:50 -08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "game/game_handler.hpp"
|
|
|
|
|
#include "game/inventory.hpp"
|
2026-02-21 19:41:21 -08:00
|
|
|
// WorldMap is now owned by Renderer, accessed via getWorldMap()
|
2026-02-06 14:24:38 -08:00
|
|
|
#include "rendering/character_preview.hpp"
|
2026-02-02 12:24:50 -08:00
|
|
|
#include "ui/inventory_screen.hpp"
|
2026-02-06 13:47:03 -08:00
|
|
|
#include "ui/quest_log_screen.hpp"
|
2026-02-04 11:31:08 -08:00
|
|
|
#include "ui/spellbook_screen.hpp"
|
2026-02-06 16:04:25 -08:00
|
|
|
#include "ui/talent_screen.hpp"
|
2026-03-11 06:51:48 -07:00
|
|
|
#include "ui/keybinding_manager.hpp"
|
2026-03-31 08:53:14 +03:00
|
|
|
#include "ui/chat_panel.hpp"
|
2026-03-31 09:18:17 +03:00
|
|
|
#include "ui/toast_manager.hpp"
|
2026-03-31 10:07:58 +03:00
|
|
|
#include "ui/dialog_manager.hpp"
|
|
|
|
|
#include "ui/settings_panel.hpp"
|
2026-03-31 19:49:52 +03:00
|
|
|
#include "ui/combat_ui.hpp"
|
|
|
|
|
#include "ui/social_panel.hpp"
|
|
|
|
|
#include "ui/action_bar_panel.hpp"
|
|
|
|
|
#include "ui/window_manager.hpp"
|
`chore(application): extract appearance controller and unify UI flow`
- Refactor UI application architecture: extracted appearance controller into ui_services.hpp + implementation updates
- Update UI components and managers to use new service layer:
- `action_bar_panel`, `auth_screen`, `character_screen`, `chat_panel`, `combat_ui`, `dialog_manager`, `game_screen`, `settings_panel`, `social_panel`, `toast_manager`, `ui_manager`, `window_manager`
- Adjust core application entrypoints:
- application.cpp
- Update component implementations for new controller flow:
- action_bar_panel.cpp, `chat_panel.cpp`, `combat_ui.cpp`, `dialog_manager.cpp`, `game_screen.cpp`, `settings_panel.cpp`, `social_panel.cpp`, `toast_manager.cpp`, `window_manager.cpp`
These staged changes implement a major architectural refactor for UI/appearance controller separation
2026-04-01 20:59:17 +03:00
|
|
|
#include "ui/ui_services.hpp"
|
2026-02-22 03:32:08 -08:00
|
|
|
#include <vulkan/vulkan.h>
|
2026-02-02 12:24:50 -08:00
|
|
|
#include <imgui.h>
|
|
|
|
|
#include <string>
|
2026-02-05 15:07:13 -08:00
|
|
|
#include <unordered_map>
|
2026-02-02 12:24:50 -08:00
|
|
|
|
2026-02-06 14:30:54 -08:00
|
|
|
namespace wowee {
|
2026-04-01 20:38:37 +03:00
|
|
|
namespace core { class AppearanceComposer; }
|
2026-02-06 14:30:54 -08:00
|
|
|
namespace pipeline { class AssetManager; }
|
2026-03-25 12:52:07 -07:00
|
|
|
namespace rendering { class Renderer; }
|
2026-02-06 14:30:54 -08:00
|
|
|
namespace ui {
|
2026-02-02 12:24:50 -08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* In-game screen UI
|
|
|
|
|
*
|
|
|
|
|
* Displays player info, entity list, chat, and game controls
|
|
|
|
|
*/
|
|
|
|
|
class GameScreen {
|
|
|
|
|
public:
|
|
|
|
|
GameScreen();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render the UI
|
|
|
|
|
* @param gameHandler Reference to game handler
|
|
|
|
|
*/
|
|
|
|
|
void render(game::GameHandler& gameHandler);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check if chat input is active
|
|
|
|
|
*/
|
2026-03-31 08:53:14 +03:00
|
|
|
bool isChatInputActive() const { return chatPanel_.isChatInputActive(); }
|
2026-02-02 12:24:50 -08:00
|
|
|
|
Fix vendor buying, improve character select, parallelize WMO culling, and optimize collision
- Fix CMSG_BUY_ITEM count field from uint8 to uint32 (server silently dropped undersized packets)
- Character select screen: remember last selected character, two-column layout with details panel, double-click to enter world, responsive window sizing
- Fix stale character data between logins by replacing static init flag with per-character GUID tracking
- Parallelize WMO visibility culling across worker threads (same pattern as M2 renderer)
- Optimize WMO collision queries with world-space group bounds early rejection in getFloorHeight, checkWallCollision, isInsideWMO, and raycastBoundingBoxes
- Reduce camera ground samples from 5 to 3 movement-aligned probes
- Add WMO interior lighting, unlit materials, vertex color multiply, and alpha blending support
2026-02-07 15:29:19 -08:00
|
|
|
void saveSettings();
|
|
|
|
|
void loadSettings();
|
|
|
|
|
|
2026-04-01 20:38:37 +03:00
|
|
|
// Dependency injection for extracted classes (Phase A singleton breaking)
|
|
|
|
|
void setAppearanceComposer(core::AppearanceComposer* ac) { appearanceComposer_ = ac; }
|
|
|
|
|
|
`chore(application): extract appearance controller and unify UI flow`
- Refactor UI application architecture: extracted appearance controller into ui_services.hpp + implementation updates
- Update UI components and managers to use new service layer:
- `action_bar_panel`, `auth_screen`, `character_screen`, `chat_panel`, `combat_ui`, `dialog_manager`, `game_screen`, `settings_panel`, `social_panel`, `toast_manager`, `ui_manager`, `window_manager`
- Adjust core application entrypoints:
- application.cpp
- Update component implementations for new controller flow:
- action_bar_panel.cpp, `chat_panel.cpp`, `combat_ui.cpp`, `dialog_manager.cpp`, `game_screen.cpp`, `settings_panel.cpp`, `social_panel.cpp`, `toast_manager.cpp`, `window_manager.cpp`
These staged changes implement a major architectural refactor for UI/appearance controller separation
2026-04-01 20:59:17 +03:00
|
|
|
// Section 3.5: UIServices injection (Phase B singleton breaking)
|
|
|
|
|
void setServices(const UIServices& services);
|
|
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
private:
|
`chore(application): extract appearance controller and unify UI flow`
- Refactor UI application architecture: extracted appearance controller into ui_services.hpp + implementation updates
- Update UI components and managers to use new service layer:
- `action_bar_panel`, `auth_screen`, `character_screen`, `chat_panel`, `combat_ui`, `dialog_manager`, `game_screen`, `settings_panel`, `social_panel`, `toast_manager`, `ui_manager`, `window_manager`
- Adjust core application entrypoints:
- application.cpp
- Update component implementations for new controller flow:
- action_bar_panel.cpp, `chat_panel.cpp`, `combat_ui.cpp`, `dialog_manager.cpp`, `game_screen.cpp`, `settings_panel.cpp`, `social_panel.cpp`, `toast_manager.cpp`, `window_manager.cpp`
These staged changes implement a major architectural refactor for UI/appearance controller separation
2026-04-01 20:59:17 +03:00
|
|
|
// Injected UI services (Section 3.5 Phase B - replaces getInstance() calls)
|
|
|
|
|
UIServices services_;
|
|
|
|
|
// Legacy pointer for Phase A compatibility (will be removed when all callsites migrate)
|
2026-04-01 20:38:37 +03:00
|
|
|
core::AppearanceComposer* appearanceComposer_ = nullptr;
|
2026-03-31 08:53:14 +03:00
|
|
|
// Chat panel (extracted from GameScreen — owns all chat state and rendering)
|
|
|
|
|
ChatPanel chatPanel_;
|
2026-03-18 04:14:44 -07:00
|
|
|
|
2026-03-31 09:18:17 +03:00
|
|
|
// Toast manager (extracted from GameScreen — owns all toast/notification state and rendering)
|
|
|
|
|
ToastManager toastManager_;
|
|
|
|
|
|
2026-03-31 10:07:58 +03:00
|
|
|
// Dialog manager (extracted from GameScreen — owns all popup/dialog rendering)
|
|
|
|
|
DialogManager dialogManager_;
|
|
|
|
|
|
|
|
|
|
// Settings panel (extracted from GameScreen — owns all settings UI and config state)
|
|
|
|
|
SettingsPanel settingsPanel_;
|
|
|
|
|
|
2026-03-31 19:49:52 +03:00
|
|
|
// Combat UI (extracted from GameScreen — owns all combat overlay rendering)
|
|
|
|
|
CombatUI combatUI_;
|
|
|
|
|
|
|
|
|
|
// Social panel (extracted from GameScreen — owns all social/group UI rendering)
|
|
|
|
|
SocialPanel socialPanel_;
|
|
|
|
|
|
|
|
|
|
// Action bar panel (extracted from GameScreen — owns action/stance/bag/xp/rep bars)
|
|
|
|
|
ActionBarPanel actionBarPanel_;
|
|
|
|
|
|
|
|
|
|
// Window manager (extracted from GameScreen — owns NPC windows, popups, overlays)
|
|
|
|
|
WindowManager windowManager_;
|
2026-03-18 04:30:33 -07:00
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
// UI state
|
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 showEntityWindow = false;
|
2026-02-02 12:24:50 -08:00
|
|
|
bool showChatWindow = true;
|
2026-03-11 09:24:37 -07:00
|
|
|
bool showMinimap_ = true; // M key toggles minimap
|
2026-03-18 11:43:39 -07:00
|
|
|
bool showNameplates_ = true; // V key toggles enemy/NPC nameplates
|
2026-03-12 00:26:47 -07:00
|
|
|
uint64_t nameplateCtxGuid_ = 0; // GUID of nameplate right-clicked (0 = none)
|
|
|
|
|
ImVec2 nameplateCtxPos_{}; // Screen position of nameplate right-click
|
2026-03-11 22:57:04 -07:00
|
|
|
uint32_t lastPlayerHp_ = 0; // Previous frame HP for damage flash detection
|
|
|
|
|
float damageFlashAlpha_ = 0.0f; // Screen edge flash intensity (fades to 0)
|
2026-03-31 09:18:17 +03:00
|
|
|
|
2026-03-12 01:15:11 -07:00
|
|
|
|
|
|
|
|
// UIErrorsFrame: WoW-style center-bottom error messages (spell fails, out of range, etc.)
|
|
|
|
|
struct UIErrorEntry { std::string text; float age = 0.0f; };
|
|
|
|
|
std::vector<UIErrorEntry> uiErrors_;
|
|
|
|
|
bool uiErrorCallbackSet_ = false;
|
|
|
|
|
static constexpr float kUIErrorLifetime = 2.5f;
|
2026-03-18 04:30:33 -07:00
|
|
|
bool castFailedCallbackSet_ = false;
|
2026-03-31 09:18:17 +03: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
|
|
|
bool showPlayerInfo = false;
|
2026-03-11 07:38:08 -07:00
|
|
|
bool showWorldMap_ = false; // W key toggles world map
|
2026-03-12 16:47:42 -07:00
|
|
|
ImVec2 questTrackerPos_ = ImVec2(-1.0f, -1.0f); // <0 = use default
|
2026-03-13 04:04:29 -07:00
|
|
|
ImVec2 questTrackerSize_ = ImVec2(220.0f, 200.0f); // saved size
|
|
|
|
|
float questTrackerRightOffset_ = -1.0f; // pixels from right edge; <0 = use default
|
2026-03-12 16:47:42 -07:00
|
|
|
bool questTrackerPosInit_ = false;
|
2026-03-31 10:07:58 +03:00
|
|
|
|
2026-03-31 19:49:52 +03:00
|
|
|
|
2026-02-17 16:26:49 -08:00
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
/**
|
|
|
|
|
* Render player info window
|
|
|
|
|
*/
|
|
|
|
|
void renderPlayerInfo(game::GameHandler& gameHandler);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render entity list window
|
|
|
|
|
*/
|
|
|
|
|
void renderEntityList(game::GameHandler& gameHandler);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render player unit frame (top-left)
|
|
|
|
|
*/
|
|
|
|
|
void renderPlayerFrame(game::GameHandler& gameHandler);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Render target frame
|
|
|
|
|
*/
|
|
|
|
|
void renderTargetFrame(game::GameHandler& gameHandler);
|
2026-03-10 21:15:24 -07:00
|
|
|
void renderFocusFrame(game::GameHandler& gameHandler);
|
2026-02-02 12:24:50 -08:00
|
|
|
|
2026-03-09 17:23:28 -07:00
|
|
|
/**
|
|
|
|
|
* Render pet frame (below player frame when player has an active pet)
|
|
|
|
|
*/
|
|
|
|
|
void renderPetFrame(game::GameHandler& gameHandler);
|
2026-03-12 10:14:44 -07:00
|
|
|
void renderTotemFrame(game::GameHandler& gameHandler);
|
2026-03-09 17:23:28 -07:00
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
/**
|
|
|
|
|
* Process targeting input (Tab, Escape, click)
|
|
|
|
|
*/
|
|
|
|
|
void processTargetInput(game::GameHandler& gameHandler);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Rebuild character geosets from current equipment state
|
|
|
|
|
*/
|
|
|
|
|
void updateCharacterGeosets(game::Inventory& inventory);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Re-composite character skin texture from current equipment
|
|
|
|
|
*/
|
|
|
|
|
void updateCharacterTextures(game::Inventory& inventory);
|
|
|
|
|
|
2026-03-31 19:49:52 +03:00
|
|
|
|
2026-03-09 14:30:48 -07:00
|
|
|
void renderMirrorTimers(game::GameHandler& gameHandler);
|
2026-03-12 01:15:11 -07:00
|
|
|
void renderUIErrors(game::GameHandler& gameHandler, float deltaTime);
|
2026-02-06 20:10:10 -08:00
|
|
|
void renderQuestMarkers(game::GameHandler& gameHandler);
|
|
|
|
|
void renderMinimapMarkers(game::GameHandler& gameHandler);
|
2026-03-09 15:05:38 -07:00
|
|
|
void renderQuestObjectiveTracker(game::GameHandler& gameHandler);
|
2026-03-09 17:01:38 -07:00
|
|
|
void renderNameplates(game::GameHandler& gameHandler);
|
2026-03-12 14:25:37 -07:00
|
|
|
void renderDurabilityWarning(game::GameHandler& gameHandler);
|
2026-03-18 10:47:34 -07:00
|
|
|
void takeScreenshot(game::GameHandler& gameHandler);
|
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
|
|
|
/**
|
|
|
|
|
* Inventory screen
|
|
|
|
|
*/
|
2026-02-04 22:27:45 -08:00
|
|
|
void renderWorldMap(game::GameHandler& gameHandler);
|
|
|
|
|
|
2026-02-02 12:24:50 -08:00
|
|
|
InventoryScreen inventoryScreen;
|
Fix vendor buying, improve character select, parallelize WMO culling, and optimize collision
- Fix CMSG_BUY_ITEM count field from uint8 to uint32 (server silently dropped undersized packets)
- Character select screen: remember last selected character, two-column layout with details panel, double-click to enter world, responsive window sizing
- Fix stale character data between logins by replacing static init flag with per-character GUID tracking
- Parallelize WMO visibility culling across worker threads (same pattern as M2 renderer)
- Optimize WMO collision queries with world-space group bounds early rejection in getFloorHeight, checkWallCollision, isInsideWMO, and raycastBoundingBoxes
- Reduce camera ground samples from 5 to 3 movement-aligned probes
- Add WMO interior lighting, unlit materials, vertex color multiply, and alpha blending support
2026-02-07 15:29:19 -08:00
|
|
|
uint64_t inventoryScreenCharGuid_ = 0; // GUID of character inventory screen was initialized for
|
2026-02-06 13:47:03 -08:00
|
|
|
QuestLogScreen questLogScreen;
|
2026-02-04 11:31:08 -08:00
|
|
|
SpellbookScreen spellbookScreen;
|
2026-02-06 16:04:25 -08:00
|
|
|
TalentScreen talentScreen;
|
2026-02-21 19:41:21 -08:00
|
|
|
// WorldMap is now owned by Renderer (accessed via renderer->getWorldMap())
|
2026-02-05 15:07:13 -08:00
|
|
|
|
2026-02-06 14:30:54 -08:00
|
|
|
// Spell icon cache: spellId -> GL texture ID
|
2026-02-22 03:32:08 -08:00
|
|
|
std::unordered_map<uint32_t, VkDescriptorSet> spellIconCache_;
|
2026-02-06 14:30:54 -08:00
|
|
|
// SpellIconID -> icon path (from SpellIcon.dbc)
|
|
|
|
|
std::unordered_map<uint32_t, std::string> spellIconPaths_;
|
|
|
|
|
// SpellID -> SpellIconID (from Spell.dbc field 133)
|
|
|
|
|
std::unordered_map<uint32_t, uint32_t> spellIconIds_;
|
|
|
|
|
bool spellIconDbLoaded_ = false;
|
2026-02-22 03:32:08 -08:00
|
|
|
VkDescriptorSet getSpellIcon(uint32_t spellId, pipeline::AssetManager* am);
|
2026-02-06 19:24:44 -08:00
|
|
|
|
2026-03-09 18:28:03 -07:00
|
|
|
// Death Knight rune bar: client-predicted fill (0.0=depleted, 1.0=ready) for smooth animation
|
|
|
|
|
float runeClientFill_[6] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
|
|
|
|
|
|
2026-03-12 19:42:31 -07:00
|
|
|
// Pet rename modal (triggered from pet frame context menu)
|
|
|
|
|
bool petRenameOpen_ = false;
|
|
|
|
|
char petRenameBuf_[16] = {};
|
|
|
|
|
|
2026-02-07 13:53:03 -08:00
|
|
|
// Left-click targeting: distinguish click from camera drag
|
|
|
|
|
glm::vec2 leftClickPressPos_ = glm::vec2(0.0f);
|
|
|
|
|
bool leftClickWasPress_ = false;
|
2026-02-17 17:23:42 -08:00
|
|
|
|
2026-03-31 09:18:17 +03:00
|
|
|
|
2026-03-18 12:17:00 -07:00
|
|
|
bool appearanceCallbackSet_ = false;
|
2026-03-14 08:31:08 -07:00
|
|
|
bool ghostOpacityStateKnown_ = false;
|
|
|
|
|
bool ghostOpacityLastState_ = false;
|
|
|
|
|
uint32_t ghostOpacityLastInstanceId_ = 0;
|
2026-03-31 09:18:17 +03:00
|
|
|
|
|
|
|
|
|
2026-03-17 16:34:39 -07:00
|
|
|
void renderWeatherOverlay(game::GameHandler& gameHandler);
|
2026-03-09 17:06:12 -07:00
|
|
|
|
2026-02-17 17:23:42 -08:00
|
|
|
public:
|
2026-03-31 19:49:52 +03:00
|
|
|
void openDungeonFinder() { socialPanel_.showDungeonFinder_ = true; }
|
2026-03-31 09:18:17 +03:00
|
|
|
ToastManager& toastManager() { return toastManager_; }
|
2026-02-02 12:24:50 -08:00
|
|
|
};
|
|
|
|
|
|
2026-02-06 14:30:54 -08:00
|
|
|
} // namespace ui
|
|
|
|
|
} // namespace wowee
|