Commit graph

711 commits

Author SHA1 Message Date
Kelsi
55fd692c1a Fix buff bar: opcode merge, isBuff flag, and duration countdown
Root cause: OpcodeTable::loadFromJson() cleared all mappings before
loading the expansion JSON, so any WotLK opcode absent from Turtle WoW's
opcodes.json (including SMSG_AURA_UPDATE and SMSG_AURA_UPDATE_ALL) was
permanently lost. Changed loadFromJson to patch/merge on top of existing
defaults so only explicitly listed opcodes are overridden.

Also fix isBuff border color: was testing flag 0x02 (effect 2 active)
instead of 0x80 (negative/debuff flag).

Add client-side duration countdown: AuraSlot.receivedAtMs is stamped
when the packet arrives; getRemainingMs(nowMs) subtracts elapsed time so
buff tooltips show accurate remaining duration instead of stale snapshot.
2026-02-17 15:49:12 -08:00
Kelsi
df0bfaea4f Fix action bar and buff bar spell tooltips showing 'Spell #xxx'
The action bar's inline Spell.dbc loader had a broken field index lookup:
operator[] on the layout map would silently insert 0 if 'Name' wasn't a
key, causing all names to be read from field 0 (the spell ID). Also the
once-only 'attempted' flag meant if assetMgr wasn't ready, it never retried.

Replace the duplicated broken DBC loading in the action bar and buff bar
with SpellbookScreen::lookupSpellName(), which reuses the spellbook's
already-correct loading (expansion layout + WotLK fallback). Remove the
now-unused actionSpellNames/actionSpellDbAttempted/actionSpellDbLoaded fields.
2026-02-17 15:41:55 -08:00
Kelsi
bd70ca17ca Fix auto-attack stalling after SMSG_ATTACKSTOP and remove stale comments
Re-send CMSG_ATTACKSWING every second while auto-attacking so combat
resumes automatically when the server pauses the attack loop (out of
range, etc). Previously the client kept autoAttacking=true but never
re-engaged, requiring the player to manually right-click again.

Also remove leftover single-player/offline references from comments.
2026-02-17 15:37:02 -08:00
Kelsi
22648870f3 Fix phantom combat text from nearby NPC/player fights
SMSG_ATTACKERSTATEUPDATE, SMSG_SPELLNONMELEEDAMAGELOG, and SMSG_SPELLDAMAGELOG
were showing combat text for all combat events in the zone, not just the
player's own fights. Added early-return in all three handlers when neither
the attacker nor target is the player.
2026-02-17 15:27:02 -08:00
Kelsi
2cad3b9c2b Fix combat text: separate incoming/outgoing positions and clarify dodge/parry
Outgoing events (player attacks enemy: damage dealt, Dodge/Parry when enemy
evades) now float on the right side of screen (near target) instead of above
the player character. Incoming events (enemy attacks player) remain at
center-left (near player).

Dodge/Parry labels now show direction: "Dodge"/"Parry" when the enemy evades
the player's attack (outgoing, gray), and "You Dodge"/"You Parry" when the
player evades an incoming attack (cyan). Crit damage now has distinct colors
for outgoing (bright yellow) vs incoming (orange).
2026-02-17 15:24:39 -08:00
Kelsi
827679579f Fix WAV decode cache and spell lookup performance
- audio_engine.cpp: cache key was based on vector pointer address, not
  content — cache never hit since each asset load produces a new
  allocation. Replace with FNV-1a over head+tail bytes + size, giving
  correct content-based identity at O(1) cost. Add 256-entry cap with
  eviction to prevent unbounded growth over long sessions.

- game_handler.hpp/cpp, spellbook_screen, game_screen: knownSpells was
  a std::vector with O(n) std::find lookups scattered across packet
  handlers and UI code. Switch to std::unordered_set for O(1) insert,
  erase, and membership checks. Update all push_back/erase-remove/find
  call sites to use set operations.
2026-02-17 15:13:54 -08:00
Kelsi
e29b67dad9 Update docs to reflect current project state
- Update README: date, Warden complete with Unicorn Engine, add trainers/nonbinary to features, add Unicorn Engine to deps
- Update status.md: date, mark quests/trainers/Warden as working, keep transports as in-progress
- Rewrite Warden docs (QUICK_REFERENCE and IMPLEMENTATION) to match actual implementation
- Remove dev-note docs (WARDEN_COMPLETE, WARDEN_MODULE_ARCHITECTURE) and stray .txt files
- Update ATTRIBUTION: add Unicorn Engine, miniaudio, AzerothCore
2026-02-17 15:05:18 -08:00
Kelsi
42e7e1ce7e Fix action bar spell icons missing on Turtle WoW
Turtle/Classic Spell.csv files are garbled (field 0 is a string rather
than a numeric ID) so loadDBC() falls back to the WotLK binary Spell.dbc
(234 fields). getSpellIcon() was still using the Turtle layout (IconID at
field 117) to read the WotLK binary, producing garbage values and no icons.

When the loaded Spell.dbc has >=200 fields it is the WotLK binary; use the
WotLK IconID field (133) directly, matching the same approach already used
in spellbook_screen.cpp.
2026-02-17 14:55:32 -08:00
Kelsi
7cf060a9f6 Handle SMSG_CHARACTER_LOGIN_FAILED (0x041) for AzerothCore/Playerbot compatibility
Previously this opcode was unrecognised and silently dropped, leaving the
client stuck in ENTERING_WORLD with no feedback when the server rejected a
login (duplicate session, world down, disabled race/class, etc.). Now we
decode the LoginFailureReason byte, reset state to CHAR_LIST_RECEIVED so
the player can retry, and surface a red error message on the character screen
via the new CharLoginFailCallback. Also adds isError colour support to
CharacterScreen::setStatus so failures show in red and successes in green.
2026-02-17 13:59:29 -08:00
Kelsi
36fc1df706 Fix Turtle WoW compatibility: NPC spawning, quests, spells, realm display, and music
- Add TurtlePacketParsers with dedicated movement block parser (Classic format + transport timestamp)
- Fix quest giver status: read uint32 and translate vanilla enum values for Classic/Turtle
- Fix quest accept packet: remove trailing uint32 that vanilla servers reject
- Fix quest details parser: auto-detect vanilla vs WotLK format (informUnit field)
- Fix spellbook and action bar icons: fallback to WotLK DBC field indices when expansion layout fails
- Fix spell cast failure messages: translate vanilla SpellCastResult codes (+1 offset)
- Fix realm list: correct type values (6=RP, 8=RP-PvP) and population thresholds
- Fix music: disable looping for zone music, auto-advance to next random track when finished
- Add music anti-repeat: avoid playing the same track back-to-back
- Make TBC update block parsing resilient (keep parsed blocks on failure instead of aborting)
- Add right-click attack on hostile mobs
- Add name query diagnostic logging
2026-02-17 05:27:03 -08:00
Kelsi
d850fe6fc0 Fix character creation on Turtle WoW (4 extra bytes + IN_PROGRESS handling)
CMSG_CHAR_CREATE was silently dropped by the server because the packet
was 4 bytes too short. Wireshark capture of the real 1.12.1 client
revealed 4 trailing zero bytes after outfitId. Also treat IN_PROGRESS
(code 46) as success since Turtle WoW sends it instead of SUCCESS.
2026-02-17 04:16:27 -08:00
Kelsi
de3a8cfa3e Add copyright protection for original music assets by Kelsi Davis 2026-02-17 04:02:01 -08:00
Kelsi
99723abfac Improve UI layout, spell casting, and realm selection screen
- Fix action bar, bag bar, chat window to track window resize (Always pos)
- Show spell names in cast bar instead of spell IDs
- Play precast/cast-complete sounds via SpellSoundManager
- Fix hearthstone to use CMSG_CAST_SPELL directly (avoids slot sync issues)
- Show map name instead of coordinates in hearthstone tooltip
- Show cooldown time remaining in action bar tooltips
- Search equipped slots and bags for action bar item icons
- Redesign realm screen: back button, larger table/buttons, auto-select
  realm with characters, double-click to enter, proportional columns
