balatro-mods/Steamodded/lovely/better_calc.toml
2025-05-20 03:22:28 +08:00

1584 lines
48 KiB
TOML

[manifest]
version = "1.0.0"
dump_lua = true
priority = -10
## G.FUNCS.evaluate_play()
# evaluate main scoring
[[patches]]
[patches.regex]
target = 'functions/state_events.lua'
pattern = '''(?<indent>[\t ]*)(?<handtext>if modded then update_hand_text\(\{sound = 'chips2', modded = modded\}, \{chips = hand_chips, mult = mult\}\) end)(.*\n)*?\s+(?<delimiter>--\++--)'''
position = 'at'
line_prepend = '$indent'
payload = '''$handtext
delay(0.3)
for _, v in ipairs(SMODS.get_card_areas('playing_cards')) do
SMODS.calculate_main_scoring({cardarea = v, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands}, v == G.play and scoring_hand or nil)
delay(0.3)
end
$delimiter'''
## eval_card()
# handle debuffed playing cards
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
function eval_card(card, context)
context = context or {}
local ret = {}
'''
position = 'at'
match_indent = true
payload = '''
function eval_card(card, context)
context = context or {}
if not card:can_calculate(context.ignore_debuff) then return {}, {} end
local ret = {}
'''
# built in config values
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
if context.cardarea == G.play then
local chips = card:get_chip_bonus()
if chips > 0 then
ret.chips = chips
end
local mult = card:get_chip_mult()
if mult > 0 then
ret.mult = mult
end
local x_mult = card:get_chip_x_mult(context)
if x_mult > 0 then
ret.x_mult = x_mult
end
local p_dollars = card:get_p_dollars()
if p_dollars > 0 then
ret.p_dollars = p_dollars
end
local jokers = card:calculate_joker(context)
if jokers then
ret.jokers = jokers
end
local edition = card:get_edition(context)
if edition then
ret.edition = edition
end
end
'''
match_indent = true
position = "at"
payload = """
if context.cardarea == G.play and context.main_scoring then
ret.playing_card = {}
local chips = card:get_chip_bonus()
if chips ~= 0 then
ret.playing_card.chips = chips
end
local mult = card:get_chip_mult()
if mult ~= 0 then
ret.playing_card.mult = mult
end
local x_mult = card:get_chip_x_mult(context)
if x_mult > 0 then
ret.playing_card.x_mult = x_mult
end
local p_dollars = card:get_p_dollars()
if p_dollars ~= 0 then
ret.playing_card.p_dollars = p_dollars
end
local x_chips = card:get_chip_x_bonus()
if x_chips > 0 then
ret.playing_card.x_chips = x_chips
end
-- TARGET: main scoring on played cards
local jokers = card:calculate_joker(context)
if jokers then
ret.jokers = jokers
end
local edition = card:calculate_edition(context)
if edition then
ret.edition = edition
end
end
if context.end_of_round and context.cardarea == G.hand and context.playing_card_end_of_round then
local end_of_round = card:get_end_of_round_effect(context)
if end_of_round then
ret.end_of_round = end_of_round
end
end
"""
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
if context.cardarea == G.hand then
local h_mult = card:get_chip_h_mult()
if h_mult > 0 then
ret.h_mult = h_mult
end
local h_x_mult = card:get_chip_h_x_mult()
if h_x_mult > 0 then
ret.x_mult = h_x_mult
end
'''
match_indent = true
position = "at"
payload = """
if context.cardarea == G.hand and context.main_scoring then
ret.playing_card = {}
local h_mult = card:get_chip_h_mult()
if h_mult ~= 0 then
ret.playing_card.h_mult = h_mult
end
local h_x_mult = card:get_chip_h_x_mult()
if h_x_mult > 0 then
ret.playing_card.x_mult = h_x_mult
end
local h_chips = card:get_chip_h_bonus()
if h_chips ~= 0 then
ret.playing_card.h_chips = h_chips
end
local h_x_chips = card:get_chip_h_x_bonus()
if h_x_chips > 0 then
ret.playing_card.x_chips = h_x_chips
end
-- TARGET: main scoring on held cards
"""
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
local seals = card:calculate_seal(context)
if seals then
ret.seals = seals
end
'''
match_indent = true
position = "at"
payload = """
if card.ability.set == 'Enhanced' then
local enhancement = card:calculate_enhancement(context)
if enhancement then
ret.enhancement = enhancement
end
end
if card.edition then
local edition = card:calculate_edition(context)
if edition then
ret.edition = edition
end
end
if card.seal then
local seals = card:calculate_seal(context)
if seals then
ret.seals = seals
end
end
for k,v in pairs(SMODS.Stickers) do
local sticker = card:calculate_sticker(context, k)
if sticker then
ret[v] = sticker
end
end
-- TARGET: evaluate your own repetition effects
"""
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = "if context.cardarea == G.jokers or context.card == G.consumeables then"
match_indent = true
position = "before"
payload = """
if card.ability.set == 'Enhanced' then
local enhancement = card:calculate_enhancement(context)
if enhancement then
ret.enhancement = enhancement
end
end
if card.edition then
local edition = card:calculate_edition(context)
if edition then
ret.edition = edition
end
end
if card.seal and not card.ability.extra_enhancement then
local seals = card:calculate_seal(context)
if seals then
ret.seals = seals
end
end
for k,v in pairs(SMODS.Stickers) do
local sticker = card:calculate_sticker(context, k)
if sticker then
ret[v] = sticker
end
end
-- TARGET: evaluate your own general effects
"""
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
if context.cardarea == G.jokers or context.card == G.consumeables then
local jokers = nil
if context.edition then
jokers = card:get_edition(context)
elseif context.other_joker then
jokers = context.other_joker:calculate_joker(context)
else
jokers = card:calculate_joker(context)
end
if jokers then
ret.jokers = jokers
end
end
return ret'''
match_indent = true
position = "at"
payload = """
local post_trig = {}
local areas = SMODS.get_card_areas('jokers')
local area_set = {}
for _,v in ipairs(areas) do area_set[v] = true end
if card.area and area_set[card.area] then
local jokers, triggered = card:calculate_joker(context)
if jokers == true then jokers = { remove = true } end
if type(jokers) ~= 'table' then jokers = nil end
if jokers or triggered then
ret.jokers = jokers
if not (context.retrigger_joker_check or context.retrigger_joker) and not (jokers and jokers.no_retrigger) then
local retriggers = SMODS.calculate_retriggers(card, context, ret)
if next(retriggers) then
ret.retriggers = retriggers
end
end
if not context.post_trigger and not context.retrigger_joker_check and SMODS.optional_features.post_trigger then
SMODS.calculate_context({blueprint_card = context.blueprint_card, post_trigger = true, other_card = card, other_context = context, other_ret = ret}, post_trig)
end
end
end
return ret, post_trig
"""
# patch card_eval_status_text to allow G.deck usage
[[patches]]
[patches.pattern]
target = "functions/common_events.lua"
pattern = '''
elseif card.area == G.hand then'''
match_indent = true
position = "at"
payload = """
elseif card.area == G.hand or card.area == G.deck then
"""
# card_eval_status_text alignment patches
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'before'
pattern = '''elseif card.area == G.hand or card.area == G.deck then'''
payload = '''elseif card == G.deck then
y_off = -0.05*G.CARD_H
card_aligned = 'tm'
elseif card.area == G.discard or card.area == G.vouchers then
y_off = card.area == G.discard and -0.35*G.CARD_H or -0.65*G.CARD_H
card = G.deck.cards[1] or G.deck
card_aligned = 'tm'
'''
# G.FUNCS.evaluate_play()
# Add deck/discard individual contexts
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
position = 'before'
match_indent = true
pattern = '''
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
--Joker Effects
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++--'''
payload = '''
'''
# Joker Effects
# Edition effects
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
--calculate the joker edition effects
local edition_effects = eval_card(_card, {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, edition = true})
if edition_effects.jokers then
edition_effects.jokers.edition = true
if edition_effects.jokers.chip_mod then
hand_chips = mod_chips(hand_chips + edition_effects.jokers.chip_mod)
update_hand_text({delay = 0}, {chips = hand_chips})
card_eval_status_text(_card, 'jokers', nil, percent, nil, {
message = localize{type='variable',key='a_chips',vars={edition_effects.jokers.chip_mod}},
chip_mod = edition_effects.jokers.chip_mod,
colour = G.C.EDITION,
edition = true})
end
if edition_effects.jokers.mult_mod then
mult = mod_mult(mult + edition_effects.jokers.mult_mod)
update_hand_text({delay = 0}, {mult = mult})
card_eval_status_text(_card, 'jokers', nil, percent, nil, {
message = localize{type='variable',key='a_mult',vars={edition_effects.jokers.mult_mod}},
mult_mod = edition_effects.jokers.mult_mod,
colour = G.C.DARK_EDITION,
edition = true})
end
percent = percent+percent_delta
end'''
match_indent = true
position = "at"
payload = '''
local effects = {}
-- remove base game joker edition calc
local eval = eval_card(_card, {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, edition = true, pre_joker = true})
if eval.edition then effects[#effects+1] = eval end
'''
# Edition mult effects
## extra end to fix syntax from adding joker-like areas
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
if edition_effects.jokers then
if edition_effects.jokers.x_mult_mod then
mult = mod_mult(mult*edition_effects.jokers.x_mult_mod)
update_hand_text({delay = 0}, {mult = mult})
card_eval_status_text(_card, 'jokers', nil, percent, nil, {
message = localize{type='variable',key='a_xmult',vars={edition_effects.jokers.x_mult_mod}},
x_mult_mod = edition_effects.jokers.x_mult_mod,
colour = G.C.EDITION,
edition = true})
end
percent = percent+percent_delta
end
end'''
match_indent = false
position = "at"
payload = '''
-- calculate edition multipliers
local eval = eval_card(_card, {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, edition = true, post_joker = true})
if eval.edition then effects[#effects+1] = eval end
SMODS.trigger_effects(effects, _card)
end end
'''
# Joker effects
# allows adding other areas (syntax is fixed further down)
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'at'
pattern = '''for i=1, #G.jokers.cards + #G.consumeables.cards do
local _card = G.jokers.cards[i] or G.consumeables.cards[i - #G.jokers.cards]'''
payload = '''for _, area in ipairs(SMODS.get_card_areas('jokers')) do for _, _card in ipairs(area.cards) do'''
## I am NOT converting this to regex (yet)
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
--calculate the joker effects
local effects = eval_card(_card, {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, joker_main = true})
--Any Joker effects
if effects.jokers then
local extras = {mult = false, hand_chips = false}
if effects.jokers.mult_mod then mult = mod_mult(mult + effects.jokers.mult_mod);extras.mult = true end
if effects.jokers.chip_mod then hand_chips = mod_chips(hand_chips + effects.jokers.chip_mod);extras.hand_chips = true end
if effects.jokers.Xmult_mod then mult = mod_mult(mult*effects.jokers.Xmult_mod);extras.mult = true end
update_hand_text({delay = 0}, {chips = extras.hand_chips and hand_chips, mult = extras.mult and mult})
card_eval_status_text(_card, 'jokers', nil, percent, nil, effects.jokers)
percent = percent+percent_delta
end'''
match_indent = true
position = "at"
payload = '''
-- Calculate context.joker_main
local joker_eval, post = eval_card(_card, {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, joker_main = true})
if next(joker_eval) then
if joker_eval.edition then joker_eval.edition = {} end
table.insert(effects, joker_eval)
for _, v in ipairs(post) do effects[#effects+1] = v end
if joker_eval.retriggers then
for rt = 1, #joker_eval.retriggers do
local rt_eval, rt_post = eval_card(_card, {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, joker_main = true, retrigger_joker = true})
table.insert(effects, {joker_eval.retriggers[rt]})
table.insert(effects, rt_eval)
for _, v in ipairs(rt_post) do effects[#effects+1] = v end
end
end
end'''
# Joker on Joker effects
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
--Joker on Joker effects
for _, v in ipairs(G.jokers.cards) do
local effect = v:calculate_joker{full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, other_joker = _card}
if effect then
local extras = {mult = false, hand_chips = false}
if effect.mult_mod then mult = mod_mult(mult + effect.mult_mod);extras.mult = true end
if effect.chip_mod then hand_chips = mod_chips(hand_chips + effect.chip_mod);extras.hand_chips = true end
if effect.Xmult_mod then mult = mod_mult(mult*effect.Xmult_mod);extras.mult = true end
if extras.mult or extras.hand_chips then update_hand_text({delay = 0}, {chips = extras.hand_chips and hand_chips, mult = extras.mult and mult}) end
if extras.mult or extras.hand_chips then card_eval_status_text(v, 'jokers', nil, percent, nil, effect) end
percent = percent+percent_delta
end
end'''
match_indent = true
position = "at"
payload = '''
-- Calculate context.other_joker effects
for _, _area in ipairs(SMODS.get_card_areas('jokers')) do
for _, _joker in ipairs(_area.cards) do
local other_key = 'other_unknown'
if _card.ability.set == 'Joker' then other_key = 'other_joker' end
if _card.ability.consumeable then other_key = 'other_consumeable' end
if _card.ability.set == 'Voucher' then other_key = 'other_voucher' end
-- TARGET: add context.other_something identifier to your cards
local joker_eval,post = eval_card(_joker, {full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, [other_key] = _card, other_main = _card })
if next(joker_eval) then
if joker_eval.edition then joker_eval.edition = {} end
joker_eval.jokers.juice_card = _joker
table.insert(effects, joker_eval)
for _, v in ipairs(post) do effects[#effects+1] = v end
if joker_eval.retriggers then
for rt = 1, #joker_eval.retriggers do
local rt_eval, rt_post = eval_card(_joker, {full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, [other_key] = _card, retrigger_joker = true})
table.insert(effects, {joker_eval.retriggers[rt]})
table.insert(effects, rt_eval)
for _, v in ipairs(rt_post) do effects[#effects+1] = v end
end
end
end
end
end
for _, _area in ipairs(SMODS.get_card_areas('individual')) do
local other_key = 'other_unknown'
if _card.ability.set == 'Joker' then other_key = 'other_joker' end
if _card.ability.consumeable then other_key = 'other_consumeable' end
if _card.ability.set == 'Voucher' then other_key = 'other_voucher' end
-- TARGET: add context.other_something identifier to your cards
local _eval,post = SMODS.eval_individual(_area, {full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, [other_key] = _card, other_main = _card })
if next(_eval) then
_eval.individual.juice_card = _area.scored_card
table.insert(effects, _eval)
for _, v in ipairs(post) do effects[#effects+1] = v end
if _eval.retriggers then
for rt = 1, #_eval.retriggers do
local rt_eval, rt_post = SMODS.eval_individual(_area, {full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, [other_key] = _card, retrigger_joker = true})
table.insert(effects, {_eval.retriggers[rt]})
table.insert(effects, rt_eval)
for _, v in ipairs(rt_post) do effects[#effects+1] = v end
end
end
end
end
'''
## Fix other evaluations
# Discarding cards
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
for j = 1, #G.jokers.cards do
local eval = nil
eval = G.jokers.cards[j]:calculate_joker({discard = true, other_card = G.hand.highlighted[i], full_hand = G.hand.highlighted})
if eval then
if eval.remove then removed = true end
card_eval_status_text(G.jokers.cards[j], 'jokers', nil, 1, nil, eval)
end
end'''
match_indent = true
position = "at"
payload = '''
local effects = {}
SMODS.calculate_context({discard = true, other_card = G.hand.highlighted[i], full_hand = G.hand.highlighted}, effects)
SMODS.trigger_effects(effects)
for _, eval in pairs(effects) do
if type(eval) == 'table' then
for key, eval2 in pairs(eval) do
if key == 'remove' or (type(eval2) == 'table' and eval2.remove) then removed = true end
end
end
end'''
# context.before
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
for i=1, #G.jokers.cards do
--calculate the joker effects
local effects = eval_card(G.jokers.cards[i], {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, before = true})
if effects.jokers then
card_eval_status_text(G.jokers.cards[i], 'jokers', nil, percent, nil, effects.jokers)
percent = percent + percent_delta
if effects.jokers.level_up then
level_up_hand(G.jokers.cards[i], text)
end
end
end'''
match_indent = true
position = "at"
payload = '''
-- context.before calculations
SMODS.calculate_context({full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, before = true})
-- TARGET: effects before scoring starts'''
# context.final_scoring_step
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''local nu_chip, nu_mult = G.GAME.selected_back:trigger_effect{context = 'final_scoring_step', chips = hand_chips, mult = mult}'''
match_indent = true
position = "before"
payload = '''
-- context.final_scoring_step calculations
SMODS.calculate_context({full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, final_scoring_step = true})
-- TARGET: effects before deck final_scoring_step
'''
# context.destroying_card
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
for j = 1, #G.jokers.cards do
destroyed = G.jokers.cards[j]:calculate_joker({destroying_card = scoring_hand[i], full_hand = G.play.cards})
if destroyed then break end
end
if scoring_hand[i].ability.name == 'Glass Card' and not scoring_hand[i].debuff and pseudorandom('glass') < G.GAME.probabilities.normal/scoring_hand[i].ability.extra then
destroyed = true
end'''
match_indent = true
position = "at"
payload = '''
-- context.destroying_card calculations
for j = 1, #G.jokers.cards do
local eval, post = eval_card(G.jokers.cards[j], {destroying_card = scoring_hand[i], full_hand = G.play.cards})
SMODS.trigger_effects({eval, post}, scoring_hand[i])
if eval.jokers then destroyed = true end
end
if SMODS.has_enhancement(scoring_hand[i], 'm_glass') and scoring_hand[i]:can_calculate() and pseudorandom('glass') < G.GAME.probabilities.normal/(scoring_hand[i].ability.name == 'Glass Card' and scoring_hand[i].ability.extra or G.P_CENTERS.m_glass.config.extra) then
destroyed = true
end
local eval, post = eval_card(scoring_hand[i], {destroying_card = scoring_hand[i], full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, cardarea = G.play})
local self_destroy = false
for key, effect in pairs(eval) do
self_destroy = SMODS.calculate_effect(effect, scoring_hand[i])
end
SMODS.trigger_effects({post}, scoring_hand[i])
if self_destroy then destroyed = true end
-- TARGET: card destroyed when played
'''
# context.remove_playing_cards
[[patches]]
[patches.regex]
target = "functions/state_events.lua"
pattern = '''(?<indent>[\t ]*)local cards_destroyed = \{\}\n(.*\n)*?\s+for j=1, #G\.jokers\.cards do\n\s+eval_card\(G\.jokers\.cards\[j\], \{cardarea = G\.jokers, remove_playing_cards = true, removed = cards_destroyed\}\)\n\s+end'''
line_prepend = '$indent'
position = "at"
payload = '''
local cards_destroyed = {}
for _,v in ipairs(SMODS.get_card_areas('playing_cards', 'destroying_cards')) do
SMODS.calculate_destroying_cards({ full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, cardarea = v }, cards_destroyed, v == G.play and scoring_hand or nil)
end
-- context.remove_playing_cards calculations
if cards_destroyed[1] then
SMODS.calculate_context({scoring_hand = scoring_hand, remove_playing_cards = true, removed = cards_destroyed})
end
-- TARGET: effects when cards are removed
'''
[[patches]]
[patches.regex]
target = 'card.lua'
line_prepend = '$indent'
position = 'at'
pattern = '(?<indent>[\t ]*)for i = 1, #G.jokers.cards do[\n\s]*G.jokers.cards\[i\]:calculate_joker\(\{remove_playing_cards = true, removed = destroyed_cards\}\)[\s\n]*end'
payload = '''SMODS.calculate_context({ remove_playing_cards = true, removed = destroyed_cards })'''
# context.remove_playing_cards from discard
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
if destroyed_cards[1] then
for j=1, #G.jokers.cards do
eval_card(G.jokers.cards[j], {cardarea = G.jokers, remove_playing_cards = true, removed = destroyed_cards})
end
end
'''
position = "at"
match_indent = true
payload = '''
-- context.remove_playing_cards from discard
if destroyed_cards[1] then
SMODS.calculate_context({remove_playing_cards = true, removed = destroyed_cards})
end
-- TARGET: effects after cards destroyed in discard'''
# context.debuffed_hand
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
for i=1, #G.jokers.cards do
--calculate the joker effects
local effects = eval_card(G.jokers.cards[i], {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, debuffed_hand = true})
--Any Joker effects
if effects.jokers then
card_eval_status_text(G.jokers.cards[i], 'jokers', nil, percent, nil, effects.jokers)
percent = percent+percent_delta
end
end'''
match_indent = true
position = "at"
payload = '''
-- context.debuffed_hand calculations
SMODS.calculate_context({full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, debuffed_hand = true})
-- TARGET: effects after hand debuffed by blind'''
# context.after
[[patches]]
[patches.pattern]
target = "functions/state_events.lua"
pattern = '''
for i=1, #G.jokers.cards do
--calculate the joker after hand played effects
local effects = eval_card(G.jokers.cards[i], {cardarea = G.jokers, full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, after = true})
if effects.jokers then
card_eval_status_text(G.jokers.cards[i], 'jokers', nil, percent, nil, effects.jokers)
percent = percent + percent_delta
end
end'''
match_indent = true
position = "at"
payload = '''
-- context.after calculations
SMODS.calculate_context({full_hand = G.play.cards, scoring_hand = scoring_hand, scoring_name = text, poker_hands = poker_hands, after = true})
-- TARGET: effects after hand evaluation'''
# calc_dollar_bonus call through consumeables
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''
for i = 1, #G.jokers.cards do
local ret = G.jokers.cards[i]:calculate_dollar_bonus()
if ret then
add_round_eval_row({dollars = ret, bonus = true, name='joker'..i, pitch = pitch, card = G.jokers.cards[i]})
pitch = pitch + 0.06
dollars = dollars + ret
end
end
'''
position = 'at'
match_indent = true
payload = '''
local i = 0
for _, area in ipairs(SMODS.get_card_areas('jokers')) do
for _, _card in ipairs(area.cards) do
local ret = _card:calculate_dollar_bonus()
-- TARGET: calc_dollar_bonus per card
if ret then
i = i+1
add_round_eval_row({dollars = ret, bonus = true, name='joker'..i, pitch = pitch, card = _card})
pitch = pitch + 0.06
dollars = dollars + ret
end
end
end
'''
# context.end_of_round
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''
for i = 1, #G.jokers.cards do
local eval = nil
eval = G.jokers.cards[i]:calculate_joker({end_of_round = true, game_over = game_over})
if eval then
if eval.saved then
game_over = false
end
card_eval_status_text(G.jokers.cards[i], 'jokers', nil, nil, nil, eval)
end
G.jokers.cards[i]:calculate_rental()
G.jokers.cards[i]:calculate_perishable()
end
'''
position = 'at'
match_indent = true
payload = '''
-- context.end_of_round calculations
SMODS.saved = false
SMODS.calculate_context({end_of_round = true, game_over = game_over })
if SMODS.saved then game_over = false end
-- TARGET: main end_of_round evaluation
'''
# context.end_of_round individual effects
[[patches]]
[patches.regex]
target = 'functions/state_events.lua'
position = 'at'
pattern = '''(?<indent>[\t ]*)for i=1, #G\.hand\.cards do\n\s+--Check for hand doubling\n(.*\n)*?\s+delay\(0\.3\)'''
line_prepend = '$indent'
payload = '''for _,v in ipairs(SMODS.get_card_areas('playing_cards', 'end_of_round')) do
SMODS.calculate_end_of_round_effects({ cardarea = v, end_of_round = true })
end
'''
# context.setting_blind
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({setting_blind = true, blind = G.GAME.round_resets.blind})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({setting_blind = true, blind = G.GAME.round_resets.blind})
-- TARGET: setting_blind effects
'''
# context.pre_discard
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
pattern = '''
for j = 1, #G.jokers.cards do
G.jokers.cards[j]:calculate_joker({pre_discard = true, full_hand = G.hand.highlighted, hook = hook})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({pre_discard = true, full_hand = G.hand.highlighted, hook = hook})
-- TARGET: pre_discard
'''
# context.selling_self in cards
[[patches]]
[patches.pattern]
target = 'card.lua'
pattern = '''
self:calculate_joker{selling_self = true}
'''
position = 'at'
match_indent = true
payload = '''
local eval, post = eval_card(self, {selling_self = true})
local effects = {eval}
for _,v in ipairs(post) do effects[#effects+1] = v end
if eval.retriggers then
for rt = 1, #eval.retriggers do
local rt_eval, rt_post = eval_card(self, { selling_self = true, retrigger_joker = true})
table.insert(effects, {eval.retriggers[rt]})
table.insert(effects, rt_eval)
for _, v in ipairs(rt_post) do effects[#effects+1] = v end
end
end
SMODS.trigger_effects(effects, self)
'''
# context.open_booster
[[patches]]
[patches.pattern]
target = 'card.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({open_booster = true, card = self})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({open_booster = true, card = self})
'''
# context.buying_card
[[patches]]
[patches.pattern]
target = 'card.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({buying_card = true, card = self})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({buying_card = true, card = self})
'''
# context.first_hand_drawn
[[patches]]
[patches.pattern]
target = 'game.lua'
pattern = '''
if G.GAME.current_round.hands_played == 0 and
G.GAME.current_round.discards_used == 0 and G.GAME.facing_blind then
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({first_hand_drawn = true})
end
end
'''
position = 'at'
match_indent = true
payload = '''
-- removed first hand drawn context
'''
# Hand Drawn Contexts
[[patches]]
[patches.pattern]
target = 'cardarea.lua'
match_indent = true
position = 'at'
pattern = '''
self:emplace(card, nil, stay_flipped)
return true
'''
payload = '''
self:emplace(card, nil, stay_flipped)
return card
'''
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
if to:draw_card_from(from, stay_flipped, discarded_only) then drawn = true end
'''
payload = '''
card = to:draw_card_from(from, stay_flipped, discarded_only)
if card then drawn = true end
'''
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'after'
pattern = '''
if sort then
to:sort()
end
'''
payload = '''
SMODS.drawn_cards = SMODS.drawn_cards or {}
if card and card.playing_card then SMODS.drawn_cards[#SMODS.drawn_cards+1] = card end
'''
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'before'
pattern = '''
for i=1, hand_space do --draw cards from deckL
if G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK then
draw_card(G.deck,G.hand, i*100/hand_space,'up', true)
else
draw_card(G.deck,G.hand, i*100/hand_space,'up', true)
end
end
'''
payload = '''
SMODS.drawn_cards = {}
'''
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'after'
pattern = '''
for i=1, hand_space do --draw cards from deckL
if G.STATE == G.STATES.TAROT_PACK or G.STATE == G.STATES.SPECTRAL_PACK then
draw_card(G.deck,G.hand, i*100/hand_space,'up', true)
else
draw_card(G.deck,G.hand, i*100/hand_space,'up', true)
end
end
'''
payload = '''
G.E_MANAGER:add_event(Event({
trigger = 'before',
delay = 0.4,
func = function()
if #SMODS.drawn_cards > 0 then
SMODS.calculate_context({first_hand_drawn = not G.GAME.current_round.any_hand_drawn and G.GAME.facing_blind,
hand_drawn = G.GAME.facing_blind and SMODS.drawn_cards,
other_drawn = not G.GAME.facing_blind and SMODS.drawn_cards})
SMODS.drawn_cards = {}
if G.GAME.facing_blind then G.GAME.current_round.any_hand_drawn = true end
end
return true
end
}))
'''
# Used to identify first hand of round
# new_round
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'after'
pattern = 'G.GAME.current_round.discards_used = 0'
payload = '''
G.GAME.current_round.any_hand_drawn = nil
'''
# context.using_consumeable
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({using_consumeable = true, consumeable = card})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({using_consumeable = true, consumeable = card, area = card.from_area})
'''
# save area of used card
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
match_indent = true
position = 'before'
pattern = '''
c1.area:remove_card(c1)
'''
payload = '''
c1.from_area = c1.area
'''
# context.selling_card
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
if G.jokers.cards[i] ~= card then
G.jokers.cards[i]:calculate_joker({selling_card = true, card = card})
end
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({selling_card = true, card = card})
'''
# context.buying_card
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
G.E_MANAGER:add_event(Event({func = function() c1:calculate_joker({buying_card = true, card = c1}) return true end}))
'''
position = 'at'
match_indent = true
payload = '''
G.E_MANAGER:add_event(Event({func = function()
local eval, post = eval_card(c1, {buying_card = true, card = c1})
SMODS.trigger_effects({eval, post}, c1)
return true
end}))
'''
# context.buying_card
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({buying_card = true, card = c1})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({buying_card = true, card = c1})
'''
# context.starting_shop
[[patches]]
[patches.pattern]
target = 'game.lua'
pattern = '''
G.CONTROLLER:snap_to({node = G.shop:get_UIE_by_ID('next_round_button')})
'''
position = 'before'
match_indent = true
payload = '''
if not nosave_shop then SMODS.calculate_context({starting_shop = true}) end
'''
# context.ending_shop
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({ending_shop = true})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({ending_shop = true})
'''
# context.skipping_booster
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({skipping_booster = true})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({skipping_booster = true, booster = booster_obj})
'''
# context.skip_blind
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({skip_blind = true})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({skip_blind = true})
'''
# context.reroll_shop
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
pattern = '''
for i = 1, #G.jokers.cards do
G.jokers.cards[i]:calculate_joker({reroll_shop = true})
end
'''
position = 'at'
match_indent = true
payload = '''
SMODS.calculate_context({reroll_shop = true, cost = reroll_cost})
'''
# reroll_cost for context
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
match_indent = true
position = 'before'
pattern = '''
if G.GAME.current_round.reroll_cost > 0 then
'''
payload = '''
local reroll_cost = G.GAME.current_round.reroll_cost
'''
# Fix purple seal calc
[[patches]]
[patches.pattern]
target = 'card.lua'
pattern = '''
if context.discard then
if self.seal == 'Purple' and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then'''
position = 'at'
match_indent = true
payload = '''
if context.discard and context.other_card == self then
if self.seal == 'Purple' and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then'''
# Fix context.blueprint persisting
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'after'
pattern = 'local other_joker_ret = other_joker:calculate_joker(context)'
payload = '''
context.blueprint = nil
local eff_card = context.blueprint_card or self
context.blueprint_card = nil'''
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'at'
pattern = 'other_joker_ret.card = context.blueprint_card or self'
payload = '''other_joker_ret.card = eff_card'''
# Auto deal with negative chips card_eval_status_text()
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
text = localize{type='variable',key='a_chips',vars={amt}}
'''
payload = '''
text = localize{type='variable',key='a_chips'..(amt<0 and '_minus' or ''),vars={math.abs(amt)}}
'''
# Auto deal with negative mult card_eval_status_text()
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
text = localize{type='variable',key='a_mult',vars={amt}}
'''
payload = '''
text = localize{type='variable',key='a_mult'..(amt<0 and '_minus' or ''),vars={math.abs(amt)}}
'''
# Auto deal with negative xmult card_eval_status_text()
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
text = localize{type='variable',key='a_xmult',vars={amt}}
'''
payload = '''
text = localize{type='variable',key='a_xmult'..(amt<0 and '_minus' or ''),vars={math.abs(amt)}}
'''
# Make percent and percent_delta globals
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'at'
pattern = '''local percent = 0.3
local percent_delta = 0.08
'''
payload = '''percent = 0.3
percent_delta = 0.08
'''
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'at'
pattern = '''local percent = (i-0.999)/(#G.hand.cards-0.998) + (j-1)*0.1'''
payload = '''percent = (i-0.999)/(#G.hand.cards-0.998) + (j-1)*0.1'''
# Add support for pitch and volume returns in effects
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'after'
pattern = '''
volume = extra.edition and 0.3 or sound == 'multhit2' and 0.7 or 1
'''
payload = '''
sound = extra.sound or sound
percent = extra.pitch or percent
volume = extra.volume or volume
'''
# Voucher cardarea
[[patches]]
[patches.pattern]
target = 'game.lua'
match_indent = true
position = 'before'
pattern = 'self.deck = CardArea('
payload = '''self.vouchers = CardArea(
G.discard.T.x, G.discard.T.y,
G.discard.T.w, G.discard.T.h,
{ type = "discard", card_limit = 1e308 }
)
'''
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'after'
pattern = 'function Card:apply_to_run(center)'
payload = '''
local card_to_save = self and copy_card(self) or Card(0, 0, G.CARD_W, G.CARD_H, G.P_CARDS.empty, center)
card_to_save.VT.x, card_to_save.VT.y = G.vouchers.T.x, G.vouchers.T.y
G.vouchers:emplace(card_to_save)
SMODS.enh_cache:clear()
'''
[[patches]]
[patches.pattern]
target = 'card.lua'
position = 'at'
match_indent = false
pattern = '''if self.ability.set == "Planet" and not self.debuff then
if context.joker_main then
if G.GAME.used_vouchers.v_observatory and self.ability.consumeable.hand_type == context.scoring_name then
return {
message = localize{type = 'variable', key = 'a_xmult', vars = {G.P_CENTERS.v_observatory.config.extra}},
Xmult_mod = G.P_CENTERS.v_observatory.config.extra
}
end
end
end'''
payload = ''
[[patches]]
[patches.regex]
target = 'back.lua'
position = 'at'
line_prepend = '$indent'
pattern = '(?<indent>[\t ]*)(?<line>Card.apply_to_run\(nil, G\.P_CENTERS\[.*?\]\))'
payload = '''G.E_MANAGER:add_event(Event({
func = function()
$line
return true
end
}))'''
#wtf
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'at'
pattern = '''self.discard_pos = {
r = 3.6*(math.random()-0.5),
x = math.random(),
y = math.random()
}'''
payload = '''self.discard_pos = {
r = 0,
x = 0,
y = 0,
}
'''
# xchip support
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'before'
pattern = '''
elseif (eval_type == 'x_mult') or (eval_type == 'h_x_mult') then
'''
payload = '''
elseif eval_type == 'x_chips' then
sound = 'xchips'
volume = 0.7
amt = amt
text = localize{type='variable',key='a_xchips'..(amt<0 and '_minus' or ''),vars={math.abs(amt)}}
colour = G.C.BLUE
config.type = 'fade'
config.scale = 0.7
'''
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
if extra.chip_mod then
'''
payload = '''
if extra.chip_mod or extra.Xchip_mod then
'''
# Modify scoring hand context
[[patches]]
[patches.pattern]
target = 'functions/state_events.lua'
match_indent = true
position = 'at'
pattern = '''
--Add all the pure bonus cards to the scoring hand
local pures = {}
for i=1, #G.play.cards do
if next(find_joker('Splash')) then
scoring_hand[i] = G.play.cards[i]
else
if G.play.cards[i].ability.effect == 'Stone Card' then
local inside = false
for j=1, #scoring_hand do
if scoring_hand[j] == G.play.cards[i] then
inside = true
end
end
if not inside then table.insert(pures, G.play.cards[i]) end
end
end
end
for i=1, #pures do
table.insert(scoring_hand, pures[i])
end
table.sort(scoring_hand, function (a, b) return a.T.x < b.T.x end )
'''
payload = '''
local final_scoring_hand = {}
for i=1, #G.play.cards do
local splashed = SMODS.always_scores(G.play.cards[i]) or next(find_joker('Splash'))
local unsplashed = SMODS.never_scores(G.play.cards[i])
if not splashed then
for _, card in pairs(scoring_hand) do
if card == G.play.cards[i] then splashed = true end
end
end
local effects = {}
SMODS.calculate_context({modify_scoring_hand = true, other_card = G.play.cards[i], full_hand = G.play.cards, scoring_hand = scoring_hand}, effects)
local flags = SMODS.trigger_effects(effects, G.play.cards[i])
if flags.add_to_hand then splashed = true end
if flags.remove_from_hand then unsplashed = true end
if splashed and not unsplashed then table.insert(final_scoring_hand, G.play.cards[i]) end
end
-- TARGET: adding to hand effects
scoring_hand = final_scoring_hand
'''
# Add ending_booster calculation context
[[patches]]
[patches.pattern]
target = 'functions/button_callbacks.lua'
match_indent = true
position = 'before'
pattern = '''
for i = 1, #G.GAME.tags do
if G.GAME.tags[i]:apply_to_run({type = 'new_blind_choice'}) then break end
end
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.2*delayfac,
func = function()
save_run()
return true
end}))
'''
payload = '''
SMODS.calculate_context({ending_booster = true, booster = booster_obj})
'''
# Fix playing_card_added jank
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'at'
pattern = '''
G.E_MANAGER:add_event(Event({
func = function()
local _card = create_playing_card({
front = pseudorandom_element(G.P_CARDS, pseudoseed('cert_fr')),
center = G.P_CENTERS.c_base}, G.hand, nil, nil, {G.C.SECONDARY_SET.Enhanced})
local seal_type = pseudorandom(pseudoseed('certsl'))
if seal_type > 0.75 then _card:set_seal('Red', true)
elseif seal_type > 0.5 then _card:set_seal('Blue', true)
elseif seal_type > 0.25 then _card:set_seal('Gold', true)
else _card:set_seal('Purple', true)
end
G.GAME.blind:debuff_card(_card)
G.hand:sort()
if context.blueprint_card then context.blueprint_card:juice_up() else self:juice_up() end
return true
end}))
playing_card_joker_effects({true})
'''
payload = '''
local _card = create_playing_card({
front = pseudorandom_element(G.P_CARDS, pseudoseed('cert_fr')),
center = G.P_CENTERS.c_base}, G.discard, true, nil, {G.C.SECONDARY_SET.Enhanced}, true)
local seal_type = pseudorandom(pseudoseed('certsl'))
if seal_type > 0.75 then _card:set_seal('Red', true)
elseif seal_type > 0.5 then _card:set_seal('Blue', true)
elseif seal_type > 0.25 then _card:set_seal('Gold', true)
else _card:set_seal('Purple', true)
end
G.E_MANAGER:add_event(Event({
func = function()
G.hand:emplace(_card)
_card:start_materialize()
G.GAME.blind:debuff_card(_card)
G.hand:sort()
if context.blueprint_card then context.blueprint_card:juice_up() else self:juice_up() end
return true
end}))
playing_card_joker_effects({_card})
'''
# create_playing_card
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
function create_playing_card(card_init, area, skip_materialize, silent, colours)
'''
payload = '''
function create_playing_card(card_init, area, skip_materialize, silent, colours, skip_emplace)
'''
[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
match_indent = true
position = 'at'
pattern = '''
if area then area:emplace(card) end
'''
payload = '''
if area and not skip_emplace then area:emplace(card) end
'''
# Marble Joker
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'at'
pattern = '''
G.E_MANAGER:add_event(Event({
func = function()
local front = pseudorandom_element(G.P_CARDS, pseudoseed('marb_fr'))
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local card = Card(G.play.T.x + G.play.T.w/2, G.play.T.y, G.CARD_W, G.CARD_H, front, G.P_CENTERS.m_stone, {playing_card = G.playing_card})
card:start_materialize({G.C.SECONDARY_SET.Enhanced})
G.play:emplace(card)
table.insert(G.playing_cards, card)
return true
end}))
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_plus_stone'), colour = G.C.SECONDARY_SET.Enhanced})
G.E_MANAGER:add_event(Event({
func = function()
G.deck.config.card_limit = G.deck.config.card_limit + 1
return true
end}))
draw_card(G.play,G.deck, 90,'up', nil)
playing_card_joker_effects({true})
'''
payload = '''
local front = pseudorandom_element(G.P_CARDS, pseudoseed('marb_fr'))
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
local card = Card(G.discard.T.x + G.discard.T.w/2, G.discard.T.y, G.CARD_W, G.CARD_H, front, G.P_CENTERS.m_stone, {playing_card = G.playing_card})
G.E_MANAGER:add_event(Event({
func = function()
card:start_materialize({G.C.SECONDARY_SET.Enhanced})
G.play:emplace(card)
table.insert(G.playing_cards, card)
return true
end}))
card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_plus_stone'), colour = G.C.SECONDARY_SET.Enhanced})
G.E_MANAGER:add_event(Event({
func = function()
G.deck.config.card_limit = G.deck.config.card_limit + 1
return true
end}))
draw_card(G.play,G.deck, 90,'up', nil)
playing_card_joker_effects({card})
'''
## Remove unneeded area check
# Card:calculate_joker
[[patches]]
[patches.pattern]
target = 'card.lua'
match_indent = true
position = 'at'
pattern = 'if context.cardarea == G.jokers then'
payload = 'do'
[[patches]]
[patches.regex]
target = 'game.lua'
position = 'at'
pattern = 'G.GAME.blind:get_loc_debuff_text\(\)'
payload = 'SMODS.debuff_text or G.GAME.blind:get_loc_debuff_text()'