Commit graph

72 commits

Author SHA1 Message Date
Kelsi
f855327054 fix: eliminate 490ms transport-doodad stall and GPU device-loss crash
Three root causes identified from wowee.log crash at frame 134368:

1. processPendingTransportDoodads() was doing N separate synchronous
   GPU uploads (vkQueueSubmit + vkWaitForFences per texture per doodad).
   With 30+ doodads × multiple textures, this caused the 489ms stall in
   the 'gameobject/transport queues' update stage. Fixed by wrapping the
   entire batch in beginUploadBatch()/endUploadBatch() so all texture
   layout transitions are submitted in a single async command buffer.

2. Game objects whose M2 model has no geometry/particles (empty or
   unsupported format) were retried every frame because loadModel()
   returns false without adding to gameObjectDisplayIdModelCache_.
   Added gameObjectDisplayIdFailedCache_ to permanently skip these
   display IDs after the first failure, stopping the per-frame spam.

3. renderM2Ribbons() only checked ribbonPipeline_ != null, not
   ribbonAdditivePipeline_. If additive pipeline creation failed, any
   ribbon with additive blending would call vkCmdBindPipeline with
   VK_NULL_HANDLE, causing VK_ERROR_DEVICE_LOST on the GPU side.
   Extended the early-return guard to cover both ribbon pipelines.
2026-03-13 01:45:31 -07:00
Kelsi
d95abfb607 feat: propagate OBJECT_FIELD_SCALE_X through creature and GO spawn pipeline
Reads OBJECT_FIELD_SCALE_X (field 4, cross-expansion) from CREATE_OBJECT
update fields and passes it through the full creature and game object spawn
chain: game_handler callbacks → pending spawn structs → async load results
→ createInstance() calls. This gives boss giants, gnomes, children, and
other non-unit-scale NPCs correct visual size, and ensures scaled GOs
(e.g. large treasure chests, oversized plants) render at the server-specified
scale rather than always at 1.0.

- Added OBJECT_FIELD_SCALE_X to UF enum and all expansion update_fields.json
- Added float scale to CreatureSpawnCallback and GameObjectSpawnCallback
- Propagated scale through PendingCreatureSpawn, PreparedCreatureModel,
  PendingGameObjectSpawn, PreparedGameObjectWMO
- Used scale in charRenderer/m2Renderer/wmoRenderer createInstance() calls
- Sanity-clamped raw float to [0.01, 100.0] range before use
2026-03-10 22:45:47 -07:00
Kelsi
acbfe99401 anim: also trigger animation update on walk/run transitions for creatures
Extend the locomotion state-change detection to include the WALKING
movement flag. Previously a creature that switched from walking to
running (or vice versa) while staying in the moving state would keep
playing the wrong animation because only the moving/idle transition
was tracked.

Add creatureWasWalking_ alongside creatureWasSwimming_ and
creatureWasFlying_; guard the walking check with isMovingNow to avoid
spurious triggers when the flag flips while the creature is idle.
Clear and erase the new map at world reset and creature/player despawn.
2026-03-10 12:04:59 -07:00
Kelsi
2717018631 anim: fix creature animation not updating on swim/fly state transitions
Previously, the animation update for other entities (creatures, players)
was only triggered when the moving/idle state changed. This meant a
creature landing while still moving would stay in FlyForward instead of
switching to Run, and a flying-idle creature touching down would keep
the FlyIdle animation instead of returning to Stand.

Fix: track creatureWasSwimming_ and creatureWasFlying_ alongside
creatureWasMoving_, and fire the animation update whenever any of the
three locomotion flags change. Clean up the new maps on world reset and
on per-creature despawn.
2026-03-10 12:03:33 -07:00
Kelsi
30a65320fb anim: add flying state tracking and Fly/FlyIdle animation selection for entities
Previously the move-flags callback only tracked SWIMMING and WALKING,
so flying players/mounts always played Run(5) or Stand(0) animations
instead of Fly(61)/FlyIdle(60).

Changes:
- Add creatureFlyingState_ (mirroring creatureSwimmingState_) set by
  the FLYING flag (0x01000000) in unitMoveFlagsCallback_.
