Commit graph

204 commits

Author SHA1 Message Date
Kelsi
687675fa14 Handle SMSG_NOTIFICATION (0x1CB) for vanilla/Turtle WoW welcome messages 2026-02-20 00:28:51 -08:00
Kelsi
e8864941dc Fix Classic field extraction, Warden PE patches, and auth/opcode corrections
Update field extraction in both CREATE_OBJECT and VALUES handlers to check
specific fields (maxHealth, level, faction, etc.) before power/maxpower range
checks. In Classic 1.12.1, power indices 23-27 are adjacent to maxHealth (28),
and maxPower indices 29-33 are adjacent to level (34) and faction (35), so
range checks like "key >= powerBase && key < powerBase+7" were incorrectly
capturing those fields.

Add build-aware WoW.exe selection and runtime global patching for Warden
SYSTEM_INFO, EndScene, WorldEnables, and LastHardwareAction chains. Fix
Classic opcodes and auth session addon data format for CMaNGOS compatibility.
2026-02-20 00:18:03 -08:00
Kelsi
38ad368c82 Add bag bar drag-to-reorder, fix three wrong WotLK opcodes
Bag bar: left-click drag bags to swap positions using CMSG_SWAP_ITEM
with INVENTORY_SLOT_BAG_0 (255). Local optimistic swap for instant
feedback. Camera controller now respects ImGui WantCaptureMouse.
Vendor auto-open bags only triggers once per session.

Fix opcodes: CMSG_GAMEOBJECT_USE 0x01B→0x0B1 (typo caused
SMSG_FORCEACTIONSHOW spam), CMSG_CANCEL_AURA 0x033→0x136,
SMSG_SELL_ITEM 0x1A4→0x1A1.
2026-02-19 22:34:22 -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
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
1fb1daea7f Fix UNIT_FIELD_BYTES_0 index (56→23) and add per-type power arrays to Unit
- Correct UNIT_FIELD_BYTES_0 to index 23 (was incorrectly 56) in update fields JSON and table
- Replace single power/maxPower with powers[7]/maxPowers[7] arrays indexed by power type
- Add setPowerByType/setMaxPowerByType helpers for setting specific power types
2026-02-19 19:33:50 -08:00
Kelsi
76e1aef62d Improve combat messages: power-type-aware errors, fix chat line breaks, better wording
- getSpellCastResultString now returns "Not enough rage/energy/focus/runic power" based on player power type instead of always "Not enough mana"
- Fix NPC combat messages concatenating onto previous lines by combining prefix+body into single renderTextWithLinks call instead of TextWrapped+SameLine
- Improve generic error strings to be more WoW-authentic (Invalid target, Target not in line of sight, etc.)
2026-02-19 19:33:02 -08:00
Kelsi
20cdff0790 Fix armor stat in character stats panel via UNIT_FIELD_RESISTANCES
The character stats panel was showing Armor: 0 because summing armor
from item query responses is fragile (depends on correct BuyCount/damage
block parsing). Instead, read the server-authoritative total armor
directly from UNIT_FIELD_RESISTANCES (physical resistance, index 0)
in the player entity update fields.

Added UNIT_FIELD_RESISTANCES to the UF enum and all four expansion
JSON files with correct wire indices:
  WotLK 3.3.5a: 99   (NPC_FLAGS=82 + emotestate + stat×5 + posstat×5 + negstat×5)
  TBC 2.4.3:   185   (NPC_FLAGS=168 + same relative layout)
  Classic 1.12: 154  (NPC_FLAGS=147 + emotestate + stat×5, no posstat/negstat)
  Turtle WoW:  154   (same as Classic)

Stats panel uses server armor when > 0, falls back to summed item-query
armor otherwise. Armor rating resets to 0 on world entry and is updated
from both CREATE_OBJECT and VALUES update blocks.
2026-02-19 17:45:09 -08:00
Kelsi
28b4a3a599 Fix TBC item query parser: add TBC-specific parseItemQueryResponse override
TBC 2.4.3 SMSG_ITEM_QUERY_SINGLE_RESPONSE differs from WotLK: no Flags2,
no BuyCount, statsCount-many stat pairs (not always 10), and no
ScalingStatDistribution/ScalingStatValue. Without this override,
TbcPacketParsers fell back to the WotLK parser and misread stats/armor
with a cascading 16-byte offset. Classic (Vanilla) was already safe via
its own independent ClassicPacketParsers::parseItemQueryResponse().
2026-02-19 16:58:18 -08:00
Kelsi
d7692ab88e Smooth other-player movement with velocity dead reckoning
Previously other players jittered because the entity sat frozen at its
destination between movement packets, then snapped to the new start
position on the next packet (stop-pop-stop-pop at ~10 Hz).

