Chase the audit's leads: verify, implement, or reject
Every lead in AUDIT.md, traced to the running source and then settled. Ceremonial Dagger DESTROYS the joker to its right at blind select (card.lua:2945) and skips Eternals. The card says so; what it cannot say is WHICH of your jokers is about to die. JCA.dagger_victim names it in the tooltip -- "WILL DESTROY Baron at the next blind" -- while there is still time to reorder, and stays quiet when the neighbour is Eternal. Four jokers that scored 0 against all 150 now have partners, all verified in card.lua rather than recalled: * Burglar + Ramen: Ramen decays per discarded card and is DESTROYED at x1 (SMODS.destroy_cards). Burglar zeroes discards, so it never decays and never dies. Same for Burglar + Green Joker, which is only punished by discarding. * Trading Card + Erosion: Erosion pays per card MISSING from the deck, and Trading Card permanently destroys the card it discards. * Chaos the Clown + Flash Card: a free reroll every shop, and a joker that grows per reroll. Both were inert. Erosion is the mirror of card_gen, so it now clashes with every joker that permanently adds a card: DNA, Marble, Certificate. Rejected, with the reasoning recorded so nobody "fixes" it later: Card Sharp and Supernova reward replaying a hand and Obelisk punishes it, but neither destroys the other's precondition -- the player's hand choice does. That is an opposed incentive, not an opposed effect. The clash list only earns trust while every entry is mechanical. The audit's own silent-check was wrong: it flagged Square Joker, which has been paired with Four Fingers all along, and I duplicated that pair before the suite caught it. Silence now means no tags AND no famous pair. 711 pass locally, 10 in-game. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,11 +11,11 @@ does not get redone from scratch every session.
|
|||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Jokers in the database | 150 |
|
| Jokers in the database | 150 |
|
||||||
| Famous pairs | 32 |
|
| Famous pairs | 36 |
|
||||||
| Clashes | 22 |
|
| Clashes | 25 |
|
||||||
| Cautions | 15 |
|
| Cautions | 15 |
|
||||||
| Themes | 29 |
|
| Themes | 29 |
|
||||||
| Jokers in no famous pair | 108 |
|
| Jokers in no famous pair | 102 |
|
||||||
|
|
||||||
## Jokers the advisor is silent about
|
## Jokers the advisor is silent about
|
||||||
|
|
||||||
@@ -25,8 +25,8 @@ answer for some of them -- but it should be a decision, not an accident.
|
|||||||
|
|
||||||
| | count |
|
| | count |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Silent, reviewed, staying that way | 20 |
|
| Silent, reviewed, staying that way | 25 |
|
||||||
| Silent, but a lead worth chasing | 12 |
|
| Silent, but a lead worth chasing | 0 |
|
||||||
| **Silent and never looked at** | **0** |
|
| **Silent and never looked at** | **0** |
|
||||||
|
|
||||||
### Leads worth chasing
|
### Leads worth chasing
|
||||||
@@ -34,22 +34,13 @@ answer for some of them -- but it should be a decision, not an accident.
|
|||||||
Unverified. Check each against the Lovely dump before acting on it -- a wrong
|
Unverified. Check each against the Lovely dump before acting on it -- a wrong
|
||||||
synergy is worse than a missing one.
|
synergy is worse than a missing one.
|
||||||
|
|
||||||
- **`j_baseball`** — xMult per Uncommon joker owned. We have no rarity tag, and adding one for a single payoff may not earn its keep.
|
|
||||||
- **`j_card_sharp`** — xMult when the hand type was already played this round -- it rewards repeating one hand, which is exactly what Obelisk punishes. Clash?
|
|
||||||
- **`j_ceremonial`** — positional like Blueprint: it DESTROYS the joker to its right. JCA.copy_source already reads board order -- the same machinery could warn "will destroy your Baron" before it eats something irreplaceable.
|
|
||||||
- **`j_chaos`** — free reroll each shop; see j_flash
|
|
||||||
- **`j_erosion`** — +Mult per card BELOW 52 in the deck, so it is the inverse of card_gen: DNA/Marble/Certificate permanently shrink it. Likely CLASHES, and possibly a synergy with anything that destroys cards (Trading Card).
|
|
||||||
- **`j_flash`** — +Mult per shop reroll. Chaos the Clown grants a free reroll each shop, which would give both of them a reason to exist (Chaos is inert today).
|
|
||||||
- **`j_green_joker`** — +Mult per hand, -Mult per discard: Burglar removes discards entirely. Same shape as the existing Burglar + Mystic Summit pair.
|
|
||||||
- **`j_obelisk`** — resets on your most-played hand, so it fights every hand-type build. Has a CAUTION already; the pairwise clashes may be worth adding.
|
|
||||||
- **`j_ramen`** — xMult decays per card discarded, so Burglar (zero discards all run) stops the decay dead. Likely a famous pair.
|
|
||||||
- **`j_ring_master`** — Showman allows duplicates in the pool. Enables copy/duplicate strategies, but we have no tag for "shop pool" effects and inventing one for a single joker is probably not worth it.
|
|
||||||
- **`j_square`** — +Chips on exactly-4-card hands; Four Fingers makes 4-card flushes and straights playable. Needs a tag that does not exist yet.
|
|
||||||
- **`j_supernova`** — Mult scales with times the hand was played; see j_card_sharp
|
|
||||||
|
|
||||||
### Reviewed, and deliberately silent
|
### Reviewed, and deliberately silent
|
||||||
|
|
||||||
|
- **`j_baseball`** — xMult per Uncommon joker owned. A rarity tag would have exactly one payoff, and every giver would be "is uncommon" -- noise, not synergy.
|
||||||
|
- **`j_card_sharp`** — REJECTED as a clash with Obelisk. Card Sharp rewards replaying a hand and Obelisk punishes replaying your MOST played hand -- but neither destroys the other precondition; the player's hand choice does. That is an opposed incentive, not an opposed effect. Flagging it would dilute the clash signal, which only earns trust while every entry is mechanical.
|
||||||
- **`j_cavendish`** — the reward for Gros Michel dying, not a partner
|
- **`j_cavendish`** — the reward for Gros Michel dying, not a partner
|
||||||
|
- **`j_ceremonial`** — RESOLVED: it destroys the joker to its right at blind select (card.lua:2945), skipping Eternals. JCA.dagger_victim now names the joker about to die, in the tooltip, while there is still time to reorder.
|
||||||
- **`j_chicot`** — disables the boss blind; no joker interaction
|
- **`j_chicot`** — disables the boss blind; no joker interaction
|
||||||
- **`j_credit_card`** — lets you go negative; a money buffer, not a combo
|
- **`j_credit_card`** — lets you go negative; a money buffer, not a combo
|
||||||
- **`j_diet_cola`** — sell for a Double Tag; tags are outside our model
|
- **`j_diet_cola`** — sell for a Double Tag; tags are outside our model
|
||||||
@@ -62,12 +53,14 @@ synergy is worse than a missing one.
|
|||||||
- **`j_luchador`** — sell to disable a boss; no joker interaction
|
- **`j_luchador`** — sell to disable a boss; no joker interaction
|
||||||
- **`j_misprint`** — random +Mult; interacts with nothing
|
- **`j_misprint`** — random +Mult; interacts with nothing
|
||||||
- **`j_mr_bones`** — death insurance; no joker interaction
|
- **`j_mr_bones`** — death insurance; no joker interaction
|
||||||
- **`j_mystic_summit`** — already paired with Burglar (zero discards, max Mult)
|
- **`j_obelisk`** — The trap is real but it is a CAUTION ("resets on your most played hand"), not a set of pairwise clashes. See j_card_sharp.
|
||||||
- **`j_popcorn`** — decays; the trap is a CAUTION
|
- **`j_popcorn`** — decays; the trap is a CAUTION
|
||||||
- **`j_red_card`** — +Mult per skipped booster; no joker interaction
|
- **`j_red_card`** — +Mult per skipped booster; no joker interaction
|
||||||
- **`j_ride_the_bus`** — scales on face-free hands; the traps are CLASHES
|
- **`j_ride_the_bus`** — scales on face-free hands; the traps are CLASHES
|
||||||
|
- **`j_ring_master`** — Showman allows duplicates in the shop pool. We have no tag for pool effects, and one joker does not justify inventing one.
|
||||||
- **`j_steel_joker`** — wants STEEL cards. The only enhance_gen givers make Gold (Midas) and Stone (Marble), so tagging it enhance_gen would invent a synergy that does not exist. No vanilla joker creates Steel cards. Leave it alone.
|
- **`j_steel_joker`** — wants STEEL cards. The only enhance_gen givers make Gold (Midas) and Stone (Marble), so tagging it enhance_gen would invent a synergy that does not exist. No vanilla joker creates Steel cards. Leave it alone.
|
||||||
- **`j_stuntman`** — big chips, -2 hand size; the trap is a CAUTION
|
- **`j_stuntman`** — big chips, -2 hand size; the trap is a CAUTION
|
||||||
|
- **`j_supernova`** — REJECTED as an Obelisk clash for the same reason as j_card_sharp
|
||||||
- **`j_throwback`** — xMult per skipped blind; no joker interaction
|
- **`j_throwback`** — xMult per skipped blind; no joker interaction
|
||||||
|
|
||||||
## Tag health
|
## Tag health
|
||||||
@@ -127,5 +120,5 @@ mis-tagged, the error is spread across the whole database.
|
|||||||
| `j_four_fingers` | 12 |
|
| `j_four_fingers` | 12 |
|
||||||
| `j_seance` | 12 |
|
| `j_seance` | 12 |
|
||||||
|
|
||||||
Jokers with **no** partner scoring >= 2 anywhere in the game: 30
|
Jokers with **no** partner scoring >= 2 anywhere in the game: 25
|
||||||
|
|
||||||
|
|||||||
@@ -51,43 +51,47 @@ local VERDICTS = {
|
|||||||
'wants GLASS cards, and no vanilla joker creates them. Same trap as ' ..
|
'wants GLASS cards, and no vanilla joker creates them. Same trap as ' ..
|
||||||
'Steel Joker: enhance_gen is too coarse a tag to use here.'},
|
'Steel Joker: enhance_gen is too coarse a tag to use here.'},
|
||||||
|
|
||||||
-- Leads worth chasing. NOT verified against the game source yet.
|
-- Chased and resolved. These now have pairs, clashes or an advisor line, so
|
||||||
j_ceremonial = {'candidate',
|
-- they no longer appear as silent -- kept here as the record of the decision.
|
||||||
'positional like Blueprint: it DESTROYS the joker to its right. ' ..
|
j_ceremonial = {'settled',
|
||||||
'JCA.copy_source already reads board order -- the same machinery could ' ..
|
'RESOLVED: it destroys the joker to its right at blind select ' ..
|
||||||
'warn "will destroy your Baron" before it eats something irreplaceable.'},
|
'(card.lua:2945), skipping Eternals. JCA.dagger_victim now names the ' ..
|
||||||
j_erosion = {'candidate',
|
'joker about to die, in the tooltip, while there is still time to reorder.'},
|
||||||
'+Mult per card BELOW 52 in the deck, so it is the inverse of card_gen: ' ..
|
j_erosion = {'settled',
|
||||||
'DNA/Marble/Certificate permanently shrink it. Likely CLASHES, and ' ..
|
'RESOLVED: pays per card missing from the deck (starting_deck_size - ' ..
|
||||||
'possibly a synergy with anything that destroys cards (Trading Card).'},
|
'#G.playing_cards, card.lua:4318) -- the exact inverse of card_gen. Now ' ..
|
||||||
j_ramen = {'candidate',
|
'clashes with DNA/Marble/Certificate, and pairs with Trading Card, which ' ..
|
||||||
'xMult decays per card discarded, so Burglar (zero discards all run) ' ..
|
'permanently destroys the card it discards.'},
|
||||||
'stops the decay dead. Likely a famous pair.'},
|
j_ramen = {'settled',
|
||||||
j_green_joker = {'candidate',
|
'RESOLVED: paired with Burglar. It decays per discarded card and is ' ..
|
||||||
'+Mult per hand, -Mult per discard: Burglar removes discards entirely. ' ..
|
'DESTROYED at x1 (card.lua:3175); Burglar zeroes discards, so it never ' ..
|
||||||
'Same shape as the existing Burglar + Mystic Summit pair.'},
|
'decays and never dies.'},
|
||||||
j_flash = {'candidate',
|
j_green_joker = {'settled', 'RESOLVED: paired with Burglar (no discards, only gains)'},
|
||||||
'+Mult per shop reroll. Chaos the Clown grants a free reroll each shop, ' ..
|
j_flash = {'settled', 'RESOLVED: paired with Chaos the Clown (free rerolls grow it)'},
|
||||||
'which would give both of them a reason to exist (Chaos is inert today).'},
|
j_chaos = {'settled', 'RESOLVED: paired with Flash Card; no longer inert'},
|
||||||
j_chaos = {'candidate', 'free reroll each shop; see j_flash'},
|
j_square = {'settled',
|
||||||
j_square = {'candidate',
|
'Not actually a gap -- it was paired with Four Fingers all along. It has ' ..
|
||||||
'+Chips on exactly-4-card hands; Four Fingers makes 4-card flushes and ' ..
|
'no TAGS, which is what made the old silent-check flag it. That check now ' ..
|
||||||
'straights playable. Needs a tag that does not exist yet.'},
|
'excludes jokers with a famous pair.'},
|
||||||
j_card_sharp = {'candidate',
|
|
||||||
'xMult when the hand type was already played this round -- it rewards ' ..
|
|
||||||
'repeating one hand, which is exactly what Obelisk punishes. Clash?'},
|
|
||||||
j_supernova = {'candidate', 'Mult scales with times the hand was played; see j_card_sharp'},
|
|
||||||
j_obelisk = {'candidate',
|
|
||||||
'resets on your most-played hand, so it fights every hand-type build. ' ..
|
|
||||||
'Has a CAUTION already; the pairwise clashes may be worth adding.'},
|
|
||||||
j_baseball = {'candidate',
|
|
||||||
'xMult per Uncommon joker owned. We have no rarity tag, and adding one ' ..
|
|
||||||
'for a single payoff may not earn its keep.'},
|
|
||||||
j_mystic_summit = {'settled', 'already paired with Burglar (zero discards, max Mult)'},
|
j_mystic_summit = {'settled', 'already paired with Burglar (zero discards, max Mult)'},
|
||||||
j_ring_master = {'candidate',
|
|
||||||
'Showman allows duplicates in the pool. Enables copy/duplicate strategies, ' ..
|
-- Chased and REJECTED. Do not "fix" these; the reasoning is the point.
|
||||||
'but we have no tag for "shop pool" effects and inventing one for a single ' ..
|
j_card_sharp = {'settled',
|
||||||
'joker is probably not worth it.'},
|
'REJECTED as a clash with Obelisk. Card Sharp rewards replaying a hand ' ..
|
||||||
|
'and Obelisk punishes replaying your MOST played hand -- but neither ' ..
|
||||||
|
'destroys the other precondition; the player\'s hand choice does. That is ' ..
|
||||||
|
'an opposed incentive, not an opposed effect. Flagging it would dilute the ' ..
|
||||||
|
'clash signal, which only earns trust while every entry is mechanical.'},
|
||||||
|
j_supernova = {'settled', 'REJECTED as an Obelisk clash for the same reason as j_card_sharp'},
|
||||||
|
j_obelisk = {'settled',
|
||||||
|
'The trap is real but it is a CAUTION ("resets on your most played hand"), ' ..
|
||||||
|
'not a set of pairwise clashes. See j_card_sharp.'},
|
||||||
|
j_baseball = {'settled',
|
||||||
|
'xMult per Uncommon joker owned. A rarity tag would have exactly one ' ..
|
||||||
|
'payoff, and every giver would be "is uncommon" -- noise, not synergy.'},
|
||||||
|
j_ring_master = {'settled',
|
||||||
|
'Showman allows duplicates in the shop pool. We have no tag for pool ' ..
|
||||||
|
'effects, and one joker does not justify inventing one.'},
|
||||||
}
|
}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
@@ -136,20 +140,27 @@ for key, e in pairs(JCA.db) do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- "Silent": nothing but engine roles to give, and nothing wanted. Such a joker
|
local in_pair = {}
|
||||||
-- can only ever earn the generic +1, so the advisor has nothing to say about it.
|
for _, p in ipairs(data.pairs) do in_pair[p[1]] = true; in_pair[p[2]] = true end
|
||||||
|
|
||||||
|
-- "Silent": nothing but engine roles to give, nothing wanted, AND no famous pair.
|
||||||
|
-- Such a joker can only ever earn the generic +1, so the advisor has nothing to
|
||||||
|
-- say about it against any of the 150.
|
||||||
|
--
|
||||||
|
-- The pair check matters: without it this list flags jokers the advisor speaks up
|
||||||
|
-- about perfectly well (Square Joker has no tags but has been paired with Four
|
||||||
|
-- Fingers all along), and a lead gets "found" that was never lost.
|
||||||
local silent = {}
|
local silent = {}
|
||||||
for key, e in pairs(JCA.db) do
|
for key, e in pairs(JCA.db) do
|
||||||
local has_theme, wants = false, 0
|
local has_theme, wants = false, 0
|
||||||
for t in pairs(e.gives) do if not ENGINE[t] then has_theme = true end end
|
for t in pairs(e.gives) do if not ENGINE[t] then has_theme = true end end
|
||||||
for _ in pairs(e.wants) do wants = wants + 1 end
|
for _ in pairs(e.wants) do wants = wants + 1 end
|
||||||
if not has_theme and wants == 0 then silent[#silent + 1] = key end
|
if not has_theme and wants == 0 and not in_pair[key] then
|
||||||
|
silent[#silent + 1] = key
|
||||||
|
end
|
||||||
end
|
end
|
||||||
table.sort(silent)
|
table.sort(silent)
|
||||||
|
|
||||||
local in_pair = {}
|
|
||||||
for _, p in ipairs(data.pairs) do in_pair[p[1]] = true; in_pair[p[2]] = true end
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Report
|
-- Report
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -191,6 +191,34 @@ function JCA.copy_source(card)
|
|||||||
return target, center.blueprint_compat ~= false
|
return target, center.blueprint_compat ~= false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Ceremonial Dagger is positional too, and it is the dangerous one: when the
|
||||||
|
-- blind is selected it DESTROYS the joker to its right and eats twice its sell
|
||||||
|
-- value as Mult (card.lua:2945). The card text says so; what it cannot tell you
|
||||||
|
-- is *which joker on your board* is about to die. Vanilla skips Eternal jokers,
|
||||||
|
-- so an Eternal neighbour is safe.
|
||||||
|
--
|
||||||
|
-- Returns the joker it will eat (or nil), and whether that joker is safe.
|
||||||
|
function JCA.dagger_victim(card)
|
||||||
|
if not (G.jokers and G.jokers.cards and card.config and card.config.center) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
if card.config.center.key ~= 'j_ceremonial' then return nil end
|
||||||
|
local cards, idx = G.jokers.cards, nil
|
||||||
|
for i, c in ipairs(cards) do
|
||||||
|
if c == card then idx = i break end
|
||||||
|
end
|
||||||
|
if not idx then return nil end
|
||||||
|
local target = cards[idx + 1]
|
||||||
|
if not target or not (target.config and target.config.center) then return nil end
|
||||||
|
|
||||||
|
local eternal = target.ability and target.ability.eternal
|
||||||
|
if SMODS and SMODS.is_eternal then
|
||||||
|
local ok, res = pcall(SMODS.is_eternal, target, card)
|
||||||
|
if ok then eternal = res end
|
||||||
|
end
|
||||||
|
return target, not not eternal
|
||||||
|
end
|
||||||
|
|
||||||
-- Sell advisor: on a full board, the owned joker contributing the least
|
-- Sell advisor: on a full board, the owned joker contributing the least
|
||||||
-- total synergy to the rest is the natural cut when something better shows
|
-- total synergy to the rest is the natural cut when something better shows
|
||||||
-- up. Returns nil when slots are free, the board is tiny, or every joker
|
-- up. Returns nil when slots are free, the board is tiny, or every joker
|
||||||
@@ -434,10 +462,11 @@ local function tooltip_rows(card)
|
|||||||
local caution = in_buy_area(card) and JCA.cautions[key]
|
local caution = in_buy_area(card) and JCA.cautions[key]
|
||||||
if caution then text_row('Caution: ' .. caution, G.C.RED) end
|
if caution then text_row('Caution: ' .. caution, G.C.RED) end
|
||||||
|
|
||||||
-- Copy jokers: say what this one is copying RIGHT NOW. The board order decides
|
-- Positional jokers: say what this one is doing to its neighbour RIGHT NOW.
|
||||||
-- it, and a Blueprint in the wrong slot is a dead card that looks fine. This is
|
-- The board order decides it, so only an owned joker has an answer. These are
|
||||||
-- an explanation, not a verdict, so learning mode keeps it.
|
-- explanations, not verdicts, so learning mode keeps them.
|
||||||
if card.area == G.jokers then
|
if card.area == G.jokers then
|
||||||
|
-- Copy jokers. A Blueprint in the wrong slot is a dead card that looks fine.
|
||||||
local target, copyable = JCA.copy_source(card)
|
local target, copyable = JCA.copy_source(card)
|
||||||
if not target then
|
if not target then
|
||||||
if COPIERS[key] then
|
if COPIERS[key] then
|
||||||
@@ -451,6 +480,20 @@ local function tooltip_rows(card)
|
|||||||
else
|
else
|
||||||
text_row('Copying ' .. name_of(target.config.center.key), G.C.GREEN)
|
text_row('Copying ' .. name_of(target.config.center.key), G.C.GREEN)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Ceremonial Dagger. This one is about to eat a joker, permanently, at the
|
||||||
|
-- next blind — worth shouting about while there is still time to reorder.
|
||||||
|
local victim, safe = JCA.dagger_victim(card)
|
||||||
|
if victim then
|
||||||
|
local vname = name_of(victim.config.center.key)
|
||||||
|
if safe then
|
||||||
|
text_row(vname .. ' is Eternal - the blade cannot eat it', G.C.GREEN)
|
||||||
|
else
|
||||||
|
text_row('WILL DESTROY ' .. vname .. ' at the next blind', G.C.RED)
|
||||||
|
end
|
||||||
|
elseif key == 'j_ceremonial' then
|
||||||
|
text_row('Nothing to its right - the blade goes hungry', G.C.GREEN)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sell advisor verdict (owned jokers only; suppressed in learning mode
|
-- Sell advisor verdict (owned jokers only; suppressed in learning mode
|
||||||
|
|||||||
@@ -239,6 +239,25 @@ local PAIRS = {
|
|||||||
-- two red + two black cards fill the pot. It is a top-tier combo, and this
|
-- two red + two black cards fill the pot. It is a top-tier combo, and this
|
||||||
-- mod used to warn against it.
|
-- mod used to warn against it.
|
||||||
{'j_smeared', 'j_flower_pot', 'any 2 red + 2 black fill 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'},
|
||||||
|
|
||||||
|
-- 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
|
-- Known traps: pairs that actively hurt each other. Warning-only — they
|
||||||
@@ -280,6 +299,12 @@ local CLASHES = {
|
|||||||
-- Splash makes every played card score, so a face card that used to be a
|
-- 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.
|
-- harmless kicker now lands in the scoring hand and resets the counter.
|
||||||
{'j_splash', 'j_ride_the_bus', 'any played face card resets it'},
|
{'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
|
-- Per-joker cautions for the buy-area tooltip: the joker is fine on its
|
||||||
|
|||||||
@@ -302,6 +302,28 @@ eq(copyable, false, 'and flags that vanilla will not copy it (blueprint_compat)'
|
|||||||
local fine = field('j_blueprint', 'j_baron')
|
local fine = field('j_blueprint', 'j_baron')
|
||||||
eq(select(2, JCA.copy_source(fine[1])), true, 'a copyable target reports as copyable')
|
eq(select(2, JCA.copy_source(fine[1])), true, 'a copyable target reports as copyable')
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
section('Engine: Ceremonial Dagger names its victim')
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- It destroys the joker to its RIGHT at the next blind, permanently.
|
||||||
|
local dagger = field('j_baron', 'j_ceremonial', 'j_mime')
|
||||||
|
local victim, safe = JCA.dagger_victim(dagger[2])
|
||||||
|
eq(victim, dagger[3], 'it names the joker on its right as the victim')
|
||||||
|
eq(safe, false, 'and an ordinary joker is not safe from it')
|
||||||
|
|
||||||
|
field('j_baron', 'j_mime', 'j_ceremonial')
|
||||||
|
eq(JCA.dagger_victim(G.jokers.cards[3]), nil, 'a rightmost Dagger eats nothing')
|
||||||
|
|
||||||
|
field('j_ceremonial', 'j_baron')
|
||||||
|
eq(JCA.dagger_victim(G.jokers.cards[2]), nil, 'a non-Dagger has no victim')
|
||||||
|
|
||||||
|
-- Vanilla refuses to slice Eternal jokers, so the advisor must not cry wolf.
|
||||||
|
local eternal = field('j_ceremonial', 'j_baron')
|
||||||
|
eternal[2].ability = {eternal = true}
|
||||||
|
local _, is_safe = JCA.dagger_victim(eternal[1])
|
||||||
|
eq(is_safe, true, 'an Eternal neighbour is reported as safe')
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
section('Engine: the sell advisor weighs clashes')
|
section('Engine: the sell advisor weighs clashes')
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user