promotional bannermobile promotional banner

CooldownCollaborator

CooldownCollaborator gives your group a live shared view of every major defensive and utility cooldown — who has it, how long until it's back, and whether it's ready to assign.

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.
  • 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)
  • 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