Commit graph

857 commits

Author SHA1 Message Date
Kelsi
6cd3c613ef feat: add macro conditional support to /target and /focus commands
/target [target=mouseover], /target [mod:shift] BossName; DefaultMob,
/focus [target=mouseover], and /focus PlayerName all now evaluate WoW
macro conditionals and resolve named/mouseover targets correctly.
2026-03-18 03:21:27 -07:00
Kelsi
e2a484256c feat: show spell icon on macro buttons via #showtooltip directive
- getMacroShowtooltipArg() parses the #showtooltip [SpellName] directive
- Action bar macro buttons now display the named spell's icon when
  #showtooltip SpellName is present at the top of the macro body
- For bare #showtooltip (no argument), derives the icon from the first
  /cast line in the macro (stripping conditionals and rank suffixes)
- Falls back to "Macro" text label only when no spell can be resolved
2026-03-18 03:16:05 -07:00
Kelsi
28d7d3ec00 feat: track mouseover on party frames; fix /cast !spell; update macro editor hint 2026-03-18 03:11:34 -07:00
Kelsi
7967bfdcb1 feat: implement [target=mouseover] macro conditional via nameplate/raid hover
- Adds mouseoverGuid_ to GameHandler (set/cleared each frame by UI)
- renderNameplates() sets mouseoverGuid when the cursor is inside a
  nameplate's hit region; resets to 0 at frame start
- Raid frame cells set mouseoverGuid while hovered (IsItemHovered)
- evaluateMacroConditionals() resolves @mouseover / target=mouseover to
  the hover GUID; returns false (skip alternative) when no unit is hovered

This enables common healer macros like:
  /cast [target=mouseover,help,nodead] Renew; Renew
2026-03-18 03:09:43 -07:00
Kelsi
d2b2a25393 feat: extend macro conditionals to /use command 2026-03-18 03:06:23 -07:00
Kelsi
30513d0f06 feat: implement WoW macro conditional evaluator for /cast
Adds evaluateMacroConditionals() which parses the [cond1,cond2] Spell;
[cond3] Spell2; Default syntax and returns the first matching
alternative. Supported conditions:

- mod:shift/ctrl/alt, nomod  — keyboard modifier state
- target=player/focus/target, @player/@focus/@target — target override
- help / harm (noharm / nohelp)  — target faction check
- dead / nodead                  — target health check
- exists / noexists              — target presence check
- combat / nocombat              — player combat state
- noform / nostance / form:0     — shapeshift/stance state
- Unknown conditions are permissive (true) to avoid false negatives.

/cast now resolves conditionals before spell lookup and routes
castSpell() to the [target=X] override GUID when specified.
isHostileFaction() exposed as isHostileFactionPublic() for UI use.
2026-03-18 03:04:45 -07:00
Kelsi
ed3bca3d17 fix: escape newlines in macro cfg persistence; execute all macro lines
- Macro text is now escaped (\\n, \\\\) on save and unescaped on load,
  fixing multiline macros silently truncating after the first line in
  the character config file.
- executeMacroText() runs every non-comment line of a macro body in
  sequence (WoW behaviour), replacing the firstMacroCommand() approach
  that only fired the first actionable line. The server still enforces
  one spell-cast per click; non-cast commands (target, equip, pet, etc.)
  now all execute correctly in the same macro activation.
2026-03-18 02:44:28 -07:00
Kelsi
c676d99fc2 feat: add /petattack, /petfollow, /petstay, /petpassive, /petaggressive macro commands
Adds the standard WoW pet control slash commands used in macros:
- /petattack     — attack current target
- /petfollow     — follow player
- /petstay / /pethalt — stop and hold position
- /petpassive    — set passive react mode
- /petdefensive  — set defensive react mode
- /petaggressive — set aggressive react mode
- /petdismiss    — dismiss the pet

All commands also appear in Tab-autocomplete.
2026-03-18 02:32:49 -07:00
Kelsi
ae3e57ac3b feat: add /cancelform, /cancelshapeshift, /cancelaura slash commands
These are standard WoW macro commands:

