Commit graph

193 commits

Author SHA1 Message Date
Kelsi
95e8fcb88e Implement minimap ping: parse MSG_MINIMAP_PING and render animated ping circles
Parse party member minimap pings (packed GUID + posX + posY), store with
5s lifetime, and render as expanding concentric circles on the minimap.
2026-03-09 20:36:20 -07:00
Kelsi
5024e8cb32 Implement SMSG_SET_PROFICIENCY: track weapon/armor proficiency bitmasks
- Parse uint8 itemClass + uint32 subClassMask from SMSG_SET_PROFICIENCY
- Store weaponProficiency_ (itemClass=2) and armorProficiency_ (itemClass=4)
- Expose getWeaponProficiency(), getArmorProficiency(), canUseWeaponSubclass(n),
  canUseArmorSubclass(n) on GameHandler for use by equipment UI
- Enables future equipment slot validation (grey out non-proficient items)
2026-03-09 20:23:38 -07:00
Kelsi
1c1cdf0f23 Fix Windows socket WSAENOTCONN disconnect; add boss encounter frames
Socket fixes (fixes Windows-only connection failure):
- WorldSocket::connect() now waits for non-blocking connect to complete with
  select() before returning, preventing WSAENOTCONN on the first recv() call
  on Windows (Linux handles this implicitly but Windows requires writability
  poll after non-blocking connect)
- Add net::isConnectionClosed() helper: treats WSAENOTCONN/WSAECONNRESET/
  WSAESHUTDOWN/WSAECONNABORTED as graceful peer-close rather than recv errors
- Apply isConnectionClosed() in both WorldSocket and TCPSocket recv loops

UI:
- Add renderBossFrames(): displays boss unit health bars in top-right corner
  when SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT has active slots; supports
  click-to-target and color-coded health bars (red→orange→yellow as HP drops)
2026-03-09 20:05:09 -07:00
Kelsi
b6dfa8b747 Implement SMSG_RESUME_CAST_BAR, SMSG_THREAT_UPDATE, SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT
- SMSG_RESUME_CAST_BAR: parse packed_guid caster/target + spellId + remainingMs +
  totalMs; restores cast bar state when server re-syncs a cast in progress
- SMSG_THREAT_UPDATE: properly consume packed_guid host/target + threat entries
  to suppress unhandled packet warnings
- SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT: track up to 5 boss encounter unit guids
  per slot; expose via getEncounterUnitGuid(slot); clear on world transfer
  These guids identify active boss units for raid/boss frame display.
2026-03-09 19:54:32 -07:00
Kelsi
63c8dfa304 Show achievement names from Achievement.dbc in chat notifications
Previously "Achievement earned! (ID 1234)" was the only message. Now
loadAchievementNameCache() lazily loads Achievement.dbc (field 4 = Title,
verified against WotLK 3.3.5a binary) on first earned event and shows
"Achievement earned: Level 10" or "Player has earned the achievement: ..."
Falls back to ID if DBC is unavailable or entry is missing.
2026-03-09 19:34:33 -07:00
Kelsi
e12e399c0a Implement SMSG_TAXINODE_STATUS parsing and NPC route status cache
Parse the flight-master POI status packet (guid + uint8 status) and cache
it per-NPC in taxiNpcHasRoutes_. Exposes taxiNpcHasRoutes(guid) accessor
for future nameplate/interaction indicators. Previously this packet was
silently consumed without any state tracking.
2026-03-09 19:30:18 -07:00
Kelsi
d4ea416dd6 Fix spell cast audio to use correct magic school from Spell.dbc
Previously all player spell casts played ARCANE school sounds regardless
of the actual spell school. Now loadSpellNameCache() reads SchoolMask
(bitmask, TBC/WotLK) or SchoolEnum (Vanilla/Classic) from Spell.dbc and
stores it in SpellNameEntry. handleSpellStart/handleSpellGo look up the
spell's school and select the correct MagicSchool for cast sounds.

