Commit graph

391 commits

Author SHA1 Message Date
Kelsi
90c878729e Prefer canonical case-resolved files for Warden MPQ hash checks 2026-02-20 01:49:43 -08:00
Kelsi
d8ab69f9c3 Fix stale opcode mappings and handler wiring across expansions 2026-02-20 01:13:01 -08:00
Kelsi
70e579157d Fix classic SMSG_MONSTER_MOVE parsing using wrong WotLK format
handleMonsterMove called MonsterMoveParser::parse() directly (WotLK
format with extra uint8 after PackedGuid) instead of going through
the polymorphic packetParsers_->parseMonsterMove(). Added parseVanilla
override to ClassicPacketParsers so classic/turtle use the correct
vanilla format.
2026-02-20 00:52:59 -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
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
328ec9ea78 Fix combat vocalizations with correct MPQ paths, add combat idle stance
Use actual WoW 3.3.5a PlayerExertions and Vox sound paths from MPQ
manifests for attack grunts, wounds, and death sounds. Handle Blizzard
naming quirks (HumanFeamle typo, OrcMale no Final suffix, Scourge→Undead).
Add COMBAT_IDLE animation state with ready weapon stance between swings.
Restore deleted MPQ sound manifest docs.
2026-02-19 21:50:32 -08:00
Kelsi
8a9d9f47db Add combat sounds, melee ability animations, and player vocalizations
Wire CombatSoundManager into SMSG_ATTACKERSTATEUPDATE for weapon swing,
impact, and miss sounds. Add attack grunt and wound vocalizations to
ActivitySoundManager using correct WoW MPQ PC-suffix paths. Trigger
attack animation on SMSG_SPELL_GO for warrior melee abilities. Add
client-side melee range and facing checks to prevent server rejections.
Snap charge arrival to target's current position for reliable melee range.
2026-02-19 21:31:37 -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
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
c69457ae3b apply pending protocol, ui, audio, and CodeQL fixes 2026-02-19 16:17:06 -08:00
Kelsi
00086c2ad9 Add CI security suite and scrub hardcoded local host/path defaults 2026-02-19 06:46:11 -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
dddd2a71ca Fix creature flame alpha-key rendering and emissive flicker 2026-02-19 02:39:33 -08:00
Kelsi
8d4d9b7169 Fix quest flow regressions, tooltip compare stats, and M2 alpha-key handling 2026-02-19 02:27:01 -08:00
Kelsi
b3ea6d8e81 Refine bag UI layout and add shift-hover item compare 2026-02-19 01:50:50 -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
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
a30525d7c9 Fix WMO visibility culling and renderer initialization guards 2026-02-18 22:41:05 -08:00
Kelsi
ff8ffc3bfb Fix transport/WMO diagnostics and terrain WMO dedup lifecycle 2026-02-18 22:36:34 -08:00
Kelsi
514b914068 Add shadow frustum culling to terrain and M2 depth passes
Both passes were rendering the entire loaded scene (17×17 tile radius)
into a shadow map that only covers 360×360 world units — submitting
10-50× more geometry than the shadow frustum can actually use.

- TerrainRenderer::renderShadow: skip chunks whose bounding sphere
  doesn't overlap the shadow frustum AABB in XY. Reduces terrain draw
  calls from O(all loaded chunks) to O(chunks within ~180 units).
- M2Renderer::renderShadow: skip instances whose world AABB doesn't
  overlap the shadow frustum in XY. Reduces M2 draw calls similarly.
- Both functions now take shadowCenter + halfExtent parameters.
2026-02-18 21:15:24 -08:00
Kelsi
c4d0a21713 Improve shadow performance: halve resolution, 9x fewer PCF taps, throttle depth pass
- SHADOW_MAP_SIZE 2048→1024: 4x fewer pixels rasterized in depth pass
- Replace 9-tap manual PCF loop with single hardware PCF tap in all 4 receiver
  shaders (terrain.frag, wmo_renderer, m2_renderer, character_renderer).
  GL_LINEAR + GL_COMPARE_REF_TO_TEXTURE already gives 2×2 bilinear PCF per
  tap for free, so quality is maintained while doing 9x fewer texture fetches.
- Throttle shadow depth pass to every 2 frames; OpenGL depth texture persists
  between frames so receivers always have a valid shadow map. 1-frame lag at
  60 fps is invisible.
2026-02-18 21:09:00 -08:00
Kelsi
7ab25c63c9 Optimize release builds: LTO, -O3, visibility, micro-perf fixes
- CMakeLists.txt: enable LTO for Release, add -O3 and -fvisibility=hidden
- scene: addMesh uses std::move, removeMesh takes const shared_ptr&
- entity: std::move entity into map instead of copy
- clouds: cosf/sinf instead of cos/sin (float math, avoids double promotion)
- game_screen: reserve trainer spell vector before push_back loop
- warden_module/emulator: replace std::endl (121 stream flushes) with '\n'
2026-02-18 20:10:47 -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
fbb0b76362 Fix two packaging bugs
logger.hpp: extend ERROR macro push/pop region to cover entire header so
LogLevel::ERROR inside template bodies compiles correctly on Windows

CMakeLists.txt: move tool install() rules next to each target definition
so they run after the targets exist (fixes macOS 'target does not exist')
2026-02-18 18:29:34 -08:00
Kelsi
456aa90eda Fix two more Windows/MinGW compile errors
- net_platform.hpp: guard ssize_t typedef with !__MINGW32__ since MinGW-w64
  already defines ssize_t as __int64 in corecrt.h
- logger.hpp: push/pop ERROR macro around LogLevel enum (same wingdi.h clash
  as world_packets.hpp)
2026-02-18 17:59:11 -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