- /cancelform / /cancelshapeshift: exits current shapeshift form by
  cancelling the first permanent aura (flag 0x20) on the player
- /cancelaura <name|#id>: cancels a specific player buff by spell name
  or numeric ID (e.g. /cancelaura Stealth, /cancelaura #1784)

Also expand the Tab-autocomplete command list to include /cancelaura,
/cancelform, /cancelshapeshift, /dismount, /sit, /stand, /startattack,
/stopcasting, /target, and other commands that were previously missing.
2026-03-18 02:30:35 -07:00
Kelsi
c3be43de58 fix: skip #showtooltip and other # directives when executing macros
Macros often start with a #showtooltip or #show directive line; these
should not be executed as chat commands.  The firstMacroCommand() helper
now scans forward through the macro text, skipping blank lines and any
line starting with '#', and executes the first actual command line.

Applies to all three execution paths: left-click, keyboard shortcut,
and right-click Execute menu item.
2026-03-18 02:27:34 -07:00
Kelsi
db0f868549 feat: extend /use command to support bag/slot notation and equip slot numbers
Adds WoW macro-standard /use argument forms alongside the existing
item-name search:

- /use 0 <slot>   — backpack slot N (1-based, bag 0)
- /use 1-4 <slot> — equipped bag slot N (1-based bag index)
- /use <N>        — equip slot N (1-based, e.g. /use 16 = main hand)

These are the standard forms used in macros like:
  #showtooltip
  /use 13          (trinket 1)
  /cast Arcane Blast
2026-03-18 02:23:47 -07:00
Kelsi
fa3a5ec67e fix: correct water refraction barrier srcAccessMask to prevent VK_ERROR_DEVICE_LOST
The captureSceneHistory barrier was using srcAccessMask=0 with
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT when transitioning the swapchain
image from PRESENT_SRC_KHR to TRANSFER_SRC_OPTIMAL.  This does not
flush the GPU's color attachment write caches, causing VK_ERROR_DEVICE_LOST
on strict drivers (AMD, Mali) that require explicit cache invalidation
before transfer reads.

Fix: use VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT + COLOR_ATTACHMENT_OUTPUT
as the source mask so color writes are properly made visible to the
transfer unit before the image copy begins.

Also remove the now-unnecessary "requires FSR" restriction in the
settings UI — water refraction can be enabled independently of FSR.
2026-03-18 02:20:35 -07:00
Kelsi
8abb65a813 feat: execute macros via keyboard shortcuts; support numeric /cast spell IDs
Two companion improvements for the macro system:

- Keyboard shortcut handler now executes MACRO slots (1-0 keys) by running
  the first line of their text as a command, same as left-click
- /cast now accepts a numeric spell ID or #ID prefix (e.g. /cast 133,
  /cast #133) in addition to spell names — enables standard WoW macro
  syntax and direct spell ID testing
2026-03-18 02:14:10 -07:00
Kelsi
2c86fb4fa6 feat: implement client-side macro text storage and execution
Macros in WoW are client-side — the server sends only a macro index via
SMSG_ACTION_BUTTONS, never the text. This commit adds local storage and
a UI so macro slots are actually usable.

- GameHandler: getMacroText/setMacroText accessors backed by macros_ map;
  text is persisted to the character .cfg file as macro_N_text= entries
- Action bar left-click: MACRO slot executes first line of macro text as
  a chat/slash command (same path as /cast, /use, etc.)
- Context menu: "Execute" and "Edit" items for MACRO slots; "Edit" opens
  a multiline modal editor (320×80 px, up to 255 chars) with Save/Cancel
- Tooltip: shows macro text body below the index; hints "right-click to
  Edit" when no text is set yet
2026-03-18 02:07:59 -07:00
Kelsi
36158ae3e3 fix: show macro ID in action bar tooltip and context menu header
Macro slots stored from SMSG_ACTION_BUTTONS had no tooltip and no context
menu header — hovering or right-clicking gave a blank result.  Add an
"else if MACRO" branch to both the tooltip and the popup-context-item so
that "Macro #N" is displayed in both places.  Clearing via right-click
still works via the existing "Clear Slot" item which was already outside
the type branches.
2026-03-18 01:42:07 -07:00
Kelsi
76ba428b87 fix: /target command selects nearest matching entity
Previously used arbitrary map-iteration order (last match), meaning
'/target Kobold' might target a far-away enemy instead of the closest.

Now computes squared distance for every prefix-matching entity and
keeps the nearest one, matching WoW's own /target behaviour.
2026-03-18 00:39:32 -07:00
Kelsi
5a5c2dcda3 feat: implement self-resurrection (Reincarnation/Twisting Nether)
SMSG_PRE_RESURRECT was silently discarded; Shamans with Reincarnation
and Warlocks with Twisting Nether could never see or use the self-res
ability. Now:

- SMSG_PRE_RESURRECT sets selfResAvailable_ flag when addressed to the
  local player
- Death dialog gains a "Use Self-Resurrection" button (blue, shown above
  Release Spirit) when the flag is set
- Clicking it sends CMSG_SELF_RES (empty body) and clears the flag
- selfResAvailable_ is cleared on all resurrection and session-reset
  paths so it never bleeds across deaths or logins
2026-03-18 00:06:39 -07:00
Kelsi
b0046fa777 feat: track PvP corpse-reclaim delay and show countdown in UI
SMSG_CORPSE_RECLAIM_DELAY is now stored as an absolute expiry timestamp
(steady_clock ms) instead of being discarded after a chat message.

GameHandler::getCorpseReclaimDelaySec() returns remaining seconds (0 when
reclaim is available). The "Resurrect from Corpse" button now:
- Disables and shows the remaining seconds when a PvP delay is active
- Shows the usual "Corpse: N yards" helper text when available
Also resets corpseReclaimAvailableMs_ on world/session teardown.
2026-03-17 23:52:45 -07:00
Kelsi
d99fe8de0f feat: add Sort Bags button to backpack window
Adds Inventory::sortBags() which collects all items from the backpack
and equip bags, sorts them client-side by quality descending → item ID
ascending → stack count descending, then writes them back. A "Sort Bags"
SmallButton is rendered in the backpack footer with a tooltip explaining
the sort order.

The sort is purely local (no server packets) since the WoW protocol has
no sort-bags opcode; it provides an instant, session-persistent visual
reorder.
2026-03-17 23:29:50 -07:00
Kelsi
b00025918c feat: draw player facing arrow at minimap center
The minimap had a comment "skip self (already drawn as arrow)" but no
code that actually drew the arrow. Players had no visual indication of
which direction they were facing on the minimap.

Draws a chevron-shaped white/gold arrow at the minimap center:
- On fixed-north minimap: arrow rotates to match camera compass bearing
  (computed from camera forward vector: atan2(-fwd.x, fwd.y))
- On rotating minimap: arrow points straight up because the minimap
  already rotates to put camera-forward at the top
- Style: two filled triangles (tip+left half, tip+right half) with dark
  outline for readability against all map backgrounds
- Rendered last so it sits on top of all other minimap markers
2026-03-17 22:05:24 -07:00
Kelsi
a731223e47 fix: right-clicking a quest-starting item now opens the quest offer dialog
Items with startQuestId != 0 were calling useItemBySlot()/useItemInBag()
which sends CMSG_USE_ITEM — but quest-starting items have no on-use spell,
so the server silently ignored the packet and no quest dialog appeared.

Fix:
- offerQuestFromItem(itemGuid, questId): sends CMSG_QUESTGIVER_QUERY_QUEST
  with the item's own GUID as the questgiver GUID. The server responds with
  SMSG_QUESTGIVER_QUEST_DETAILS which handleQuestDetails() already picks up
  and opens the Accept/Decline dialog with full rewards/description.
- getBagItemGuid(bagIndex, slotIndex): resolves the per-slot item GUID from
  the bag's containerContents_ map (mirrors the logic inside useItemInBag).
- inventory_screen.cpp right-click handler: checks item.startQuestId != 0
  before the equip/use branch; if set, resolves item GUID and calls
  offerQuestFromItem. Works for both backpack slots and bag slots.
2026-03-17 21:38:08 -07:00
Kelsi
c70740fcdf feat: wire Warden funcList_ dispatchers and implement PacketHandler call
Previously initializeModule() read the 4 WardenFuncList function addresses
from emulated memory, logged them, then discarded them — funcList_ was never
populated, so tick(), generateRC4Keys(), and processCheckRequest() were
permanently no-ops even when the Unicorn emulator successfully ran the module.

Changes:
- initializeModule() now wraps each non-null emulated function address in a
  std::function lambda that marshals args to/from emulated memory via
  emulator_->writeData/callFunction/freeMemory
- generateRC4Keys: copies 4-byte seed to emulated space, calls function
- unload: calls function with NULL (module saves own RC4 state)
- tick: direct uint32_t(deltaMs) dispatch, returns emulated EAX
- packetHandler: 2-arg variant for generic callers
- Stores emulatedPacketHandlerAddr_ for full 4-arg call in processCheckRequest
- processCheckRequest() now calls the emulated PacketHandler with the proper
  4-argument stdcall convention: (data, size, responseOut, responseSizeOut),
  reads back the response size and bytes, returns them in responseOut
- unload() resets emulatedPacketHandlerAddr_ to 0 for clean re-initialization
- Remove dead no-op renderObjectiveTracker() (no call sites, superseded)
2026-03-17 21:29:09 -07:00
Kelsi
b29d76bbc8 feat: highlight quest-starting items in loot window with gold indicator
Items with startQuestId != 0 now show:
- Gold outer glow border (2px) around the item icon
- Gold "!" badge in the top-right corner of the icon
- "Begins a Quest" label in gold on the second text line

Matches WoW's visual convention for quest-pickup items in loot rolls.
2026-03-17 21:17:22 -07:00
Kelsi
49ba89dfc3 feat: handle SMSG_PET_UNLEARN_CONFIRM with pet talent respec dialog
Parses the pet talent wipe confirm packet (petGuid + cost), shows a
confirmation dialog matching the player talent reset UX, and sends
CMSG_PET_UNLEARN_TALENTS on confirmation. Completes the pet talent
respec flow for Hunters/Warlocks on WotLK servers.
2026-03-17 21:13:27 -07:00
Kelsi
67c8101f67 fix: add missing TOGGLE_SKILLS to keybinding_manager (fixes CI build failure) 2026-03-17 21:08:02 -07:00
Kelsi
5df5f4d423 feat: handle SMSG_PET_RENAMEABLE to auto-open pet rename dialog on first tame
When the server sends SMSG_PET_RENAMEABLE (after taming a pet for the first
time), the pet rename modal now automatically opens so the player can name
their new pet without needing to right-click the pet frame.
2026-03-17 20:59:29 -07:00
Kelsi
113be66314 feat: parse MSG_BATTLEGROUND_PLAYER_POSITIONS and show flag carriers on minimap
Replaces the silent consume with full packet parsing: reads two lists of
(guid, x, y) positions (typically ally and horde flag carriers) and stores
them in bgPlayerPositions_. Renders each as a colored diamond on the minimap
(blue=group0, red=group1) with a "Flag carrier" tooltip showing the player's
name when available.
2026-03-17 20:54:59 -07:00
Kelsi
48cb7df4b4 feat: add Skills/Professions window (K key) with per-category progress bars
Implements renderSkillsWindow() showing all player skills grouped by
DBC category (Professions, Secondary Skills, Class Skills, Weapon Skills,
Armor, Languages) with value/max progress bars and a bonus breakdown tooltip.
Hooked up to the TOGGLE_SKILLS keybinding (K by default).
2026-03-17 20:46:41 -07:00
Kelsi
d44d462686 feat: add auto-repair at vendor open
When 'Auto Repair' is enabled in Settings > Gameplay, all damaged
equipment is automatically repaired when opening any armorer vendor
(canRepair=true). The repair is skipped when no items are actually
damaged to avoid a pointless server round-trip. A system chat message
confirms the repair. Setting persists to ~/.wowee/settings.cfg as
auto_repair.
2026-03-17 20:27:45 -07:00
Kelsi
072f256af6 feat: add auto-sell grey items on vendor open
When 'Auto Sell Greys' is enabled in Settings > Gameplay, all grey
(ItemQuality::POOR) items in the backpack and extra bags are sold
automatically when opening a vendor window. Items with no sell price
are skipped. A system chat message reports the number of items sold
and total gold received. The setting persists to ~/.wowee/settings.cfg
under the key auto_sell_grey.
2026-03-17 20:21:06 -07:00
Kelsi
e62ae8b03e feat: add local time clock display below minimap coordinates
Shows current local time in HH:MM format in a small dimmed label just
below the coordinate display near the minimap. Uses localtime_r (POSIX)
with a _WIN32 fallback. The clock complements the existing coordinate
and zone name overlays, matching the WoW default UI minimap area.
2026-03-17 20:06:05 -07:00
Kelsi
63f4d10ab1 fix: apply interruptibility coloring to target-of-target cast bar
The ToT (target-of-target) cast bar was still using a fixed orange-yellow
color regardless of spell interruptibility. Now uses the same green/red
scheme as the target frame and nameplate cast bars: green = interruptible
(can Kick/Counterspell), red = not interruptible, both pulse at >80%.
2026-03-17 20:02:02 -07:00
Kelsi
4ce6fdb5f3 feat: color player cast bar by spell school from Spell.dbc
The player's own cast bar now uses spell-school-based colors for quick
identification: Fire=orange-red, Frost=icy blue, Shadow=purple,
Arcane=violet, Nature=green, Holy=golden, Physical=gold. Channels
remain blue regardless of school. Adds getSpellSchoolMask() using the
already-loaded Spell.dbc cache (schoolMask field, covering all
expansions including Classic SchoolEnum→bitmask conversion).
2026-03-17 19:56:52 -07:00
Kelsi
d0df6eed2c feat: show corpse skull marker on world map when player is a ghost
When the player dies and releases spirit, the world map now renders a
bone-white X cross at the corpse's location (matching the existing
minimap skull marker). The marker appears only when the player is a
ghost with an unclaimed corpse on the same map, and shows a "Your
corpse" tooltip on hover. Implemented via setCorpsePos() on WorldMap,
called from renderWorldMap() using getCorpseCanonicalPos().
2026-03-17 19:52:17 -07:00
Kelsi
614fcf6b98 feat: show orange nameplate border when hostile NPC is targeting player
When a hostile unit has UNIT_FIELD_TARGET pointing to the local player,
highlight its nameplate with an orange border so players can immediately
see which enemies are attacking them vs. attacking group members.

