Commit graph

93 commits

Author SHA1 Message Date
Kelsi
1108aa9ae6 feat: implement M2 ribbon emitter rendering for spell trail effects
Parse M2RibbonEmitter data (WotLK format) from M2 files — bone index,
position, color/alpha/height tracks, edgesPerSecond, edgeLifetime,
gravity. Add CPU-side trail simulation per instance (edge birth at bone
world position, lifetime expiry, gravity droop). New m2_ribbon.vert/frag
shaders render a triangle-strip quad per emitter using the existing
particleTexLayout_ descriptor set. Supports both alpha-blend and additive
pipeline variants based on material blend mode. Fixes invisible spell
trail effects (~5-10%% of spell visuals) that were silently skipped.
2026-03-13 01:17:30 -07:00
Kelsi
19eb7a1fb7 fix: animation stutter, resolution crash, memory cap, spell tooltip hints, GO collision
- Animation stutter: skip playAnimation(Run) for the local player in the
  server movement callback — the player renderer state machine already manages
  it; resetting animTime on every movement packet caused visible stutter
- Resolution crash: reorder swapchain recreation so old swapchain is only
  destroyed after confirming the new build succeeded; add null-swapchain
  guard in beginFrame to survive the retry window
- Memory cap: reduce cache budget from 80% uncapped to 50% hard-capped at
  16 GB to prevent excessive RAM use on high-memory systems
- Spell tooltip: suppress "Drag to action bar / Double-click to cast" hints
  when the tooltip is shown from the action bar (showUsageHints=false)
- M2 collision: add watermelon/melon/squash/gourd to foliage (no-collision);
  exclude chair/bench/stool/seat/throne from smallSolidProp so invisible chair
  bounding boxes no longer trap the player
2026-03-10 22:26:50 -07:00
Kelsi
0ea8e55ad4 ui,game,pipeline: player nameplates always-on, level-up ring effect, vanilla tile fallback, warden null guard
- Nameplates: player names always rendered regardless of V-key toggle;
  separate cull distance 40u (players/target) vs 20u (NPCs); cyan name
  color for other players; fade alpha scales with cull distance
- Level-up: add expanding golden ring burst (3 staggered waves, 420u
  max radius) + full-screen flash to renderDingEffect(); M2 LevelUp.m2
  is still attempted as a bonus on top
- Vanilla tile loading: add AssetManager::setBaseFallbackPath() so that
  when the primary manifest is an expansion-specific DBC-only subset
  (e.g. Data/expansions/vanilla/), world terrain files fall back to
  the base Data/ extraction; wired in Application::initialize()
- Warden: map a null guard page at address 0x0 in the Unicorn emulator
  so NULL-pointer reads in the module don't crash with UC_ERR_MAP;
  execution continues past the NULL read for better diagnostics
2026-03-10 07:25:04 -07:00
Kelsi
3cdaf78369 game,warden,assets: fix unknown player names, warden heap overlap, and Vanilla Item.dbc
- game: clear pendingNameQueries on player out-of-range and DESTROY_OBJECT so
  re-entering players get a fresh name query instead of being silently skipped
- game: add 5s periodic name resync scan that re-queries players with empty names
  and no pending query, recovering from dropped CMSG_NAME_QUERY responses
- warden: fix UC_ERR_MAP by moving HEAP_BASE from 0x200000 to 0x20000000; the old
  heap [0x200000, 0x1200000) overlapped the module at 0x400000, causing Unicorn to
  reject the heap mapping and abort emulator initialisation
- warden: add early overlap check between module and heap regions to catch future
  layout bugs at init time
- assets: add loadDBCOptional() which logs at DEBUG level when a DBC is absent,
  for files that are not distributed on all expansions
- assets: use loadDBCOptional for Item.dbc (absent on Vanilla 1.12 clients) and
  fall back to server-sent itemInfoCache displayInfoId for NPC weapon resolution
2026-03-10 07:00:43 -07:00
Kelsi
4d1be18c18 wmo: apply MOHD ambient color to interior group lighting
Read the ambient color from the MOHD chunk (BGRA uint32) and store it
on WMOModel as a normalized RGB vec3.  Pass it through ModelData into
the per-batch WMOMaterialUBO (replacing the unused pad[3] bytes, keeping
the struct at 64 bytes).  The GLSL interior branch now floors vertex
colors against the WMO ambient instead of a hardcoded 0.5, so dungeon
interiors respect the artist-specified ambient tint from the WMO root
rather than always clamping to grey.
2026-03-09 21:27:01 -07:00
Kelsi
0a528935e2 Auto-detect WoW locale from data directory; override with WOWEE_LOCALE env 2026-03-09 15:36:26 -07:00
Kelsi
ee4e6a31ce Filter WMO decorative geometry from collision, fix tram portal trigger IDs
Parse MOPY per-triangle flags in WMO groups and exclude detail/decorative
triangles (flag 0x04) from collision detection. This prevents invisible
walls from objects like gears and railings in WMO interiors.

Add WotLK area trigger IDs 2173/2175 to extended-range tram triggers.
2026-03-06 10:37:32 -08:00
Kelsi
08d40583c9 Fix MLIQ water parsing, skip interior water, clear movement on teleport
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
- Remove bogus 2-byte skip after materialId in MLIQ parser that shifted
  all vertex heights and tile flags by 2 bytes (garbage data)
- Skip liquid loading for interior WMO groups (flag 0x2000) to prevent
  indoor water from rendering as outdoor canal water
- Clear movement inputs on teleport/portal to prevent auto-running after
  zone transfer (held keys persist through loading screen)
2026-03-05 15:12:51 -08:00
Kelsi
19652ae521 Add purgeExtractedAssets() to clear all extracted asset data from disk
Some checks failed
Build / Build (arm64) (push) Has been cancelled
Build / Build (x86-64) (push) Has been cancelled
Build / Build (macOS arm64) (push) Has been cancelled
Build / Build (windows-arm64) (push) Has been cancelled
Build / Build (windows-x86-64) (push) Has been cancelled
Security / CodeQL (C/C++) (push) Has been cancelled
Security / Semgrep (push) Has been cancelled
Security / Sanitizer Build (ASan/UBSan) (push) Has been cancelled
2026-02-28 09:07:47 -08:00
Kelsi
543535a892 Add clean.sh reset utility, exclude CSVs from repo, prefer binary DBCs
- Add clean.sh with granular options (--build, --assets, --cache, --csvs, --user, --all, --dry-run)
- Remove 119 CSV files from git tracking and add to .gitignore
- Flip DBC loading order: try binary from extracted MPQs first, CSV as fallback
- Remove forceBinaryDbc workaround and garbled-CSV validation (no longer needed)
2026-02-28 09:04:43 -08:00
Kelsi
16d88f19fc Fix instance portals: WDT byte order, box trigger sizing, suppress ping-pong, WMO cache cleanup
- Fix WDT chunk magic constants to big-endian ASCII (matching ADTLoader)
- Add minimum effective size for box area triggers (90 units, like sphere 45-unit radius)
- Add areaTriggerSuppressFirst_ flag to prevent portal ping-pong on map transfer
- Add WMORenderer::clearAll() to clear models/textures on map change (prevents GPU crash)
- Increase WMO texture cache default to 8GB
- Fix setMapName called after loadTestTerrain so WMO renderer exists
- Save/restore player position around CMSG_AREATRIGGER to prevent bad DB persistence
2026-02-27 04:59:12 -08:00
Kelsi
d0e8b44866 Add instance support: WDT parser, WMO-only map loading, area triggers, BG queue accept
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
- WDT parser detects WMO-only maps (dungeons/raids/BGs) via MPHD flag 0x01
- WMO-only loading branch in loadOnlineWorldTerrain loads root WMO directly
- Area trigger system: loads AreaTrigger.dbc, checks player proximity, sends CMSG_AREATRIGGER
- BG queue acceptance via /join command sending CMSG_BATTLEFIELD_PORT
- SMSG_INSTANCE_DIFFICULTY handler stub
- Map change cleanup (clear old WMO/M2/terrain on map transfer)
- 5-second area trigger cooldown after map transfer to prevent ping-pong loops
2026-02-26 17:56:11 -08:00
Kelsi
25412ff5cc Fix DBC loading and bank drag-and-drop reliability
- Force binary loading for SkillLine.dbc (CSV exports are garbled)
- Handle quoted numeric values in DBC CSV parser
- Fix bank slot drag-and-drop to use mouse-release detection instead
  of click detection, preventing item drops on wrong slots
- Fix action bar item drop to use hoveredOnRelease for consistency
2026-02-26 02:33:10 -08:00
Kelsi
94e4a0bdb3 Fix letter-named patch MPQs not loading on case-sensitive filesystems
Some checks are pending
Build / Build (arm64) (push) Waiting to run
Build / Build (x86-64) (push) Waiting to run
Build / Build (macOS arm64) (push) Waiting to run
Build / Build (windows-arm64) (push) Waiting to run
Build / Build (windows-x86-64) (push) Waiting to run
Security / CodeQL (C/C++) (push) Waiting to run
Security / Semgrep (push) Waiting to run
Security / Sanitizer Build (ASan/UBSan) (push) Waiting to run
Two bugs in loadPatchArchives():
1. isLetterPatch detection was inverted (rfind != 0 is false for all
   "patch-*" entries), making the disable flags non-functional
2. Patch file lookup used exact std::filesystem::exists() which is
   case-sensitive on Linux — Patch-A.MPQ wouldn't match patch-a.mpq

Now scans the data directory once and builds a case-insensitive lookup
map, so any case variant (Patch-A.MPQ, patch-a.mpq, PATCH-A.MPQ) is
found correctly.
2026-02-25 12:18:36 -08:00
Kelsi
d045c1215a Fix Warden module parsing and DBC loading for Classic expansion
Warden: copy/skip pair order was reversed — format is [copy][data][skip]
per MaNGOS/TrinityCore, not [skip][copy][data]. All copy sizes read as 0,
causing module load failure and server disconnect.

DBC: when binary DBCs aren't available (no MPQ extraction), fall back to
expansion CSV files even for visual DBCs (CreatureDisplayInfo, CharSections,
ItemDisplayInfo, etc.) instead of failing with "DBC not found".
2026-02-24 04:42:36 -08:00
Kelsi
aaab2115d1 Fix all remaining build warnings and eliminate UB in binary parsers
Resolve 57 compiler warnings (unused params/vars, ignored return values,
enum mismatch) and replace undefined-behavior reinterpret_cast with
memcpy in DBC, BLP, and Warden module loaders for ARM64 portability.
2026-02-23 19:58:38 -08:00
Kelsi
3e6de8485b Fix ground clutter height sampling and terrain shader GPU crash
- Fix HeightMap::getHeight() to use interleaved 17-wide row layout
  matching MCVT storage (was using wrong 9-wide contiguous indexing)
- Guard terrain bump mapping normalize against zero-length vectors
  to prevent NaN propagation and GPU faults
2026-02-23 06:46:31 -08:00
Kelsi
a7cf0d0c4e Fix WMO LOD shell culling and MOGP header parsing
- Fix MOGP header: skip 8-byte groupName/descriptiveName prefix before flags
- Fix fogIndices: read as 4×uint8 (4 bytes) instead of 4×uint32 (16 bytes)
- Detect LOD shell groups: city shells, facades, flag 0x80 indoor, low-vert
- Per-group distance culling at 196 units instead of whole-WMO distance
2026-02-23 03:23:18 -08:00
Kelsi
3ffb7ccc50 Fix lamp posts as glass and hide distance-only LOD groups when close
Two WMO rendering fixes:

1. Glass batch merging: BatchKey didn't include isWindow, so window and
   non-window batches sharing the same texture got merged together. If
   the window batch was processed first, the entire merged batch (lamp
   base, iron frame, etc.) rendered as transparent glass. Add isWindow
   to the batch key so glass/non-glass batches stay separate.

2. LOD group culling: WMO groups named with "LOD" are distance-only
   impostor geometry (e.g. cathedral tower extension, hill tower). They
   should only render beyond 200 units. Store raw MOGN chunk for
   offset-based name lookup, detect "lod" in group names during load,
   and skip LOD groups in both main and shadow passes when camera is
   within range.
2026-02-23 01:54:05 -08:00
Kelsi
fb4ff46fe3 Fix WMO water rendering: correct MLIQ parsing, tile masking, and depth effects
- Fix MLIQ vertex stride: each vertex is 8 bytes (4 flow + 4 height), not 4
- Use MLIQ tile flags to mask out tiles with no liquid (bridges, covered areas)
- Disable wave displacement on WMO water to prevent edge slosh artifacts
- Convert screen-space depth to vertical depth for shoreline foam and water
  transparency, preventing false shoreline effects on occluding geometry
