Stop giving advice the game will not let you follow

Four fixes, all traced to the running source.

* The sell advisor could tell you to sell an ETERNAL joker, which
  Card:can_sell_card refuses outright (card.lua:1993). It now never names
  one, though they still count toward the best score -- they are part of
  the build you are keeping. Advice you cannot take is worse than none.

* Copiers CHAIN. SMODS.blueprint_effect recurses (utils.lua:2269) and
  Blueprint's own blueprint_compat is true, so Blueprint -> Blueprint ->
  Baron really does give two Barons. The tooltip used to answer "Copying
  Blueprint", the one reply that helps nobody; it now walks the chain to
  the joker actually copied and shows the route. Capped at the board size
  like vanilla, and a Blueprint/Brainstorm ring resolves to nothing
  instead of hanging.

* blueprint_compat is tested for TRUTH by vanilla (utils.lua:2254), not
  for `~= false` as I had it. A modded joker that simply omits the flag is
  NOT copyable, and this mod supports other mods' jokers by design, so
  saying otherwise was a lie about someone else's content.

* A debuffed joker copies as nothing (same line), and a debuffed joker
  does nothing at all this blind -- both now say so. Scoring is left
  alone: a debuff is temporary and the advisor advises on the build, so
  hiding a debuffed partner from "Active combos" would misrepresent it.

Also: never call SMODS.is_eternal() from an advisor path. It runs a full
SMODS.calculate_context per call (utils.lua:3079) -- far too heavy for a
hover -- and outside a live run it reported EVERY joker as Eternal, which
silently disabled the sell advisor. The smoke harness caught that; the
stub could not have.

721 pass locally, 12 in-game.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-14 12:50:47 -07:00
parent 8ce5619273
commit de67970a15
3 changed files with 165 additions and 49 deletions
+21 -8
View File
@@ -115,14 +115,27 @@ Three-layer split; `JCA` is the single global namespace:
another one's payoff is the one you want to cut. This is the **only**
place a clash changes a number; `JCA.score` stays pure, because a trap
must never make a card look like a combo.
- Copy advisor: `JCA.copy_source(card)` returns what an owned Blueprint or
Brainstorm is *actually* copying, from the live board order — Blueprint
takes the joker to its right, Brainstorm the leftmost — plus whether
vanilla will copy it at all (29 centers carry `blueprint_compat = false`).
The tooltip names the target, or says it is copying nothing. Do not
rebuild this with the `a and b or c` idiom: for a rightmost Blueprint the
right-hand slot is nil and the idiom falls through to the leftmost joker,
confidently reporting the wrong card.
- Copy advisor: `JCA.copy_source(card)` `target, status, chain`. Reports what
an owned Blueprint/Brainstorm is *actually* copying, from the live board order
(Blueprint takes the joker to its right, Brainstorm the leftmost). Copiers
**chain**`SMODS.blueprint_effect` recurses (`utils.lua:2269`) and
Blueprint's own `blueprint_compat` is true, so Blueprint→Blueprint→Baron
really gives two Barons; the chain is walked to the joker actually copied,
capped at the board size like vanilla, and a copier ring yields nothing.
`status` is `ok`/`none`/`incompatible`/`debuffed`. Test `blueprint_compat`
for **truth**, not `~= false` — vanilla does (`utils.lua:2254`), so a modded
joker that omits the flag is *not* copyable. A debuffed target copies as
nothing. Do not rebuild the neighbour lookup with the `a and b or c` idiom:
for a rightmost Blueprint the right-hand slot is nil and the idiom falls
through to the leftmost joker, confidently reporting the wrong card.
- `JCA.is_eternal(card)` reads `card.ability.eternal` — the flag vanilla itself
uses for the badge (`card.lua:1141`). **Never call `SMODS.is_eternal()` from
an advisor path**: it runs a full `SMODS.calculate_context` per call
(`utils.lua:3079`), far too heavy for a hover, and outside a live run it
reported *every* joker as Eternal, silently disabling the sell advisor.
Eternal jokers cannot be sold at all (`Card:can_sell_card`, `card.lua:1993`),
so `weakest_link` never names one — advice you are not allowed to take is
worse than none — though they still count toward the best score.
- Public API for other mods: `JCA.register(key, gives, wants, opts)`,
`JCA.register_pair(a, b, blurb)` (sets `JCA._pairs_dirty` so the
Combos tab re-sorts), `JCA.register_clash(a, b, warning)`. Unknown