Commit graph

240 commits

Author SHA1 Message Date
Kelsi
512d60c9be Fix gossip quest flow and questgiver marker state 2026-02-19 02:04:56 -08:00
Kelsi
fc0ac6dd0f Fix combat facing updates and dead-on-spawn creature pose 2026-02-19 01:19:29 -08:00
Kelsi
8efc21115f Fix quest turn-in flow and WoW quest text placeholders 2026-02-19 01:12:14 -08:00
Kelsi
a37004db03 Remove temporary quest query diagnostics 2026-02-19 00:59:46 -08:00
Kelsi
4fcf869e34 Stabilize quest log details loading and turn-in item sync 2026-02-19 00:56:24 -08:00
Kelsi
334d4d3df6 Fix quest log titles and full-row selection behavior 2026-02-19 00:30:21 -08:00
Kelsi
cabf897683 Ignore zero-id forced quest removals to prevent spawn spam 2026-02-18 23:48:11 -08:00
Kelsi
0c99e2ee95 Suppress remaining unknown Turtle opcodes with safe consume mappings 2026-02-18 23:42:28 -08:00
Kelsi
ddcd2b302e Map and handle additional Turtle combat/movement world opcodes 2026-02-18 23:38:34 -08:00
Kelsi
494a8b5acc Tie opcode handlers into movement, quest log, and world state caches 2026-02-18 23:30:38 -08:00
Kelsi
a1c16762af Handle remaining Turtle world opcodes with safe minimal parsers 2026-02-18 23:26:58 -08:00
Kelsi
e2b3c3c265 Remove leftover compressed update debug trace 2026-02-18 23:16:20 -08:00
Kelsi
4684db10af Reduce unhandled opcode spam and add missing Turtle opcode names 2026-02-18 23:14:01 -08:00
Kelsi
ff8ffc3bfb Fix transport/WMO diagnostics and terrain WMO dedup lifecycle 2026-02-18 22:36:34 -08:00
Kelsi
eacecddfb0 Fix real bugs found by clang-tidy
- game_handler.cpp: use-after-move on node.id after std::move(node)
  (save nodeId before the move)
- tcp_socket.cpp, world_socket.cpp: virtual call in destructor bypasses
  dispatch; use qualified TCPSocket::disconnect() / WorldSocket::disconnect()
  to make intent explicit
- wmo_renderer.cpp: float loop counters risk precision drift; replace with
  integer step counts and reconstruct float from index
- game_screen.cpp: (float + 0.5) cast to int is incorrect rounding;
  use std::lround instead
2026-02-18 20:02:12 -08:00
Kelsi
c0c0210b66 Fix Windows build errors in warden and CharCreateResult
warden_emulator.cpp: guard unicorn include + entire implementation with
HAVE_UNICORN; provide stub implementations for platforms without Unicorn
(Windows ARM64 which has no unicorn MSYS2 package)

warden_module.cpp: include <windows.h> for VirtualAlloc/HMODULE/etc on
Windows; always include warden_emulator.hpp so unique_ptr destructor compiles
regardless of HAVE_UNICORN

world_packets.hpp + game_handler.cpp: rename CharCreateResult::ERROR to
CharCreateResult::CHAR_ERROR to avoid wingdi.h #define ERROR 0 collision
2026-02-18 18:39:07 -08:00
Kelsi
cb01821d89 Add Windows build support via MSYS2 and fix platform-specific code
Guard X11 display crash handler with __linux__, add Windows GlobalMemoryStatusEx
path in memory_monitor, guard warden cache paths with APPDATA on Windows, and
make pkg-config optional in CMakeLists with a find_library fallback. Add Windows
x86-64 CI job using MSYS2 MINGW64 to the build workflow.
2026-02-18 17:38:08 -08:00
Kelsi
50f9651868 Fix quest log not showing server-side quests on login
SMSG_QUEST_QUERY_RESPONSE skipped only 18 uint32s before reading the
title string, but Classic layout has 40 fields before the title
(16 header + 8 reward items + 12 choice items + 4 POI fields).
Reading from the wrong position landed inside reward item data where
empty slots contain 0-bytes, so readString() returned "", overwriting
the "Quest #N" placeholder with an empty title — making quests
invisible in the UI even though they were in the quest log.