Priority: gold=selected, orange=targeting you, dark=default.
2026-03-17 19:47:45 -07:00
Kelsi
7c932559e0 fix: apply interruptibility coloring to boss frame cast bars
Boss encounter frames were still using the old fixed orange/red cast bar
color. Update them to match the target frame: green = interruptible,
red = SPELL_ATTR_EX_NOT_INTERRUPTIBLE, both pulse at >80% completion.
2026-03-17 19:44:48 -07:00
Kelsi
279b4de09a feat: color cast bars green/red by spell interruptibility from Spell.dbc
Load AttributesEx from Spell.dbc for all expansions (Classic/TBC/WotLK/
Turtle). Check SPELL_ATTR_EX_NOT_INTERRUPTIBLE (bit 4 = 0x10) to classify
each cast as interruptible or not when SMSG_SPELL_START arrives.

Target frame and nameplate cast bars now use:
- Green: spell can be interrupted by Kick/Counterspell/Pummel etc.
- Red: spell is immune to interrupt (boss abilities, instant-cast effects)
Both colors pulse faster at >80% completion to signal the closing window.

Adds GameHandler::isSpellInterruptible() and UnitCastState::interruptible.
2026-03-17 19:43:19 -07:00
Kelsi
b8712f380d fix: show sub-zone name in minimap label using server-reported zone ID
The zone label above the minimap now preferentially uses the zone/area
name from getWorldStateZoneId() (populated via SMSG_INIT_WORLD_STATES)
rather than the renderer's map-level zone name. This means the label
correctly shows "Ironforge", "Wailing Caverns", etc. instead of always
showing the parent continent zone name.
2026-03-17 19:16:02 -07:00
Kelsi
f9947300da feat: show zone entry text on every zone crossing via SMSG_INIT_WORLD_STATES
Previously the "Entering: [Zone]" overlay only triggered when the terrain
renderer loaded a new map. Now it also fires whenever worldStateZoneId_
changes (sent by the server via SMSG_INIT_WORLD_STATES on each zone
crossing), giving correct "Entering: Ironforge", "Entering: Wailing
Caverns" etc. display for sub-zones and dungeon entries without requiring
a full map reload.

