3.1.0
What's new
NARC
3.1.0 (2026-08-19)
Full Changelog Previous Releases
- Attach to RCLootCouncil's windows when it builds them
The links onto RC's own frames never appeared and auto open never fired
once. RCLootCouncil calls SetDefaultModuleState(false) in core.lua, so
neither RCLootFrame nor RCVotingFrame is enabled at login and neither has
built its frame: the loot popup is enabled by the first item that
arrives, the voting frame by the first session. The install polled for
forty seconds from PLAYER_LOGIN and gave up long before either window
existed, so there was nothing to click and no OnShow hook to fire.
Measuring RC's anchor offsets out of its source and then assuming its
frames existed at login was the inconsistency that produced this.
GetFrame is where both frames are born and both assign self.frame before
returning, so a post hook on it lands exactly when RC creates a window,
however much later that is. It also lands when RC creates one again,
which is a real case: RCVotingFrame:OnDisable drops its frame entirely,
so a council member who leaves and rejoins a raid gets a new frame that
needs the link putting back on it. No timeout could have covered that.
The retry now waits for the module tables rather than for their frames,
so it settles in a tick or two instead of running down a clock. L.Install
still runs beside it to cover a reload taken while a window is already
open, where the frame exists and GetFrame will not be called again.
GetFrame is also RC's ordinary accessor and NARC_RC.lua calls it on its
own refresh interval, so the hook returns immediately once the frame
carries the link. The council test that decides whether the link is
visible runs from OnShow, which is the moment it matters.
Bumps the TOC to 3.1.0 for the release.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Say how many answers are still outstanding on the board
A claim is a numbered button press, and P.ClaimIndex answers nil for
every other value RCLootCouncil stores in that field. A candidate who was
still choosing was therefore dropped from the item entirely, which made
an item nobody had answered yet look exactly like an item nobody wanted.
The council had no way to tell the two apart, and P.ClassifyItem files
both as unwanted.
P.ResponseState splits RC's statuses three ways: NOTANNOUNCED, ANNOUNCED
and WAIT mean still deciding; PASS, AUTOPASS and TIMEOUT mean answered;
NOTHING, DISABLED, NOTINRAID, NOTELIGIBLE and REMOVED mean never will.
item.waiting carries the names in the first group, counted against
P.CandidateUsable, which is the same weapon predicate P.BuildClaim
applies to a claimant.
Armour type is deliberately not tested. RC autopasses a class that cannot
wear the piece and that lands as AUTOPASS, already counted as answered,
so testing it again here could only disagree with RC.
Four surfaces, in the order a lead meets them: the item column header
carries the count in amber beside the difficulty, its hover names up to
six of the people, the rail hover carries a WAITING row directly under
CLAIMS because that is the figure which says what "nobody yet" is worth,
and the status line carries the whole clear view.
Surfaced, never enforced. Disconnected and stuck raiders are normal, and
a blanket refusal to stage would block a real clear for a case the master
looter can simply correct, so nothing new gates NarcLootBoardStageUnwanted.
The design doc gains section 1.5b with the status table and says so
explicitly, because the temptation to turn this into a gate is obvious
and wrong.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com - Stop a repaint from eating a note as it is typed
Typing a note on the Loot Sheet during a live clear was impossible. Two
separate causes, both here.
Refresh recycles every row, and ReleaseAll clears and hides the note box
on each one with the busy flag raised. That flag is what suppresses
CommitNote, so a repaint landing mid sentence did not merely take the
focus: it discarded what had been typed rather than sending it.
Refresh now refuses to run at all while a note box holds focus, and
CommitNote and CancelNote run the held repaint the moment the box closes.
ReleaseAll is only ever reached from Refresh, so that seals it against
every source rather than against the one that was noticed.
The second cause is why it happened so often. P.HookVotingFrame hooks
OnResponseReceived and OnChangeResponseReceived, and RCLootCouncil fires
those for EVERY candidate whose answer arrives. On a council member with
the Sheet open, every raider's click was repainting a window that shows
the viewer's own data only. That is also what made it flicker all
evening.
Those hooks are now gated on the two fingerprints the backstop ticker has
always used, factored into P.RefreshIfMoved and shared by both. The gate
is deliberately not applied to every caller: answering RCLootCouncil's
own popup moves nothing either fingerprint watches, because a client with
no voting frame has no candidate row for MyAnswerFor to read, so
P.Schedule takes a force flag and the four callers that change something
no fingerprint covers pass it.
Filtering those hooks by candidate name would have been the obvious
alternative and is a trap: RC strips spaces from the realm in candidate
keys and NARC's playerKey keeps them. The fingerprint route compares no
names at all.
One deliberate behaviour change. A session change while typing used to
discard the note; it now survives and is sent on commit, against the item
the raider was actually looking at when they typed it.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
This mod has no additional files