DBC field indices: WotLK SchoolMask=225 (verified), TBC=215, Classic/Turtle
SchoolEnum=1 (Vanilla enum 0-6 converted to bitmask).
2026-03-09 19:24:09 -07:00
Kelsi
c887a460ea Implement Death Knight rune tracking and rune bar UI
Parse SMSG_RESYNC_RUNES, SMSG_ADD_RUNE_POWER, and SMSG_CONVERT_RUNE to
track the state of all 6 DK runes (Blood/Unholy/Frost/Death type,
ready flag, and cooldown fraction). Render a six-square rune bar below
the Runic Power bar when the player is class 6, with per-type colors
(Blood=red, Unholy=green, Frost=blue, Death=purple) and client-side
fill animation so runes visibly refill over the 10s cooldown.
2026-03-09 18:28:03 -07:00
Kelsi
97192ab2a4 Upgrade SMSG_PLAY_OBJECT_SOUND/SPELL_IMPACT to 3D positional audio
Add PlayPositionalSoundCallback that carries both soundId and sourceGuid.
In Application, look up the source entity position and play via
AudioEngine::playSound3D(); fall back to playSound2D() when the entity
is unknown. Also read the 8-byte sourceGuid field from the packet
(previously the full 12-byte payload was ignored).
2026-03-09 16:16:39 -07:00
Kelsi
a2c2675039 Wire SMSG_PLAY_SOUND to AudioEngine via SoundEntries.dbc lookup
Add PlaySoundCallback to GameHandler (same pattern as PlayMusicCallback).
When SMSG_PLAY_SOUND arrives, resolve the soundId through SoundEntries.dbc
(fields 3-12 = files, field 23 = DirectoryBase) and play the first found
file as a 2-D sound effect via AudioEngine::playSound2D(). Previously the
opcode was parsed and dropped.
2026-03-09 16:11:19 -07:00
Kelsi
4e3d50fc20 Wire SMSG_PLAY_MUSIC to MusicManager via SoundEntries.dbc lookup
Add PlayMusicCallback to GameHandler so SMSG_PLAY_MUSIC (and the
vanilla 0x0103 alias) dispatch a soundId to the registered handler
instead of being silently consumed. Application.cpp registers the
callback, loads SoundEntries.dbc, resolves the first non-empty
Name+DirectoryBase into an MPQ path, and passes it to MusicManager
for non-looping playback. Resolves the TODO in the SMSG_PLAY_MUSIC
handler.
2026-03-09 15:46:19 -07:00
Kelsi
28c755040f Request completed quests on world entry and expose via public API
- Send CMSG_QUERY_QUESTS_COMPLETED on initial world entry so
  completedQuests_ is populated from the server response
- Clear completedQuests_ on world entry to avoid stale data across sessions
- Add isQuestCompleted(questId) and getCompletedQuests() public accessors
  to allow UI layers to filter NPC quest offers by completion state
2026-03-09 15:32:11 -07:00
Kelsi
99f2b30594 Handle 35+ more SMSG opcodes for quests, combat, pet system, and protocol
- SMSG_QUESTGIVER_QUEST_FAILED: show specific failure reason in chat
- SMSG_SUSPEND_COMMS: reply with CMSG_SUSPEND_COMMS_ACK (required by server)
- SMSG_PRE_RESURRECT: consume packed GUID
- SMSG_PLAYERBINDERROR: show bind error message
- SMSG_RAID_GROUP_ONLY: show instance requires raid group message
- SMSG_RAID_READY_CHECK_ERROR: show ready check error message
- SMSG_RESET_FAILED_NOTIFY: show instance reset blocked message
- SMSG_REALM_SPLIT / SMSG_REAL_GROUP_UPDATE: consume
- SMSG_PLAY_MUSIC: consume (hook point for future music integration)
- SMSG_PLAY_OBJECT_SOUND / SMSG_PLAY_SPELL_IMPACT: consume
- SMSG_RESISTLOG: consume
- SMSG_READ_ITEM_OK / SMSG_READ_ITEM_FAILED: show result messages
- SMSG_QUERY_QUESTS_COMPLETED_RESPONSE: parse and cache completed quest IDs
- SMSG_QUESTUPDATE_ADD_PVP_KILL: show PVP kill progress in chat
- SMSG_NPC_WONT_TALK: show "creature can't talk" message
- SMSG_OFFER_PETITION_ERROR: show specific petition error
- SMSG_PETITION_QUERY_RESPONSE / SHOW_SIGNATURES / SIGN_RESULTS: consume
- SMSG_PET_GUIDS / MODE / BROKEN / CAST_FAILED / SOUND / LEARN / UNLEARN / etc: consume
- SMSG_INSPECT: consume (character inspection)
- SMSG_MULTIPLE_MOVES / SMSG_MULTIPLE_PACKETS: consume
- SMSG_SET_PLAYER_DECLINED_NAMES_RESULT / PROPOSE_LEVEL_GRANT: consume
- SMSG_REFER_A_FRIEND_* / REPORT_PVP_AFK_RESULT / REDIRECT_CLIENT: consume
- SMSG_PVP_QUEUE_STATS / NOTIFY_DEST_LOC_SPELL_CAST / RESPOND_INSPECT_ACHIEVEMENTS: consume
- SMSG_PLAYER_SKINNED / QUEST_POI_QUERY_RESPONSE / PLAY_TIME_WARNING: consume
- SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA / RESET_RANGED_COMBAT_TIMER: consume
- SMSG_PROFILEDATA_RESPONSE: consume

