Commit graph

491 commits

Author SHA1 Message Date
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
6df36f4588 Handle exploration XP, pet tame failure, quest fail timers, pet action/name responses
- SMSG_EXPLORATION_EXPERIENCE: parse areaId+xpGained, show discovery message
- SMSG_PET_TAME_FAILURE: parse reason byte, show descriptive failure message
- SMSG_PET_ACTION_FEEDBACK: consumed silently (no pet action bar UI yet)
- SMSG_PET_NAME_QUERY_RESPONSE: consumed silently (names shown via unit objects)
- SMSG_QUESTUPDATE_FAILED: "Quest X failed!" notification
- SMSG_QUESTUPDATE_FAILEDTIMER: "Quest X timed out!" notification
2026-03-09 14:21:17 -07:00
Kelsi
8e4a0053c4 Handle SMSG_DISPEL_FAILED, SMSG_TOTEM_CREATED, SMSG_AREA_SPIRIT_HEALER_TIME, SMSG_DURABILITY_DAMAGE_DEATH
- SMSG_DISPEL_FAILED: parse caster/victim/spellId, show "Dispel failed!" chat
- SMSG_TOTEM_CREATED: parse slot/guid/duration/spellId, log (no totem bar yet)
- SMSG_AREA_SPIRIT_HEALER_TIME: show "resurrect in N seconds" message
- SMSG_DURABILITY_DAMAGE_DEATH: show durability loss notification on death
2026-03-09 14:18:36 -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
e793b44151 Handle SMSG_ITEM_COOLDOWN, fishing fail/escape, minimap ping, zone attack
- SMSG_ITEM_COOLDOWN: parse guid+spellId+cdMs, update spellCooldowns
  map and action bar slots (same path as SMSG_SPELL_COOLDOWN)
- SMSG_FISH_NOT_HOOKED: "Your fish got away." chat notification
- SMSG_FISH_ESCAPED: "Your fish escaped!" chat notification
- MSG_MINIMAP_PING: consumed silently (no visual yet)
- SMSG_ZONE_UNDER_ATTACK: parse areaId, show chat notification
2026-03-09 14:12:20 -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
b4f6ca2ca7 Handle SMSG_SERVER_MESSAGE, SMSG_CHAT_SERVER_MESSAGE, SMSG_AREA_TRIGGER_MESSAGE, SMSG_TRIGGER_CINEMATIC
- SMSG_SERVER_MESSAGE: parse type+string, show as [Server] chat message
- SMSG_CHAT_SERVER_MESSAGE: parse type+string, show as [Announcement]
- SMSG_AREA_TRIGGER_MESSAGE: parse len+string, display as system chat
- SMSG_TRIGGER_CINEMATIC: consume silently (no cinematic playback)
2026-03-09 14:03:07 -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
63c6039dbb Handle SMSG_CLEAR_COOLDOWN and SMSG_MODIFY_COOLDOWN
SMSG_CLEAR_COOLDOWN: remove spell cooldown from cache and clear action bar
slot's remaining cooldown immediately (e.g. after item use, trinket proc).

SMSG_MODIFY_COOLDOWN: adjust an existing cooldown duration by a signed delta
in milliseconds (used by glyphs, Borrowed Time, etc.).
2026-03-09 13:40:19 -07:00
Kelsi
9d37f4c946 Add instance state packet handlers: reset, save, lock, warning query
- SMSG_INSTANCE_SAVE_CREATED: notify player they are saved to instance
- SMSG_RAID_INSTANCE_MESSAGE: surface warning/save/welcome notifications
- SMSG_INSTANCE_RESET: clear matching lockout from cache + notify
- SMSG_INSTANCE_RESET_FAILED: report reset failure reason to player
- SMSG_INSTANCE_LOCK_WARNING_QUERY: auto-confirm with CMSG_INSTANCE_LOCK_RESPONSE
  (entering a saved instance; sends acceptance so the player can proceed)
2026-03-09 13:38:19 -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
6a7287bde3 Implement transport spline movement and fix SMSG_QUESTLOG_FULL
SMSG_MONSTER_MOVE_TRANSPORT (handleMonsterMoveTransport):
- Parse full WotLK 3.3.5a spline payload after the transport-local start
  position: splineId, moveType, facing data (spot/target/angle), splineFlags,
  Animation flag block, duration, Parabolic flag block, pointCount, waypoints