- Update animation selection: moving+flying → 61 (Fly/FlyForward),
  idle+flying → 60 (FlyIdle/hover). Flying takes priority over swim
  in the priority chain: fly > swim > walk > run.
- Clear creatureFlyingState_ on world reset.
2026-03-10 11:56:50 -07:00
Kelsi
d7ebc5c8c7 game/rendering: drive Walk(4) and swim state from movement flags
Add UnitMoveFlagsCallback fired on every MSG_MOVE_* with the raw
movement flags field. Application.cpp uses it to update swimming
and walking state from any packet, not just explicit START_SWIM/
STOP_SWIM opcodes — fixing cold-join cases where a player is already
swimming when we enter the world.

Per-frame animation sync now selects Walk(4) when the WALKING flag is
set, Run(5) otherwise, and Swim(42)/SwimIdle(41) when swimming.
UnitAnimHintCallback is simplified to jump (38=JumpMid) only.
2026-03-10 10:55:23 -07:00
Kelsi
333ada8eb6 rendering/game: track per-entity swim state for correct water animations
- Add creatureSwimmingState_ map to track which units are swimming
- unitAnimHintCallback with animId=42 (Swim): marks entity as swimming
- unitAnimHintCallback with animId=0 (MSG_MOVE_STOP_SWIM): clears swim state
- Per-frame sync: uses Swim(42)/SwimIdle(41) when swimming, Run(5)/Stand(0) otherwise
  — creatures/players now show SwimIdle when standing still in water
- Clear creatureSwimmingState_ on creature/player despawn and world reset
2026-03-10 10:36:45 -07:00
Kelsi
4e137c4061 rendering: drive Run/Stand animations from actual movement state
CameraController now transitions the player character to Run (anim 4)
on movement start and back to Stand (anim 0) on stop, guarded by a
prevPlayerMoving_ flag so animation time is not reset every frame.
Death animation (anim 1) is never overridden.

Application creature sync similarly switches creature models to Run (4)
when they move between server positions and Stand (0) when they stop,
with per-guid creatureWasMoving_ tracking to avoid per-frame resets.
2026-03-10 10:06:56 -07:00
Kelsi
dc2aab5e90 perf: limit NPC composite texture processing to 2ms per frame
processAsyncNpcCompositeResults() had no per-frame budget cap, so when
many NPCs finished async skin compositing simultaneously (e.g. right
after world load), all results were finalized in a single frame causing
up to 284ms frame stalls. Apply the same 2ms budget pattern used by
processAsyncCreatureResults. Load screen still processes all pending
composites without the cap (unlimited=true).
2026-03-10 06:47:33 -07:00
Kelsi
ea9c7e68e7 rendering,ui: sync selection circle to renderer instance position
The selection circle was positioned using the entity's game-logic
interpolator (entity->getX/Y/Z), while the actual M2 model is
positioned by CharacterRenderer's independent interpolator (moveInstanceTo).
These two systems can drift apart during movement, causing the circle
to appear under the wrong position relative to the visible model.

Fix: add CharacterRenderer::getInstancePosition / Application::getRenderPositionForGuid
and use the renderer's inst.position for XY (with footZ override for Z)
so the circle always tracks the rendered model exactly. Falls back to
the entity game-logic position when no CharacterRenderer instance exists.
2026-03-10 06:33:44 -07:00
Kelsi
a4966e486f Fix WMO wall collision, normal mapping, POM backfill, and M2/WMO rendering performance
- Fix MOPY flag check (0x08 not 0x01) for proper wall collision detection
- Cap MAX_PUSH to PLAYER_RADIUS to prevent gradual clip-through
- Fix WMO doodad quaternion component ordering (X/Y swap)
- Linear normal map strength blend in shader for smooth slider control
- Enable shadow sampling for interior WMO groups (covered outdoor areas)
- Backfill deferred normal/height maps after streaming with descriptor rebind
- M2: prepareRender only iterates animated instances, bone dirty flag
- M2: remove worker thread VMA allocation, skip unready bone instances
- WMO: persistent visibility vectors, sequential culling
- Add FSR EASU/RCAS shaders
2026-03-07 22:03:28 -08:00
Kelsi
63efac9fa6 Unlimited creature model uploads during load screen, remove duplicate code
Loading screen now calls processCreatureSpawnQueue(unlimited=true) which
removes the 1-upload-per-frame cap and 2ms time budget, allowing all pending
creature models to upload to GPU in bulk. Also increases concurrent async
background loads from 4 to 16 during load screen. Replaces 40-line inline
duplicate of processAsyncCreatureResults with the shared function.
2026-03-07 17:31:47 -08:00
Kelsi
faca22ac5f Async humanoid NPC texture pipeline to eliminate 30-150ms main-thread stalls
Move all DBC lookups (CharSections, ItemDisplayInfo), texture path resolution,
and BLP decoding for humanoid NPCs to background threads. Only GPU texture
uploads remain on the main thread via pre-decoded BLP cache.
2026-03-07 16:54:58 -08:00
Kelsi
7ac990cff4 Background BLP texture pre-decoding + deferred WMO normal maps (12x streaming perf)
Move CPU-heavy BLP texture decoding from main thread to background worker
threads for all hot paths: terrain M2 models, WMO doodad M2s, WMO textures,
creature models, and gameobject WMOs. Each renderer (M2, WMO, Character) now
accepts a pre-decoded BLP cache that loadTexture() checks before falling back
to synchronous decode.

