File Details
EnemyList 1.8.185.zip
- R
- May 21, 2026
- 356.89 KB
- 42
- 2.5.5
- Classic TBC
File Name
EnemyList 1.8.185.zip
Supported Versions
- 2.5.5
[1.8.185]
Changed — new shipped defaults
User supplied an EL1! share-string of their preferred configuration; merged into the central defaults table at the top of EnemyListUI.lua and embedded as the Default preset's encoded field in EnemyListPresets.lua. Fresh installs now boot into this configuration; users who run /el preset default get the same state.
Highlights of the new defaults (compared to the previous):
- Compact single-column rows by default (
compactRow = true,singleColumn = true). - Aggro/other rows capped at 2 each so the list is short by default (was 10).
- Party frames on by default with vertical orientation, role icon, incoming heals, incoming rez, player buffs, low-HP / low-mana flash, debuff strip, and HP-deficit text all enabled.
- HP bar on the left, mana bar on the right of party frames (vertical layout).
- Unit name shown centered with -1/-10 offset and 0.6 font scale (small, mid-frame label).
- Aggro count digit offset to -5 / -14 with a magenta-ish color (1, 0, 0.251) for visibility against the bar fill.
- Nameplate list mirror on, threat overlay off (mirror is the bigger feature; threat color is opt-in).
- Nameplate "2nd on threat" distinct color on.
- Runner-up threat bar on with 2 slots (was off).
- Predictive damage bar mode with 65 % alpha, height 8, position "left", bar color overridden to black so the segment reads as a "shadow" rather than competing with the HP fill.
predictiveShowPartyText = false(visual only, no minus-number text).
Position state (x, y, point, relPoint, minimapButtonAngle) intentionally kept neutral in both the central defaults and the Default preset — applying the preset on another character won't teleport the frame to the source character's coordinates.
EXPORT_SKIP updated to filter x, y, point, relPoint, minimapButtonAngle so any future /el export / share-string round-trip strips position state too.
Fixed — Profiles tab no scrollbar with many entries
The Profiles tab scroll-child used a static baseH = 260 estimate for content above the saved-profiles list. The actual content (title + intro + active label + group line + auto-switch + 4 buttons in 2 rows + saved header + saved hint + save-row) is closer to 330 px — so scroll-child height undercounted by ~70 px and the bottom of the cross-character snapshot list got clipped below the scrollable region (the scrollbar appeared to "stop early" because there was no scroll target beyond the calculated bottom).
Two-stage fix:
- Estimate refined:
baseHis now measured fromsaveRow's actual on-screenGetTop()relative toscrollChild5's top, with a 330 px conservative fallback if positions aren't ready yet. - Post-layout measurement:
refreshCrossCharRowsnow applies the estimate immediately (so the scrollbar isn't zero between frames), then schedules aC_Timer.After(0, ...)callback that walks every visible child ofscrollChild5, finds the lowest pixel any of them occupies, and sets the scroll-child height to span + 40 px bottom padding. Robust to any future additions to the tab — no more guess-and-pray height math.
[1.8.184]
Diagnostic — settings revert on /reload
User reported "checkbox settings revert every /reload" (specifically the role-icon checkbox on the Party tab). Code review found no obvious bug — every write path I traced should persist correctly through SavedVariables. To make the next round of debugging tractable, this release adds a diagnostic command + a defensive guard.
/el debugsave (new diagnostic command)
Prints the current saved-state of EnemyListDB to chat so you can see exactly what's in memory:
activeProfileNamevalue.- Whether
profilestable exists. - Whether
profiles[active]slot exists. - For ~15 common boolean settings: top-level value, profile-slot value, and whether they match.
Run it before toggling a setting, after toggling, and after /reload — comparing the three outputs will pinpoint whether the issue is:
- The write didn't happen (top-level still false after toggle),
- The save didn't persist (was true after toggle, nil after reload),
- A profile-load is wiping the change (top-level true after toggle, profile-slot still false, profile-load runs at reload and uses stale slot).
Defensive guard in profileWrite
Added a safety hatch: if a profileWrite updates an inactive profile's slot and the matching top-level value is nil, seed top-level from the active profile's slot so a subsequent save doesn't write nil for a key the user set. This is a no-op in the common case; it only kicks in when the write paths and active-profile state are out of sync (a class of corner case that's hard to repro from the code alone).
How to use
If the user can reproduce the revert, the most useful followup is to run /el debugsave at three points and paste the chat output:
- Right after toggling the offending setting (before any /reload).
- Right after the next /reload (before touching anything).
- After re-opening the config window (to see what state the widget read).
That sequence will tell us exactly which step is dropping the value, and the fix becomes targeted instead of speculative.
[1.8.183]
Added — share-by-string + built-in starter presets
Three intertwined features in one release.
1. Import / export share-strings
- New format
EL1!<base64-of-lua-source>— chat-pasteable, no special-character issues. - Encoded with a deterministic Lua-table serializer (stable key order, no functions / userdata) so the same settings always produce the same string.
- Decoded via sandboxed
loadstring+ empty environment (no global access; can't call functions or touch the filesystem). Returns(table, nil)on success or(nil, err)on failure. EnemyList.Presets.Apply(t)writes the decoded table ontoEnemyListDB(respecting the export skip-set so user positions / per-character flags / debug state / profile machinery are never trampled) and cascades every relevant live-refresh helper so the UI updates without a reload.
2. Built-in starter presets
- New module file
EnemyListPresets.lua. Ships with five starters: Default, Healer, Tank, DPS, Minimal. Each entry is just{ id, name, description, settings = { … } }— adding a preset is a single table entry. - Entries can also use
encoded = "EL1!…"instead of a rawsettingstable. The author can mass-add presets by chat-pasting their/el exportstring into a newencoded =field. EnemyList.Presets.GetById(id)resolves either form (decodes lazily, caches the result).
3. New Presets config tab (#12)
- New file
EnemyListConfigTabPresets.luaadds tab Presets to the config window's nav. - Layout: title + description, Built-in presets list (one row per preset with name + description + Apply button), Import section (multi-line scroll edit-box → Apply pasted button + status text), Export section (Generate button fills an edit-box you can select-all + copy).
- Apply asks for confirmation via
StaticPopupso a misclick doesn't nuke the user's tuning.
Added — setup wizard quick-start preset row
- New section on page 1 of the setup wizard between "Copy from another character" and the layout chooser. Up to 5 compact preset buttons (one per built-in preset) with hover-tooltips showing the preset's description. Click → apply → refresh every wizard widget so the user can preview before committing.
- Frame height grew 620 → 680 px to fit the new row.
Added — slash commands
/el export— prints current settings as anEL1!string (chat-copyable)./el exportlua— prints current settings as a raw Lua-table source. Used for adding new built-in presets to the file: configure the addon however you like, run/el exportlua, paste the chat output into a newBUILTIN[#BUILTIN + 1] = { id = "...", name = "...", description = "...", settings = <paste here> }entry. Same form is paste-able into the centraldefaultstable if the author wants to ship updated defaults./el import <EL1!...>— applies a share-string in-place from chat./el preset <id>— applies a built-in preset by id./el presetor/el preset listshows the available ids.
Locale
- 23 new strings — tab title, section headers / hints, every confirmation / status message, slash-command hints, wizard preset header / hint.
Implementation
- All persistence goes through the existing
EnemyListDB+EnemyListDB.profiles[activeProfileName]writes, so a preset survives the next auto-switch between Party / Raid. - Decoder uses
setfenv(fn, {})so a malicious string can't read globals or call functions. Worst case a hostile string can construct a (huge) table to DoS the client; same threat surface as every other share-string addon (WeakAuras, ElvUI profiles, etc.). - Configurable export filter (
EXPORT_SKIP) so user-positioning data (window XY, frame width/height), per-character flags (setupWizardCompleted,testMode,minimapButtonHidden), debug state, and the recursiveprofilestable are never included. gridLayoutIS exported (it's a layout setting, not state) so preset authors can ship a custom grid-element arrangement as part of a preset.
For future maintenance
To update the default settings later: configure the addon how you want defaults to be, run /el exportlua in chat, copy the printed table, and either:
- Replace the
settings = { }block in the "Default" preset entry inEnemyListPresets.lua(recommended — keeps the addon's centraldefaultsclean and gives users a one-click "factory reset" path), or - Paste each key-value into the central
defaults = { ... }table at the top ofEnemyListUI.luaif you want them to be the hard-coded defaults for fresh installs that don't run the setup wizard.