2026-02-17 03:50:36 -08:00
Kelsi
b8f1f15eb4 Fix CharSections.dbc field layout for classic/tbc/turtle expansions
The binary DBC files for all expansions use the same field ordering
(VariationIndex=4, ColorIndex=5, Texture1=6), but classic/tbc/turtle
dbc_layouts.json had swapped texture and variation/color fields, causing
all skin/face/hair/underwear lookups to fail. Also adds generalized
NxN texture scaling and a second video to README.
2026-02-17 03:18:01 -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
4a08271b75 Fix Classic item query to include GUID (server requires it)
VMaNGOS reads uint32 entry + uint64 guid for CMSG_ITEM_QUERY_SINGLE,
same as WotLK. Removing the GUID caused the server to silently drop
all item queries, leaving equipment with no names or display info.
2026-02-17 01:24:37 -08:00
Kelsi
b448aa1ffc Add item query debug logging to diagnose equipment display issues
Log item query requests and responses at INFO level to diagnose why
equipment slots show numbers instead of names on Turtle WoW.
2026-02-17 01:22:34 -08:00
Kelsi
d153bcb62c Enable equipment slot drag-and-drop via server swap packets
Replace the "not supported" error message with actual pickup from
equipment slots. Placing equipment items into backpack or bag slots
sends CMSG_SWAP_ITEM to the server.
2026-02-17 01:18:52 -08:00
Kelsi
eace8753c6 Fix taxi griffin animation and improve mount texture loading
Use FlyForward/FlyIdle animations (IDs 158/159) for taxi mounts instead
of ground movement animations (Stand/Run). Add detailed mount texture
debug logging and improve fallback texture resolution for gryphon/wyvern
models with multiple skin slots.
2026-02-17 01:16:23 -08:00
Kelsi
0b28dbf140 Fix duplicate whisper display in Classic chat parser
Vanilla SMSG_MESSAGECHAT writes senderGuid twice for all standard chat
types. Parser only read one GUID for WHISPER/WHISPER_INFORM, shifting
the read position and causing the server echo filter to fail to match
the player's GUID.
2026-02-17 01:08:22 -08:00
Kelsi
67fdd7809a Fix Classic item query packet format for auction house item names
Vanilla CMSG_ITEM_QUERY_SINGLE has no GUID field (just uint32 entry),
causing servers to reject the oversized WotLK-format packets. Also fix
response parser: remove nonexistent statsCount field and use 5 damage
types instead of 2 to match Vanilla protocol.
2026-02-17 01:05:15 -08:00
Kelsi
a1457ee801 Fix NPC textures, bag item interactions, and Classic item query parsing
Rebuild creature display lookups after expansion-specific DBC layout loads
(was using WotLK defaults before turtle layout was available). Add full
drag-and-drop support for bag items with server-side CMSG_SWAP_ITEM packets.
Add Classic-specific SMSG_ITEM_QUERY_SINGLE_RESPONSE parser for Vanilla
format differences (fewer damage types, no scaling stats, no Flags2).
2026-02-17 01:00:04 -08:00
Kelsi
44d1431b60 Suppress login bind point message and auto-join Local channel
Only show "Your home has been set" when the player actively changes their
bind point (via innkeeper), not on the initial login sync from the server.
Add "Local" to the auto-join channel list for Turtle WoW compatibility,
with a settings checkbox and persistence.
2026-02-16 21:16:25 -08:00
Kelsi
381d896348 Implement bank, guild bank, and auction house systems
Add 27 new opcodes, packet builders/parsers, handler methods, inventory
extension with 28 bank slots + 7 bank bags, and UI windows for personal
bank, guild bank (6 tabs x 98 slots), and auction house (browse/sell/bid).
Fix Classic gossip parser to omit boxMoney/boxText fields not present in
Vanilla protocol, fix gossip icon labels with text-based NPC type detection,
and add Turtle WoW opcode mappings for bank and auction interactions.
2026-02-16 21:11:18 -08:00
Kelsi
0d4a9c38f7 Add guild features, fix channel joining, and improve whisper reply
Guild: add disband, leader transfer, public/officer note commands with
roster context menu showing rank names and officer notes column. Auto-refresh
roster after guild events.

Channels: fix city/region channels not working by accepting SMSG_CHANNEL_NOTIFY
during ENTERING_WORLD state (server auto-joins before VERIFY_WORLD) and handling
PLAYER_ALREADY_MEMBER notification.

Whisper: /r now switches to whisper tab and sets target to last sender,
matching WoW behavior.