- Add underwater blue fog overlay and scene fog shift (terrain water only)
- Add getNearestWaterHeightAt to avoid false underwater detection from
  elevated WMO water surfaces
- Tint refracted scene toward water color to mask occlusion edge artifacts
- Lower WMO water by 1 unit to match terrain water level
2026-02-23 00:18:32 -08:00
Kelsi
9c8cd44803 Optimize threading and texture fallback stability 2026-02-22 08:12:08 -08:00
Kelsi
ae88b226b5 Stabilize streaming memory and parser handling; revert socket recv optimizations 2026-02-22 07:26:54 -08:00
Kelsi
e12141a673 Add configurable MSAA anti-aliasing, update auth screen and terrain shader
- MSAA: conditional 2-att (off) vs 3-att (on) render pass with auto-resolve
- MSAA: multisampled color+depth images, query max supported sample count
- MSAA: .setMultisample() on all 25+ main-pass pipelines across 17 renderers
- MSAA: recreatePipelines() on every sub-renderer for runtime MSAA changes
- MSAA: Renderer::setMsaaSamples() orchestrates swapchain+pipeline+ImGui rebuild
- MSAA: Anti-Aliasing combo (Off/2x/4x/8x) in Video settings, persisted
- Update auth screen assets and terrain fragment shader
2026-02-22 02:59:24 -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
1003b25ff4 Improve runtime stutter handling and ground clutter performance
- reduce per-tile ground clutter generation pressure and enforce tighter caps to avoid spikes

- remove expensive detail dedupe scans from the hot render path

- add progressive/lazy clutter updates around player movement to smooth frame pacing

- lower noisy runtime INFO logging to DEBUG/throttled paths

- keep terrain/game screen updates responsive while preserving existing behavior
2026-02-21 01:26:16 -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
68896b5233 Remove hardcoded WotLK defaults, use JSON as single source of truth for opcodes/fields/DBC layouts 2026-02-20 00:39:20 -08:00
Kelsi
da49593268 Add 3D level-up effect using LevelUp.m2 spell model
Replace 2D screen-space ding rings with real WoW LevelUp.m2 particle/geometry
effect. Fix FBlock particle color parsing (C3Vector floats, not CImVector bytes)
which was producing blue/red instead of golden yellow. Spell effect models bypass
particle dampeners, glow sprite conversion, Mod→Additive blend override, and all
collision (floor/wall/camera) to prevent camera zoom-in. Other players' level-ups
trigger the 3D effect at their position with group chat notification. F7 hotkey
for testing.
2026-02-19 20:36:25 -08:00
Kelsi
9a950ce09f Fix M2 white shell artifact from missing textures, add opacity track support
Batches whose named texture fails to load now render invisible instead of
white (the swampreeds01a.blp case causing a white shell around aquatic plants).

Also implements proper M2 opacity plumbing:
- Parse texture weight tracks (M2Track<fixed16>) and color animation alpha
  tracks (M2Color.alpha) to resolve per-batch opacity at load time
- Skip batches with batchOpacity < 0.01 in the render loop
- Apply M2Texture.flags (bit0=WrapS, bit1=WrapT) to GL sampler wrap mode
- Upload both UV sets (texCoords[0] and texCoords[1]) and select via
  textureUnit uniform, so batches referencing UV set 1 render correctly
2026-02-17 23:52:44 -08:00
Kelsi
eebc0007a6 Fix quest required item display and add NPC spawn diagnostics
- Fix SMSG_QUESTGIVER_REQUEST_ITEMS: read emoteDelay(u32)+emoteId(u32)+autoFinish(u8)
  instead of 5 uint32s — the 11-byte over-read corrupted requiredMoney, itemCount,
  and all item data (itemId/count/displayInfoId)
- Fix garbled CSV fallback in asset_manager: return nullptr instead of silently
  returning garbled DBC data when binary fallback is unavailable
- Add NPC spawn diagnostics: log when UNIT blocks have displayId=0 (wrong field index)
  and when spawn callback fires with displayId + position
- Improve getModelPathForDisplayId failure logging: distinguish displayDataMap_ miss
  vs modelIdToPath_ miss, and include map sizes for context
