b88fd0ea07
Card Sharp's x3 needs the same hand twice in ONE round -- it checks played_this_round > 1 (card.lua:4465) and that counter resets each round (state_events.lua:252). Burglar's +3 hands makes the replay routine, so it gets the famous pair plus a hands_up want, same shape as Burglar + Acrobat. The old verdict rejecting the Obelisk clash stands; the audit entry now records both decisions. Troubadour and Merry Andy join the cautions: their buried costs (one fewer hand every round, one hand size) are the same shape as Stuntman's existing warning. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
476 lines
30 KiB
Lua
476 lines
30 KiB
Lua
--- Synergy database for Joker Combo Advisor.
|
|
--- Each joker lists tags it GIVES (capabilities it adds to a build) and tags
|
|
--- it WANTS (capabilities that make it stronger). The scorer matches one
|
|
--- joker's gives against another's wants, in both directions.
|
|
---
|
|
--- Tag glossary:
|
|
--- mult / chips / xmult engine roles (also used for the generic
|
|
--- "scaler + multiplier" complement rule)
|
|
--- money earns money; money = wants money (econ payoffs)
|
|
--- faces makes cards count as face cards / wants face cards
|
|
--- retrig_scoring retriggers (or multiplies triggers of) ANY played
|
|
--- card -- reserve it for rank-agnostic retriggerers
|
|
--- retrig_low / retrig_faces rank-limited retriggers (Hack's 2s-5s, Sock
|
|
--- and Buskin's faces); wanted only by payoffs those
|
|
--- ranks can reach, so Hack never claims to feed a
|
|
--- face payoff like Business Card
|
|
--- retrig_held retriggers cards held in hand
|
|
--- hand_size / hands_up / discards_up resource increases
|
|
--- probability improves listed probabilities / cares about them
|
|
--- tarot_gen / spectral_gen / planet consumable economies
|
|
--- stone_gen / gold_gen / enhance_gen / card_gen deck modification
|
|
--- joker_gen / sell_value sell-fodder economies
|
|
--- copy_target a strong effect worth copying (for Blueprint et al.)
|
|
--- pair, two_pair, three_kind, four_kind, straight, flush hand-type
|
|
--- clusters (jokers keying the same hand reinforce
|
|
--- each other; enablers like Four Fingers give these)
|
|
--- hearts, diamonds, spades, clubs, suit_flex suit clusters
|
|
---
|
|
--- Jokers not in this table (e.g. from other mods) simply score 0.
|
|
|
|
local J = {}
|
|
local function j(key, gives, wants, opts)
|
|
J[key] = { gives = gives or {}, wants = wants or {},
|
|
no_generic = opts and opts.no_generic or nil }
|
|
end
|
|
|
|
-- Common jokers ------------------------------------------------------------
|
|
j('j_joker', {'mult'})
|
|
j('j_greedy_joker', {'mult','diamonds'}, {'diamonds','suit_flex'})
|
|
j('j_lusty_joker', {'mult','hearts'}, {'hearts','suit_flex'})
|
|
j('j_wrathful_joker', {'mult','spades'}, {'spades','suit_flex'})
|
|
j('j_gluttenous_joker', {'mult','clubs'}, {'clubs','suit_flex'})
|
|
j('j_jolly', {'mult','pair'}, {'pair'})
|
|
j('j_zany', {'mult','three_kind'}, {'three_kind'})
|
|
j('j_mad', {'mult','two_pair'}, {'two_pair'})
|
|
j('j_crazy', {'mult','straight'}, {'straight'})
|
|
j('j_droll', {'mult','flush'}, {'flush'})
|
|
j('j_sly', {'chips','pair'}, {'pair'})
|
|
j('j_wily', {'chips','three_kind'}, {'three_kind'})
|
|
j('j_clever', {'chips','two_pair'}, {'two_pair'})
|
|
j('j_devious', {'chips','straight'}, {'straight'})
|
|
j('j_crafty', {'chips','flush'}, {'flush'})
|
|
j('j_half', {'mult'})
|
|
j('j_credit_card', {})
|
|
j('j_banner', {'chips'}, {'discards_up'})
|
|
j('j_mystic_summit', {'mult'})
|
|
j('j_8_ball', {'tarot_gen'}, {'probability','retrig_scoring'})
|
|
j('j_misprint', {'mult'})
|
|
j('j_raised_fist', {'mult'}, {'retrig_held','hand_size'})
|
|
j('j_chaos', {})
|
|
j('j_scary_face', {'chips'}, {'faces','retrig_scoring','retrig_faces'})
|
|
-- Abstract Joker's Mult is the joker count (`#G.jokers.cards`, card.lua:4119), so
|
|
-- anything that hands you spare Jokers feeds it. Riff-Raff is +6 Mult on its own.
|
|
j('j_abstract', {'mult'}, {'joker_gen'})
|
|
j('j_delayed_grat', {'money'}, {'discards_up'})
|
|
j('j_gros_michel', {'mult'})
|
|
j('j_even_steven', {'mult'}, {'retrig_scoring','retrig_low'})
|
|
j('j_odd_todd', {'chips'}, {'retrig_scoring','retrig_low'})
|
|
j('j_scholar', {'chips','mult'}, {'retrig_scoring'})
|
|
j('j_business', {'money'}, {'faces','probability','retrig_scoring','retrig_faces'})
|
|
j('j_supernova', {'mult'})
|
|
j('j_ride_the_bus', {'mult'})
|
|
j('j_egg', {'sell_value'})
|
|
j('j_runner', {'chips','straight'}, {'straight'})
|
|
j('j_ice_cream', {'chips'})
|
|
j('j_splash', {'retrig_scoring'}) -- makes every played card score
|
|
-- Blue Joker's Chips scale with the cards left in the deck (`#G.deck.cards`,
|
|
-- card.lua:4311), so every joker that permanently adds cards grows it.
|
|
j('j_blue_joker', {'chips'}, {'card_gen'})
|
|
j('j_faceless', {'money'}, {'faces','discards_up'})
|
|
j('j_green_joker', {'mult'})
|
|
j('j_superposition', {'tarot_gen','straight'}, {'straight'})
|
|
j('j_todo_list', {'money'})
|
|
j('j_cavendish', {'xmult'})
|
|
j('j_red_card', {'mult'})
|
|
j('j_square', {'chips'})
|
|
j('j_riff_raff', {'joker_gen'})
|
|
j('j_shortcut', {'straight'})
|
|
j('j_vagabond', {'tarot_gen'})
|
|
j('j_cloud_9', {'money'})
|
|
j('j_rocket', {'money'})
|
|
j('j_luchador', {})
|
|
j('j_gift', {'sell_value'})
|
|
j('j_turtle_bean', {'hand_size'})
|
|
j('j_erosion', {'mult'})
|
|
j('j_reserved_parking', {'money'}, {'faces','retrig_held','probability','hand_size'})
|
|
j('j_mail', {'money'}, {'discards_up'})
|
|
j('j_to_the_moon', {'money'}, {'money'})
|
|
j('j_hallucination', {'tarot_gen'}, {'probability'})
|
|
j('j_fortune_teller', {'mult'}, {'tarot_gen'})
|
|
j('j_juggler', {'hand_size'})
|
|
j('j_drunkard', {'discards_up'})
|
|
j('j_golden', {'money'})
|
|
j('j_popcorn', {'mult'})
|
|
j('j_walkie_talkie', {'chips','mult'}, {'retrig_scoring','retrig_low'})
|
|
j('j_smiley', {'mult'}, {'faces'})
|
|
j('j_ticket', {'money'}, {'gold_gen'})
|
|
j('j_swashbuckler', {'mult'}, {'sell_value','joker_gen'})
|
|
j('j_hanging_chad', {'retrig_scoring'})
|
|
j('j_shoot_the_moon', {'mult'}, {'retrig_held','hand_size'})
|
|
|
|
-- Uncommon jokers ----------------------------------------------------------
|
|
-- Stencil's xMult shrinks as slots fill, so the generic "+Mult feeds the
|
|
-- multiplier" rule is backwards for it; its real synergy is being copied.
|
|
j('j_stencil', {'xmult','copy_target'}, nil, {no_generic = true})
|
|
j('j_four_fingers', {'straight','flush'})
|
|
j('j_mime', {'retrig_held','copy_target'})
|
|
j('j_ceremonial', {'mult'})
|
|
j('j_marble', {'stone_gen','card_gen','enhance_gen'})
|
|
j('j_loyalty_card', {'xmult'})
|
|
j('j_dusk', {'retrig_scoring'})
|
|
j('j_fibonacci', {'mult'}, {'retrig_scoring','retrig_low'})
|
|
j('j_steel_joker', {'xmult'})
|
|
j('j_hack', {'retrig_low'}) -- retriggers 2-5 ONLY, never faces/aces
|
|
j('j_pareidolia', {'faces'})
|
|
j('j_space', {}, {'probability'})
|
|
j('j_burglar', {'hands_up'})
|
|
j('j_blackboard', {'xmult'}, {'spades','clubs'})
|
|
j('j_sixth_sense', {'spectral_gen'}, {'spectral_gen'})
|
|
j('j_constellation', {'xmult','planet'}, {'planet'})
|
|
j('j_hiker', {'chips'}, {'retrig_scoring','retrig_low','retrig_faces'})
|
|
j('j_card_sharp', {'xmult'}, {'hands_up'})
|
|
j('j_madness', {'xmult','copy_target'})
|
|
j('j_seance', {'spectral_gen'}, {'straight','flush','spectral_gen'})
|
|
j('j_vampire', {'xmult'}, {'enhance_gen'})
|
|
j('j_hologram', {'xmult','copy_target'}, {'card_gen'})
|
|
j('j_cartomancer', {'tarot_gen'})
|
|
j('j_astronomer', {'planet'}, {'planet'})
|
|
j('j_burnt', {}, {'discards_up'})
|
|
j('j_bootstraps', {'mult'}, {'money'})
|
|
-- DNA copies a played card into the deck, which is how you stack duplicate
|
|
-- ranks -- the only vanilla route to a reliable Four of a Kind. Pure enabler:
|
|
-- it gives the matching-hand tags without wanting them.
|
|
j('j_dna', {'card_gen','three_kind','four_kind'})
|
|
j('j_midas_mask', {'gold_gen','enhance_gen'}, {'faces'})
|
|
j('j_photograph', {'xmult','copy_target'}, {'faces','retrig_scoring','retrig_faces'})
|
|
j('j_stone', {'chips'}, {'stone_gen'})
|
|
j('j_lucky_cat', {'xmult'}, {'probability'})
|
|
j('j_baseball', {'xmult'})
|
|
j('j_bull', {'chips'}, {'money'})
|
|
j('j_diet_cola', {})
|
|
j('j_trading', {'money'}, {'discards_up'})
|
|
j('j_flash', {'mult'})
|
|
j('j_trousers', {'mult','two_pair'}, {'two_pair'})
|
|
j('j_ramen', {'xmult'})
|
|
j('j_selzer', {'retrig_scoring'})
|
|
j('j_castle', {'chips'}, {'discards_up'})
|
|
j('j_mr_bones', {})
|
|
j('j_acrobat', {'xmult'}, {'hands_up'})
|
|
j('j_sock_and_buskin', {'retrig_faces'}, {'faces'}) -- retriggers faces ONLY
|
|
j('j_troubadour', {'hand_size'})
|
|
j('j_certificate', {'card_gen'})
|
|
j('j_smeared', {'flush','suit_flex'})
|
|
j('j_throwback', {'xmult'})
|
|
j('j_rough_gem', {'money','diamonds'}, {'retrig_scoring','retrig_low','retrig_faces','diamonds','suit_flex'})
|
|
j('j_bloodstone', {'xmult','hearts'}, {'retrig_scoring','retrig_low','retrig_faces','hearts','suit_flex','probability'})
|
|
j('j_arrowhead', {'chips','spades'}, {'retrig_scoring','retrig_low','retrig_faces','spades','suit_flex'})
|
|
j('j_onyx_agate', {'mult','clubs'}, {'retrig_scoring','retrig_low','retrig_faces','clubs','suit_flex'})
|
|
j('j_glass', {'xmult'})
|
|
j('j_ring_master', {})
|
|
j('j_flower_pot', {'xmult'}, {'suit_flex'})
|
|
j('j_merry_andy', {'discards_up'})
|
|
j('j_oops', {'probability'})
|
|
j('j_idol', {'xmult','copy_target'}, {'retrig_scoring','retrig_low','retrig_faces','suit_flex'})
|
|
j('j_seeing_double', {'xmult','clubs'}, {'clubs','suit_flex'})
|
|
j('j_matador', {'money'})
|
|
j('j_hit_the_road', {'xmult'}, {'discards_up'})
|
|
j('j_satellite', {'money','planet'}, {'planet'})
|
|
|
|
-- Rare jokers ---------------------------------------------------------------
|
|
j('j_obelisk', {'xmult'})
|
|
j('j_ancient', {'xmult'}, {'suit_flex'})
|
|
j('j_campfire', {'xmult'}, {'joker_gen','sell_value'})
|
|
j('j_baron', {'xmult','copy_target'}, {'retrig_held','hand_size'})
|
|
j('j_duo', {'xmult','pair'}, {'pair'})
|
|
j('j_trio', {'xmult','three_kind'}, {'three_kind'})
|
|
j('j_family', {'xmult','four_kind'}, {'four_kind'})
|
|
j('j_order', {'xmult','straight'}, {'straight'})
|
|
j('j_tribe', {'xmult','flush'}, {'flush'})
|
|
j('j_stuntman', {'chips'})
|
|
-- Sell Invisible Joker to duplicate one of your Jokers: the same "the stronger
|
|
-- the target, the better" logic as Blueprint and Brainstorm.
|
|
j('j_invisible', {}, {'copy_target'})
|
|
j('j_blueprint', {}, {'copy_target'})
|
|
j('j_brainstorm', {}, {'copy_target'})
|
|
j('j_drivers_license', {'xmult'}, {'enhance_gen'})
|
|
j('j_wee', {'chips'}, {'retrig_scoring','retrig_low'})
|
|
|
|
-- Legendary jokers ----------------------------------------------------------
|
|
j('j_caino', {'xmult','copy_target'}, {'faces'})
|
|
j('j_triboulet', {'xmult','copy_target'}, {'retrig_scoring','retrig_faces'})
|
|
j('j_yorick', {'xmult','copy_target'}, {'discards_up'})
|
|
j('j_chicot', {})
|
|
j('j_perkeo', {'tarot_gen'}, {'tarot_gen'})
|
|
|
|
-- Famous explicit combos (flat bonus on top of tag matching), each with a
|
|
-- short "why it works" line shown in the tooltip. Keep blurbs under ~34
|
|
-- characters so a name + blurb fits on one tooltip row.
|
|
local PAIRS = {
|
|
{'j_baron', 'j_mime', 'held Kings trigger twice'},
|
|
{'j_baron', 'j_shoot_the_moon', 'Kings and Queens pay in hand'},
|
|
{'j_burglar', 'j_mystic_summit', 'zero discards, max Mult'},
|
|
{'j_burglar', 'j_acrobat', 'more hands, big final hand'},
|
|
{'j_hack', 'j_wee', 'retriggered 2s grow Wee fast'},
|
|
{'j_hanging_chad', 'j_photograph', 'first face scores three times'},
|
|
{'j_pareidolia', 'j_sock_and_buskin', 'every card is a face to retrigger'},
|
|
{'j_pareidolia', 'j_photograph', 'any first card is the face'},
|
|
{'j_pareidolia', 'j_midas_mask', 'every played card turns Gold'},
|
|
{'j_midas_mask', 'j_ticket', 'Gold cards feed Golden Ticket'},
|
|
{'j_midas_mask', 'j_vampire', 'eats the new Gold for xMult'},
|
|
{'j_dna', 'j_hologram', 'copied cards grow Hologram'},
|
|
{'j_constellation', 'j_astronomer', 'cheap Planets stack xMult'},
|
|
{'j_fortune_teller','j_cartomancer', 'free Tarots grow the Mult'},
|
|
{'j_egg', 'j_swashbuckler', 'growing sell value becomes Mult'},
|
|
{'j_gift', 'j_swashbuckler', 'inflated sell values become Mult'},
|
|
{'j_four_fingers', 'j_square', 'four-card hands suit them both'},
|
|
{'j_marble', 'j_stone', 'adds Stones that pay chips'},
|
|
{'j_oops', 'j_lucky_cat', 'better odds, more Lucky payoffs'},
|
|
{'j_blueprint', 'j_brainstorm', 'copy chains double your best'},
|
|
{'j_mime', 'j_raised_fist', 'lowest held card pays twice'},
|
|
{'j_mime', 'j_shoot_the_moon', 'held Queens trigger twice'},
|
|
{'j_hack', 'j_fibonacci', 'retriggered low cards pay again'},
|
|
{'j_photograph', 'j_sock_and_buskin', 'the first face fires again'},
|
|
{'j_smiley', 'j_sock_and_buskin', 'faces pay their Mult twice'},
|
|
{'j_four_fingers', 'j_shortcut', '4-card gap Straights'},
|
|
{'j_four_fingers', 'j_smeared', '4-card two-suit Flushes'},
|
|
{'j_smeared', 'j_bloodstone', 'half the deck counts as Hearts'},
|
|
{'j_bull', 'j_to_the_moon', 'interest piles up, chips follow'},
|
|
{'j_marble', 'j_hologram', 'every added Stone grows Hologram'},
|
|
{'j_egg', 'j_campfire', 'sell the grown Egg for xMult'},
|
|
-- Flower Pot fills its four suit slots with a greedy if/elseif chain
|
|
-- (card.lua:4256) and Smeared makes Hearts answer for Diamonds and Spades
|
|
-- for Clubs, so the second Heart falls through into the Diamond slot: any
|
|
-- two red + two black cards fill the pot. It is a top-tier combo, and this
|
|
-- mod used to warn against it.
|
|
{'j_smeared', 'j_flower_pot', 'any 2 red + 2 black fill it'},
|
|
|
|
-- Burglar zeroes discards_left for the whole run (card.lua:2905). That is a
|
|
-- disaster for nine jokers (see CLASHES) but a gift to the two that are
|
|
-- PUNISHED by discarding -- same shape as the Burglar + Mystic Summit pair.
|
|
-- Ramen is the sharper one: it decays x0.01 per discarded card and is
|
|
-- DESTROYED when it reaches x1 (SMODS.destroy_cards, card.lua:3175). No
|
|
-- discards means it never decays and never dies.
|
|
{'j_burglar', 'j_ramen', 'no discards, no decay'},
|
|
{'j_burglar', 'j_green_joker', 'no discards, only gains'},
|
|
|
|
-- Card Sharp fires while played_this_round > 1 (card.lua:4465), and that
|
|
-- counter resets every round (state_events.lua:252) -- so its x3 needs the
|
|
-- same hand twice in ONE round. Burglar's +3 hands makes that routine.
|
|
{'j_burglar', 'j_card_sharp', 'extra hands make replays easy'},
|
|
|
|
-- Erosion pays per card MISSING from the deck (starting_deck_size -
|
|
-- #G.playing_cards, card.lua:4318), and Trading Card permanently destroys the
|
|
-- card it discards (remove = true, card.lua:3214). Thinning the deck is
|
|
-- exactly what Erosion is paid for.
|
|
{'j_trading', 'j_erosion', 'destroyed cards feed Erosion'},
|
|
|
|
-- Flash Card gains Mult per shop reroll; Chaos the Clown hands you a free one
|
|
-- every shop. Both jokers were inert in this database until now.
|
|
{'j_chaos', 'j_flash', 'free rerolls grow Flash Card'},
|
|
}
|
|
|
|
-- Known traps: pairs that actively hurt each other. Warning-only — they
|
|
-- never subtract from the synergy score; the tooltip just flags them with
|
|
-- a red "Clashes" line. Keep warnings under ~34 chars (one tooltip row).
|
|
local CLASHES = {
|
|
{'j_ride_the_bus', 'j_pareidolia', 'every card counts as a face'},
|
|
|
|
-- Burglar sets discards_left to 0 when the blind is selected
|
|
-- (`ease_discard(-discards_left)`, card.lua:2905), so every joker that
|
|
-- reads a discard is switched off for the whole run.
|
|
{'j_burglar', 'j_banner', 'no discards left to count'},
|
|
{'j_burglar', 'j_delayed_grat', 'pays per discard; you get 0'},
|
|
{'j_burglar', 'j_castle', 'no discards, never grows'},
|
|
{'j_burglar', 'j_yorick', 'no discards, never grows'},
|
|
{'j_burglar', 'j_hit_the_road', 'no discards, never grows'},
|
|
{'j_burglar', 'j_burnt', 'no discards to level a hand'},
|
|
{'j_burglar', 'j_mail', 'no discards, no rebate'},
|
|
{'j_burglar', 'j_faceless', 'no discards, no payout'},
|
|
{'j_burglar', 'j_trading', 'no discards to trade in'},
|
|
{'j_burglar', 'j_drunkard', 'its extra discards get wiped'},
|
|
{'j_burglar', 'j_merry_andy', 'its extra discards get wiped'},
|
|
|
|
-- Vampire strips enhancements in the `before` pass (card.lua:3851/3906),
|
|
-- which runs ahead of the per-card `individual` pass where the enhancement
|
|
-- payoffs are read — so it eats the cards they are counting, permanently.
|
|
{'j_vampire', 'j_steel_joker', 'drains the Steel it counts'},
|
|
{'j_vampire', 'j_lucky_cat', 'strips Lucky cards before they pay'},
|
|
{'j_vampire', 'j_ticket', 'eats Gold before Ticket pays'},
|
|
{'j_vampire', 'j_glass', 'strips Glass before it shatters'},
|
|
{'j_vampire', 'j_drivers_license', 'strips the 16 enhanced cards'},
|
|
{'j_vampire', 'j_stone', 'eats the Stone cards it counts'},
|
|
-- j_vampire + j_marble is NOT here on purpose: Vampire gains xMult from any
|
|
-- non-base scoring card (card.lua:3907), Stones included, so Marble is a
|
|
-- renewable supply for it -- the same shape as the Midas Mask pair. The
|
|
-- harm only appears via a third joker (Stone Joker), which carries its own
|
|
-- clash line; third-party harm is not a clash (see the Card Sharp verdict).
|
|
|
|
-- Joker Stencil's xMult is the count of EMPTY joker slots.
|
|
{'j_stencil', 'j_riff_raff', 'fills the slots Stencil needs'},
|
|
{'j_stencil', 'j_abstract', 'one wants jokers, one wants slots'},
|
|
|
|
-- Splash makes every played card score, so a face card that used to be a
|
|
-- harmless kicker now lands in the scoring hand and resets the counter.
|
|
{'j_splash', 'j_ride_the_bus', 'any played face card resets it'},
|
|
|
|
-- Erosion is the mirror image of card_gen: it pays per card MISSING from the
|
|
-- deck, so every joker that permanently ADDS one shrinks its Mult for good.
|
|
{'j_erosion', 'j_dna', 'added cards shrink its Mult'},
|
|
{'j_erosion', 'j_marble', 'each Stone shrinks its Mult'},
|
|
{'j_erosion', 'j_certificate', 'added cards shrink its Mult'},
|
|
}
|
|
|
|
-- Per-joker cautions for the buy-area tooltip: the joker is fine on its
|
|
-- own, but it interacts badly with a board you want to keep. Same length
|
|
-- budget as clash warnings.
|
|
local CAUTIONS = {
|
|
j_ceremonial = 'eats the joker to its right',
|
|
j_madness = 'destroys a random joker each blind',
|
|
j_stencil = 'xMult grows with EMPTY joker slots',
|
|
|
|
-- Positional traps: both copy a neighbour, and neither says so on the card.
|
|
j_blueprint = 'dead in the rightmost slot',
|
|
j_brainstorm = 'dead in the leftmost slot',
|
|
j_riff_raff = 'needs free joker slots',
|
|
|
|
-- Does nothing on its own: Mime retriggers held-card abilities, so with no
|
|
-- Steel/Gold cards and no Baron/Shoot the Moon it retriggers nothing.
|
|
j_mime = 'dead without held-card payoffs',
|
|
|
|
-- Board-wide side effects the card text buries.
|
|
j_burglar = 'wipes ALL discards each blind',
|
|
j_troubadour = 'plays one fewer hand each round',
|
|
j_merry_andy = 'costs you 1 hand size',
|
|
j_vampire = 'permanently eats enhancements',
|
|
j_obelisk = 'resets on your most played hand',
|
|
j_stuntman = 'costs you 2 hand size',
|
|
|
|
-- Decay: the numbers are exact (chips 100 / chip_mod 5, mult 20 / extra 4,
|
|
-- h_size 5 / h_mod 1, odds 6 -- all from game.lua).
|
|
j_ice_cream = 'melts to nothing in 20 hands',
|
|
j_popcorn = 'decays to nothing in 5 rounds',
|
|
j_turtle_bean = 'hand size shrinks back each round',
|
|
j_gros_michel = '1 in 6 to self-destruct each round',
|
|
}
|
|
|
|
-- 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.
|
|
-- Every tag that appears in the joker table must have an entry here.
|
|
local TAG_TEXT = {
|
|
faces = {give = 'turns cards into faces', want = 'pays off face cards'},
|
|
retrig_scoring = {give = 'retriggers scored cards', want = 'pays per extra trigger'},
|
|
retrig_low = {give = 'retriggers 2s through 5s', want = 'pays per extra trigger'},
|
|
retrig_faces = {give = 'retriggers face cards', want = 'pays per extra trigger'},
|
|
retrig_held = {give = 'retriggers cards in hand', want = 'pays off held-card triggers'},
|
|
hand_size = {give = 'adds hand size', want = 'wants a big hand'},
|
|
hands_up = {give = 'grants extra hands', want = 'uses the extra hands'},
|
|
discards_up = {give = 'grants extra discards', want = 'feeds on discards'},
|
|
probability = {give = 'improves listed odds', want = 'relies on listed odds'},
|
|
money = {give = 'earns money', want = 'scales with your money'},
|
|
tarot_gen = {give = 'creates Tarot cards', want = 'rewards Tarot use'},
|
|
planet = {both = 'shares the Planet economy',
|
|
give = 'creates Planet cards', want = 'rewards Planet use'},
|
|
spectral_gen = {both = 'shares the Spectral theme',
|
|
give = 'creates Spectral cards', want = 'rewards Spectral use'},
|
|
gold_gen = {give = 'creates Gold cards', want = 'pays off Gold cards'},
|
|
stone_gen = {give = 'adds Stone cards', want = 'pays off Stone cards'},
|
|
enhance_gen = {give = 'enhances cards', want = 'feeds on enhancements'},
|
|
card_gen = {give = 'adds cards to the deck', want = 'grows as the deck grows'},
|
|
-- The want text has to fit every wanter: Campfire sells the spares, Swashbuckler
|
|
-- sums their sell value, Abstract Joker just counts them.
|
|
joker_gen = {give = 'creates spare Jokers', want = 'rewards spare Jokers'},
|
|
sell_value = {give = 'raises sell values', want = 'turns sell value into Mult'},
|
|
copy_target = {give = 'is a prime copy target', want = 'copies your best Joker'},
|
|
suit_flex = {give = 'makes suits count as others', want = 'cares which suits score'},
|
|
-- Cluster tags need all three phrasings. `both` is only right when BOTH jokers
|
|
-- sit on both sides of the tag; a pure enabler (Four Fingers, DNA) gives the
|
|
-- tag without wanting it, and "both reward Straights" would be a lie -- Four
|
|
-- Fingers does not reward Straights, it makes them reachable.
|
|
pair = {both = 'both reward Pairs',
|
|
give = 'makes Pairs easier', want = 'rewards Pairs'},
|
|
two_pair = {both = 'both reward Two Pair',
|
|
give = 'makes Two Pair easier', want = 'rewards Two Pair'},
|
|
three_kind = {both = 'both reward Three of a Kind',
|
|
give = 'makes Three of a Kind easier', want = 'rewards Three of a Kind'},
|
|
four_kind = {both = 'both reward Four of a Kind',
|
|
give = 'makes Four of a Kind easier', want = 'rewards Four of a Kind'},
|
|
straight = {both = 'both reward Straights',
|
|
give = 'makes Straights easier', want = 'rewards Straights'},
|
|
flush = {both = 'both reward Flushes',
|
|
give = 'makes Flushes easier', want = 'rewards Flushes'},
|
|
-- No vanilla joker converts cards to a suit; every suit "giver" is a payoff
|
|
-- in the same cluster. The give phrasing must stay true for those (it shows
|
|
-- when the wanter is one-sided, e.g. Blackboard vs Wrathful/Arrowhead).
|
|
hearts = {both = 'both love Hearts',
|
|
give = 'also builds around Hearts', want = 'rewards Hearts'},
|
|
diamonds = {both = 'both love Diamonds',
|
|
give = 'also builds around Diamonds', want = 'rewards Diamonds'},
|
|
spades = {both = 'both love Spades',
|
|
give = 'also builds around Spades', want = 'rewards Spades'},
|
|
clubs = {both = 'both love Clubs',
|
|
give = 'also builds around Clubs', want = 'rewards Clubs'},
|
|
}
|
|
|
|
-- Order in which tags are considered when picking the one reason to show;
|
|
-- most specific mechanics first, broad engine roles last.
|
|
local TAG_ORDER = {
|
|
'retrig_held', 'retrig_low', 'retrig_faces', 'retrig_scoring', 'faces',
|
|
'gold_gen', 'stone_gen', 'enhance_gen', 'card_gen',
|
|
'tarot_gen', 'spectral_gen', 'planet',
|
|
'probability', 'discards_up', 'hands_up', 'hand_size',
|
|
'money', 'sell_value', 'joker_gen',
|
|
'hearts', 'diamonds', 'spades', 'clubs',
|
|
'pair', 'two_pair', 'three_kind', 'four_kind', 'straight', 'flush',
|
|
'copy_target', 'suit_flex',
|
|
}
|
|
|
|
-- One-sentence mechanic explainers shown at the top of each catalog theme
|
|
-- page. Teaching voice: explain how the mechanic works, not what to buy.
|
|
-- Every tag listed in main.lua's THEME_TABS needs an entry (max ~90 chars).
|
|
local THEME_INFO = {
|
|
faces = 'Face cards trigger these effects; makers like Pareidolia turn every card into one.',
|
|
retrig_scoring = 'Retriggers make each scored card count again, so per-card payoffs double up.',
|
|
retrig_low = 'Hack replays each scored 2-5; low-rank payoffs like Fibonacci collect twice.',
|
|
retrig_faces = 'Sock and Buskin replays scored face cards, so face payoffs trigger again.',
|
|
retrig_held = 'Some jokers pay for cards sitting in hand; retriggering the hand pays them again.',
|
|
copy_target = 'Blueprint and Brainstorm mirror a joker - the stronger the target, the better.',
|
|
probability = 'Listed "1 in X" odds are dice rolls; odds boosters make gambling jokers hit more.',
|
|
hand_size = 'A bigger hand holds more Kings, steel and gold - held-card builds love the space.',
|
|
hands_up = 'Extra hands per round are fuel for jokers that reward or count hands played.',
|
|
discards_up = 'Extra discards are fuel: several jokers grow or pay out each time you discard.',
|
|
money = 'Money is an engine too - some jokers earn it, others turn savings into power.',
|
|
sell_value = 'Sell value can be inflated first, then cashed in as Mult or a big sale.',
|
|
joker_gen = 'Spare jokers are fodder: sell them for profit or feed them to scaling jokers.',
|
|
tarot_gen = 'Free Tarot cards fix your deck and feed the jokers that count Tarot use.',
|
|
planet = 'Planets level up poker hands; this crew makes them cheaper and rewards each one.',
|
|
spectral_gen = 'Spectral cards warp the deck; these jokers create or lean on that chaos.',
|
|
gold_gen = 'Gold cards pay while held - creators supply them, payoffs cash them in.',
|
|
stone_gen = 'Stone cards are pure chips; add them, then pay off the heavier deck.',
|
|
enhance_gen = 'Enhanced cards (gold, steel, stone...) power the jokers that eat or count them.',
|
|
card_gen = 'Adding cards grows the deck - and the jokers that scale with its size.',
|
|
pair = 'These all fire on a Pair, so one played hand triggers the whole set at once.',
|
|
two_pair = 'Two Pair sets off every one of these together - stack them and replay it.',
|
|
three_kind = 'Three of a Kind triggers all of these in a single played hand.',
|
|
four_kind = 'Four of a Kind is rare but sets off this whole crew at once.',
|
|
straight = 'Straights trigger all of these; enablers make gaps and 4-card runs count.',
|
|
flush = 'Flushes trigger all of these; enablers make them far easier to assemble.',
|
|
suit_flex = 'Suit benders make cards count as two suits, unlocking every suit joker.',
|
|
hearts = 'Hearts pay these jokers when scored - suit benders widen the supply.',
|
|
diamonds = 'Diamonds pay these jokers when scored - suit benders widen the supply.',
|
|
spades = 'Spades pay these jokers when scored - suit benders widen the supply.',
|
|
clubs = 'Clubs pay these jokers when scored - suit benders widen the supply.',
|
|
}
|
|
|
|
-- Convert gives/wants arrays into sets for fast lookup.
|
|
for _, entry in pairs(J) do
|
|
local g, w = {}, {}
|
|
for _, t in ipairs(entry.gives) do g[t] = true end
|
|
for _, t in ipairs(entry.wants) do w[t] = true end
|
|
entry.gives, entry.wants = g, w
|
|
end
|
|
|
|
return { jokers = J, pairs = PAIRS, clashes = CLASHES, cautions = CAUTIONS,
|
|
tag_text = TAG_TEXT, tag_order = TAG_ORDER, theme_info = THEME_INFO }
|