- Extract destination in transport-local server coords, compose to world
  space via TransportManager, then call entity->startMoveTo() with the
  spline duration so NPC movement interpolates smoothly instead of teleporting
- Handle all facing modes (FacingSpot/Target/Angle/normal) in transport space
- Degenerate cases (no spline data, moveType==1 stop, no transport manager)
  fall back to snapping start position as before

SMSG_QUESTLOG_FULL:
- This opcode is a zero-payload notification meaning the quest log is at
  capacity (25 quests); it does not carry quest log data
- Replace placeholder LOG_INFO stubs with a proper "Your quest log is full."
  chat notification and a single LOG_INFO
2026-03-09 13:04:35 -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
0313bd8692 Performance: ring buffer UBOs, batched load screen uploads, background world preloader
- Replace per-frame VMA alloc/free of material UBOs with a ring buffer in
  CharacterRenderer (~500 allocations/frame eliminated)
- Batch all ready terrain tiles into a single GPU upload during load screen
  (processAllReadyTiles instead of one-at-a-time with individual fence waits)
- Lift per-frame creature/GO spawn budgets during load screen warmup phase
- Add background world preloader: saves last world position to disk, pre-warms
  AssetManager file cache with ADT files starting at app init (login screen)
  so terrain workers get instant cache hits when Enter World is clicked
- Distance-filter expensive collision guard to 8-unit melee range
- Merge 3 CharacterRenderer update loops into single pass
- Time-budget instrumentation for slow update stages (>3ms threshold)
- Count-based async creature model upload budget (max 3/frame in-game)
- 1-per-frame game object spawn + per-doodad time budget for transport loading
- Use deque for creature spawn queue to avoid O(n) front-erase
2026-03-07 13:44:09 -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
dfc53f30a8 Effect model additive blend, teleport facing, tighter area triggers
Classify light shafts, portals, spotlights, bubbles, and similar M2
doodads as spell effects so they render with additive blending instead
of as solid opaque objects.

Set camera yaw from server orientation on world load so teleports face
the correct direction.

Reduce area trigger minimum radius (3.0 sphere, 4.0 box) to prevent
premature portal firing near tram entrances.
2026-03-06 18:03:08 -08:00
Kelsi
4cbceced67 Fix invisible walls from WMO doodad M2 collision and MOPY filtering
WMO interior doodads (gears, decorations) were blocking player movement
via M2 collision. Skip collision for all WMO doodad M2 instances since
the WMO itself handles wall collision.

Also filter WMO wall collision using MOPY per-triangle flags: only
rendered+collidable triangles block the player, skipping invisible
collision hulls.

Revert tram portal extended range (no longer needed with collision fix).
2026-03-06 12:26:17 -08:00
Kelsi
ee4e6a31ce Filter WMO decorative geometry from collision, fix tram portal trigger IDs
Parse MOPY per-triangle flags in WMO groups and exclude detail/decorative
triangles (flag 0x04) from collision detection. This prevents invisible
walls from objects like gears and railings in WMO interiors.

Add WotLK area trigger IDs 2173/2175 to extended-range tram triggers.
2026-03-06 10:37:32 -08:00
Kelsi
cefb05c027 Extend Deeprun Tram portal trigger range to bypass WMO collision walls
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-03-05 21:17:45 -08:00
Kelsi
16daa2baf7 Reduce instance portal area trigger range to prevent premature teleports
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-03-04 19:52:47 -08:00
Kelsi
b948720ec3 Fix NPC chat showing only name without message text
Two bugs in SMSG_MESSAGECHAT parser for MONSTER_SAY/YELL/EMOTE:

1. Sender name included trailing null byte from server (nameLen includes
   null terminator). The embedded null in std::string caused ImGui to
   truncate the concatenated display string at the NPC name, hiding
   " says: <message>" entirely.

2. Missing NamedGuid receiver name for non-player/non-pet targets. When
   the receiver GUID is a creature, the server writes an additional
   SizedCString (target name) that we weren't reading, shifting all
   subsequent field reads.

