mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-06 17:13:51 +00:00
feat(animation): 452 named constants, 30-phase character animation state machine
Add animation_ids.hpp/cpp with all 452 WoW animation ID constants (anim::STAND, anim::RUN, anim::FIRE_BOW, ... anim::FLY_BACKWARDS, etc.), nameFromId() O(1) lookup, and flyVariant() compact 218-element ground→FLY_* resolver. Expand AnimationController into a full state machine with 20+ named states: spell cast (directed→omni→cast fallback chain, instant one-shot release), hit reactions (WOUND/CRIT/DODGE/BLOCK/SHIELD_BLOCK), stun, wounded idle, stealth animation substitution, loot, fishing channel, sit/sleep/kneel down→loop→up transitions, sheathe/unsheathe combat enter/exit, ranged weapons (BOW/GUN/CROSSBOW/THROWN with reload states), game object OPEN/CLOSE/DESTROY, vehicle enter/exit, mount flight directionals (FLY_LEFT/RIGHT/UP/DOWN/BACKWARDS), emote state variants, off-hand/pierce/dual-wield alternation, NPC birth/spawn/drown/rise, sprint aura override, totem idle, NPC greeting/farewell. Add spell_defines.hpp with SpellEffect (~45 constants) and SpellMissInfo (12 constants) namespaces; replace all magic numbers in spell_handler.cpp. Add GAMEOBJECT_BYTES_1 to update field table (all 4 expansion JSONs) and wire GameObjectStateCallback. Add DBC cross-validation on world entry. Expand tools/_ANIM_NAMES from ~35 to 452 entries in m2_viewer.py and asset_pipeline_gui.py. Add tests/test_animation_ids.cpp. Bug fixes included: - Stand state 1 was animating READY_2H(27) — fixed to SITTING(97) - Spell casts ended freeze-frame — add one-shot release animation - NPC 2H swing probe chain missing ATTACK_2H_LOOSE (polearm/staff) - Chair sits (states 2/4/5/6) incorrectly played floor-sit transition - STOP(3) used for all spell casts — replaced with model-aware chain
This commit is contained in:
parent
d54e262048
commit
e58f9b4b40
59 changed files with 3903 additions and 483 deletions
|
|
@ -1,5 +1,6 @@
|
|||
#include "ui/auth_screen.hpp"
|
||||
#include "ui/ui_colors.hpp"
|
||||
#include "ui/settings_panel.hpp"
|
||||
#include "auth/crypto.hpp"
|
||||
#include "core/application.hpp"
|
||||
#include "core/logger.hpp"
|
||||
|
|
@ -13,8 +14,9 @@
|
|||
#include <imgui_impl_vulkan.h>
|
||||
#include "stb_image.h"
|
||||
#include <filesystem>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
|
@ -492,6 +494,11 @@ void AuthScreen::render(auth::AuthHandler& authHandler) {
|
|||
if (ImGui::Button("Clear", ImVec2(160, 40))) {
|
||||
statusMessage.clear();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Settings", ImVec2(160, 40))) {
|
||||
showLoginSettings_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
|
|
@ -503,6 +510,8 @@ void AuthScreen::render(auth::AuthHandler& authHandler) {
|
|||
ImGui::TextWrapped("Default port is 3724.");
|
||||
|
||||
ImGui::End();
|
||||
|
||||
renderLoginSettingsWindow();
|
||||
}
|
||||
|
||||
void AuthScreen::stopLoginMusic() {
|
||||
|
|
@ -945,4 +954,216 @@ void AuthScreen::destroyBackgroundImage() {
|
|||
if (bgMemory) { vkFreeMemory(device, bgMemory, nullptr); bgMemory = VK_NULL_HANDLE; }
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Login-screen graphics settings popup
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void AuthScreen::applyPresetToState(LoginGraphicsState& s, int preset) {
|
||||
switch (preset) {
|
||||
case 1: // Low
|
||||
s.shadows = false; s.shadowDistance = 75.0f; s.antiAliasing = 0;
|
||||
s.fxaa = false; s.normalMapping = false; s.pom = false; s.pomQuality = 1;
|
||||
s.upscalingMode = 0; s.waterRefraction = false; s.groundClutter = 25;
|
||||
s.brightness = 50; s.vsync = false; s.fullscreen = false;
|
||||
break;
|
||||
case 2: // Medium
|
||||
s.shadows = true; s.shadowDistance = 150.0f; s.antiAliasing = 0;
|
||||
s.fxaa = false; s.normalMapping = true; s.pom = true; s.pomQuality = 1;
|
||||
s.upscalingMode = 0; s.waterRefraction = true; s.groundClutter = 100;
|
||||
s.brightness = 50; s.vsync = false; s.fullscreen = false;
|
||||
break;
|
||||
case 3: // High
|
||||
s.shadows = true; s.shadowDistance = 250.0f; s.antiAliasing = 1;
|
||||
s.fxaa = true; s.normalMapping = true; s.pom = true; s.pomQuality = 1;
|
||||
s.upscalingMode = 0; s.waterRefraction = true; s.groundClutter = 130;
|
||||
s.brightness = 50; s.vsync = false; s.fullscreen = false;
|
||||
break;
|
||||
case 4: // Ultra
|
||||
s.shadows = true; s.shadowDistance = 400.0f; s.antiAliasing = 2;
|
||||
s.fxaa = true; s.normalMapping = true; s.pom = true; s.pomQuality = 2;
|
||||
s.upscalingMode = 0; s.waterRefraction = true; s.groundClutter = 150;
|
||||
s.brightness = 50; s.vsync = false; s.fullscreen = false;
|
||||
break;
|
||||
default: // Custom — no change
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AuthScreen::loadLoginGraphicsState() {
|
||||
std::ifstream file(SettingsPanel::getSettingsPath());
|
||||
if (!file.is_open()) {
|
||||
// File doesn't exist yet — keep struct defaults (Medium equivalent)
|
||||
return;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
auto eq = line.find('=');
|
||||
if (eq == std::string::npos) continue;
|
||||
std::string key = line.substr(0, eq);
|
||||
std::string val = line.substr(eq + 1);
|
||||
|
||||
if (key == "graphics_preset") loginGfx_.preset = std::stoi(val);
|
||||
else if (key == "shadows") loginGfx_.shadows = (val == "1");
|
||||
else if (key == "shadow_distance") loginGfx_.shadowDistance = std::stof(val);
|
||||
else if (key == "antialiasing") loginGfx_.antiAliasing = std::stoi(val);
|
||||
else if (key == "fxaa") loginGfx_.fxaa = (val == "1");
|
||||
else if (key == "normal_mapping") loginGfx_.normalMapping = (val == "1");
|
||||
else if (key == "pom") loginGfx_.pom = (val == "1");
|
||||
else if (key == "pom_quality") loginGfx_.pomQuality = std::stoi(val);
|
||||
else if (key == "upscaling_mode") loginGfx_.upscalingMode = std::stoi(val);
|
||||
else if (key == "water_refraction") loginGfx_.waterRefraction = (val == "1");
|
||||
else if (key == "ground_clutter_density") loginGfx_.groundClutter = std::stoi(val);
|
||||
else if (key == "brightness") loginGfx_.brightness = std::stoi(val);
|
||||
else if (key == "vsync") loginGfx_.vsync = (val == "1");
|
||||
else if (key == "fullscreen") loginGfx_.fullscreen = (val == "1");
|
||||
}
|
||||
}
|
||||
|
||||
void AuthScreen::saveLoginGraphicsState() {
|
||||
// Read the full settings file into a map to preserve non-graphics keys.
|
||||
std::map<std::string, std::string> cfg;
|
||||
std::ifstream in(SettingsPanel::getSettingsPath());
|
||||
if (in.is_open()) {
|
||||
std::string line;
|
||||
while (std::getline(in, line)) {
|
||||
auto eq = line.find('=');
|
||||
if (eq != std::string::npos)
|
||||
cfg[line.substr(0, eq)] = line.substr(eq + 1);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
|
||||
// Overwrite graphics keys.
|
||||
cfg["graphics_preset"] = std::to_string(loginGfx_.preset);
|
||||
cfg["shadows"] = loginGfx_.shadows ? "1" : "0";
|
||||
cfg["shadow_distance"] = std::to_string(static_cast<int>(loginGfx_.shadowDistance));
|
||||
cfg["antialiasing"] = std::to_string(loginGfx_.antiAliasing);
|
||||
cfg["fxaa"] = loginGfx_.fxaa ? "1" : "0";
|
||||
cfg["normal_mapping"] = loginGfx_.normalMapping ? "1" : "0";
|
||||
cfg["pom"] = loginGfx_.pom ? "1" : "0";
|
||||
cfg["pom_quality"] = std::to_string(loginGfx_.pomQuality);
|
||||
cfg["upscaling_mode"] = std::to_string(loginGfx_.upscalingMode);
|
||||
cfg["water_refraction"] = loginGfx_.waterRefraction ? "1" : "0";
|
||||
cfg["ground_clutter_density"]= std::to_string(loginGfx_.groundClutter);
|
||||
cfg["brightness"] = std::to_string(loginGfx_.brightness);
|
||||
cfg["vsync"] = loginGfx_.vsync ? "1" : "0";
|
||||
cfg["fullscreen"] = loginGfx_.fullscreen ? "1" : "0";
|
||||
|
||||
// Write everything back.
|
||||
std::ofstream out(SettingsPanel::getSettingsPath());
|
||||
if (!out.is_open()) return;
|
||||
for (const auto& [k, v] : cfg)
|
||||
out << k << "=" << v << "\n";
|
||||
}
|
||||
|
||||
void AuthScreen::renderLoginSettingsWindow() {
|
||||
if (showLoginSettings_) {
|
||||
ImGui::OpenPopup("Graphics Settings");
|
||||
showLoginSettings_ = false;
|
||||
loginGfxLoaded_ = false; // Reload from disk each time the popup opens.
|
||||
}
|
||||
|
||||
ImVec2 center = ImGui::GetMainViewport()->GetCenter();
|
||||
ImGui::SetNextWindowPos(center, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
ImGui::SetNextWindowSize(ImVec2(500, 560), ImGuiCond_Always);
|
||||
|
||||
if (ImGui::BeginPopupModal("Graphics Settings", nullptr, ImGuiWindowFlags_NoResize)) {
|
||||
if (!loginGfxLoaded_) {
|
||||
loadLoginGraphicsState();
|
||||
loginGfxLoaded_ = true;
|
||||
}
|
||||
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.85f, 0.0f, 1.0f), "Graphics Settings");
|
||||
ImGui::TextWrapped("Adjust settings below or reset to a safe preset. Changes take effect on next login.");
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Preset selector
|
||||
const char* presetNames[] = {"Custom", "Low", "Medium", "High", "Ultra"};
|
||||
ImGui::Text("Preset:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(160.0f);
|
||||
if (ImGui::Combo("##preset", &loginGfx_.preset, presetNames, 5)) {
|
||||
if (loginGfx_.preset != 0) // 0 = Custom — don't override manually set values
|
||||
applyPresetToState(loginGfx_, loginGfx_.preset);
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Shadow settings
|
||||
ImGui::Checkbox("Shadows", &loginGfx_.shadows);
|
||||
if (loginGfx_.shadows) {
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(200.0f);
|
||||
float sd = loginGfx_.shadowDistance;
|
||||
if (ImGui::SliderFloat("Shadow Distance", &sd, 50.0f, 600.0f, "%.0f"))
|
||||
loginGfx_.shadowDistance = sd;
|
||||
}
|
||||
|
||||
// Anti-aliasing
|
||||
const char* aaNames[] = {"Off", "2x MSAA", "4x MSAA"};
|
||||
ImGui::Text("Anti-Aliasing:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(130.0f);
|
||||
ImGui::Combo("##aa", &loginGfx_.antiAliasing, aaNames, 3);
|
||||
|
||||
ImGui::Checkbox("FXAA", &loginGfx_.fxaa);
|
||||
ImGui::Checkbox("Normal Mapping", &loginGfx_.normalMapping);
|
||||
|
||||
// POM
|
||||
ImGui::Checkbox("Parallax Occlusion Mapping (POM)", &loginGfx_.pom);
|
||||
if (loginGfx_.pom) {
|
||||
const char* pomQ[] = {"Medium", "High"};
|
||||
ImGui::Text(" POM Quality:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(110.0f);
|
||||
ImGui::Combo("##pomq", &loginGfx_.pomQuality, pomQ, 2);
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Water Refraction", &loginGfx_.waterRefraction);
|
||||
|
||||
// Ground clutter density
|
||||
ImGui::Text("Ground Clutter:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(200.0f);
|
||||
ImGui::SliderInt("##clutter", &loginGfx_.groundClutter, 0, 200);
|
||||
|
||||
// Brightness
|
||||
ImGui::Text("Brightness:");
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(200.0f);
|
||||
ImGui::SliderInt("##brightness", &loginGfx_.brightness, 0, 100);
|
||||
|
||||
ImGui::Checkbox("V-Sync", &loginGfx_.vsync);
|
||||
ImGui::Checkbox("Fullscreen", &loginGfx_.fullscreen);
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Separator();
|
||||
ImGui::Spacing();
|
||||
|
||||
// Action buttons
|
||||
if (ImGui::Button("Reset to Medium", ImVec2(160, 32))) {
|
||||
applyPresetToState(loginGfx_, 2);
|
||||
loginGfx_.preset = 2;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
|
||||
float rightEdge = ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + rightEdge - 220.0f);
|
||||
if (ImGui::Button("Cancel", ImVec2(100, 32))) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Apply", ImVec2(100, 32))) {
|
||||
saveLoginGraphicsState();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace wowee::ui
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ namespace ui {
|
|||
|
||||
|
||||
// ============================================================
|
||||
// Cast Bar (Phase 3)
|
||||
// Cast Bar
|
||||
// ============================================================
|
||||
|
||||
void CombatUI::renderCastBar(game::GameHandler& gameHandler, SpellIconFn getSpellIcon) {
|
||||
|
|
@ -341,7 +341,7 @@ void CombatUI::renderRaidWarningOverlay(game::GameHandler& gameHandler) {
|
|||
|
||||
|
||||
// ============================================================
|
||||
// Floating Combat Text (Phase 2)
|
||||
// Floating Combat Text
|
||||
// ============================================================
|
||||
|
||||
void CombatUI::renderCombatText(game::GameHandler& gameHandler) {
|
||||
|
|
@ -838,7 +838,7 @@ void CombatUI::renderDPSMeter(game::GameHandler& gameHandler,
|
|||
|
||||
|
||||
// ============================================================
|
||||
// Buff/Debuff Bar (Phase 3)
|
||||
// Buff/Debuff Bar
|
||||
// ============================================================
|
||||
|
||||
void CombatUI::renderBuffBar(game::GameHandler& gameHandler,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void DialogManager::renderLateDialogs(game::GameHandler& gameHandler) {
|
|||
}
|
||||
|
||||
// ============================================================
|
||||
// Group Invite Popup (Phase 4)
|
||||
// Group Invite Popup
|
||||
// ============================================================
|
||||
|
||||
void DialogManager::renderGroupInvitePopup(game::GameHandler& gameHandler) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "core/coordinates.hpp"
|
||||
#include "core/input.hpp"
|
||||
#include "rendering/renderer.hpp"
|
||||
#include "rendering/animation_controller.hpp"
|
||||
#include "rendering/wmo_renderer.hpp"
|
||||
#include "rendering/terrain_manager.hpp"
|
||||
#include "rendering/minimap.hpp"
|
||||
|
|
@ -104,10 +105,10 @@ GameScreen::GameScreen() {
|
|||
loadSettings();
|
||||
}
|
||||
|
||||
// Section 3.5: Set UI services and propagate to child components
|
||||
// Set UI services and propagate to child components
|
||||
void GameScreen::setServices(const UIServices& services) {
|
||||
services_ = services;
|
||||
// Update legacy pointer for Phase A compatibility
|
||||
// Update legacy pointer for compatibility
|
||||
appearanceComposer_ = services.appearanceComposer;
|
||||
// Propagate to child panels
|
||||
chatPanel_.setServices(services);
|
||||
|
|
@ -503,7 +504,37 @@ void GameScreen::render(game::GameHandler& gameHandler) {
|
|||
auto* r = services_.renderer;
|
||||
if (r) {
|
||||
const auto& mh = gameHandler.getInventory().getEquipSlot(game::EquipSlot::MAIN_HAND);
|
||||
r->setEquippedWeaponType(mh.empty() ? 0 : mh.item.inventoryType);
|
||||
const auto& oh = gameHandler.getInventory().getEquipSlot(game::EquipSlot::OFF_HAND);
|
||||
if (mh.empty()) {
|
||||
r->setEquippedWeaponType(0, false);
|
||||
} else {
|
||||
// Polearms and staves use ATTACK_2H_LOOSE instead of ATTACK_2H
|
||||
bool is2HLoose = (mh.item.subclassName == "Polearm" || mh.item.subclassName == "Staff");
|
||||
bool isFist = (mh.item.subclassName == "Fist Weapon");
|
||||
bool isDagger = (mh.item.subclassName == "Dagger");
|
||||
bool hasOffHand = !oh.empty() &&
|
||||
(oh.item.inventoryType == game::InvType::ONE_HAND ||
|
||||
oh.item.subclassName == "Fist Weapon");
|
||||
bool hasShield = !oh.empty() && oh.item.inventoryType == game::InvType::SHIELD;
|
||||
r->setEquippedWeaponType(mh.item.inventoryType, is2HLoose, isFist, isDagger, hasOffHand, hasShield);
|
||||
}
|
||||
// Detect ranged weapon type from RANGED slot
|
||||
const auto& rangedSlot = gameHandler.getInventory().getEquipSlot(game::EquipSlot::RANGED);
|
||||
if (rangedSlot.empty()) {
|
||||
r->setEquippedRangedType(rendering::RangedWeaponType::NONE);
|
||||
} else if (rangedSlot.item.inventoryType == game::InvType::RANGED_BOW) {
|
||||
// subclassName distinguishes Bow vs Crossbow
|
||||
if (rangedSlot.item.subclassName == "Crossbow")
|
||||
r->setEquippedRangedType(rendering::RangedWeaponType::CROSSBOW);
|
||||
else
|
||||
r->setEquippedRangedType(rendering::RangedWeaponType::BOW);
|
||||
} else if (rangedSlot.item.inventoryType == game::InvType::RANGED_GUN) {
|
||||
r->setEquippedRangedType(rendering::RangedWeaponType::GUN);
|
||||
} else if (rangedSlot.item.inventoryType == game::InvType::THROWN) {
|
||||
r->setEquippedRangedType(rendering::RangedWeaponType::THROWN);
|
||||
} else {
|
||||
r->setEquippedRangedType(rendering::RangedWeaponType::NONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4103,7 +4134,7 @@ void GameScreen::renderWorldMap(game::GameHandler& gameHandler) {
|
|||
}
|
||||
|
||||
// ============================================================
|
||||
// Action Bar (Phase 3)
|
||||
// Action Bar
|
||||
// ============================================================
|
||||
|
||||
VkDescriptorSet GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManager* am) {
|
||||
|
|
@ -4217,36 +4248,6 @@ VkDescriptorSet GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManage
|
|||
return ds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Stance / Form / Presence Bar
|
||||
// Shown for Warriors (stances), Death Knights (presences),
|
||||
// Druids (shapeshift forms), Rogues (stealth), Priests (Shadowform).
|
||||
// Buttons display the player's known stance/form spells.
|
||||
// Active form is detected by checking permanent player auras.
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Bag Bar
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// XP Bar
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Reputation Bar
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Cast Bar (Phase 3)
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Mirror Timers (breath / fatigue / feign death)
|
||||
// ============================================================
|
||||
|
|
@ -4527,18 +4528,6 @@ void GameScreen::renderQuestObjectiveTracker(game::GameHandler& gameHandler) {
|
|||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Raid Warning / Boss Emote Center-Screen Overlay
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Floating Combat Text (Phase 2)
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// DPS / HPS Meter
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Nameplates — world-space health bars projected to screen
|
||||
// ============================================================
|
||||
|
|
@ -5147,10 +5136,6 @@ void GameScreen::renderNameplates(game::GameHandler& gameHandler) {
|
|||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Party Frames (Phase 4)
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Durability Warning (equipment damage indicator)
|
||||
// ============================================================
|
||||
|
|
@ -5313,95 +5298,6 @@ void GameScreen::renderUIErrors(game::GameHandler& /*gameHandler*/, float deltaT
|
|||
ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Boss Encounter Frames
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Social Frame — compact online friends panel (toggled by socialPanel_.showSocialFrame_)
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Buff/Debuff Bar (Phase 3)
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Loot Window (Phase 5)
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Gossip Window (Phase 5)
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Quest Details Window
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Quest Request Items Window (turn-in progress check)
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Quest Offer Reward Window (choose reward)
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// ItemExtendedCost.dbc loader
|
||||
// ============================================================
|
||||
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Vendor Window (Phase 5)
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Trainer
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Teleporter Panel
|
||||
// ============================================================
|
||||
|
||||
// ============================================================
|
||||
// Escape Menu
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Barber Shop Window
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Pet Stable Window
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Taxi Window
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Logout Countdown
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ============================================================
|
||||
// Death Screen
|
||||
// ============================================================
|
||||
|
||||
|
||||
|
||||
void GameScreen::renderQuestMarkers(game::GameHandler& gameHandler) {
|
||||
const auto& statuses = gameHandler.getNpcQuestStatuses();
|
||||
if (statuses.empty()) return;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue