diff --git a/CLAUDE.md b/CLAUDE.md index c46e22e..b205c3d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,6 +86,12 @@ Three-layer split; `JCA` is the single global namespace: `config.discovered` (saved immediately via `SMODS.save_mod_config`) and 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. + 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 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 diff --git a/README.md b/README.md index 19788fa..568b004 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ recommends joker combos while you play: "New combo!" toast fires and the pair is permanently inked into the catalog — until then its cards sit face-down with a "???" caption, so 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 lineup. - **Browse the synergy catalog** any time: a purple **Combos** button in the diff --git a/config.lua b/config.lua index cd0c827..1bfe3bf 100644 --- a/config.lua +++ b/config.lua @@ -6,4 +6,5 @@ return { threshold = 4, -- total synergy score needed to recommend a card learning_mode = false, -- hide verdicts (pulse, "Strong pick!"), keep reasons discovered = {}, -- famous pairs the player has fielded (pair keys) + themes_found = {}, -- synergy themes the player has assembled (tags) } diff --git a/main.lua b/main.lua index 891aba4..45ed776 100644 --- a/main.lua +++ b/main.lua @@ -18,8 +18,10 @@ JCA.db = data.jokers -- Fallback defaults keep the engine usable outside the game (tests). JCA.mod = SMODS.current_mod 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.themes_found = JCA.config.themes_found or {} -- Explicit famous pairs, stored under a canonical "a|b" key (a < b). JCA.pair_list = data.pairs @@ -315,8 +317,43 @@ function JCA.check_discoveries() 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 JCA.mod and SMODS.save_mod_config then SMODS.save_mod_config(JCA.mod) end pcall(function() attention_text({ text = 'New combo: ' .. new_pair .. '!', @@ -326,6 +363,18 @@ function JCA.check_discoveries() }) play_sound('card1', 1.1, 0.6) 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 @@ -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 -- (want only), and cluster members (both). Sorted by display name. 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 #sources > 0 then groups[#groups + 1] = sources; 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 = {} - 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) if #both > 0 then 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_card_rows(nodes, payoffs, layout.scale, layout.per_row) 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 = {} 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)