diff --git a/main.lua b/main.lua index 083f2c0..d78da90 100644 --- a/main.lua +++ b/main.lua @@ -13,6 +13,7 @@ end local data = assert(SMODS.load_file('synergies.lua'))() JCA.db = data.jokers +JCA.scalers = data.scalers -- Settings from config.lua, persisted by Steamodded across sessions. -- Fallback defaults keep the engine usable outside the game (tests). @@ -331,6 +332,24 @@ function JCA.is_rental(card) return not not (card.ability and card.ability.rental) end +-- Sticker traps on a specific shop card, as caution strings. Per-instance, +-- unlike JCA.cautions (which warns about the joker itself): the same joker is +-- a fine buy without the sticker. Perishable debuffs for good after +-- G.GAME.perishable_rounds (card.lua:2652); rental charges rental_rate ($3) +-- every round (card.lua:2647), which can eat a money joker's whole payout. +function JCA.sticker_cautions(card) + local out = {} + local key = card.config and card.config.center and card.config.center.key + local a = card.ability or {} + if a.perishable and key and JCA.scalers[key] then + out[#out + 1] = 'perishable: gains die in 5 rounds' + end + if a.rental and key and JCA.db[key] and JCA.db[key].gives.money then + out[#out + 1] = 'rental: rent may eat its payout' + end + return out +end + function JCA.is_perished(card) local a = card.ability return not not (a and a.perishable and (a.perish_tally or 0) <= 0) @@ -732,6 +751,11 @@ local function tooltip_rows(card) end local caution = in_buy_area(card) and JCA.cautions[key] if caution then text_row('Caution: ' .. caution, G.C.RED) end + if in_buy_area(card) then + for _, warn in ipairs(JCA.sticker_cautions(card)) do + text_row('Caution: ' .. warn, G.C.RED) + end + end -- Copiers in the shop: a purchase always lands rightmost (see -- copy_source_if_bought), so say what THIS board hands the copier the diff --git a/synergies.lua b/synergies.lua index 85e126f..83b80e8 100644 --- a/synergies.lua +++ b/synergies.lua @@ -354,6 +354,21 @@ local CAUTIONS = { j_gros_michel = '1 in 6 to self-destruct each round', } +-- Jokers whose stored ability values grow across rounds (Ride the Bus's Mult, +-- Hologram's xMult...). A PERISHABLE copy of one of these is a trap the card +-- text hides: perishable debuffs the joker for good after 5 rounds +-- (Card:calculate_perishable, card.lua:2652 -> set_debuff), so every round +-- spent growing it is investment about to be wiped. Computed jokers (Bull +-- reads your money, Abstract counts jokers) are excluded -- they lose nothing +-- stored -- as are round-scoped ones (Hit the Road resets each round) and +-- Egg, whose sell value survives a debuff. +local SCALERS = { + 'j_ride_the_bus', 'j_green_joker', 'j_obelisk', 'j_hologram', + 'j_constellation', 'j_campfire', 'j_vampire', 'j_lucky_cat', 'j_caino', + 'j_yorick', 'j_glass', 'j_flash', 'j_red_card', 'j_madness', 'j_trousers', + 'j_wee', 'j_square', 'j_runner', 'j_ceremonial', 'j_castle', +} + -- How to phrase a tag link in the tooltip, from the partner's perspective: -- `give` when the partner provides the tag, `want` when the partner consumes -- it, `both` for cluster tags where the pair simply shares the theme. @@ -471,5 +486,9 @@ for _, entry in pairs(J) do entry.gives, entry.wants = g, w end +local SCALER_SET = {} +for _, k in ipairs(SCALERS) do SCALER_SET[k] = true end + return { jokers = J, pairs = PAIRS, clashes = CLASHES, cautions = CAUTIONS, + scalers = SCALER_SET, tag_text = TAG_TEXT, tag_order = TAG_ORDER, theme_info = THEME_INFO } diff --git a/test.lua b/test.lua index 7756828..89c711d 100644 --- a/test.lua +++ b/test.lua @@ -658,6 +658,32 @@ eq(JCA.consumable_partners(consumable('Booster', 'Buffoon')), nil, eq(JCA.consumable_partners({config = {center = {set = 'Voucher'}}}), nil, 'a Voucher yields no consumable advice') +-------------------------------------------------------------------------------- +section('Engine: sticker cautions are per-instance, not per-joker') +-------------------------------------------------------------------------------- + +-- Every scaler is a real joker; a typo here would silently disarm the caution. +for k in pairs(JCA.scalers) do + ok(JCA.db[k] ~= nil, 'scaler ' .. k .. ' exists in the database') +end + +local function stickered(key, ability) + return {config = {center = {key = key}}, ability = ability} +end + +eq(#JCA.sticker_cautions(stickered('j_ride_the_bus', {perishable = true})), 1, + 'a perishable scaler earns a caution') +eq(#JCA.sticker_cautions(stickered('j_golden', {perishable = true})), 0, + 'a perishable static joker loses nothing stored - no caution') +eq(#JCA.sticker_cautions(stickered('j_golden', {rental = true})), 1, + 'a rental money joker earns a caution (rent can eat the payout)') +eq(#JCA.sticker_cautions(stickered('j_baron', {rental = true})), 0, + 'a rental non-money joker is just a cheap joker - no caution') +eq(#JCA.sticker_cautions(stickered('j_ride_the_bus', {})), 0, + 'no sticker, no caution') +eq(#JCA.sticker_cautions(stickered('j_mod_unknown', {perishable = true, rental = true})), 0, + 'unknown keys never warn and never error') + -------------------------------------------------------------------------------- section('Data: themes are reachable') --------------------------------------------------------------------------------