Defer WMO normal/height map generation (3 per-pixel passes: luminance, box
blur, Sobel) during terrain streaming finalization — this was the dominant
remaining bottleneck after BLP pre-decoding.

Terrain streaming stalls: 1576ms → 124ms worst case.
2026-03-07 15:46:56 -08:00
Kelsi
0313bd8692 Performance: ring buffer UBOs, batched load screen uploads, background world preloader
- Replace per-frame VMA alloc/free of material UBOs with a ring buffer in
  CharacterRenderer (~500 allocations/frame eliminated)
- Batch all ready terrain tiles into a single GPU upload during load screen
  (processAllReadyTiles instead of one-at-a-time with individual fence waits)
- Lift per-frame creature/GO spawn budgets during load screen warmup phase
- Add background world preloader: saves last world position to disk, pre-warms
  AssetManager file cache with ADT files starting at app init (login screen)
  so terrain workers get instant cache hits when Enter World is clicked
- Distance-filter expensive collision guard to 8-unit melee range
- Merge 3 CharacterRenderer update loops into single pass
- Time-budget instrumentation for slow update stages (>3ms threshold)
- Count-based async creature model upload budget (max 3/frame in-game)
- 1-per-frame game object spawn + per-doodad time budget for transport loading
- Use deque for creature spawn queue to avoid O(n) front-erase
2026-03-07 13:44:09 -08:00
Kelsi
f9410cc4bd Fix city NPC stuttering: async model loading, CharSections cache, frame budgets
- Async creature model loading: M2 file I/O and parsing on background threads
  via std::async, GPU upload on main thread when ready (MAX_ASYNC_CREATURE_LOADS=4)
- CharSections.dbc lookup cache: O(1) hash lookup instead of O(N) full DBC scan
  per humanoid NPC spawn (was scanning thousands of records twice per spawn)
- Frame time budget: 4ms cap on creature spawn processing per frame
- Wolf/worg model name check cached per modelId (was doing tolower+find per
  hostile creature per frame)
- Weapon attach throttle: max 2 per 1s tick (was attempting all unweaponized NPCs)
- Separate texture application tracking (displayIdTexturesApplied_) so async-loaded
  models still get skin/equipment textures applied correctly
2026-03-07 11:44:14 -08:00
Kelsi
48eb0b70a3 Fix GPU resource leaks and re-entrant world loading for instance transitions
Reset descriptor pools in CharacterRenderer/M2Renderer/WMORenderer on map
change to prevent VK_ERROR_DEVICE_LOST from pool exhaustion. Defer re-entrant
SMSG_NEW_WORLD during active world load to avoid recursive cleanup crashes.
Gate swim bubbles on swimming state, skip redundant shadow pipeline re-init,
add WOWEE_SKIP_* env vars for render isolation debugging.
2026-03-02 08:06:35 -08:00
Kelsi
956e2c8bb1 Reduce city stutter: lower spawn rate, resync interval, M2 render distance
- MAX_SPAWNS_PER_FRAME 8→3 (each spawn does sync M2 load, 5-50ms each)
- Creature resync scan interval 1s→3s (O(N) entity iteration)
- M2 render distance: add 1000+ instance tier at 500 units, reduce 2000+
  tier from 350→300 units to cap draw call count in dense cities
