[manifest]
version = "1.0.0"
dump_lua = true
priority = -10

### Playing Card API

# Game:init_game_object()
[[patches]]
[patches.pattern]
target = 'game.lua'
pattern = 'function Game:init_game_object()'
position = 'after'
match_indent = true
payload = '''
    local cards_played = {}
    for _,v in ipairs(SMODS.Rank.obj_buffer) do
        cards_played[v] = { suits = {}, total = 0 }
    end'''

[[patches]]
[patches.regex]
target = "game.lua"
pattern = '(?<indent>[\t ]*)cards_played = \{\n(.*\n){13}[\t ]*\},'
position = 'at'
line_prepend = '$indent'
payload = '''
    cards_played = cards_played,
    disabled_suits = {},
    disabled_ranks = {},'''

# Game:start_run()
[[patches]]
[patches.pattern]
target = "game.lua"
pattern = 'local _ = nil'
position = 'before'
match_indent = true
payload = '''
if type(SMODS.Ranks[v.value].in_pool) == 'function' and not SMODS.Ranks[v.value]:in_pool({initial_deck = true, suit = v.suit})
or type(SMODS.Suits[v.suit].in_pool) == 'function' and not SMODS.Suits[v.suit]:in_pool({initial_deck = true, rank = v.value}) then
    goto continue
end'''