- Added lastKnownWorldStateZoneId_ to track server-reported zone changes
- renderZoneText() now takes GameHandler& to access getWorldStateZoneId()
  and getWhoAreaName() for name lookup via WorldMapArea.dbc cache
- Renderer zone name still checked as a fallback for map-level transitions
- Both sources de-duplicate to avoid triggering the same text twice
2026-03-17 19:14:17 -07:00
Kelsi
4a439fb0d1 feat: add clock-sweep arc to buff bar and target aura icons
Aura icons on the player buff bar and the target frame now display a
WoW-style dark fan overlay that sweeps clockwise as the buff/debuff
elapses, providing instant visual feedback on remaining duration.
The sweep uses AuraSlot::maxDurationMs / getRemainingMs() — the same
data that already drives the numeric countdown — so no new state is
required. Only temporary auras (maxDurationMs > 0) show a sweep;
permanent buffs remain unaffected.
2026-03-17 19:04:40 -07:00
Kelsi
d60d296b77 feat: show discovered taxi nodes as markers on the world map
Add gold diamond markers for every flight master the player has already
discovered (knownTaxiMask_), read from TaxiNodes.dbc and filtered to the
current continent/map being displayed:
- WorldMapTaxiNode struct carries canonical WoW coords + known flag
- WorldMap::setTaxiNodes() accepts the per-frame list from game_screen
- renderImGuiOverlay() projects each known node to UV, draws a gold
  diamond (AddQuadFilled) with a dark outline, and shows the node name
  as a tooltip on hover