Entity interpolation now tracks a smoothed velocity and dead-reckons
past the end of each packet window, so the entity keeps gliding at the
estimated speed until the next server update arrives. Movement stops
only after two consecutive intervals with no new packet (entity has
genuinely stopped).

Also replaced the raw packet-delta duration with an exponential moving
average (EMA) per player. A single slow or fast packet no longer spikes
the playback speed; the EMA converges on the actual send rate (~100 ms)
and absorbs jitter without adding a fixed input-latency penalty.
2026-02-19 16:45:39 -08:00
Kelsi
c69457ae3b apply pending protocol, ui, audio, and CodeQL fixes 2026-02-19 16:17:06 -08:00
Kelsi
550366df07 Fix item destroy packet format and wire destroy confirmation UI 2026-02-19 06:34:06 -08:00
Kelsi
3c754801c4 Stabilize buyback flow and single-row buyback UI
- keep vendor buyback as one-item LIFO row in vendor window

- add robust pending buyback tracking with wire slot probing (74..85)

- recover from stale optimistic sell/buyback entries and refresh vendor list

- keep buy packet construction branch-compatible (direct packet build)
2026-02-19 05:48:40 -08:00
Kelsi
1fdf450c5e Fix buyback request flow and prune temporary diagnostics
- implement vendor buyback state in GameHandler (buyback item list + pending sell tracking)

- send CMSG_BUYBACK_ITEM with WotLK/AzerothCore absolute buyback slot (74 + ui index)

- consume 0x46A/0x480 vendor side-channel packets safely without relying on token slot mapping

- keep sell/buy failure handling synced with buyback list and chat errors

- remove temporary packet hex/trace logging used during buyback debugging
2026-02-19 05:28:13 -08:00
Kelsi
871da33942 Clean README mentions and finalize current gameplay/UI fixes 2026-02-19 03:31:49 -08:00
Kelsi
19525067cf Fix quest reward selection index mapping for choose-reward 2026-02-19 03:12:57 -08:00
Kelsi
506e841ce0 Handle SMSG_QUESTGIVER_QUEST_LIST (0x185) for questgiver flows 2026-02-19 02:53:44 -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
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
4684db10af Reduce unhandled opcode spam and add missing Turtle opcode names 2026-02-18 23:14:01 -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
f67a6f1692 Fix three Windows-specific compile errors
- logger.cpp: use localtime_s on Windows (reversed arg order vs localtime_r)
- process.hpp: drop constexpr on INVALID_PROCESS (INVALID_HANDLE_VALUE is a
  reinterpret_cast, not valid in constexpr context)
- world_packets.hpp: push/pop ERROR macro around CharCreateResult enum to avoid
  clash with wingdi.h #define ERROR 0
2026-02-18 17:52:28 -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
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
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
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
1de2f4c8a0 Show weapon damage/speed in item tooltips
- parse and cache item class/subclass, damage range, and attack delay from item query responses
- render weapon damage, speed, and DPS in the shared item-link tooltip
- render weapon damage, speed, and DPS in vendor hover tooltips
- keep armor and primary stat lines intact
2026-02-18 03:46:03 -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
bd0ce17794 Update opcode data and movement integration docs/code 2026-02-18 03:18:22 -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
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
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
a55399fad6 Add mute button and original soundtrack toggle
- Mute button: small [M] button alongside minimap zoom controls, turns red when active; directly sets AudioEngine master volume to 0, restores on unmute; persists in settings.cfg
- Original Soundtrack: checkbox in Settings > Audio that controls whether custom original music tracks (file: prefix) are included in zone music rotation; when disabled, only WoW MPQ tracks play; persists in settings.cfg
- ZoneManager.getRandomMusic() now filters file: paths when OST is disabled, falling back to full list if zone has no non-file tracks
2026-02-17 16:26:49 -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
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
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