Public API: JCA.register / register_pair / register_clash

Other mods can teach the advisor their jokers (which otherwise score 0):
JCA.register(key, gives, wants, opts) adds a db entry with tag
validation — unknown tags are dropped with a log line so a typo can't
break anyone's load; opts.no_generic opts out of the mult/xmult
complement. register_pair adds a famous pair (discoverable, shown in
the Combos tab — its sort cache now invalidates via JCA._pairs_dirty)
and warns when a blurb exceeds the 34-char tooltip budget.
register_clash adds a warning-only trap line. Usage example in README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-07-10 14:06:43 -07:00
parent 1d28180db0
commit cbbf9babf5
2 changed files with 81 additions and 1 deletions
+22
View File
@@ -86,6 +86,28 @@ Defaults live in `config.lua`.
`j('j_key', {gives...}, {wants...})`, or add a famous pair to the `PAIRS` `j('j_key', {gives...}, {wants...})`, or add a famous pair to the `PAIRS`
table at the bottom. Modded jokers can be added the same way using their table at the bottom. Modded jokers can be added the same way using their
full key (e.g. `j_mymod_cooljoker`) — unknown jokers simply score 0. full key (e.g. `j_mymod_cooljoker`) — unknown jokers simply score 0.
- **From another mod:** if your mod adds jokers, teach the advisor about
them at load time (any point after Combo Advisor has loaded):
```lua
if JCA then
-- gives/wants use the tag names from synergies.lua
JCA.register('j_mymod_cooljoker', {'xmult'}, {'faces'})
-- optional: opts {no_generic = true} if the generic
-- "+Mult feeds the multiplier" logic misreads your joker
JCA.register('j_mymod_slotless', {'xmult'}, nil, {no_generic = true})
-- famous pair (+4, discoverable, shown in the Combos tab);
-- keep the blurb under ~34 characters
JCA.register_pair('j_mymod_cooljoker', 'j_pareidolia',
'every card becomes a face for it')
-- known trap: warning-only red tooltip line
JCA.register_clash('j_mymod_cooljoker', 'j_vampire',
'drains the enhancements it needs')
end
```
Unknown tags are dropped with a `JCA:` log line instead of erroring, so
a typo in your registration can never break a load.
- **Tune sensitivity:** use the in-game Config tab, or change the defaults - **Tune sensitivity:** use the in-game Config tab, or change the defaults
in `config.lua`. in `config.lua`.
+59 -1
View File
@@ -174,6 +174,63 @@ function JCA.weakest_link()
if worst and worst_total < best_total then return worst end if worst and worst_total < best_total then return worst end
end end
-- Public API for other mods ----------------------------------------------------
-- Lets a mod teach the advisor its own jokers (which otherwise score 0).
-- Call any time after this mod has loaded. Tags must come from the sets in
-- synergies.lua; unknown tags are dropped with a log line rather than
-- crashing someone else's load.
local KNOWN_TAGS = { mult = true, chips = true, xmult = true }
for t in pairs(data.tag_text) do KNOWN_TAGS[t] = true end
local function checked_tag_set(key, list)
local set = {}
for _, t in ipairs(list or {}) do
if KNOWN_TAGS[t] then
set[t] = true
else
print(('JCA: %s: dropping unknown tag %q'):format(key, tostring(t)))
end
end
return set
end
-- gives/wants are arrays of tag names. opts: {no_generic = true} excludes
-- the joker from the generic mult/xmult complement (see Joker Stencil).
-- Re-registering a key overwrites its entry.
function JCA.register(key, gives, wants, opts)
assert(type(key) == 'string' and key ~= '', 'JCA.register: key required')
JCA.db[key] = {
gives = checked_tag_set(key, gives),
wants = checked_tag_set(key, wants),
no_generic = opts and opts.no_generic or nil,
}
end
-- Famous pair: flat +4, shown in the Combos tab, discoverable in play.
-- Keep the blurb under ~34 chars so it fits one tooltip row.
function JCA.register_pair(a, b, blurb)
assert(type(a) == 'string' and type(b) == 'string',
'JCA.register_pair: two joker keys required')
if blurb and #blurb > 34 then
print(('JCA: pair %s|%s blurb exceeds 34 chars, may clip'):format(a, b))
end
local pk = pair_key(a, b)
if not JCA.pair_bonus[pk] then
JCA.pair_list[#JCA.pair_list + 1] = {a, b, blurb}
end
JCA.pair_bonus[pk] = true
JCA.pair_blurb[pk] = blurb
JCA._pairs_dirty = true -- combos tab re-sorts on next open
end
-- Known trap: warning-only red tooltip line, never affects the score.
function JCA.register_clash(a, b, warning)
assert(type(a) == 'string' and type(b) == 'string',
'JCA.register_clash: two joker keys required')
JCA.clash_blurb[pair_key(a, b)] = warning
end
local function in_buy_area(card) local function in_buy_area(card)
return card.area and (card.area == G.shop_jokers or card.area == G.pack_cards) return card.area and (card.area == G.shop_jokers or card.area == G.pack_cards)
end end
@@ -829,7 +886,8 @@ end
local PAIRS_PER_PAGE = 6 local PAIRS_PER_PAGE = 6
local sorted_pairs local sorted_pairs
local function combos_tab_def(page_no) local function combos_tab_def(page_no)
if not sorted_pairs then if not sorted_pairs or JCA._pairs_dirty then
JCA._pairs_dirty = false
sorted_pairs = {} sorted_pairs = {}
for _, p in ipairs(JCA.pair_list) do for _, p in ipairs(JCA.pair_list) do
sorted_pairs[#sorted_pairs + 1] = {p[1], p[2], score = JCA.score(p[1], p[2])} sorted_pairs[#sorted_pairs + 1] = {p[1], p[2], score = JCA.score(p[1], p[2])}