[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "if self.GAME.starting_params.erratic_suits_and_ranks then _, k = pseudorandom_element(G.P_CARDS, pseudoseed('erratic')) end"
position = 'at'
match_indent = true
payload = '''if self.GAME.starting_params.erratic_suits_and_ranks then
    v, k = pseudorandom_element(G.P_CARDS, pseudoseed('erratic'), {starting_deck = true})
end'''

[[patches]]
[patches.pattern]
target = "game.lua"
pattern = 'local _r, _s = string.sub(k, 3, 3), string.sub(k, 1, 1)'
position = 'at'
match_indent = true
payload = 'local _r, _s = SMODS.Ranks[v.value].card_key, SMODS.Suits[v.suit].card_key'

[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "if self.GAME.starting_params.no_faces and (_r == 'K' or _r == 'Q' or _r == 'J') then keep = false end"
position = 'at'
match_indent = true
payload = '''
if self.GAME.starting_params.no_faces and SMODS.Ranks[v.value].face then keep = false end'''

[[patches]]
[patches.pattern]
target = "game.lua"
pattern = "if keep then card_protos[#card_protos+1] = {s=_s,r=_r,e=_e,d=_d,g=_g} end"
position = "after"
payload = "::continue::"
match_indent = true

# loc_colour()
[[patches]]
[patches.pattern]
target = 'functions/misc_functions.lua'
pattern = 'return G.ARGS.LOC_COLOURS[_c] or _default or G.C.UI.TEXT_DARK'
position = 'before'
match_indent = true
payload = '''
    for _, v in ipairs(SMODS.Rarity.obj_buffer) do
        G.ARGS.LOC_COLOURS[v:lower()] = G.C.RARITY[v]
    end
    for _, v in ipairs(SMODS.Gradient.obj_buffer) do
        G.ARGS.LOC_COLOURS[v:lower()] = SMODS.Gradients[v]
    end
    for _, v in ipairs(SMODS.ConsumableType.ctype_buffer) do
        G.ARGS.LOC_COLOURS[v:lower()] = G.C.SECONDARY_SET[v]
    end
    for _, v in ipairs(SMODS.Suit.obj_buffer) do
        G.ARGS.LOC_COLOURS[v:lower()] = G.C.SUITS[v]
    end'''

# get_flush()
[[patches]]
[patches.regex]
target = "functions/misc_functions.lua"
pattern = '(?<indent>[\t ]*)local suits = \{\n[\t ]*"Spades",\n[\t ]*"Hearts",\n[\t ]*"Clubs",\n[\t ]*"Diamonds"\n[\t ]*\}\n[\t ]*if #hand > 5 or (?<restcond>#hand < \(5 - \(four_fingers and 1 or 0\)\) then return ret else)'
position = 'at'
line_prepend = '$indent'
payload = '''
local suits = SMODS.Suit.obj_buffer
if $restcond'''

# get_X_same()
[[patches]]
[patches.pattern]
target = 'functions/misc_functions.lua'
pattern = 'local vals = {{},{},{},{},{},{},{},{},{},{},{},{},{},{}}'
position = 'at'
match_indent = true
payload = '''
local vals = {}
for i = 1, SMODS.Rank.max_id.value do
    vals[i] = {}
end'''

[[patches]]
[patches.pattern]
target = 'functions/misc_functions.lua'
pattern = 'function get_X_same(num, hand)'
position = 'at'
match_indent = true
payload = '''function get_X_same(num, hand, or_more)'''

[[patches]]
[patches.pattern]
target = 'functions/misc_functions.lua'
pattern = 'if #curr == num then'
position = 'at'
match_indent = true
payload = '''if or_more and (#curr >= num) or (#curr == num) then'''

# Card:get_nominal()
[[patches]]
[patches.regex]
target = "card.lua"
pattern = 'function Card:get_nominal\(mod\)\n([\t ]+.*\n)*end'
position = 'at'
payload = '''
function Card:get_nominal(mod)
    local mult = 1
    local rank_mult = 1
    if mod == 'suit' then mult = 10000 end
    if self.ability.effect == 'Stone Card' or (self.config.center.no_suit and self.config.center.no_rank) then
        mult = -10000
    elseif self.config.center.no_suit then
        mult = 0
    elseif self.config.center.no_rank then
        rank_mult = 0
    end
    return 10*self.base.nominal*rank_mult + self.base.suit_nominal*mult + (self.base.suit_nominal_original or 0)*0.0001*mult + 10*self.base.face_nominal*rank_mult + 0.000001*self.unique_val
end'''

# Card:set_base()
[[patches]]
[patches.regex]
target = 'card.lua'
pattern = "(?<indent>[\t ]*)if self.base.value == '2' then self.base.nominal = 2; self.base.id = 2(\n[\t ]+elseif .*)*"
position = 'at'
line_prepend = '$indent'
payload = '''
local rank = SMODS.Ranks[self.base.value] or {}
self.base.nominal = rank.nominal or 0
self.base.face_nominal = rank.face_nominal or 0
self.base.id = rank.id'''

[[patches]]
[patches.regex]
target = 'card.lua'
pattern = "(?<indent>[\t ]*)if self.base.suit == 'Diamonds' then self.base.suit_nominal = 0.01; self.base.suit_nominal_original = suit_base_nominal_original or 0.001 (\n[\t ]+elseif .*)*"
position = 'at'
line_prepend = '$indent'
payload = '''
local suit = SMODS.Suits[self.base.suit] or {}
self.base.suit_nominal = suit.suit_nominal or 0
self.base.suit_nominal_original = suit_base_nominal_original or suit.suit_nominal or 0'''

# Card:change_suit()
[[patches]]
[patches.regex]
target = 'card.lua'
pattern = "(?<indent>[\t ]*)local new_code = [\\s\\S]*?local new_val = [\\s\\S]*?local new_card = G.P_CARDS\\[new_code..new_val\\]"
position = 'at'
line_prepend = '$indent'
payload = '''
local new_code = SMODS.Suits[new_suit].card_key
local new_val = SMODS.Ranks[self.base.value].card_key
local new_card = G.P_CARDS[new_code..'_'..new_val]'''

# Card:is_face()
[[patches]]
[patches.regex]
target = 'card.lua'
pattern = "(?<indent>[\t ]*)if id == 11 or id == 12 or id == 13 or next\\(find_joker\\(\"Pareidolia\"\\)\\) then"
position = 'at'
line_prepend = '$indent'
payload = '''
local rank = SMODS.Ranks[self.base.value]
if not id then return end
if (id > 0 and rank and rank.face) or next(find_joker("Pareidolia")) then'''


# tally_sprite()
[[patches]]
[patches.regex]
target = 'functions/UI_definitions.lua'
pattern = '(?<start>[\t ]*local t_s = Sprite\(0,0,0.5,0.5,)G.ASSET_ATLAS\[.*?\](?<rest>.*?\))'
position = 'at'
payload = '$start G.ASSET_ATLAS[suit and SMODS.Suits[suit][G.SETTINGS.colourblind_option and "hc_ui_atlas" or "lc_ui_atlas"]] or G.ASSET_ATLAS[("ui_"..(G.SETTINGS.colourblind_option and "2" or "1"))]$rest'

[[patches]]
[patches.pattern]
target = 'functions/UI_definitions.lua'
pattern = 'function tally_sprite(pos, value, tooltip)'
position = 'at'
match_indent = true
payload = 'function tally_sprite(pos, value, tooltip, suit)'

# G.UIDEF.challenge_description_tab()
[[patches]]
[patches.regex]
target = 'functions/UI_definitions.lua'
pattern = "(?<indent>[\t ]*)local SUITS = \\{(\n.*){5}\n[\t ]*local suit_map = \\{'S', 'H', 'C', 'D'\\}"
position = 'at'
line_prepend = '$indent'
payload = '''
local SUITS = {}
local suit_map = {}
for i = #SMODS.Suit.obj_buffer, 1, -1 do
    local suit = SMODS.Suits[SMODS.Suit.obj_buffer[i]]
    SUITS[suit.card_key] = {}
    suit_map[#suit_map+1] = suit.card_key
end'''

[[patches]]
[patches.pattern]
target = "functions/UI_definitions.lua"
pattern = 'local _r, _s = string.sub(k, 3, 3), string.sub(k, 1, 1)'
position = 'at'
match_indent = true
payload = 'local _r, _s = SMODS.Ranks[v.value].card_key, SMODS.Suits[v.suit].card_key'

# TODO there may need to be a way to let in_pool know what challenge is being displayed
[[patches]]
[patches.pattern]
target = "functions/UI_definitions.lua"
pattern = 'local keep, _e, _d, _g = true, nil, nil, nil'
position = 'after'
match_indent = true
payload = '''
if type(SMODS.Ranks[v.value].in_pool) == 'function' and not SMODS.Ranks[v.value]:in_pool({initial_deck = true, suit = v.suit}) then
    keep = false
end
if type(SMODS.Suits[v.suit].in_pool) == 'function' and not SMODS.Suits[v.suit]:in_pool({initial_deck = true, rank = v.value}) then
    keep = false
end'''

[[patches]]
[patches.regex]
target = 'functions/UI_definitions.lua'
pattern = '(?<indent>[\t ]*)for j = 1, 4 do\n[\t ]*(?<mid>if SUITS\[suit_map\[j\]\]\[1\] then\n[\t ]*table.sort.*(\n.*)*?)\n[\t ]*0\.42\*G.CARD_H,'
position = 'at'
line_prepend = '$indent'
payload = '''
local num_suits = 0
for j = 1, #suit_map do
    if SUITS[suit_map[j]][1] then num_suits = num_suits + 1 end
end
for j = 1, #suit_map do
    $mid
            (0.42 - (num_suits <= 4 and 0 or num_suits >= 8 and 0.28 or 0.07 * (num_suits - 4))) * G.CARD_H,'''

[[patches]]
[patches.pattern]
target = 'functions/common_events.lua'
pattern = '--Fill all remaining info if this is the main desc'
position = 'before'
match_indent = true
payload = '''if card_type == 'Default' or card_type == 'Enhanced' and not _c.replace_base_card and card and card.base then
    if not _c.no_suit then
        local suit = SMODS.Suits[card.base.suit] or {}
        if suit.loc_vars and type(suit.loc_vars) == 'function' then
            suit:loc_vars(info_queue, card)
        end
    end
    if not _c.no_rank then
        local rank = SMODS.Ranks[card.base.value] or {}
        if rank.loc_vars and type(rank.loc_vars) == 'function' then
            rank:loc_vars(info_queue, card)
        end
    end
end

'''
