Skip to content

Failed cast alert - #1204

Open
realCronox wants to merge 2 commits into
EllesmereGaming:mainfrom
realCronox:failed-cast-alert
Open

Failed cast alert#1204
realCronox wants to merge 2 commits into
EllesmereGaming:mainfrom
realCronox:failed-cast-alert

Conversation

@realCronox

@realCronox realCronox commented Aug 5, 2026

Copy link
Copy Markdown

What does this PR do?

Adds an optional Failed Cast Alert to the Quality of Life module: a configurable
sound when an action fails for a positional or targeting reason (no target,
out of range, not facing the target, line of sight, moving while casting).

New section on the QoL page with three settings, off by default:

  • Enable Failed Cast Alert - master toggle, ships off
  • Combat Only - restrict alerts to combat
  • Pick Sound - the shared EUI sound list, default Robot Blip

Matching is deliberately not done on the numeric errorType, which shifts
between patches. Two tiers instead:

  1. errors whose GetGameMessageInfo(errorType) name is already unambiguous
    are matched by that name - ERR_GENERIC_NO_TARGET,
    ERR_SPELL_OUT_OF_RANGE, ERR_BADATTACKFACING, ERR_NO_ATTACK_TARGET;
  2. ERR_SPELL_FAILED_S is a generic carrier for many reasons, so for that one
    the message is compared against a set built from the localized
    SPELL_FAILED_UNIT_NOT_INFRONT, SPELL_FAILED_LINE_OF_SIGHT and
    SPELL_FAILED_MOVING globals.

That makes it both locale-correct and patch-stable. It is a whitelist, so a
failure reason Blizzard adds later is silent rather than making noise at users
who never asked for it. Every global is nil-guarded, and the set is built
lazily on first enable.

Cost when disabled is zero: no frame is created and no event registered until
the feature is switched on. Disabling calls UnregisterAllEvents.

Sound playback reuses the existing EllesmereUI._groupDeathSoundPaths /
_Names / _Order tables and EllesmereUI._PlayLSMSound, rather than
calling the new EllesmereUI.BuildAlertSoundTables(). Reasoning: inside
EllesmereUIQoL those tables are already built once and merged with
SharedMedia once at login, and EllesmereUIQoL_MovementAlert.lua - the
nearest precedent, same module, same shape, its own sound picker - reads
them the same way. Building a second set would add a second SharedMedia
merge pass within one module for no functional gain. Happy to switch it to
the builder if you would rather every consumer be uniform.

Files: two new (EllesmereUIQoL_FailedCastAlert.lua,
EUI_QoL_FailedCastAlert_Options.lua), the .toc entries, and two small
hunks in EUI_QoL_Options.lua (the section call site and the onReset
delegate). Purely additive, no deletions.

The second commit regenerates Locales/_keys.txt. That drift predates this
branch - the feature adds no EllesmereUI.L() literals - but the
locale-check workflow fails any PR touching Lua while it is stale.

How was it tested?

Live retail 8.7.5 and the 12.1 PTR client, both with the module loaded from
this branch.

  • All matched cases triggered in game and confirmed to fire, on PTR as
    well as retail, so 12.1 renames nothing the whitelist depends on. No
    IS_121 branch is needed.
  • Enable, disable and re-enable without reloading; /reload while enabled
    (setting and behaviour persist); /reload while disabled (no frame, no
    events, nothing in BugSack).
  • Combat Only greys out behind the master toggle and gates correctly.
  • Sound picker saves, previews, and survives a reload.
  • QoL reset restores defaults and unregisters the event.

Screenshots

before-fca after-fca-off after-fca-on

Checklist

  • New settings default OFF (no behavior change without opt-in)
  • Zero cost while disabled: no events registered, no polling, no hooks doing work, no frames built
  • Cheap while enabled: event-driven (no polling, no timer-based logic, no per-frame allocations)
  • No writes onto Blizzard-owned frames (weak-table pattern used); HookScript/hooksecurefunc only, never SetScript on Blizzard frames
  • Tested in-game, works on live retail; no load errors on the 12.1 PTR client

In its current state it plays a selectable sound file when a cast
fails due to LoS, positioning, player moving while attempting a cast
that can't be used on the move and similar scenarios. Feature can be
set to alert only in combat, is disabled by default and costs nothing
when disabled. Reuses the functionality already in EUI to manage
sounds etc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant