Commit graph

602 commits

Author SHA1 Message Date
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
caea24f6ea Fix animated M2 flicker: free bone descriptor sets on instance removal
The boneDescPool_ had MAX_BONE_SETS=2048 but sets were never freed when
instances were removed (only when clear() reset the whole pool on map load).
As tiles streamed in/out, each new animated instance consumed 2 pool slots
(one per frame index) permanently. After ~1024 animated instances created
total, vkAllocateDescriptorSets began failing silently and returning
VK_NULL_HANDLE. render() skips instances with null boneSet[frameIndex],
making them invisible — appearing as per-frame flicker as the culling pass
included them but the render pass excluded them.

Fix: destroyInstanceBones() now calls vkFreeDescriptorSets() for each
non-null boneSet before destroying the bone SSBO. The pool already had
VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT set for this purpose.
Also increased MAX_BONE_SETS from 2048 to 8192 for extra headroom.
2026-03-09 18:09:33 -07:00
Kelsi
7b3b33e664 Fix NPC orientation (server yaw convention) and nameplate Y projection
coordinates.hpp: serverToCanonicalYaw now computes s - π/2 instead of π/2 - s.
The codebase uses atan2(-dy, dx) as its canonical yaw convention, where server
direction (cos s, sin s) in (server_X, server_Y) becomes (sin s, cos s) in
canonical after the X/Y swap, giving atan2(-cos s, sin s) = s - π/2.
canonicalToServerYaw is updated as its proper inverse: c + π/2.
The old formula (π/2 - s) was self-inverse and gave the wrong east/west facing
for any NPC not pointing north or south.

game_screen.cpp: Nameplate NDC→screen Y no longer double-inverts. The camera
bakes the Vulkan Y-flip into the projection matrix (NDC y=-1 = screen top,
y=+1 = screen bottom), so sy = (ndc.y*0.5 + 0.5) * screenH is correct.
The previous formula subtracted from 1.0 which reflected nameplates vertically.
2026-03-09 17:59:55 -07:00
Kelsi
8b495a1ce9 Add pet frame UI below player frame
Shows active pet name, level, health bar, and power bar (mana/focus/rage/energy)
when the player has an active pet. Clicking the pet name targets it. A Dismiss
button sends CMSG_PET_ACTION to dismiss the pet. Frame uses green border to
visually distinguish it from the player/target frames.
2026-03-09 17:23:28 -07:00
Kelsi
18a3a0fd01 Add XP_GAIN combat text type; show '+N XP' in purple on kills
XP gain was previously shown as a HEAL entry (green +N) which conflates
it with actual healing.  New XP_GAIN type renders as purple '+N XP' in the
outgoing column, matching WoW's floating XP style.
2026-03-09 17:13:31 -07:00
Kelsi
6d1f3c4caf Add zone discovery text: 'Entering: <ZoneName>' fades in on zone change
Polls the renderer's currentZoneName each frame and triggers a 5-second
fade-in/hold/fade-out toast at the upper-centre of screen when the zone
changes.  Matches WoW's standard zone transition display.
2026-03-09 17:06:12 -07:00
Kelsi
9d26f8c29e Add V key toggle for nameplates (WoW default binding)
nameplates default to visible; pressing V in the game world toggles them
off/on while the keyboard is not captured by a UI element.
2026-03-09 17:03:06 -07:00
Kelsi
01e0c2f9a3 Add world-space unit nameplates projected to screen via camera VP matrix
For each visible Unit entity within 40 yards, projects the canonical WoW
position (converted to render space) through the camera view-projection
matrix to screen pixels.  Draws a health bar (hostile=red, friendly=green,
target=gold border) and name label with drop shadow using ImGui's background
draw list.  Fades out smoothly in the last 5 yards of range.
2026-03-09 17:01:38 -07:00
Kelsi
f1d31643fc Implement SMSG_SPELLENERGIZELOG and fix missing combat text cases
Parse SPELLENERGIZELOG (victim/caster packed GUIDs + spellId + powerType +
amount) and emit ENERGIZE combat text for mana/energy gains.  Add ENERGIZE
to CombatTextEntry::Type enum (blue +N text).

Also add explicit renderCombatText cases for BLOCK, PERIODIC_DAMAGE,
PERIODIC_HEAL, and ENVIRONMENTAL — previously all fell through to the
colourless default handler.
2026-03-09 16:55:23 -07:00
Kelsi
13e3e5ea35 Implement MusicManager fade-out in stopMusic() — was a stub
stopMusic(fadeMs) previously had (void)fadeMs with no fade logic.
Added fadingOut/fadeOutTimer/fadeOutDuration/fadeOutStartVolume state
and wired update() to interpolate volume to zero then stop playback.
Also clean up DuelProposedPacket comment (removed misleading TODO label).
2026-03-09 16:30:42 -07:00
Kelsi
68bf3d32b0 Wire ambient sound zone detection: setZoneType/setCityType was never called
Add AmbientSoundManager::setZoneId() that maps WoW zone IDs to the
appropriate ZoneType (forest/grasslands/desert/jungle/marsh/beach) or
CityType (Stormwind/Ironforge/Darnassus/Orgrimmar/Undercity/ThunderBluff)
and delegates to setZoneType/setCityType. Call it from the renderer's
zone transition handler so zone ambience (looping sounds, city bells,
etc.) actually activates when the player enters a zone.
2026-03-09 16:24:12 -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
b23cf06f1c Remove dead legacy GL Texture class
texture.hpp / texture.cpp implemented an unfinished OpenGL texture loader
(loadFromFile was a TODO stub) that had no callers — the project's texture
loading is entirely handled by VkTexture (vk_texture.hpp/cpp) after the
Vulkan migration. Remove both files and their CMakeLists entries.
2026-03-09 16:07:08 -07:00
Kelsi
43b9ecd857 Enrich zone music from AreaTable/ZoneMusic/SoundEntries DBC chain
Add ZoneManager::enrichFromDBC() which walks AreaTable.dbc (field 8 = ZoneMusicId)
→ ZoneMusic.dbc (fields 6/7 = day/night SoundEntryIds) → SoundEntries.dbc
(fields 3-12 = files, field 23 = DirectoryBase) and appends MPQ music paths for
all zones in the DBC, covering ~2300+ areas vs the previous ~15 hardcoded entries.

Existing hardcoded paths are preserved as the primary pool; DBC paths are added
only if not already present. Called from Renderer::init() after initialize().
2026-03-09 16:04:52 -07:00
Kelsi
46f2c0df85 Fix SoundEntries.dbc field indices for SMSG_PLAY_MUSIC and remove dead NpcVoiceManager code
Correct SoundEntries.dbc field access in the PlayMusic callback: file names are at
fields 3-12 (not 2-11) and DirectoryBase is at field 23 (not 22). Field 2 is the
Name label string, not a file path.

Remove dead detectVoiceType(creatureEntry) from NpcVoiceManager — it was never
called; actual voice detection uses detectVoiceTypeFromDisplayId() in Application.
2026-03-09 16:01:29 -07:00
Kelsi
e8d068c5cb Add Instance Lockouts window and fix three compiler warnings
- Add Escape Menu → Instance Lockouts button opening a new panel
  that lists active lockouts with instance name (from Map.dbc),
  difficulty, time-until-reset countdown, and locked/extended status.
  map name lookup is cached on first open.
- Fix uninitialized ChatType in sendChatMessage (default to SAY)
- Remove unused startWorld variable in handleMonsterMoveTransport
- Remove unused modelCached variable in spawnOnlineCreature
  Eliminates all -Wunused-but-set-variable and -Wmaybe-uninitialized
  warnings in the main translation units.
2026-03-09 15:52:58 -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
5c94b4e7ff Add quest objective tracker HUD on right side of screen
- Show up to 5 active quests with objective progress (kills, items, text)
- Gold title for complete quests, white for in-progress
- Item objectives show item name via getItemInfo() lookup
- Transparent semi-opaque background, docked below minimap on right
2026-03-09 15:05:38 -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
bae32c1823 Add FSR3 Generic API path and harden runtime diagnostics
- AmdFsr3Runtime now probes both the legacy ffxFsr3* API and the newer
  generic ffxCreateContext/ffxDispatch API; selects whichever the loaded
  runtime library exports (GenericApi takes priority fallback)
- Generic API path implements full upscale + frame-generation context
  creation, configure, dispatch, and destroy lifecycle
- dlopen error captured and surfaced in lastError_ on Linux so runtime
  initialization failures are actionable
- FSR3 runtime init failure log now includes path kind, error string,
  and loaded library path for easier debugging
- tools/generate_ffx_sdk_vk_permutations.sh added: auto-bootstraps
  missing VK permutation headers; DXC auto-downloaded on Linux/Windows
  MSYS2; macOS reads from PATH (CI installs via brew dxc)
- CMakeLists: add upscalers/include to probe include dirs, invoke
  permutation script before SDK build, scope FFX pragma/ODR warning
  suppressions to affected TUs, add runtime-copy dependency on wowee
- UI labels updated from "FSR2" → "FSR3" in settings, tuning panel,
  performance HUD, and combo boxes
- CI macOS job now installs dxc via Homebrew for permutation codegen
2026-03-09 12:51:59 -07:00
Kelsi
e916ef9bda Fix Windows frustum enum macro collision 2026-03-09 04:41:04 -07:00
Kelsi
1c7b87ee78 Remove FSR3 wrapper path and keep official Path-A runtime only 2026-03-09 04:33:05 -07:00
Kelsi
9ff9f2f1f1 Fix cross-platform FSR3 compile path and Path-A runtime wiring 2026-03-09 04:24:24 -07:00
Kelsi
78fa10c6ba Gate bridge interop export by wrapper capability bits
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-09 02:45:37 -07:00
Kelsi
40289c5f8e Add wrapper capability query and runtime capability gating 2026-03-09 02:19:11 -07:00
Kelsi
45c2ed7a64 Expose wrapper backend mode in runtime diagnostics 2026-03-09 02:15:55 -07:00
Kelsi
1bcc2c6b85 Use monotonic interop fence values for FSR3 bridge dispatch 2026-03-09 02:03:03 -07:00
Kelsi
1c7908f02d Add ABI v3 fence-value sync for DX12 bridge dispatch 2026-03-09 01:58:45 -07:00
Kelsi
53a692b9ef Add wrapper last-error API and DX12 handle-import probe 2026-03-09 01:36:26 -07:00
Kelsi
61cb2df400 Add ABI v2 external-handle plumbing for FSR3 bridge dispatch 2026-03-09 01:31:01 -07:00