- GameHandler::isKnownTaxiNode(id) checks knownTaxiMask_[] efficiently
- Markers update live — newly discovered nodes appear without reopening
  the map
2026-03-17 19:01:03 -07:00
Kelsi
488ec945b6 feat: display glancing and crushing blows in combat text and log
Add GLANCING (hitInfo 0x800) and CRUSHING (hitInfo 0x1000) as distinct
combat text types so players see mechanics feedback they expect from
Classic/TBC content:
- Glancing: shown as "~{amount}" in muted yellow/red; "glances for N" in
  the combat log
- Crushing: shown as "{amount}!" in bright orange/red; "crushes for N!"
  in the combat log
Both types are counted toward DPS meter accumulation. AttackerStateUpdateData
gains isGlancing()/isCrushing() helpers alongside the existing isCrit()/isMiss().
2026-03-17 18:51:48 -07:00
Kelsi
caad20285b feat: add hover tooltips to character sheet stats panel
Hovering over Armor, primary stats (Strength/Agility/Stamina/
Intellect/Spirit), and secondary rating stats now shows a brief
description of the stat's in-game effect — matching WoW's native
character screen behavior.

Uses ImGui::BeginGroup/EndGroup to make multi-widget rows (stat +
green bonus) respond to a single IsItemHovered check.
2026-03-17 17:16:56 -07:00
Kelsi
d1a392cd0e feat: add colors for SKILL, LOOT, BG system, and monster chat types
Added distinct colors for chat types that previously fell through to
the gray default: SKILL (cyan), LOOT (light purple), GUILD_ACHIEVEMENT
(gold), MONSTER_WHISPER/RAID_BOSS_WHISPER (pink), RAID_BOSS_EMOTE
(orange), MONSTER_PARTY (blue), BG_SYSTEM_NEUTRAL/ALLIANCE/HORDE
(gold/blue/red), and AFK/DND (light gray).
2026-03-17 17:00:46 -07:00
Kelsi
1e80e294f0 feat: add Heroic and Unique-Equipped indicators to chat link tooltips
Chat item link tooltips now show "Heroic" (green) for items with
ITEM_FLAG_HEROIC_TOOLTIP (0x8) and "Unique-Equipped" for items with
ITEM_FLAG_UNIQUE_EQUIPPABLE (0x1000000), matching InventoryScreen.
"Unique" text is now gold-colored to match as well.
2026-03-17 16:56:37 -07:00
Kelsi
cb99dbaea4 feat: add elemental resistances and full spell descriptions to chat link tooltips
Chat item link tooltips now show per-school elemental resistances
(Holy/Fire/Nature/Frost/Shadow/Arcane) when non-zero, matching the
inventory tooltip. Spell effect text (Use/Equip/Chance on Hit) now
shows the full spell description instead of just the spell name,
consistent with InventoryScreen::renderItemTooltip.
2026-03-17 16:54:40 -07:00
Kelsi
7e6de75e8a feat: show skill, reputation, class and race requirements in chat link tooltips
Chat item link tooltips now match InventoryScreen for required-skill
(SkillLine.dbc), required-reputation (Faction.dbc), class restriction,
and race restriction. Red text when the player does not meet the
requirement, grey otherwise.
2026-03-17 16:47:33 -07:00
Kelsi
dab03f2729 feat: show item set name and bonuses in chat item link tooltips
Chat link tooltips (hover over item links in chat) were missing item set
information already shown in the inventory tooltip.  Now shows:
- Set name with equipped/total piece count (e.g. "Tier 9 (2/5)")
- Each set bonus with its piece-threshold, colored green when active
  and grey when inactive