2026-02-17 17:15:48 -08:00
Kelsi
6dd811a926 Hide M2 particle emitter volumes rendering as grey boxes
M2 models like OrgrimmarFloatingEmbers and OrgrimmarSmokeEmitter have a
simple box mesh (24 verts, 36 indices) meant only to define particle
emitter bounds. Their blendMode was 0 (opaque), causing them to render
as large grey boxes. Detect these by checking for box geometry with
particle emitters and large bounds (>5 units), then mark as invisible.
Also add ANTIPORTAL and batch-disable flag checks to WMO group filtering.
2026-02-16 19:50:35 -08:00
Kelsi
bbcc18aa22 Fix M2 particle rendering: color, gravity, transparency, and animation
- Fix FBlock color keys from 3-byte BGR to 4-byte RGBA (CImVector) to
  prevent garbled purple/red colors from byte misalignment
- Add circular soft-edge falloff in particle fragment shader (GL_POINTS
  rendered as squares by default)
- Apply default gravity (4.0 spray, 1.5 mist) when M2 gravity is 0 since
  bone animation from .anim files isn't loaded yet
- Add drift velocity to speed=0 emitters so particles spread as mist
  instead of clustering at static bone positions
- Run particle updates for all nearby instances, not just those in
  boneWorkIndices_, to prevent particles freezing when bone culled
- Wrap animation time for particle models to keep emission tracks looping
- Cap particle scale to 1.5 and reduce point size multiplier (800→400)
- Desaturate FBlock colors 70% toward white for natural water appearance
- Reduce additive blend alpha to 5% and volume particles to 2%
2026-02-16 02:12:43 -08:00
Kelsi
d87a86e35c Remove debug logging and add negative texture cache to fix lag spikes
Remove PPM composite dumps, MODEL1_BOUNDS vertex analysis, TEX_REGION
logging, FOUNTAIN_PARTICLES debug output, and verbose chat/warden gate
logging. Add negative cache for failed texture loads to prevent repeated
file I/O for missing textures like deathknighteyeglow.blp.
2026-02-16 00:45:47 -08:00
Kelsi
ed6b305158 Fix character geoset mapping and texture corruption on equipment change
Corrected CharGeosets group assignments verified via vertex bounding boxes:
- Group 4 (401+) = gloves/forearms, Group 5 (501+) = boots/shins,
  Group 8 (801+) = sleeves (chest-controlled), Group 9 = kneepads,
  Group 13 (1301+) = pants/trousers, Group 20 (2002) = bare feet
- Changed bare shin default from 501 to 502 for better width match
  with thigh mesh (0.39 vs 0.32, thighs are 0.42)
- Added clearCompositeCache() to prevent stale composite textures
  from being reused across equipment changes
- Fixed character preview geoset defaults to match corrected mapping
2026-02-15 20:53:01 -08:00
Kelsi
8a468e9533 Add mailbox system and fix logging performance stutter
Implement full mail send/receive: SMSG_SHOW_MAILBOX, CMSG_GET_MAIL_LIST,
SMSG_MAIL_LIST_RESULT, CMSG_SEND_MAIL, SMSG_SEND_MAIL_RESULT, mail take
money/item/delete/mark-as-read, and inbox/compose UI windows.

Fix periodic stuttering in Stormwind caused by synchronous per-line disk
flushes in the logger — remove fileStream.flush() and std::endl, downgrade
high-volume per-packet/per-model/per-texture LOG_INFO to LOG_DEBUG.
2026-02-15 14:00:41 -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
630019aea9 Fix particle glow transparency for textures without alpha 2026-02-14 22:32:12 -08:00
Kelsi
a2c049b00b Prefer higher-res variants for all textures 2026-02-14 22:09:28 -08:00
Kelsi
9044cef3af Prefer higher-res character textures across overlays 2026-02-14 22:06:15 -08:00
Kelsi
bf31da8c13 Add MCLQ water, TaxiPathNode transports, and vanilla M2 particles
- Parse MCLQ sub-chunks in vanilla ADTs for water rendering (WotLK uses MH2O)
- Load TaxiPathNode.dbc for MO_TRANSPORT world-coordinate paths (vanilla boats)
- Parse data[] from SMSG_GAMEOBJECT_QUERY_RESPONSE (taxiPathId for transports)
- Support vanilla M2 particle emitters (504-byte struct, different from WotLK 476)
- Add character preview texture diagnostic logging
- Fix disconnect handling on character screen (show error only when no chars)
2026-02-14 20:20:43 -08:00
Kelsi
0ef4af9c99 Fix CharSections DBC layout and Warden SHA1 hash computation
CharSections fields were mapped incorrectly (Variation/Color at 4-5,
textures at 6-8) — corrected to textures at 4-6, Flags at 7,
Variation at 8, Color at 9. Fixed in both dbc_layout.cpp and all
expansion JSON configs. Also fix Warden HASH_REQUEST to SHA1 over
seed+moduleImage instead of just seed.
2026-02-14 18:35:08 -08:00
Kelsi
58d8b88721 Fix inspect spam and emote text lookup for other players
Two bugs fixed:
1. SMSG_INSPECT_RESULTS (0x115) was falling through to the inspect
   handler, but this opcode is not the real inspect response. Removed
   the case so only SMSG_INSPECT_TALENT (0x3F4) triggers the handler.
2. EmotesText DBC layout was missing "ID" field in all 4 expansion
   JSON files, causing operator[] to return 0xFFFFFFFF instead of 0.
   This broke the dbcId reverse lookup, so other players' emotes
   always fell back to generic "performs an emote" text. Added ID
   and OthersTargetTextID/OthersNoTargetTextID to all layouts.
2026-02-14 15:23:32 -08:00
Kelsi
3acb42b363 Resolve emote text from DBC for other players' text emotes
Load third-person emote text templates (othersTarget/othersNoTarget)
from EmotesText.dbc fields 3 and 7 alongside existing sender text.
Build reverse lookup map from dbcId to EmoteInfo for incoming
SMSG_TEXT_EMOTE resolution. Other players now show proper emote
descriptions like "Player dances with Target" instead of generic
"Player performs an emote" text.
2026-02-14 15:11:43 -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
811a2a97a8 Fix vanilla M2 walk animation timestamp normalization
Vanilla M2 tracks store absolute timestamps in the flat array (e.g.
1000-2000ms) but the renderer plays animTime from 0 to duration.
Normalize timestamps to 0-relative after slicing per-sequence ranges
so findKeyframeIndex matches correctly.
2026-02-13 21:43:14 -08:00
Kelsi
22728b461f Fix vanilla M2 animations, movement packets, and DBC locale
- Parse vanilla M2 animation tracks (flat arrays with M2Range indices)
  instead of skipping them, fixing T-pose on all vanilla models
- Use C4Quaternion (float[4]) for vanilla bone rotations instead of
  CompressedQuat (int16[4]) which produced garbage transforms
- Fix vanilla M2 attachment struct size (48 bytes, not 40) so weapons
  attach to correct bones instead of model origin
- Route movement packets through expansion-specific packet parsers
  instead of hardcoded WotLK format, fixing server-side position sync
- Fix Spell.dbc field indices for classic/turtle (Name=120, Rank=129,
  IconID=117) - were pointing to Portuguese locale column (+7 offset)
- Change guild roster keybind from J to O (WoW default)
- Add guild opcodes for all expansions
2026-02-13 21:39:48 -08:00
Kelsi
fb0ae26fe6 Vanilla/Turtle WoW compatibility: fix UPDATE_OBJECT, chat, equipment, creatures
- Route SMSG_UPDATE_OBJECT through polymorphic parsers for correct
  vanilla format (uint8 updateFlags, 6 speeds vs WotLK uint16/9)
- Fix SMSG_DESTROY_OBJECT for vanilla (8 bytes, no isDeath field)
- Add MSG_MOVE_* handlers for other player movement relay
- Add ClassicPacketParsers::parseMessageChat with targetGuid read
  and monster-type name handling
- Resolve chat sender names from player name cache before display
- Fix CSV DBC field 0 always treated as numeric ID (fixes 16+ garbled
  Turtle CSVs including Map, AreaTable, Spell, CreatureDisplayInfo)
- Add CSV DBC validation: reject garbled CSVs (>80% zero IDs) and
  fall back to binary DBC files
- Fix ItemDisplayInfo texture component field index (14+ not 15+)
  for binary DBC with gender-aware suffix resolution
- Spawn other players as visible M2 models via creature callback
- Map name cache dedup prevents overwrites from duplicate CSV records
2026-02-13 18:59:09 -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
f247d53309 Add expansion DBC CSVs, Turtle support, and server-specific login 2026-02-13 00:10:01 -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