Point a dead copier at its fix: name the best target one reorder away

JCA.best_copy_target scans the board for copyable jokers (same truth
test as copy_source: blueprint_compat must be true, debuffed excluded,
other copiers excluded) and prefers the ones the database marks
copy_target. When a Blueprint or Brainstorm reports anything but 'ok',
the tooltip now adds the reorder that revives it: 'Fix: slot this just
left of Baron' / 'Fix: make Baron your leftmost joker'. Explanation,
not verdict, so learning mode keeps it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-14 13:42:50 -07:00
parent b81a6c6dcd
commit 665bd9b396
2 changed files with 60 additions and 0 deletions
+36
View File
@@ -421,6 +421,30 @@ local function tag_labels(tag_set)
return labels
end
-- When a copier is copying nothing (or something it cannot use), the fix is a
-- reorder -- so name the best target actually on the board. Copyable means the
-- same thing it means in copy_source: blueprint_compat tested for TRUTH, not
-- debuffed, and not another copier (suggesting a copier would re-ask the same
-- question one slot over). Jokers the database marks copy_target are preferred;
-- the leftmost candidate wins a tie so the suggestion is stable across hovers.
-- Returns the card and whether it carried the copy_target tag.
function JCA.best_copy_target(copier)
if not (G.jokers and G.jokers.cards) then return nil end
local best, best_prime
for _, c in ipairs(G.jokers.cards) do
if c ~= copier and is_joker(c) and not c.debuff
and not COPIERS[c.config.center.key]
and c.config.center.blueprint_compat then
local entry = JCA.db[c.config.center.key]
local prime = not not (entry and entry.gives.copy_target)
if not best or (prime and not best_prime) then
best, best_prime = c, prime
end
end
end
return best, best_prime
end
-- Build gaps: what the current board is shopping for. A tag is a gap when
-- some owned joker wants it and no OTHER owned joker gives it (same rule as
-- scoring and theme discovery: a joker cannot feed itself). The reverse -- a
@@ -574,6 +598,18 @@ local function tooltip_rows(card)
and 'Copying nothing - it IS the leftmost joker'
or 'Copying nothing - no joker to its right', G.C.RED)
end
-- A dead copier usually has a live fix one reorder away. This is
-- an explanation of the mechanic, so learning mode keeps it.
if status ~= 'ok' then
local best = JCA.best_copy_target(card)
if best then
local bname = name_of(best.config.center.key)
text_row(key == 'j_brainstorm'
and ('Fix: make ' .. bname .. ' your leftmost joker')
or ('Fix: slot this just left of ' .. bname), G.C.GREEN)
end
end
end
-- Ceremonial Dagger. This one is about to eat a joker, permanently, at the