2026-02-25 12:16:55 -08:00
Kelsi
21f7b0f199 Remove nearest-known displayId model fallback cache for missing creature display mappings - that was weird and I'm done with the horror show 2026-02-21 04:18:14 -08:00
Kelsi
fa3060bdf7 Harden runtime against stutter-inducing log floods and missing display IDs
- Re-gate M2 glow diagnostics behind WOWEE_M2_GLOW_DIAG and DEBUG

- Deduplicate missing/failed texture warnings in asset and M2 texture loaders

- Deduplicate unhandled opcode warnings by state/opcode key in non-IN_WORLD phases

- Throttle malformed spline point-count warnings across world/classic/tbc parsers

- Ignore suspiciously huge display IDs from malformed packets with throttled warning

- Add nearest-known displayId model fallback cache for missing creature display mappings

- Clear display fallback caches on expansion reload and logout
2026-02-21 04:05:53 -08:00
Kelsi
b2b196aa33 Reduce creature spawn stutter from repeated missing-display logging
- add one-time warning caches for missing CreatureDisplayInfo and missing model path lookups
- log each missing displayId/model-path only once instead of every spawn retry/frame
- remove duplicate empty-model-path warning in spawnOnlineCreature (already reported by lookup path)

This cuts high-frequency log I/O and string formatting in hotspots when server sends unknown displayIds, while preserving first-occurrence diagnostics.
2026-02-21 02:43:06 -08:00
Kelsi
d76537a8aa Fix NPC virtual weapons and stabilize facial hair geosets
- resolve creature virtual item values as Item.dbc entry -> DisplayID before direct ItemDisplayInfo fallback\n- use correct WotLK virtual item base index set (starting at 56) and keep retry attach loop for late update fields\n- keep NPC main-hand weapon attachment path and clear erroneous offhand attachments\n- refactor NPC virtual weapon attach into helper with per-creature retry tracking\n- tighten humanoid facial hair geoset selection to avoid loading all beard/sideburn meshes\n- adjust facial 3xx preference to favor chin-hair channel when available
2026-02-20 23:04:57 -08:00
Kelsi
3368dbb9ec Fix NPC apparel fallback and reduce world-entry stutter
Hide NPC cloak/object-skin mesh when no cape texture resolves by using a transparent texture fallback, preventing skin-texture bleed on cloaks. Tighten NPC equipment region compositing by slot and add safe humanoid geoset selection to avoid robe-over-pants conflicts and odd pants texturing.

Reduce login/runtime hitching by deferring non-critical world-system initialization across frames, lowering per-frame transport doodad spawn budget, and demoting high-volume transport/MO_TRANSPORT diagnostics to debug. Gate M2 glow diagnostics behind WOWEE_M2_GLOW_DIAG and make zone music prewarm opt-in via WOWEE_PREWARM_ZONE_MUSIC.
2026-02-20 20:31:04 -08:00
Kelsi
48d9de810d Reduce runtime streaming stutter by throttling heavy spawn workloads
- Add per-frame cap for first-time creature model loads to spread expensive model/texture decode work across frames instead of burst loading.

- Keep cached creature spawns flowing while deferring uncached display IDs, preserving world population updates with smoother frame pacing.

- Defer transport WMO doodad instancing into a queued batch processor with a strict per-frame budget to avoid multi-hundred-ms spikes when ships/elevators register.

- Process deferred transport doodad batches in both normal gameplay update and loading-screen warmup loop so heavy transport setup can be amortized before and after world entry.

- Cleanup pending transport doodad batches on gameobject despawn to prevent stale work and avoid attaching children to removed parents.

- Lower character texture cache miss logging from INFO to DEBUG to reduce log I/O contention during movement-heavy asset streaming.
2026-02-20 20:00:44 -08:00
Kelsi
acb63d4f6e Hide post-login world hitch behind loading screen
- keep character-selection state until world entry load/finalize completes
- move expensive post-load setup (test transport + creature callback prep) before loading screen shutdown
- add bounded world warmup pass under loading screen to drain initial network/spawn backlog
- start intro camera pan after warmup so rotation begins when gameplay becomes visible
- guard test transport setup so it runs once per session
- add per-update world socket parse budget to prevent single-frame packet-drain stalls

This reduces visible 3-4s stutter after login by shifting startup work behind the loading screen and time-slicing packet processing.
2026-02-20 17:29:09 -08:00
Kelsi
ebaeea43cb Fix NPC movement animation sync and minimap marker behavior
- Use interpolated moveInstanceTo() for normal server NPC position deltas so walk/run animations play instead of visual sliding
- Keep hard snaps only for dead units and large corrections/teleports
- Add per-creature render position cache to drive interpolation safely across frames and clear it on spawn/despawn/reset
- Keep minimap controls visible regardless of quest-status availability
- Correct minimap NPC/quest marker projection mapping to match minimap shader transform
- Add optional nearby NPC minimap dots setting (default OFF), exposed in Gameplay > Interface and persisted in settings
2026-02-20 16:40:22 -08:00
Kelsi
f7372a282d Improve selected-NPC ring visuals, anchoring, and occlusion behavior
Selection ring rendering has been upgraded to better match WoW-like target feedback and remain readable across complex geometry.

Visual updates:
- Reworked ring mesh/shader from a simple two-band strip to a unit-disc + radial fragment shaping.
- Implemented a thinner outer ring profile.
- Added an inward color/alpha gradient that fades from the ring toward the center.

Placement/anchoring updates:
- Added CharacterRenderer::getInstanceFootZ() to query model foot plane from instance bounds.
- Added Application::getRenderFootZForGuid() to resolve per-GUID foot height via live instance mapping.
- Updated GameScreen target selection placement to anchor the effect at target foot Z.

Ground/surface stability:
- In renderSelectionCircle(), added floor clamping against terrain, WMO, and M2 floor probes at target XY.
- Raised final placement offset to reduce residual clipping on uneven surfaces.

Depth/visibility behavior:
- Added polygon offset during ring draw to reduce z-fighting.
- Disabled depth testing for the selection effect draw pass (with state restore) so the ring remains visible through terrain/WMO occluders, per requested behavior.

State safety:
- Restored modified GL state after selection pass (depth test / polygon offset / depth mask / cull).

Build validation:
- Verified with cmake build target "wowee" after each stage; final build succeeds.
2026-02-20 16:02:34 -08:00
Kelsi
52ac3bcba3 Opcode tables: sync Classic/WotLK to canonical headers and expand logical mapping coverage
Classic: synchronized Data/expansions/classic/opcodes.json to /home/k/Desktop/classicopcodes.h with exact symbol/value parity (0 missing, 0 mismatches).

WotLK: synchronized Data/expansions/wotlk/opcodes.json to /home/k/Desktop/azerothcoreOpcodes.h and aligned symbol names to AzerothCore naming.

Logical opcode layer: expanded include/game/opcode_table.hpp and src/game/opcode_table.cpp to include missing canonical opcode symbols required by synced tables, and removed legacy alias fallback block so canonical names are used directly.

Gameplay/handler updates included from ongoing fixes: duel/taxi stale opcode cleanup, level-up/sound handling adjustments, and related parser/packet references updated to match canonical opcode identifiers.

Validated by successful full build: cmake --build build -j32.
2026-02-20 02:50:59 -08:00
Kelsi
e163813dee Add Warrior Charge ability with ribbon trail visual effect
Implements charge rush-to-target for spell IDs 100/6178/11578 with
smoothstep lerp movement, vertical red-orange ribbon trail, dust puffs,
client-side range validation, and sound fallback chain.
2026-02-19 21:13:13 -08:00
Kelsi
2bbd0fdc5f Fix movement desync: strafe animation and missing SET_FACING
Two bugs caused the client to look like a bot to server GMs:

1. Strafe animation played during forward+strafe (W+A) instead of the
   walk/run animation. Added pureStrafe guard so strafe animations only
   play when exclusively strafing (no forward key or auto-run active).

2. CMSG_MOVE_SET_FACING was never sent on mouse-look turns. The server
   predicts movement from the last known facing; without SET_FACING the
   heartbeat position appeared to teleport each time the player changed
   direction. Now sent at up to 10 Hz whenever facing changes >3°,
   skipped while keyboard-turning (handled server-side by TURN flags).
