Commit graph

726 commits

Author SHA1 Message Date
Kelsi
fd7886f4ce feat: show NPC subtitle on nameplates
Display creature subtitles (e.g. <Reagent Vendor>, <Innkeeper>) below
NPC names on nameplates, mirroring the guild tag display for players.
The subtitle is fetched from the creature info cache populated by
SMSG_CREATURE_QUERY_RESPONSE.
2026-03-18 10:05:49 -07:00
Kelsi
209f60031e feat: respect loot roll voteMask for button visibility
Store the voteMask from SMSG_LOOT_START_ROLL and use it to conditionally
show Need/Greed/Disenchant/Pass buttons. Previously all four buttons were
always shown regardless of the server's allowed roll types.
2026-03-18 10:01:53 -07:00
Kelsi
63b4394e3e feat: world-space floating combat text above entities
Combat text (damage, heals, misses, crits, etc.) now floats above the
target entity in 3D space instead of appearing at fixed screen positions.
Text rises upward from the entity's head, with random horizontal stagger
to prevent stacking. HUD-only types (XP, Honor, Procs) and entries
without a valid entity anchor fall back to the original screen overlay.
2026-03-18 09:54:52 -07:00
Kelsi
6aea48aea9 feat: show guild name on target frame for players
Display <GuildName> below the player name in the target frame,
using the same guild name cache as nameplates.
2026-03-18 09:48:03 -07:00
Kelsi
e572cdfb4a feat: show guild names on player nameplates
Read PLAYER_GUILDID from entity update fields (UNIT_END + 3) and query
guild names via CMSG_GUILD_QUERY. Cache results in guildNameCache_ so
each guild ID is queried only once. Display <Guild Name> in grey below
the player name on nameplates. Fix handleGuildQueryResponse to not
overwrite the local player's guild data when querying other guilds.
2026-03-18 09:44:43 -07:00
Kelsi
8b7786f2b3 feat: display combo points on target frame
Add 5-dot combo point indicator between target power bar and cast bar.
Lit dots are yellow (1-4 CP) or red (5 CP) with glow effect; unlit
dots show as dark outlines. Only visible when the player's combo target
matches the current target.
2026-03-18 09:08:46 -07:00
Kelsi
f8f514d28c fix: add $C (class) and $R (race) quest text placeholders
Quest dialogs were showing literal "$C" instead of the player's class
name. Added support for $c/$C (class) and $r/$R (race) placeholders
in both game_screen and quest_log_screen substitution functions.
2026-03-18 06:49:37 -07:00
Kelsi
fabcde42a5 fix: clarify death dialog — auto-release label and resurrection hint
'Release in X:XX' implied a client-enforced forced release; renamed to
'Auto-release in X:XX' (server-driven) and added 'Or wait for a player
to resurrect you.' hint so players know they can stay dead without
clicking Release Spirit.
2026-03-18 05:39:42 -07:00
Kelsi
d0f544395e feat: add mounted/group/channeling/casting/vehicle macro conditionals
Extends evaluateMacroConditionals() with [mounted], [nomounted],
[group], [nogroup], [raid], [channeling], [nochanneling],
[channeling:SpellName], [casting], [nocasting], [vehicle], [novehicle].
2026-03-18 05:23:32 -07:00
Kelsi
4e13a344e8 feat: add buff:/nobuff:/debuff:/nodebuff: macro conditionals
Macro conditions now support checking aura presence:
  [buff:Power Word: Fortitude]  — player has the named buff
  [nobuff:Frost Armor]          — player does NOT have the named buff
  [debuff:Faerie Fire]          — target has the named debuff
  [nodebuff:Hunter's Mark]      — target does NOT have the named debuff

Name matching is case-insensitive. When a target override (@target etc.)
is active the check uses that unit's aura list instead of the player's.
2026-03-18 05:20:15 -07:00
Kelsi
a802e05091 feat: add /mark slash command for setting raid target icons
Adds /mark [icon], /marktarget, and /raidtarget slash commands that
set a raid mark on the current target. Accepts icon names (star,
circle, diamond, triangle, moon, square, cross, skull), numbers 1-8,
or "clear"/"none" to remove the mark. Defaults to skull when no
argument is given.
2026-03-18 05:16:14 -07:00
Kelsi
e7fe35c1f9 feat: add right-click pet spell autocast toggle via CMSG_PET_SPELL_AUTOCAST
Right-clicking a castable pet ability (actionId > 6) in the pet action
bar now sends CMSG_PET_SPELL_AUTOCAST to toggle the spell's autocast
state. The local petAutocastSpells_ set is updated optimistically and
the tooltip shows the current state with a right-click hint.
2026-03-18 05:08:10 -07:00
Kelsi
5f3bc79653 feat: show queued spell icon in cast bar and expose getQueuedSpellId()
When a spell is queued in the 400ms window before the current cast ends,
render its icon dimmed (0.8 alpha) to the right of the cast bar progress,
with a "Queued: <name>" tooltip. The progress bar shrinks to accommodate
the icon when one is present.

Also exposes getQueuedSpellId() as a public const accessor on GameHandler
so the UI can observe the spell queue state without friend access.
2026-03-18 04:34:36 -07:00
Kelsi
277a26b351 feat: flash action bar button red when spell cast fails
Add SpellCastFailedCallback to GameHandler, fired from SMSG_CAST_RESULT
when result != 0. GameScreen registers the callback and records each failed
spellId in actionFlashEndTimes_ (keyed by spell ID, value = expiry time).

During action bar rendering, if a slot's spell has an active flash entry,
an AddRectFilled overlay is drawn over the button with alpha proportional
to remaining time (1.0→0.0 over 0.5 s), giving the same error-red flash
visual feedback as the original WoW client.
2026-03-18 04:30:33 -07:00
Kelsi
09b0bea981 feat: add /stopmacro support and low durability warning for equipped items
- /stopmacro [conditions] halts remaining macro commands; supports all existing
  macro conditionals ([combat], [nocombat], [mod:shift], etc.) via the sentinel
  action trick on evaluateMacroConditionals
- macroStopped_ flag in GameScreen; executeMacroText resets and checks it after
  each command so /stopmacro mid-macro skips all subsequent lines
- Emit a "X is about to break!" UI error + system chat when an equipped item's
  durability drops below 20% via SMSG_UPDATE_OBJECT field delta; warning fires
  once per threshold crossing (prevDur >= maxDur/5, newDur < maxDur/5)
2026-03-18 04:14:44 -07:00
Kelsi
167e710f92 feat: add /equipset macro command for saved equipment set switching
/equipset <name> equips a saved set by case-insensitive prefix match;
/equipset with no argument lists available sets in chat.
2026-03-18 03:53:59 -07:00
Kelsi
4025e6576c feat: implement /castsequence macro command
Supports: /castsequence [conds] [reset=N/target/combat] Spell1, Spell2, ...
Cycles through the spell list on successive button presses. State is keyed
by spell list so the same sequence shared across macros stays in sync.
2026-03-18 03:36:05 -07:00
Kelsi
df7150503b feat: /assist now accepts name and macro conditional arguments
/assist TankName targets whoever TankName is targeting; /assist [target=focus]
assists your focus target. Mirrors /target and /focus conditional support.
2026-03-18 03:31:40 -07:00
Kelsi
5d4b0b0f04 feat: show target-of-focus with health bar in focus frame
Healers and tanks can now see who their focus target is targeting,
with a compact percentage health bar — mirrors the ToT in the target frame.
2026-03-18 03:29:48 -07:00
Kelsi
a151531a2a feat: show health bar on target-of-target in target frame
The ToT health bar gives healers immediate % health readout of whoever
the target is attacking, without needing to click-through to that unit.
2026-03-18 03:28:06 -07:00
Kelsi
11c07f19cb feat: add macro conditional support to /cleartarget and /startattack
/cleartarget [dead] now clears target only when it meets conditions;
/startattack [harm,nodead] respects conditionals including target=mouseover.
2026-03-18 03:25:34 -07:00
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
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
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
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