Also adds MONSTER_WHISPER, MONSTER_PARTY, RAID_BOSS_EMOTE, RAID_BOSS_WHISPER
chat types with proper parsing and display formatting (says/yells/whispers).
2026-03-02 08:31:34 -08:00
Kelsi
f1caf8c03e Fix Stockades crash: suppress area triggers on initial login, handle VK_ERROR_DEVICE_LOST
Root cause: LOGIN_VERIFY_WORLD path did not set areaTriggerCheckTimer_ or
areaTriggerSuppressFirst_, so the Stockades exit portal (AT 503) fired
immediately on login, teleporting the player back to Stormwind and crashing
the GPU during the unexpected map transition.

Fixes:
- Set 5s area trigger cooldown + suppress-first in handleLoginVerifyWorld
  (same as SMSG_NEW_WORLD handler already did for teleports)
- Add deviceLost_ flag to VkContext so beginFrame returns immediately once
  VK_ERROR_DEVICE_LOST is detected, preventing infinite retry loops
- Track device lost from both fence wait and queue submit paths
2026-03-02 08:19:14 -08:00
Kelsi
3c55b09a3f Refactor instance loading: extract initializeRenderers, fix deferred state transition
- Extract initializeRenderers() from loadTestTerrain() so WMO-only maps
  (dungeons/raids) initialize renderers directly without a dummy ADT path
- Defer setState(IN_GAME) until after processing any pending deferred world
  entry, preventing brief IN_GAME flicker on the wrong map
- Remove verbose area trigger debug logging (every-second position spam)
2026-03-02 08:11:36 -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
a559d5944b Fix shutdown hangs, bank bag icons/drag-drop, loading screen progress, and login spawn
- Fix shutdown hang: skip vmaDestroyAllocator (walked thousands of allocations),
  replace unsafe pthread_timedjoin_np with plain join + early-exit checks in workers
- Bank window: full icon rendering, click-and-hold pickup (0.10s), drag-drop for
  all bank slots including bank bag equip slots, same-slot drop detection
- Loading screen: process one tile per frame for live progress updates
- Camera reset: trust server position in online mode to avoid spawning under WMOs
- Fix PLAYER_BYTES/PLAYER_BYTES_2 field indices, preserve purchasedBankBagSlots
  across inventory rebuilds, fix bank slot purchase result codes
2026-02-26 13:38:29 -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
5d92152701 Fix bank items not appearing by deferring inventory rebuild after item creation 2026-02-26 10:46:47 -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
c919477e74 Fix item use (CMSG_USE_ITEM), mount tab, and inventory right-click
- Fix SMSG_ITEM_QUERY_SINGLE_RESPONSE parsing: read statsCount stat
  pairs instead of always 10, use 2 damage entries (MAX_ITEM_PROTO_DAMAGES),
  and parse item spell data (spellId + spellTrigger per slot)
- Pass item spell ID in CMSG_USE_ITEM packet so server processes item
  use requests (spellId=0 caused silent server rejection)
- Add spellId parameter to buildUseItem interface across all expansions
- Fix spellbook mount tab to use SkillLine 777 (Mounts) instead of 762
  (Riding), so known mount summon spells appear correctly
- Fix inventory right-click: use IsItemHovered+IsMouseClicked instead
  of IsItemClicked for InvisibleButton (which only tracks left-clicks)
- Fix SlotKind enum declaration order in inventory_screen.hpp
2026-02-26 00:59:07 -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
52accfde80 Optimize login music scanning and warden debug formatting 2026-02-25 09:50:33 -08:00
Kelsi
c26353eda1 Reduce release log spam and harden release logging defaults 2026-02-25 09:46:27 -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
e98450f283 Upgrade displayId=0 creature spawn skip to WARNING level
Makes it visible in logs when a creature entity spawns without a
display ID, which would cause it to be invisible but still active.
2026-02-23 05:11:35 -08:00
Kelsi
2cfa9d6b19 Remove per-frame chrono profiling from application and game handler
Strip ~30 chrono::now() calls per frame from Application::update() and
GameHandler::update() that existed only for periodic LOG_DEBUG dumps.
Retain renderer timing used by the live performance HUD overlay.
2026-02-23 04:41:22 -08:00