Fixes:
- Expansion-aware skip count: 40 for Classic/Turtle, 55 for WotLK
- Guard: only update title if parsed string is non-empty and printable
- Also scan quest log fields in VALUES update path (not just CREATE_OBJECT2),
  so quests are detected even when the server sends partial updates
2026-02-18 05:11:29 -08:00
Kelsi
dd3149e3c1 Fix quest system for Classic/Turtle: correct packet formats and log stride
- CMSG_QUESTGIVER_QUERY_QUEST: Classic override omits trailing unk1 byte
  (WotLK sends 13 bytes, Classic servers expect 12 — extra byte caused
  server to silently drop the packet, preventing quest details dialog)
- SMSG_QUESTGIVER_QUEST_DETAILS: Classic override skips informUnit GUID
  (WotLK prepends 8-byte informUnit before questId; Vanilla does not)
- Quest log UPDATE_OBJECT stride: use packetParsers_->questLogStride()
  (WotLK=5 fields/slot, Classic=3 fields/slot)
- handleQuestDetails: route through packetParsers_->parseQuestDetails()
- selectGossipQuest: route through packetParsers_->buildQueryQuestPacket()
2026-02-18 04:56:23 -08:00
Kelsi
2dffba63d8 Fix combat facing, tab-target filtering, and spirit healer resurrection
- Add Entity::setOrientation() to update facing without cancelling movement
- Force attacker and victim to face each other on SMSG_ATTACKSTART
- Fix orientation sign error in MonsterMove: use atan2(-dy, dx) throughout so
  NPCs don't glide backward; clamp FacingAngle moves that are >90° off travel vector
- Tab-target: skip dead units and non-hostiles at both build and advance time;
  stale entries (killed between presses) are skipped inline rather than cycling to them
- Spirit healer resurrection: detect same-map SMSG_NEW_WORLD with resurrectPending_
  and skip the full world reload/entity clear, preventing the fall-forever bug