Adds completedQuests_ set for tracking server-reported completed quest IDs.
2026-03-09 15:27:20 -07:00
Kelsi
22513505fa Handle 50+ missing SMSG opcodes for logout, guild, talents, items, LFG, and GM tickets
- SMSG_LOGOUT_CANCEL_ACK: consume server acknowledgment
- SMSG_GUILD_DECLINE: show decliner name in chat
- SMSG_TALENTS_INVOLUNTARILY_RESET: show reset notification
- SMSG_UPDATE_ACCOUNT_DATA / COMPLETE: consume account data sync
- SMSG_SET_REST_START: show resting state change message
- SMSG_UPDATE_AURA_DURATION: update aura slot duration + timestamp
- SMSG_ITEM_NAME_QUERY_RESPONSE: cache item name in itemInfoCache_
- SMSG_MOUNTSPECIAL_ANIM: consume packed GUID
- SMSG_CHAR_CUSTOMIZE / SMSG_CHAR_FACTION_CHANGE: show result messages
- SMSG_INVALIDATE_PLAYER: evict player name cache entry
- SMSG_TRIGGER_MOVIE: consume
- SMSG_EQUIPMENT_SET_LIST: parse and store equipment sets
- SMSG_EQUIPMENT_SET_USE_RESULT: show failure message if non-zero
- SMSG_LFG_UPDATE / LFG / LFM / QUEUED / PENDING_*: consume
- SMSG_GMTICKET_CREATE / UPDATETEXT / DELETETICKET: show result messages
- SMSG_GMTICKET_GETTICKET / SYSTEMSTATUS: consume
- SMSG_ADD_RUNE_POWER / SMSG_RESYNC_RUNES: consume (DK rune tracking)
- SMSG_AURACASTLOG, SMSG_SPELL*LOG*, SMSG_SPELL_CHANCE_*: consume
- SMSG_CLEAR_EXTRA_AURA_INFO / COMPLAIN_RESULT / ITEM_REFUND_INFO_RESPONSE: consume
- SMSG_ITEM_ENCHANT_TIME_UPDATE / LOOT_LIST / RESUME_CAST_BAR: consume
- SMSG_THREAT_UPDATE / UPDATE_INSTANCE_* / SEND_ALL_COMBAT_LOG: consume
- SMSG_SET_PROJECTILE_POSITION / AUCTION_LIST_PENDING_SALES: consume
- SMSG_SERVER_FIRST_ACHIEVEMENT: parse name + achievement ID, show message
- SMSG_SET_FORCED_REACTIONS: parse and store forced faction reaction overrides
- SMSG_SPLINE_SET_FLIGHT/SWIM_BACK/WALK_SPEED / TURN_RATE / PITCH_RATE: consume
- SMSG_SPLINE_MOVE_UNROOT / UNSET_FLYING / UNSET_HOVER / WATER_WALK: consume
- SMSG_MOVE_GRAVITY_*/LAND_WALK/NORMAL_FALL/CAN_TRANSITION/COLLISION_HGT/FLIGHT: consume

Adds EquipmentSet struct + equipmentSets_ storage, forcedReactions_ map.
2026-03-09 15:23:02 -07:00
Kelsi
aa737def7f Handle SMSG_BUY_ITEM, SMSG_CRITERIA_UPDATE, SMSG_BARBER_SHOP_RESULT, SMSG_OVERRIDE_LIGHT
- SMSG_BUY_ITEM: log successful purchase and clear pending buy state
- SMSG_CRITERIA_UPDATE: log achievement criteria progress (no UI yet)
- SMSG_BARBER_SHOP_RESULT: show success/failure message in chat
- SMSG_OVERRIDE_LIGHT: store zone light override id + transition time, expose via getOverrideLightId()/getOverrideLightTransMs()
2026-03-09 14:57:46 -07:00
Kelsi
deed8011d7 Add Reputation tab to character screen with colored tier progress bars
- Add Reputation tab in character screen tab bar (Equipment/Stats/Reputation/Skills)
- Implement renderReputationPanel() showing all tracked factions sorted alphabetically
- Progress bars colored per WoW reputation tier: Hated/Hostile/Unfriendly/Neutral/Friendly/Honored/Revered/Exalted
- Add public getFactionNamePublic() backed by DBC name cache with lazy load
2026-03-09 14:52:13 -07:00
Kelsi
26eefe9529 Add ready check popup UI and fix party leader lookup
- Implement renderReadyCheckPopup() showing initiator name with Ready/Not Ready buttons
- Fix MSG_RAID_READY_CHECK fallback: use partyData.leaderGuid instead of non-existent isLeader field
- Add faction standing handler with loadFactionNameCache() (Faction.dbc field 22)
- Add gossip POI handler writing canonical WoW coords to gossipPois_ for minimap rendering
2026-03-09 14:48:30 -07:00
Kelsi
f89840a6aa Handle gossip POI, combat clearing, dismount, spell log miss, and loot notifications
- SMSG_GOSSIP_POI: parse map POI markers (x/y/icon/name) from quest NPCs, render as
  cyan diamonds on the minimap with hover tooltips for quest navigation
- SMSG_ATTACKSWING_DEADTARGET: clear auto-attack when target dies mid-swing
- SMSG_CANCEL_COMBAT: server-side combat reset (clears autoAttacking + target)
- SMSG_BREAK_TARGET / SMSG_CLEAR_TARGET: server-side targeting clears
- SMSG_DISMOUNT: server-forced dismount triggers mountCallback(0)
- SMSG_MOUNTRESULT / SMSG_DISMOUNTRESULT: mount feedback in system chat
- SMSG_LOOT_ALL_PASSED: "Everyone passed on [Item]" system message, clears loot roll
- SMSG_LOOT_ITEM_NOTIFY / SMSG_LOOT_SLOT_CHANGED: consumed
- SMSG_SPELLLOGMISS: decode miss/dodge/parry/block from spell casts into combat text
- SMSG_ENVIRONMENTALDAMAGELOG: environmental damage (drowning/lava/fall) in combat text
- GossipPoi struct + gossipPois_ vector in GameHandler with public getters/clearers
2026-03-09 14:38:45 -07:00
Kelsi
bd3bd1b5a6 Handle missing WotLK packets: health/power updates, mirror timers, combo points, loot roll, titles, phase shift
- SMSG_HEALTH_UPDATE / SMSG_POWER_UPDATE: update entity HP/power via entityManager
- SMSG_UPDATE_WORLD_STATE: single world state variable update (companion to INIT)
- SMSG_UPDATE_COMBO_POINTS: store comboPoints_/comboTarget_ in GameHandler
- SMSG_START_MIRROR_TIMER / SMSG_STOP_MIRROR_TIMER / SMSG_PAUSE_MIRROR_TIMER: breath/fatigue/feign timer state
- MirrorTimer struct + getMirrorTimer() public getter; renderMirrorTimers() draws colored breath/fatigue bars above cast bar
- SMSG_CAST_RESULT: WotLK extended cast result; clear cast bar and show reason on failure (result != 0)
- SMSG_SPELL_FAILED_OTHER / SMSG_PROCRESIST: consume silently
- SMSG_LOOT_START_ROLL: correct trigger for Need/Greed popup (replaces rollType=128 heuristic)
- SMSG_STABLE_RESULT: show pet stable feedback in system chat (store/retrieve/buy slot/error)
- SMSG_TITLE_EARNED: system chat notification for title earned/removed
- SMSG_PLAYERBOUND / SMSG_BINDER_CONFIRM: hearthstone binding notification
- SMSG_SET_PHASE_SHIFT: consume (WotLK phasing, no client action needed)
- SMSG_TOGGLE_XP_GAIN: system chat notification
2026-03-09 14:30:48 -07:00
Kelsi
001c80a3db Add item text reading (books/notes): SMSG_ITEM_TEXT_QUERY_RESPONSE + renderItemTextWindow
- Parse SMSG_ITEM_TEXT_QUERY_RESPONSE (guid + isEmpty + string text),
  store in itemText_ and open book window when non-empty
- queryItemText(guid) sends CMSG_ITEM_TEXT_QUERY for readable items
- renderItemTextWindow(): scrollable book window with parchment-toned
  text, "Close" button; opens via isItemTextOpen() flag
2026-03-09 14:15:59 -07:00
Kelsi
acde6070cf Handle SMSG_QUEST_CONFIRM_ACCEPT (shared quest) with accept/decline popup
- Parse SMSG_QUEST_CONFIRM_ACCEPT (questId + title + sharerGuid),
  show chat notification with quest title and sharer name
- acceptSharedQuest() sends CMSG_QUEST_CONFIRM_ACCEPT with questId
- renderSharedQuestPopup(): shows sharer name, gold quest title,
  Accept/Decline buttons (stacked below other social popups)
2026-03-09 14:14:15 -07:00
Kelsi
b381f1e13f Tick summon request timeout down in UI render loop; auto-expire on timeout 2026-03-09 14:08:49 -07:00
Kelsi
770ac645d5 Handle SMSG_SUMMON_REQUEST with accept/decline popup
- Parse SMSG_SUMMON_REQUEST (summonerGuid + zoneId + timeoutMs),
  store summoner name from entity list, show chat notification
- acceptSummon() sends CMSG_SUMMON_RESPONSE(1), declineSummon() sends
  CMSG_SUMMON_RESPONSE(0), SMSG_SUMMON_CANCEL clears pending state
- renderSummonRequestPopup(): shows summoner name + countdown timer
  with Accept/Decline buttons
2026-03-09 14:07:50 -07:00
Kelsi
f369fe9c6e Implement basic trade request/accept/decline flow
- Parse SMSG_TRADE_STATUS for all 20+ status codes: incoming request,
  open/cancel/complete/accept notifications, error conditions (too far,
  wrong faction, stunned, dead, trial account, etc.)
- SMSG_TRADE_STATUS_EXTENDED consumed via shared handler (no full item
  window yet; state tracking sufficient for accept/decline flow)
- Add acceptTradeRequest() (CMSG_BEGIN_TRADE), declineTradeRequest(),
  acceptTrade() (CMSG_ACCEPT_TRADE), cancelTrade() (CMSG_CANCEL_TRADE)
- Add BeginTradePacket, CancelTradePacket, AcceptTradePacket builders
- Add renderTradeRequestPopup(): shows "X wants to trade" with
  Accept/Decline buttons when tradeStatus_ == PendingIncoming
- TradeStatus enum tracks None/PendingIncoming/Open/Accepted/Complete
2026-03-09 14:05:42 -07:00
Kelsi
3114e80fa8 Implement group loot roll: SMSG_LOOT_ROLL, SMSG_LOOT_ROLL_WON, CMSG_LOOT_ROLL
- Parse SMSG_LOOT_ROLL: if rollType==128 and it's our player, store
  pending roll (itemId, slot, name from itemInfoCache_) and show popup;
  otherwise show chat notification of another player's roll result
- Parse SMSG_LOOT_ROLL_WON: show winner announcement in chat with item
  name and roll type/value
- sendLootRoll() sends CMSG_LOOT_ROLL (objectGuid+slot+rollType) and
  clears pending roll state
- SMSG_LOOT_MASTER_LIST consumed silently (no UI yet)
- renderLootRollPopup(): ImGui window with Need/Greed/Disenchant/Pass
  buttons; item name colored by quality (poor/common/uncommon/rare/epic/
  legendary color scale)
2026-03-09 14:01:27 -07:00
Kelsi
2d124e7e54 Implement duel request/accept/decline UI and packet handling
- Parse SMSG_DUEL_REQUESTED: store challenger guid/name, set
  pendingDuelRequest_ flag, show chat notification
- Parse SMSG_DUEL_COMPLETE: clear pending flag, notify on cancel
- Parse SMSG_DUEL_WINNER: show "X defeated Y in a duel!" chat message
- Handle SMSG_DUEL_OUTOFBOUNDS with warning message
- Add acceptDuel() method sending CMSG_DUEL_ACCEPTED (new builder)
- Wire forfeitDuel() to clear pendingDuelRequest_ on decline
- Add renderDuelRequestPopup() ImGui window (Accept/Decline buttons)
  positioned near group invite popup; shown when challenge is pending
- Add DuelAcceptPacket builder to world_packets.hpp/cpp
2026-03-09 13:58:02 -07:00
Kelsi
e4f53ce0c3 Handle SMSG_ACHIEVEMENT_EARNED with toast banner and chat notification
- Parse SMSG_ACHIEVEMENT_EARNED (guid + achievementId + PackedTime date)
  and fire AchievementEarnedCallback for self, chat notify for others
- Add renderAchievementToast() to GameScreen: slides in from right,
  gold-bordered panel with "Achievement Earned!" title + ID, 5s duration
  with 0.4s slide-in/out animation and fade at end
- Add triggerAchievementToast(uint32_t) public method on GameScreen
- Wire AchievementEarnedCallback in application.cpp
- Add playAchievementAlert() to UiSoundManager, loads
  Sound\Interface\AchievementSound.wav with level-up fallback
- SMSG_ALL_ACHIEVEMENT_DATA silently consumed (no tracker UI yet)
2026-03-09 13:53:42 -07:00
Kelsi
200a00d4f5 Implement Dungeon Finder UI window with role/dungeon selection
- Add renderDungeonFinderWindow() with status display (not queued /
  role check / queued+wait time / proposal / in dungeon / finished)
- Role checkboxes (Tank/Healer/DPS) and dungeon combo (25 entries
  covering Vanilla, TBC, and WotLK including Random/Heroic)
- Accept/Decline buttons during Proposal state, Teleport button
  while InDungeon, Leave Queue button while Queued/RoleCheck
- Store lfgProposalId_ on GameHandler so UI can pass it to
  lfgAcceptProposal(); expose getLfgProposalId() and
  getLfgTimeInQueueMs() getters
- Toggle window with I key (when chat input is not active)
2026-03-09 13:47:07 -07:00
Kelsi
8f7c4a58cd Implement SMSG_RAID_INSTANCE_INFO handler to track instance lockouts
Parse and store dungeon/raid lockout data sent on login:
- mapId, difficulty, resetTime (Unix timestamp), locked, extended flags
- Stored in instanceLockouts_ vector for UI / LFG / dungeon state queries
- Public InstanceLockout struct + getInstanceLockouts() accessor
2026-03-09 13:36:23 -07:00
Kelsi
b33831d833 Implement WotLK 3.3.5a LFG/Dungeon Finder packet handlers
Add full client-side handling for the Looking For Dungeon system:
- SMSG_LFG_JOIN_RESULT: parse join success/failure, surface error message
- SMSG_LFG_QUEUE_STATUS: track dungeon ID, avg wait time, time in queue
- SMSG_LFG_PROPOSAL_UPDATE: detect proposal state (active/passed/failed)
- SMSG_LFG_ROLE_CHECK_UPDATE: surface role check progress/failure
- SMSG_LFG_UPDATE_PLAYER/PARTY: track queue state transitions
- SMSG_LFG_PLAYER_REWARD: show dungeon completion reward in chat
- SMSG_LFG_BOOT_PROPOSAL_UPDATE: show vote-kick status in chat
- SMSG_LFG_TELEPORT_DENIED: surface reason for teleport failure
- SMSG_LFG_DISABLED/OFFER_CONTINUE and informational packets consumed

Outgoing: lfgJoin(), lfgLeave(), lfgAcceptProposal(), lfgTeleport()
State: LfgState enum + lfgState_/lfgDungeonId_/lfgAvgWaitSec_ members
2026-03-09 13:30:23 -07:00
Kelsi
b0d7dbc32c Implement SMSG_STANDSTATE_UPDATE and SMSG_ITEM_PUSH_RESULT handlers
SMSG_STANDSTATE_UPDATE:
- Parse uint8 stand state from server confirmation packet
- Store in standState_ member (0=stand, 7=dead, 8=kneel, etc.)
- Expose getStandState(), isSitting(), isDead(), isKneeling() accessors

SMSG_ITEM_PUSH_RESULT:
- Parse full WotLK 3.3.5a payload: guid, received, created, showInChat,
  bagSlot, itemSlot, itemId, suffixFactor, randomPropertyId, count, totalCount
- Show "Received: <name> x<count>" chat notification when showInChat=1
- Queue item info lookup via queryItemInfo so name resolves asap
2026-03-09 12:58:52 -07:00
Kelsi
a4966e486f Fix WMO wall collision, normal mapping, POM backfill, and M2/WMO rendering performance
- Fix MOPY flag check (0x08 not 0x01) for proper wall collision detection
- Cap MAX_PUSH to PLAYER_RADIUS to prevent gradual clip-through
- Fix WMO doodad quaternion component ordering (X/Y swap)
- Linear normal map strength blend in shader for smooth slider control
- Enable shadow sampling for interior WMO groups (covered outdoor areas)
- Backfill deferred normal/height maps after streaming with descriptor rebind
- M2: prepareRender only iterates animated instances, bone dirty flag
- M2: remove worker thread VMA allocation, skip unready bone instances
- WMO: persistent visibility vectors, sequential culling
- Add FSR EASU/RCAS shaders
2026-03-07 22:03:28 -08:00
Kelsi
f4c115ade9 Fix Deeprun Tram: visual movement, direction, and player riding
- Fix NULL renderer pointers by moving TransportManager connection after
  initializeRenderers for WMO-only maps
- Fix tram direction by negating DBC TransportAnimation X/Y local offsets
  before serverToCanonical conversion