2026-02-19 16:40:17 -08:00
Kelsi
fc0ac6dd0f Fix combat facing updates and dead-on-spawn creature pose 2026-02-19 01:19:29 -08:00
Kelsi
85714fd7f6 Fix taxi flight: camera panning, world reload, gryphon display, and animations
- Clear introActive/idleOrbit in externalFollow block so mouse panning works during taxi
- Skip full world reload on same-map teleports (taxi landing) by tracking loadedMapId
- Collect all model IDs for a path when resolving gryphon display ID (fixes displayId=0)
- Remove incorrect MountDisplayId fields from Vanilla/Turtle TaxiNodes DBC layouts
- Add Vanilla fly animation IDs (234/229/233) to taxi mount animation candidates
2026-02-17 02:23:41 -08:00
Kelsi
35034ca544 Throttle player equipment compositing and spawning to fix walking stutter
Defer equipment texture compositing to a queue processed max 1 per frame
instead of compositing immediately on callback (each compositeWithRegions
call does file I/O + CPU blit + GPU upload on the main thread). Reduce
MAX_SPAWNS_PER_FRAME from 96 to 8 and increase inspect rate limit from
0.75s to 2s. Demote noisy per-frame logs to DEBUG level.
2026-02-16 00:51:59 -08:00
Kelsi
d7e2b26af7 Unify asset system: one asset set, always high-res
Remove HDPackManager, expansion overlay manifests, and BLP size-comparison
logic. Assets now resolve through a single manifest with a simple override
directory (Data/override/) for future HD upgrades.
2026-02-15 04:18:34 -08:00
Kelsi
886f4daf2e Add per-expansion asset overlay system and fix CharSections DBC layout
Expansion overlays allow each expansion to supplement the base asset data
via an assetManifest field in expansion.json, loaded at priority 50 (below
HD packs). The asset extractor gains --reference-manifest for delta-only
extraction. Also fixes CharSections field indices (VariationIndex=4,
ColorIndex=5, Texture1=6) across all DBC layout references.
2026-02-14 00:00:26 -08:00
Kelsi
d3211f5493 Show online player equipment 2026-02-13 20:10:19 -08:00
Kelsi
5afd1b65a8 Fix Turtle/Classic parsing and online player textures 2026-02-13 19:40:54 -08:00
Kelsi
430c2bdcfa Vanilla/Turtle WoW support: M2 loading, bone parsing, textures, auth
- Vanilla M2 bone struct (108 bytes) with 28-byte animation tracks
- Version-aware bone parsing (vanilla vs WotLK format detection)
- Fix CharSections.dbc field layout for vanilla (variation/color at 4-5)
- Remove broken CharSections.csv files (all fields marked as strings)
- Expansion data reload on profile switch (DBC cache clear, layout reload)
- Vanilla packet encryption (VanillaCrypt XOR-based header crypt)
- Extended character preview geoset range (0-99) for vanilla models
- DBC cache clear support in AssetManager
2026-02-13 16:53:28 -08:00
Kelsi
7092844b5e Add multi-expansion support with data-driven protocol layer
Replace hardcoded WotLK protocol constants with a data-driven architecture
supporting Classic 1.12.1, TBC 2.4.3, and WotLK 3.3.5a. Each expansion
has JSON profiles for opcodes, update fields, and DBC layouts, plus C++
polymorphic packet parsers for binary format differences (movement flags,
speed fields, transport data, spline format, char enum layout).