2026-02-18 04:43:23 -08:00
Kelsi
24be81c679 Turtle chest interact: stop auto-attack, force select, and relax click throttle 2026-02-18 04:21:05 -08:00
Kelsi
40504ac92e Scope chest loot retry workaround to Turtle expansion only 2026-02-18 04:18:51 -08:00
Kelsi
fdfb480785 Turtle chest interaction: retry GAMEOBJECT_USE together with LOOT 2026-02-18 04:17:11 -08:00
Kelsi
4a61eeda8a Make chest looting robust with unconditional GO loot + timed retry 2026-02-18 04:13:26 -08:00
Kelsi
1a9cc82248 Fix loot money notifications fallback and chest loot trigger 2026-02-18 04:11:00 -08:00
Kelsi
c998ed6335 Fix looting of chest-type gameobjects
- send CMSG_LOOT after CMSG_GAMEOBJECT_USE for lootable GO types (chest/fishing hole)
- keeps mailbox handling unchanged
2026-02-18 04:07:47 -08:00
Kelsi
98212a3f91 Fix quest item loot parsing and quest item progress tracking
- add SMSG_QUESTUPDATE_ADD_ITEM logical opcode mapping (0x197)
- handle quest item progress updates in GameHandler
- parse quest-item section in SMSG_LOOT_RESPONSE (regular + quest items)
- add quest item progress storage in quest log entries
- show tracked kill/item progress in Quest Log UI
2026-02-18 04:06:14 -08:00
Kelsi
d3b04640f3 Fix creature render desync and corpse/loot state edge cases
- add per-frame nearby creature render sync from entity positions/orientation to prevent model-vs-target-circle drift
- treat lootable dynflag as dead state hint for unit spawn/deferred-display paths
- fire NPC death callback when a late display spawn is already dead/lootable
- remove loot-response money fallback announce/SFX to stop duplicate copper messages on re-opened corpses
2026-02-18 04:02:08 -08:00
Kelsi
08c956a6e5 Fix creature chase animation and target-circle tracking
- use movement animation (prefer run, fallback walk) for server-driven creature moves
- synthesize short movement duration for duration-less movement deltas to avoid glide/attack-pose sliding
- return to idle after both walk/run movement states
- drive target circle from entity latest position and always interpolate selected/engaged targets
2026-02-18 03:53:53 -08:00
Kelsi
dd8f04ac99 Add weapon stats to inventory tooltips and fix login camera pitch
- propagate item damage range and delay into ItemDef during inventory rebuild
- show weapon damage, speed, and DPS in inventory/character slot tooltips
- fix online spawn camera pitch sign so third-person camera starts above ground
2026-02-18 03:50:47 -08:00
Kelsi
a100baff39 Fix vendor buy packet count and stale list parsing
- send CMSG_BUY_ITEM as vendorGuid + itemId + count (drop extra slot/bag fields)
- reset vendor list state before parsing SMSG_LIST_INVENTORY to prevent stale items carrying over
- add packet length guards for list-inventory header and per-item rows
- keep optional extended-cost parsing for cross-core compatibility
2026-02-18 03:40:59 -08:00
Kelsi
3be1d2ecb9 Fix NPC death state on login and harden loot money notifications
- trigger NPC death callback for dead-at-spawn units on create
- handle UNIT_DYNAMIC_FLAGS dead/alive transitions for NPC death/respawn callbacks
- avoid duplicate NPC death/respawn callback dispatch in mixed health+dynflag updates
- keep player dead/ghost behavior unchanged
- improve loot money fallback chat and coin SFX handling
2026-02-18 03:37:03 -08:00
Kelsi
1ad3f47baf Handle vanilla weather and play-music opcode aliases 2026-02-18 03:23:37 -08:00
Kelsi
86127f0ddf Fix Turtle monster movement packet parsing 2026-02-18 03:13:17 -08:00
Kelsi
369ad26476 Implement SMSG_WEATHER and wire real game state (map ID, weather, underwater) to lighting system 2026-02-17 17:59:41 -08:00
Kelsi
60ebb4dc3f Fix vendor: correct CMSG_BUY_ITEM field order (slot before itemId), handle buy failures, show token costs; remove level-up test button (animation triggers on real level-up) 2026-02-17 17:44:48 -08:00
Kelsi
897867bf7b Add level-up ding animation with cheer emote and test button
- Trigger ding when UNIT_FIELD_LEVEL increases for player: plays LevelUp sound,
  cheer emote animation, and shows screen overlay
- renderDingEffect(): 3 expanding golden rings + "LEVEL X!" / "DING!" text
  drawn via ImDrawList foreground (3s duration, fades out last 0.8s)
- triggerDing() wires sound (UiSoundManager::playLevelUp) + emote + overlay
- LevelUpCallback in GameHandler fires on genuine level increase (newLevel > oldLevel)
- "Test: Level Up" button in escape menu triggers ding at current player level
2026-02-17 17:23:42 -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
0e18c8871d Add auto loot setting to gameplay settings
Checkbox in Settings > Gameplay > Loot section. When enabled, all items
are automatically sent CMSG_AUTOSTORE_LOOT_ITEM on loot response (same
as right-click looting each item). Gold always auto-loots regardless.
Setting persists in settings.cfg as auto_loot=0/1.
2026-02-17 16:31:00 -08:00
Kelsi
ca3cf209d9 Fix quest turn-in loop and register SMSG_CANCEL_AUTO_REPEAT
The gossip questIcon field is an integer enum (2=available, 4=incomplete,
5=ready-to-turn-in), not a bitmask. Using (questIcon & 0x04) caused icon=4
(in-progress quests) to be treated as completable, so the client sent
CMSG_QUESTGIVER_REQUEST_REWARD for incomplete quests. The server rejected
these silently and re-sent SMSG_GOSSIP_MESSAGE, causing an infinite loop.

Fix: use exact equality (questIcon == 5 for completable, == 4 for incomplete).

Also register SMSG_CANCEL_AUTO_REPEAT (0x06B) to suppress the unhandled
opcode warning logged on every login.
2026-02-17 15:57:51 -08:00
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
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
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
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
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
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
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