- Implement client-side M2 transport boarding via proximity detection
  (server doesn't send transport attachment for trams)
- Use position-delta approach: player keeps normal movement while
  transport's frame-to-frame motion is applied on top
- Prevent server movement packets from clearing client-side M2 transport
  state (isClientM2Transport guard)
- Fix getPlayerWorldPosition for M2 transports: simple canonical addition
  instead of render-space matrix multiplication
2026-03-06 23:01:11 -08:00
Kelsi
16d44c5bb3 Fix interior WMO floor gaps, water exit stair clipping, NPC equipment, portal animation
- Fix Stormwind barracks floor: interior WMO groups named "facade" were
  incorrectly marked as LOD shells and hidden when close. Add !isIndoor
  guard to all LOD detection conditions so interior groups always render.
- Fix water exit stair clipping: anchor lastGroundZ to current position
  on swim exit, set grounded=true for full step-up budget, add upward
  velocity boost to clear stair lip geometry.
- Re-enable NPC humanoid equipment geosets (kEnableNpcHumanoidOverrides)
  so guards render with proper armor instead of underwear.
- Keep instance portal GameObjects animated (spinning/glowing) instead
  of freezing all GO animations indiscriminately.
- Fix equipment disappearing after instance round-trip by resetting
  dirty tracking on world reload.
- Fix multi-doodad-set loading: load both set 0 (global) and placement-
  specific doodad set, with dedup to avoid double-loading.
- Clear placedWmoIds in softReset/unloadAll to prevent stale dedup.
- Apply MODF rotation to instance WMOs, snap player to WMO floor.
- Re-enable rebuildSpatialIndex in setInstanceTransform.
- Store precomputeFloorCache results in precomputed grid.
- Add F8 debug key for WMO floor diagnostics at player position.
- Expand mapIdToName with all Classic/TBC/WotLK instance map IDs.
2026-03-04 19:47:01 -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
804b947203 Fix bank for all expansions: add missing field indices and per-expansion slot counts
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
2026-02-26 11:12:34 -08:00
Kelsi
74b78cd10b Add pet tracking via SMSG_PET_SPELLS and dismiss pet button 2026-02-26 10:41:29 -08:00
Kelsi
a1f73fdd39 Handle SMSG_PARTY_MEMBER_STATS to show group health out of visual range
Parse SMSG_PARTY_MEMBER_STATS and SMSG_PARTY_MEMBER_STATS_FULL packets
so party frames display health, power, level, and online status even
when group members are not nearby. Expansion-aware field sizes: uint16
health for Classic/TBC, uint32 for WotLK, plus per-expansion aura and
vehicle seat handling.
2026-02-26 10:25:55 -08:00
Kelsi
1c07e87b7e Add missing movement ACK responses to avoid server stalls
Implement generic handlers for force speed changes (walk, run back,
swim, swim back, flight, flight back, turn rate, pitch rate),
movement flag toggles (CAN_FLY, HOVER, feather fall, water walk),
and knockback ACKs. Fix SMSG_TIME_SYNC_REQ to respond with
CMSG_TIME_SYNC_RESP instead of silently dropping.
2026-02-26 03:02:51 -08:00
Kelsi
1ae5fe867c Improve auction house UI with search filters, pagination, sell picker, and tooltips
- Add item class/subclass category filters (Weapon, Armor, etc.) with correct WoW 3.3.5a IDs
- Add sell item picker dropdown with icons and Create Auction button
- Add pagination (Prev/Next) for browse results with filter preservation
- Add Buy/Bid action buttons to Bids tab
- Add item icons and stat tooltips on hover across all three tabs
- Add Enter-to-search from name field and search delay countdown
- Parse SMSG_AUCTION_OWNER/BIDDER_NOTIFICATION into chat messages
- Auto-refresh browse results after bid/buyout using saved search params
- Clamp level range inputs to 0-80
2026-02-25 14:44:44 -08:00
Kelsi
9906269671 Add mail item attachment support for sending
- CMSG_SEND_MAIL now includes item GUIDs (up to 12 per WotLK)
- Right-click items in bags to attach when mail compose is open
- Compose window shows 12-slot attachment grid with item icons
- Click attached items to remove them
- Classic/Vanilla falls back to single item GUID format
2026-02-25 14:11:09 -08:00
Kelsi
639df4815e Handle SMSG_GAMEOBJECT_CUSTOM_ANIM to unfreeze gameobjects on use
When the server sends a custom animation packet (e.g. chest being
opened), unfreeze the M2 instance so it plays its open animation.
2026-02-23 05:39:02 -08:00
Kelsi
c04e97e375 Fix street sign interaction text and M2 sign orientation
Add page-text support for sign-like gameobject interactions by handling SMSG_GAMEOBJECT_PAGETEXT and SMSG_PAGE_TEXT_QUERY_RESPONSE, and issuing CMSG_PAGE_TEXT_QUERY when page IDs are available from cached GO template data.

Normalize received page text tokens before chat display and add a fallback for basic signpost GO type clicks to print sign names when no page data is present.

Correct M2 gameobject yaw alignment for signposts/arrows by applying render-space -90deg offset consistently across spawn, position update, and move-callback transforms; keep WMO orientation path unchanged.
2026-02-20 23:31:30 -08:00
Kelsi
ace24e8ccc Fix quest accept/abandon flow and expansion-specific accept packet format
Normalize WoW quest text tokens during parsing so quest titles/details no longer leak raw markup like  and |n into UI. Apply to WotLK and Classic parser paths, including quest list parsing in GameHandler.

Harden quest state handling by mapping abandon requests to authoritative server quest-log slots (PLAYER_QUEST_LOG_START) instead of local vector order, with a guarded fallback when update fields are unavailable.

Improve accept de-duplication by trusting server slot state over stale local cache; allow re-accept when local/server state diverges and trigger resync semantics.

Add expansion-aware CMSG_QUESTGIVER_ACCEPT_QUEST builders: WotLK sends guid+questId+unk1(uint32), while TBC/Classic/Turtle send guid+questId only. Wire GameHandler through PacketParsers for compatibility across expansions and cores.
2026-02-20 23:20:02 -08:00
Kelsi
2da2e75253 Refine gameobject chest interaction flow and remove temporary debug logging
- Keep WotLK chest flow stock-like by relying on GAMEOBJ_USE/REPORT_USE instead of forcing eager CMSG_LOOT.

- Preserve fallback eager-loot behavior for Classic/Turtle paths with bounded retries.

- Improve GO targeting usability by allowing gameobject pick/retarget in world click logic.

- Remove temporary loot/chest diagnostic LOG_INFO traces added during chest-open debugging.
2026-02-20 19:51:04 -08:00
Kelsi
a11c9ae22b Add melee auto-attack range state fields to GameHandler
Declare autoAttackOutOfRangeTime_ and autoAttackRangeWarnCooldown_ in GameHandler to match existing combat logic in game_handler.cpp and keep header/source state in sync.
2026-02-20 17:53:33 -08:00
Kelsi
954edc91b8 Harden quest accept state and resync quest log on login
- add idempotent pending-accept tracking with timeout and per-quest cleanup hooks
- stop optimistic local quest insertion on accept; rely on server-authoritative updates
- handle QUEST_INVALID already-on/completed as reconciliation paths for pending accepts
- trigger quest metadata + status resync when accept state drifts
- add login-time quest log rebuild from PLAYER_QUEST_LOG server slots
- query quest metadata for server-slot quests to hydrate titles/objectives
- clear stale pending quest accept/query state on fresh world entry
- improve gossip quest selection fallback by trusting server quest slots when local cache is missing

This reduces duplicate accept/state mismatch loops (notably reason=13) and stabilizes WotLK quest behavior after relogs.
2026-02-20 17:14:13 -08:00
Kelsi
eaba378b5b Fix classic combat desync and separate attack intent from confirmed combat
Combat state/UI:

- Split attack intent from server-confirmed auto attack in GameHandler.

- Add explicit combat state helpers (intent, confirmed, combat-with-target).

- Update player/target frame and renderer in-combat indicators to use confirmed combat.

- Add intent-only visual state in UI to avoid false combat feedback.

Animation correctness:

- Correct combat-ready animation IDs to canonical ready stances (22/23/24/25).

- Remove hit/wound-like stance behavior caused by incorrect ready IDs.

Classic/TBC/Turtle melee reliability:

- Tighten melee sync while attack intent is active: faster swing resend, tighter facing threshold, and faster facing cadence for classic-like expansions.

- Send immediate movement heartbeat after facing corrections and during stationary melee sync windows.

- Handle melee error opcodes explicitly (NOTINRANGE/BADFACING/NOTSTANDING/CANT_ATTACK) and immediately resync facing/swing where appropriate.

- On ATTACKSTOP with persistent intent, immediately reassert ATTACKSWING.

- Increase movement heartbeat cadence during active classic-like melee intent.

Server compatibility/anti-cheat stability:

- Restrict legacy force-movement/speed/teleport ACK behavior for classic-like flows to avoid unsolicited order acknowledgements.

- Preserve local movement state updates while preventing bad-order ACK noise.
2026-02-20 03:38:12 -08:00
Kelsi
cb044e3985 Combat fix: restore reliable melee hits via movement/state sync
Resolved a melee desync where attacks could fail unless constantly moving through target.

Movement opcode handling:

- In 0x006B compatibility path, prefer compressed-move batch detection before weather alias routing.

- Route 0x006B payloads shaped like SMSG_COMPRESSED_MOVES sub-packets to handleCompressedMoves().

Root/unroot state synchronization:

- Added handling for SMSG_FORCE_MOVE_ROOT and SMSG_FORCE_MOVE_UNROOT.

- Added handleForceMoveRootState() to apply server-authoritative ROOT flag locally.

- Send CMSG_FORCE_MOVE_ROOT_ACK / CMSG_FORCE_MOVE_UNROOT_ACK with current movement payload and counter.

Melee facing stability:

- Added periodic facing sync during auto-attack (MSG_MOVE_SET_FACING) when angular drift to target exceeds threshold.

- Keeps server front-arc/facing checks aligned while stationary meleeing.

Noise reduction / stream hygiene:

- Consume optional legacy/system packets safely: SMSG_FRIEND_LIST, SMSG_IGNORE_LIST, SMSG_ADDON_INFO, SMSG_EXPECTED_SPAM_RECORDS.

Validation:

- Rebuilt successfully with cmake --build build -j32.
2026-02-20 03:14:48 -08:00