- Falls back to "Set (id N)" when ItemSet.dbc is unavailable

Lazy-loads ItemSet.dbc on first hover; consistent with
InventoryScreen::renderItemTooltip formatting.
2026-03-17 16:43:57 -07:00
Kelsi
dee33db0aa feat: show gem socket slots and socket bonus in chat item link tooltips
Item tooltips shown when hovering chat links already displayed all stats,
spells, and flavor text, but gem sockets were missing.  Add the same
socket rendering used in the inventory tooltip:

- Iterate socketColor[0..2]; for each non-zero slot show a colored label
  (Meta / Red / Yellow / Blue Socket) in the socket's faction color
- Lazy-load SpellItemEnchantment.dbc to resolve the socketBonus enchant
  name; fall back to "(id N)" when the record is not found
- Consistent with InventoryScreen::renderItemTooltip formatting
2026-03-17 16:42:19 -07:00
Kelsi
973db16658 feat: add screen-space weather particle overlay (rain/snow/storm)
Weather type and intensity are already tracked from SMSG_WEATHER, but
only an icon was shown next to the zone name.  This adds a fullscreen
ImDrawList overlay that renders:
- Rain (type 1): diagonal rain streaks proportional to intensity
- Snow (type 2): gently swaying snowflakes with two-tone highlight
- Storm (type 3): heavy rain + dark fog-vignette on screen edges

Particles wrap at screen boundaries and are re-seeded on type or
resolution change.  Delta time is capped at 50 ms to prevent teleporting
after focus loss.  No heap allocations at runtime (static local arrays).
2026-03-17 16:34:39 -07:00