Add theme-level discovery
A synergy theme counts as explored the first time two different fielded jokers connect it (one gives the tag, one wants it; cluster members carry both sides, so any two qualify). Explored themes persist in config.themes_found, badge their catalog page with "explored!", and feed a per-tab progress line. One toast per emplacement, with famous pairs outranking themes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,12 @@ Three-layer split; `JCA` is the single global namespace:
|
|||||||
`config.discovered` (saved immediately via `SMODS.save_mod_config`) and
|
`config.discovered` (saved immediately via `SMODS.save_mod_config`) and
|
||||||
per-run in `G.GAME.jca_run_combos`. Undiscovered pairs render face-down
|
per-run in `G.GAME.jca_run_combos`. Undiscovered pairs render face-down
|
||||||
with a `???` caption in the Combos tab; blurb replaces it once fielded.
|
with a `???` caption in the Combos tab; blurb replaces it once fielded.
|
||||||
|
Themes (every `theme_info` tag) persist in `config.themes_found` once
|
||||||
|
two DIFFERENT jokers connect the tag (giver + wanter; a joker carrying
|
||||||
|
both sides needs a second joker). One toast per emplacement, famous
|
||||||
|
pair outranking theme. Badge/progress render in `theme_tab_def`; toast
|
||||||
|
names come from `JCA.theme_names` (filled after THEME_TABS, used only
|
||||||
|
at gameplay time).
|
||||||
- Post-run recap: wraps `create_UIBox_game_over`/`create_UIBox_win` and
|
- Post-run recap: wraps `create_UIBox_game_over`/`create_UIBox_win` and
|
||||||
inserts a "Combos fielded this run" row (from `G.GAME.jca_run_combos`)
|
inserts a "Combos fielded this run" row (from `G.GAME.jca_run_combos`)
|
||||||
relative to vanilla button ids (`from_game_over`; `from_game_won` or
|
relative to vanilla button ids (`from_game_over`; `from_game_won` or
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ recommends joker combos while you play:
|
|||||||
"New combo!" toast fires and the pair is permanently inked into the
|
"New combo!" toast fires and the pair is permanently inked into the
|
||||||
catalog — until then its cards sit face-down with a "???" caption, so
|
catalog — until then its cards sit face-down with a "???" caption, so
|
||||||
filling in the Combos tab becomes its own collection hunt.
|
filling in the Combos tab becomes its own collection hunt.
|
||||||
|
- **Theme discovery**: assembling any synergy theme for the first time —
|
||||||
|
one joker that provides it plus another that wants it — fires a
|
||||||
|
"Theme explored!" toast, badges that theme's catalog page, and counts
|
||||||
|
toward a per-tab progress line ("3 of 10 themes explored").
|
||||||
- **Hover a joker you own** to see its active combos with the rest of your
|
- **Hover a joker you own** to see its active combos with the rest of your
|
||||||
lineup.
|
lineup.
|
||||||
- **Browse the synergy catalog** any time: a purple **Combos** button in the
|
- **Browse the synergy catalog** any time: a purple **Combos** button in the
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ return {
|
|||||||
threshold = 4, -- total synergy score needed to recommend a card
|
threshold = 4, -- total synergy score needed to recommend a card
|
||||||
learning_mode = false, -- hide verdicts (pulse, "Strong pick!"), keep reasons
|
learning_mode = false, -- hide verdicts (pulse, "Strong pick!"), keep reasons
|
||||||
discovered = {}, -- famous pairs the player has fielded (pair keys)
|
discovered = {}, -- famous pairs the player has fielded (pair keys)
|
||||||
|
themes_found = {}, -- synergy themes the player has assembled (tags)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ JCA.db = data.jokers
|
|||||||
-- Fallback defaults keep the engine usable outside the game (tests).
|
-- Fallback defaults keep the engine usable outside the game (tests).
|
||||||
JCA.mod = SMODS.current_mod
|
JCA.mod = SMODS.current_mod
|
||||||
JCA.config = SMODS.current_mod and SMODS.current_mod.config
|
JCA.config = SMODS.current_mod and SMODS.current_mod.config
|
||||||
or { pulse = true, owned_tooltip = true, threshold = 4, discovered = {} }
|
or { pulse = true, owned_tooltip = true, threshold = 4,
|
||||||
|
discovered = {}, themes_found = {} }
|
||||||
JCA.config.discovered = JCA.config.discovered or {}
|
JCA.config.discovered = JCA.config.discovered or {}
|
||||||
|
JCA.config.themes_found = JCA.config.themes_found or {}
|
||||||
|
|
||||||
-- Explicit famous pairs, stored under a canonical "a|b" key (a < b).
|
-- Explicit famous pairs, stored under a canonical "a|b" key (a < b).
|
||||||
JCA.pair_list = data.pairs
|
JCA.pair_list = data.pairs
|
||||||
@@ -315,8 +317,43 @@ function JCA.check_discoveries()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- Theme discovery: a theme is explored once two DIFFERENT fielded jokers
|
||||||
|
-- connect it — one gives the tag, another wants it (cluster members do
|
||||||
|
-- both, so any two of them qualify).
|
||||||
|
local new_theme
|
||||||
|
for tag in pairs(data.theme_info or {}) do
|
||||||
|
if not JCA.config.themes_found[tag] then
|
||||||
|
local giver, wanter
|
||||||
|
for idx, k in ipairs(keys) do
|
||||||
|
local e = JCA.db[k]
|
||||||
|
if e then
|
||||||
|
if e.gives[tag] and not giver then giver = idx end
|
||||||
|
if e.wants[tag] and not wanter then wanter = idx end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if giver and wanter and giver == wanter then
|
||||||
|
wanter = nil -- same joker on both sides: find a second one
|
||||||
|
for idx, k in ipairs(keys) do
|
||||||
|
local e = JCA.db[k]
|
||||||
|
if e and idx ~= giver and (e.gives[tag] or e.wants[tag]) then
|
||||||
|
wanter = idx
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if giver and wanter then
|
||||||
|
JCA.config.themes_found[tag] = true
|
||||||
|
new_theme = new_theme or tag
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (new_pair or new_theme) and JCA.mod and SMODS.save_mod_config then
|
||||||
|
SMODS.save_mod_config(JCA.mod)
|
||||||
|
end
|
||||||
|
-- One toast per emplacement; a famous pair outranks a theme (both stay
|
||||||
|
-- recorded either way).
|
||||||
if new_pair then
|
if new_pair then
|
||||||
if JCA.mod and SMODS.save_mod_config then SMODS.save_mod_config(JCA.mod) end
|
|
||||||
pcall(function()
|
pcall(function()
|
||||||
attention_text({
|
attention_text({
|
||||||
text = 'New combo: ' .. new_pair .. '!',
|
text = 'New combo: ' .. new_pair .. '!',
|
||||||
@@ -326,6 +363,18 @@ function JCA.check_discoveries()
|
|||||||
})
|
})
|
||||||
play_sound('card1', 1.1, 0.6)
|
play_sound('card1', 1.1, 0.6)
|
||||||
end)
|
end)
|
||||||
|
elseif new_theme then
|
||||||
|
pcall(function()
|
||||||
|
attention_text({
|
||||||
|
text = 'Theme explored: '
|
||||||
|
.. ((JCA.theme_names and JCA.theme_names[new_theme]) or new_theme)
|
||||||
|
.. '!',
|
||||||
|
scale = 0.7, hold = 4, major = G.play, align = 'cm',
|
||||||
|
offset = {x = 0, y = -3.5}, silent = true,
|
||||||
|
backdrop_colour = G.C.SECONDARY_SET.Planet,
|
||||||
|
})
|
||||||
|
play_sound('card1', 1.1, 0.6)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -463,6 +512,13 @@ local THEME_TABS = {
|
|||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Display names for theme tags (used by the discovery toast, which runs
|
||||||
|
-- before this point in the file but only ever fires during gameplay).
|
||||||
|
JCA.theme_names = {}
|
||||||
|
for _, group in ipairs(THEME_TABS) do
|
||||||
|
for _, t in ipairs(group.themes) do JCA.theme_names[t.tag] = t.name end
|
||||||
|
end
|
||||||
|
|
||||||
-- Joker keys for a tag, split into pure sources (give only), pure payoffs
|
-- Joker keys for a tag, split into pure sources (give only), pure payoffs
|
||||||
-- (want only), and cluster members (both). Sorted by display name.
|
-- (want only), and cluster members (both). Sorted by display name.
|
||||||
local function theme_members(tag)
|
local function theme_members(tag)
|
||||||
@@ -625,10 +681,18 @@ local function theme_tab_def(group, page_no)
|
|||||||
if #both > 0 then groups[#groups + 1] = both end
|
if #both > 0 then groups[#groups + 1] = both end
|
||||||
if #sources > 0 then groups[#groups + 1] = sources; captions = captions + 1 end
|
if #sources > 0 then groups[#groups + 1] = sources; captions = captions + 1 end
|
||||||
if #payoffs > 0 then groups[#groups + 1] = payoffs; captions = captions + 1 end
|
if #payoffs > 0 then groups[#groups + 1] = payoffs; captions = captions + 1 end
|
||||||
local layout = pick_layout(groups, 1 + #blurb_lines + captions)
|
-- +2 text rows: the title and the group progress line above the pager
|
||||||
|
local layout = pick_layout(groups, 2 + #blurb_lines + captions)
|
||||||
|
|
||||||
local nodes = {}
|
local nodes = {}
|
||||||
add_caption(nodes, theme.name)
|
if JCA.config.themes_found[theme.tag] then
|
||||||
|
nodes[#nodes + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.02}, nodes = {
|
||||||
|
{n = G.UIT.T, config = {text = theme.name, colour = G.C.GOLD, scale = 0.3}},
|
||||||
|
{n = G.UIT.T, config = {text = ' explored!', colour = G.C.GREEN, scale = 0.3}},
|
||||||
|
}}
|
||||||
|
else
|
||||||
|
add_caption(nodes, theme.name)
|
||||||
|
end
|
||||||
add_info_rows(nodes, data.theme_info[theme.tag], 70, 0.26)
|
add_info_rows(nodes, data.theme_info[theme.tag], 70, 0.26)
|
||||||
if #both > 0 then
|
if #both > 0 then
|
||||||
add_card_rows(nodes, both, layout.scale, layout.per_row)
|
add_card_rows(nodes, both, layout.scale, layout.per_row)
|
||||||
@@ -641,6 +705,16 @@ local function theme_tab_def(group, page_no)
|
|||||||
add_caption(nodes, 'Payoffs - these want it')
|
add_caption(nodes, 'Payoffs - these want it')
|
||||||
add_card_rows(nodes, payoffs, layout.scale, layout.per_row)
|
add_card_rows(nodes, payoffs, layout.scale, layout.per_row)
|
||||||
end
|
end
|
||||||
|
local explored = 0
|
||||||
|
for _, t in ipairs(group.themes) do
|
||||||
|
if JCA.config.themes_found[t.tag] then explored = explored + 1 end
|
||||||
|
end
|
||||||
|
nodes[#nodes + 1] = {n = G.UIT.R, config = {align = 'cm', padding = 0.02}, nodes = {
|
||||||
|
{n = G.UIT.T, config = {
|
||||||
|
text = ('%d of %d themes explored - field a source and a payoff together')
|
||||||
|
:format(explored, #group.themes),
|
||||||
|
colour = G.C.UI.TEXT_LIGHT, scale = 0.24}},
|
||||||
|
}}
|
||||||
local options = {}
|
local options = {}
|
||||||
for i, t in ipairs(group.themes) do options[i] = t.name end
|
for i, t in ipairs(group.themes) do options[i] = t.name end
|
||||||
nodes[#nodes + 1] = pager_row(options, page_no, 'jca_page_' .. group.label)
|
nodes[#nodes + 1] = pager_row(options, page_no, 'jca_page_' .. group.label)
|
||||||
|
|||||||
Reference in New Issue
Block a user