Camera: extend WMO collision raycasting to work outside WMOs too.
2026-02-16 20:16:14 -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
1cfe186c62 Implement mailbox interaction and expansion-aware mail system
Fix mailbox right-click (transposed CMSG_GAMEOBJECT_USE opcode, missing
mail opcodes in Turtle WoW JSON, decorative GO type filtering). Add
expansion-aware mail packet handling via PacketParsers: Classic format
(single item, no msgSize prefix, Vanilla field order) vs WotLK format
(attachment arrays, enchant slots). Fix CMSG_MAIL_TAKE_ITEM and
CMSG_MAIL_DELETE for Vanilla (no trailing fields). Add pulsing "New
Mail" indicator below minimap, SMSG_RECEIVED_MAIL and
MSG_QUERY_NEXT_MAIL_TIME handlers, and async sender name backfill.
2026-02-16 18:46:44 -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
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
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
4190cb796f Fix composite cache clearing to not delete NPC textures
clearCompositeCache() now only clears the lookup map without deleting
GPU textures, preventing NPC and other instance textures from being
accidentally destroyed during player equipment changes.
2026-02-16 00:19:07 -08:00
Kelsi
dcd6c488fa Clean up bare shin geoset comments 2026-02-15 20:59:29 -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
9bc8c5c85a Fix character texture compositing and add YouTube video to README
Use authoritative WoW Model Viewer atlas coordinates (256x256 reference)
for face, underwear, and body region placement. Previously all coordinates
were hardcoded at 512x512 scale causing overlays to be clipped on the
256x256 base skin. Also include face upper+lower textures from
CharSections.dbc in compositing for both player and other-player characters.
2026-02-15 12:53:15 -08:00
Kelsi
7f0eceaacc Fix PopStyleVar mismatches and character geoset IDs
Fix 9 PopStyleVar(2) calls that should be PopStyleVar(1) across
player frame, target frame, cast bar, party frames, buff bar, escape
menu, death dialog, and resurrect dialog. Fix action bar from
PopStyleVar(2) to PopStyleVar(4) to match 4 pushes.

Fix character geoset defaults: 301→302 (bare hands), 701→702 (ears),
1501→1502 (back/cloak), add 802 (wristbands). No WoW character model
uses geoset 301/701/1501; all use 302/702/1502 as base. This fixes
missing hands/arms on undead and other races with separate hand meshes.
2026-02-15 06:09:38 -08:00
Kelsi
d2b46d410a Add original music to login rotation and zone playlists
11 original tracks in assets/Original Music/ now play on the login
screen and in thematically matched zones across Eastern Kingdoms and
Kalimdor. Added crossfadeToFile to MusicManager for local file
playback during zone transitions. New zones: Tirisfal, Undercity,
Barrens, STV, Duskwood, Burning Steppes, Searing Gorge, Ironforge,
Loch Modan, Orgrimmar, Durotar, Mulgore, Thunder Bluff, Darkshore,
Teldrassil, Darnassus.
2026-02-15 05:53:27 -08:00
Kelsi
9fc41d6f30 Add asset backup script with zstd/pigz/gzip fallback 2026-02-15 04:25:56 -08:00
Kelsi
77f8ebd727 Fix PopStyleVar mismatch in settings window 2026-02-15 04:20:32 -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
1bc7b12b20 Make bag bar draggable and fix slot sizing 2026-02-15 03:17:51 -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
741e9b8cb0 Close chat input after sending 2026-02-14 22:00:26 -08:00
Kelsi
09de52f310 Fix UI window hotkey toggles and silent mount sound fallback 2026-02-14 21:56:38 -08:00
Kelsi
1a9bdfb64b Fix Classic chat parser missing second GUID for SAY/YELL/PARTY
CMaNGOS-Classic writes senderGuid twice for SAY/PARTY/YELL messages.
Our parser only read one, causing the second GUID bytes to be consumed
as messageLen, resulting in empty/garbage message text and no sender
name. Also fix MONSTER_SAY/MONSTER_YELL which have a leading
senderGuid before the name that we were skipping.
2026-02-14 21:34:09 -08:00
Kelsi
0d4eff65d0 Fix vanilla spell cast and use-item packet formats for Turtle/Classic
SpellCastTargets target mask is uint16 in vanilla 1.12.x, not uint32
like WotLK. The 2 extra bytes corrupted every spell packet. Also add
classic CMSG_USE_ITEM builder (bag+slot+spellIndex+targets only, no
spellId/itemGuid/glyphIndex/castFlags fields that WotLK added).
2026-02-14 21:29:44 -08:00
Kelsi
eb931ce0fc Fix missing taxi mount when node not found in DBC
When the taxi node ID from the server isn't in TaxiNodes.dbc (custom
server nodes, missing data), fall back to hardcoded gryphon/wyvern
display IDs so the player still appears mounted during flight.
2026-02-14 21:18:36 -08:00
Kelsi
ef0b1b45ef Fix grey WMO curtains by skipping window/sky materials, fix /unstuck
- Skip WMO batches with material flags F_SIDN (0x20) or F_WINDOW (0x40)
  which are transparent sky/window panes that render as grey curtains
- Fix /unstuck: always nudge 5 units forward first, then sample floor at
  destination instead of teleporting back to last safe position (which
  could be the stuck location itself)
2026-02-14 21:15:28 -08:00