Key components:
- ExpansionRegistry: scans Data/expansions/*/expansion.json at startup
- OpcodeTable: logical enum <-> wire values loaded from JSON
- UpdateFieldTable: field indices loaded from JSON per expansion
- DBCLayout: schema-driven DBC field lookups replacing magic numbers
- PacketParsers: WotLK/TBC/Classic parsers with correct flag positions
- Multi-manifest AssetManager: layered manifests with priority ordering
- HDPackManager: overlay texture packs with expansion compatibility
- Auth screen expansion picker replacing hardcoded version dropdown
2026-02-12 22:56:36 -08:00
Kelsi
275914b4db Fix character appearance, previews, mount seat, and online unequip 2026-02-12 14:55:27 -08:00
Kelsi
ef6be2f186 Auto-unsheath weapons on combat engage 2026-02-12 00:15:51 -08:00
Kelsi
5d63bb0988 Queue transport pre-spawn moves and add Z weapon sheath toggle 2026-02-12 00:14:39 -08:00
Kelsi
5171f9cad4 Fix taxi state sync and transport authority; reduce runtime log overhead; restore first-person self-hide 2026-02-11 22:27:02 -08:00
Kelsi
40b50454ce Stabilize taxi/state sync and creature spawn handling 2026-02-11 21:14:35 -08:00
Kelsi
f752a4f517 Fix NPC visibility and stabilize world transport/taxi updates 2026-02-11 18:25:04 -08:00
Kelsi
f3f3b62880 Transport hell 2026-02-11 00:54:38 -08:00
Kelsi
2e923311d0 Add transport system, fix NPC spawning, and improve water rendering
Transport System (Phases 1-7):
- Implement TransportManager with Catmull-Rom spline path interpolation
- Add WMO dynamic transforms for moving transport instances
- Implement player attachment via world position composition
- Add test transport with circular path around Stormwind harbor
- Add /transport board and /transport leave console commands
- Reuse taxi flight spline system and external follow camera mode

NPC Spawn Fixes:
- Add smart ocean spawn filter: blocks land creatures at high altitude over water (Z>50)
- Allow legitimate water creatures at sea level (Z≤50) to spawn correctly
- Fixes Elder Grey Bears, Highland Striders, and Plainscreepers spawning over ocean
- Snap online creatures to terrain height when valid ground exists

NpcManager Removal:
- Remove deprecated NpcManager (offline mode no longer supported)
- Delete npc_manager.hpp and npc_manager.cpp
- Simplify NPC animation callbacks to use only creatureInstances_ map
- Move NPC callbacks to game initialization in application.cpp

Water Rendering:
- Fix tile seam gaps caused by per-vertex wave randomization
- Add distance-based blending: seamless waves up close (<150u), grid effect far away (>400u)
- Smooth transition between seamless and grid modes (150-400 unit range)
- Preserves aesthetic grid pattern at horizon while eliminating gaps when swimming
2026-02-10 21:29:10 -08:00
Kelsi
71d14b77c9 Implement WoW-style 3D billboard quest markers
Replace 2D ImGui text markers with proper 3D billboard sprites using BLP textures.

Features:
- Billboard rendering using Interface\GossipFrame\ BLP textures (yellow !, yellow ?, grey ?)
- WoW-style visual effects: bob animation, distance-based scaling, glow pass, distance fade
- Proper NPC height positioning with bounding box detection
- Camera-facing quads with depth testing but no depth write
- Shader-based alpha modulation for glow and fade effects

Technical changes:
- Created QuestMarkerRenderer class with billboard sprite system
- Integrated into Renderer initialization for both online and offline terrain loading
- Rewrote updateQuestMarkers() to use billboard system instead of M2 models
- Disabled old 2D ImGui renderQuestMarkers() in game_screen.cpp
- Added debug logging for initialization and marker tracking

Quest markers now render with proper WoW visual fidelity.
2026-02-09 23:41:38 -08:00
Kelsi
a4c5f35397 Implement 3D quest markers using M2 models
Loads and renders actual quest marker M2 models from
World\Generic\PassiveDoodads\Quest\ as floating 3D objects above NPCs
based on quest status, replacing 2D ImGui text markers.

Features:
- Loads QuestExclamation.m2 (yellow !) for available quests
- Loads QuestQuestionMark.m2 (silver ?) for completable quests
- Updates marker positions dynamically as NPCs move
- Automatically spawns/despawns markers based on quest status changes
- Positions markers above NPC heads using render bounds

Quest markers are now proper 3D assets consistent with WoW 3.3.5a client.
2026-02-09 23:05:23 -08:00
Kelsi
5afc9a57d1 Auto-select newly created character in selection screen
After creating a character, automatically select it in the character
list instead of defaulting to the previously selected character.

Changes:
- Added selectCharacterByName() method to CharacterScreen
- Store created character name in Application
- On creation success, auto-select the new character by name
- Falls back to saved selection if new character name doesn't match
2026-02-09 22:51:13 -08:00