File Details
v1.0.1
- R
- Jun 16, 2026
- 30.49 KB
- 5
- 12.0.7
- Retail
File Name
CooldownCollaborator-v1.0.1.zip
Supported Versions
- 12.0.7
CooldownCollaborator
v1.0.1 (2026-06-16)
Full Changelog Previous Releases
- Update CooldownCollaborator.lua
Updating for 12.0.7 - Update CooldownCollaborator_Mainline.toc
Update for 12.0.0.7 - Update README: fix stale party/raid spellID claim, document tonight's features
- Fix Lane View stacking for non-transitive overlap chains
The original stacking offset just nudged an icon down once per prior
overlapping icon, sequentially by array index. That happens to work for
a single cluster of mutually-overlapping icons, but breaks for a chain
like A-overlaps-B, B-overlaps-C, A-does-not-overlap-C: C would land on
the same level as B (since it only overlapped B, not A) while still
being close enough on the x-axis to visually clip into B. Replaced with
proper greedy bin-packing: each icon picks the lowest vertical level
where it doesn't x-overlap anything already placed there, checked
explicitly rather than inferred from array order.
Not live-tested (requires 3+ simultaneous Battle Rez or Bloodlust
cooldowns at staggered remaining times) - flagging for verification next
session. - Fix Request Rez picking the dead target as their own rez provider
Live test: targeted Fenicia's corpse and got "Fenicia, please Rebirth
Fenicia!" - GetCapabilityStatus's ready-provider list has no concept of
who the target is or whether a candidate is alive, so it happily picked
the corpse itself. Added FindUnitToken(name) to resolve a capability
entry's name back to a live unit token, and skip any candidate who is
the target or who is also currently dead/ghost. - Add raid-lead Request Rez action
Target a dead player and click Rez on the Essentials Bar's Battle Rez
header (or run /cdc rez) to announce who should rez them, naming the
specific provider whose Battle Rez is actually ready right now rather
than a generic call-out. Gated to raid leader/assist (or party leader)
via CC:CanRequestRez() - SendChatMessage to RAID + RAID_WARNING in a
raid, PARTY in a 5-man (no warning channel there). Button only appears
on the Essentials Bar when both a Battle Rez provider exists in the
capability scan and the viewer has permission to send the announcement. - Add roster scan, Essentials Bar, Lane View, and consumable buff tracking
Four roadmap items built together since they share one data model:
Roster.lua: class-based capability scan (CC.roster), populated on group
join/roster change. Knows who CAN provide Bloodlust/Heroism/Time
Warp/Fury of the Aspects or Battle Rez before anyone has cast anything,
which the existing row list cannot show (it only ever displays a spell
once a cast has been observed). Class-only heuristic for v1, not
talent-precise - a future pass could refine with NotifyInspect.
Essentials.lua: slim always-visible frame showing only the roster-scanned
capabilities, with ready/cooldown status per provider. Pure renderer over
GetCapabilityStatus(), no tracking logic of its own. Toggle via /cdc
essentials.
Lanes.lua: alternate renderer over the same capability data, icons
sliding along a bar (0% = just used, 100% = ready) instead of a text row.
Written from scratch for the multiplayer case (several players sharing
one lane) rather than ported from cdtl3-dev/Lanes.lua, which is
single-player and tied to its own AceDB config schema - only the visual
language and basic stacking-offset idea carried over. Toggle via /cdc
lanes.
Consumables.lua: Cauldron/Feast tracking. Structurally different from a
personal CD - it's a shared buff applied to everyone nearby, not
something only the caster has, so no cross-client sync is needed at all.
Detection constraint: aura .name/.spellId are SECRET even on your own
buffs (confirmed by tonight's Eclipse/DoT crashes), so unknown buffs
cannot be auto-discovered - only checked by an ID you already know via
the new /cdc consumable <spellID> <duration> <name> command, polled via
the safe GetPlayerAuraBySpellID(knownID) lookup with rising-edge
detection so an already-active buff does not reset its timer every poll.
Also fixed Options.lua's Default Spells tab filter, which only excluded
.custom entries and would have wrongly listed new .consumable entries
alongside the built-in whitelist. - Fix bogus remaining-time display caused by cross-client clock mismatch
Live test confirmed sync delivery works (result=0), but Fenicia's Barkskin
displayed as 36839:39 remaining on Nelnamara's client. Root cause: GetTime()
is seconds since each client's own process started, not a shared clock.
Sending a raw GetTime() timestamp as usedAt and comparing it against the
receiving client's own GetTime() is meaningless - the two numbers come
from unrelated clocks.
Changed the wire format to send elapsed seconds since cast (secondsAgo)
instead of an absolute timestamp. The receiver re-anchors it to their own
GetTime() on arrival, so every client's state table always uses
locally-consistent timestamps regardless of how many relay hops a sync
message took. - Stop trusting AreOutgoingAddonChatMessagesRestricted, act on send result
Live testing showed it returning true far more often than expected - not
just around death/encounters as documented, blocking every sync send
before it was even attempted. Both test pairs (Nelnamara/Barkskin and
Nelnamara/Fenicia Rebirth) queued and never delivered.
Now attempts the real SendAddonMessage call unconditionally and queues for
retry only based on its actual return code (nil/0 = success, anything else
= queue and retry). Verbose logging now also prints the restriction check's
value alongside the real result so we can see whether they actually agree
or diverge on the next test. - Queue and retry sync messages dropped by addon-message restriction
A Rebirth cast on someone who just died never synced - confirmed by the
sync skipped: addon messages restricted verbose log from the prior fix.
AreOutgoingAddonChatMessagesRestricted() returns true briefly around
death/resurrect, not just boss encounters, and the message was simply
dropped with no retry path.
Added CC.pendingSyncs queue: a restricted send gets queued instead of
dropped, and a 2-second ticker retries the queue as soon as restriction
clears. - Fix crash: party/raid spellID is secret, not just nameplate/target
Live test with a second party member crashed 11x with attempted to index
a table that cannot be indexed with secret keys the instant their cast
fired UNIT_SPELLCAST_SUCCEEDED on this client - spellID is secret for
party/raid tokens too, contrary to the prior assumption (corrected in the
wow-midnight-api memory file). There is no way to read another player's
spellID off this event at all.
Only player gives a safe spellID, so RecordCooldown is now only called
for unitToken == player. Other party/raid members' cooldowns are only
ever populated via the addon-message sync path (OnAddonMessage to
RecordCooldownFromComm), which already only carries data each client
reported about its own safe spellID. Removed the now-unused IsTrackedUnit
helper. - Fix silent sync failure: inEncounter flag could get stuck true forever
SendCooldownSync gated every send on self.inEncounter, which is only ever
reset by ENCOUNTER_END firing. If that event fails to fire cleanly (wipe
edge case, zone transition, disconnect mid-fight) the flag sticks true and
silently blocks all future sync sends for the rest of the session with no
error output - exactly matching the reported symptom of each party member
only ever seeing their own Rebirth cast, never their partners, despite
both having the addon. Removed that gate; the real-time
AreOutgoingAddonChatMessagesRestricted() check is the actual authoritative
signal and does not have this failure mode. Added verbose logging to both
the send and receive paths so any future sync failure is visible instead
of silent. - Fix RegisterUnitEvent overwrite bug - zero cooldowns were ever tracked
RegisterUnitEvent does not accumulate across separate calls for the same
event; each call replaces the prior unit filter. Looping it once per unit
token (player + party1-4 + raid1-40, 45 calls) left the frame listening
only to the last token (raid40), so nothing fired solo or in small groups- confirmed via /cdc verbose producing zero output even for trivial casts.
Switched to a plain RegisterEvent with manual unitToken filtering via the
new CC:IsTrackedUnit helper.
- confirmed via /cdc verbose producing zero output even for trivial casts.
- Replace Blizzard Settings panel with standalone options frame
The Blizzard canvas settings panel is protected UI - it locks the spellbook
regardless of how it is opened (minimap button, slash command, or Escape
menu), and the game menu reappears on close, re-locking it again. Rebuilt
the full options UI as a standalone CCOptionsFrame (movable, Escape-closable
via UISpecialFrames) that opens independently and never touches protected
UI, matching the pattern used by WeakAuras/ArkInventory/MSCT. The Blizzard
AddOns category now just hosts a stub panel with a button that opens the
real frame.
Also added /cdc verbose to log every detected spell cast (known or not) for
diagnosing why cooldowns are not being recorded, and expanded /cdc debug
with group/encounter/filter state. - Fix empty default spell list; add spell name lookup; fix shift-click note
- Hardcode scroll frame height (was using parent:GetHeight() which returns 0
for anchor-sized frames before layout pass, making the list invisible) - Add GetSpellInfo(name) fallback so users can type spell names instead of
only IDs or shift-click links - Update instruction text to explain opening via minimap button for shift-click
(Escape menu blocks the spellbook)
- Hardcode scroll frame height (was using parent:GetHeight() which returns 0
- Fix TabButtonTemplate crash and Settings.OpenToCategory arg
TabButtonTemplate does not exist in Midnight - replaced with BackdropTemplate
frames styled as toggle tabs. OpenToCategory received the category table
instead of an integer; store category.ID at init and pass that instead. - Add two-tab Options panel: Default Spells and Custom Spells
Default Spells tab lists all built-in tracked spells organized by class with
per-spell enable/disable checkboxes that write to db.disabledSpells. Custom
Spells tab retains the shift-click/ID input and remove controls. Display
settings remain above the tabs. RecordCooldown and BuildRowData both skip
spells whose IDs are in disabledSpells. - Fix Settings.OpenToCategory - pass GetID() not the category object
- Add minimap button, in-game options panel, custom spell tracking
- Fix CC global scope - remove local so sub-files can access it
- Set Interface to 120005 for 12.0.5 client compatibility
- Change slash command from /cc to /cdc to avoid conflict

