mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-26 21: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
|
|
@ -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