2653 lines
64 KiB
Lua
2653 lines
64 KiB
Lua
--[[
|
|
gameset_config = {
|
|
modest = {extra = {chips = 1}, center = {rarity = 1, blueprint_compat = false, immutable = true, no_dbl = false}},
|
|
mainline = {center = {rarity = 2, blueprint_compat = true, immutable = true, no_dbl = true}},
|
|
madness = {extra = {chips = 100}, center = {rarity = 3}},
|
|
cryptid_in_2025 = {extra = {chips = 1e308}, center = {rarity = "cry_exotic"}},
|
|
},
|
|
-- Card.get_gameset(card) ~= "modest"
|
|
|
|
--TODO Modest descriptions for
|
|
Supercell
|
|
Old Membership card
|
|
Canvas
|
|
Nostalgic Googol Play Card
|
|
One For all
|
|
--]]
|
|
|
|
-- Supercell
|
|
-- +15 Chips, +15 Mult, X2 Chips, X2 Mult, earn $3 at end of round
|
|
local supercell = {
|
|
object_type = "Joker",
|
|
name = "cry-supercell",
|
|
key = "supercell",
|
|
config = {
|
|
extra = {
|
|
stat1 = 15,
|
|
stat2 = 2,
|
|
money = 3,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
pos = { x = 5, y = 1 },
|
|
rarity = "cry_epic",
|
|
cost = 14,
|
|
order = 64,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
return {
|
|
key = Cryptid.gameset_loc(self, { modest = "balanced" }),
|
|
vars = {
|
|
number_format(center.ability.extra.stat1),
|
|
number_format(center.ability.extra.stat2),
|
|
number_format(center.ability.extra.money),
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.joker_main then
|
|
if to_big(card.ability.extra.stat2) > to_big(1) then --misprint deck moment
|
|
if Card.get_gameset(card) ~= "modest" then
|
|
return {
|
|
message = localize("cry_gaming_ex"),
|
|
chip_mod = lenient_bignum(card.ability.extra.stat1),
|
|
mult_mod = lenient_bignum(card.ability.extra.stat1),
|
|
Xchip_mod = lenient_bignum(card.ability.extra.stat2),
|
|
Xmult_mod = lenient_bignum(card.ability.extra.stat2),
|
|
}
|
|
else
|
|
return {
|
|
message = localize("cry_gaming_ex"),
|
|
Xchip_mod = lenient_bignum(card.ability.extra.stat2),
|
|
Xmult_mod = lenient_bignum(card.ability.extra.stat2),
|
|
}
|
|
end
|
|
end
|
|
end
|
|
if context.forcetrigger then
|
|
ease_dollars(lenient_bignum(card.ability.extra.money))
|
|
return {
|
|
message = localize("cry_gaming_ex"),
|
|
chip_mod = lenient_bignum(card.ability.extra.stat1),
|
|
mult_mod = lenient_bignum(card.ability.extra.stat1),
|
|
Xchip_mod = lenient_bignum(card.ability.extra.stat2),
|
|
Xmult_mod = lenient_bignum(card.ability.extra.stat2),
|
|
}
|
|
end
|
|
end,
|
|
calc_dollar_bonus = function(self, card)
|
|
if to_big(card.ability.extra.money) > to_big(0) then
|
|
return lenient_bignum(card.ability.extra.money)
|
|
end
|
|
end,
|
|
add_to_deck = function(self, card, from_debuff)
|
|
if not from_debuff then
|
|
play_sound("cry_studiofromhelsinki")
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Old Membership Card
|
|
-- +1 Chip for each member in the Cryptid Discord
|
|
local membershipcardtwo = {
|
|
object_type = "Joker",
|
|
name = "cry-membershipcardtwo",
|
|
key = "membershipcardtwo",
|
|
config = {
|
|
extra = { chips = 1 },
|
|
immutable = { chips_mod = 1 },
|
|
},
|
|
gameset_config = {
|
|
modest = {
|
|
cost = 20,
|
|
center = { rarity = 4 },
|
|
immutable = { chips_mod = 8 },
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
pos = { x = 5, y = 4 },
|
|
rarity = "cry_epic",
|
|
cost = 17,
|
|
order = 50,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, card)
|
|
local aaa
|
|
if not Cryptid_config.HTTPS then
|
|
if G.localization.descriptions.Other.cry_https_disabled then
|
|
aaa = {}
|
|
localize({ type = "other", key = "cry_https_disabled", nodes = aaa, vars = {} })
|
|
aaa = aaa[1]
|
|
end
|
|
end
|
|
return {
|
|
key = Cryptid.gameset_loc(self, { modest = "balanced" }),
|
|
vars = {
|
|
number_format(card.ability.extra.chips),
|
|
number_format(
|
|
lenient_bignum(
|
|
to_big(card.ability.extra.chips)
|
|
* math.floor(Cryptid.member_count / card.ability.immutable.chips_mod)
|
|
)
|
|
),
|
|
},
|
|
main_end = aaa,
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if (context.joker_main and to_big(card.ability.extra.chips) > to_big(0)) or context.forcetrigger then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_chips",
|
|
vars = {
|
|
number_format(
|
|
lenient_bignum(
|
|
to_big(card.ability.extra.chips)
|
|
* math.floor(Cryptid.member_count / card.ability.immutable.chips_mod)
|
|
)
|
|
),
|
|
},
|
|
}),
|
|
chip_mod = lenient_bignum(
|
|
to_big(card.ability.extra.chips)
|
|
* math.floor(Cryptid.member_count / card.ability.immutable.chips_mod)
|
|
),
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Linus Goof Balls",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Googol Play Card
|
|
-- 1 in 8 chance for X1e100 Mult
|
|
local googol_play = {
|
|
object_type = "Joker",
|
|
name = "cry-Googol Play Card",
|
|
key = "googol_play",
|
|
config = {
|
|
extra = {
|
|
Xmult = 1e100,
|
|
odds = 8,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = { extra = { Xmult = 9, odds = 8 } },
|
|
},
|
|
pos = { x = 3, y = 0 },
|
|
rarity = "cry_epic",
|
|
cost = 10,
|
|
order = 14,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
soul_pos = { x = 10, y = 0, extra = { x = 4, y = 0 } },
|
|
loc_vars = function(self, info_queue, card)
|
|
local aaa, bbb = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, "Googol Play Card")
|
|
return {
|
|
vars = {
|
|
aaa,
|
|
bbb,
|
|
number_format(card.ability.extra.Xmult),
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if
|
|
context.joker_main
|
|
and SMODS.pseudorandom_probability(card, "cry_googol_play", 1, card.ability.extra.odds, "Googol Play Card")
|
|
then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_xmult",
|
|
vars = { number_format(card.ability.extra.Xmult) },
|
|
}),
|
|
Xmult_mod = lenient_bignum(card.ability.extra.Xmult),
|
|
}
|
|
end
|
|
if context.forcetrigger then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_xmult",
|
|
vars = { number_format(card.ability.extra.Xmult) },
|
|
}),
|
|
Xmult_mod = lenient_bignum(card.ability.extra.Xmult),
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
".asdom",
|
|
},
|
|
art = {
|
|
"Linus Goof Balls",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
unlocked = false,
|
|
check_for_unlock = function(self, args)
|
|
if args.type == "chip_score" and to_big(args.chips) >= to_big(1e100) then
|
|
unlock_card(self)
|
|
end
|
|
if args.type == "cry_lock_all" then
|
|
lock_card(self)
|
|
end
|
|
if args.type == "cry_unlock_all" then
|
|
unlock_card(self)
|
|
end
|
|
end,
|
|
}
|
|
|
|
-- Sync Catalyst
|
|
-- Balances Chips and Mult
|
|
local sync_catalyst = {
|
|
object_type = "Joker",
|
|
name = "cry-Sync Catalyst",
|
|
key = "sync_catalyst",
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = {
|
|
cost = 20,
|
|
center = { rarity = 4 },
|
|
},
|
|
},
|
|
pos = { x = 5, y = 2 },
|
|
rarity = "cry_epic",
|
|
cost = 12,
|
|
order = 54,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
immutable = true,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if (context.joker_main and not context.debuffed_hand) or context.forcetrigger then
|
|
return {
|
|
balance = true,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Project666",
|
|
},
|
|
art = {
|
|
"Ein13",
|
|
"George The Rat",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
unlocked = true,
|
|
}
|
|
|
|
-- Negative Joker
|
|
-- +4 Joker slots
|
|
local negative = {
|
|
object_type = "Joker",
|
|
name = "cry-Negative Joker",
|
|
key = "negative",
|
|
pos = { x = 1, y = 3 },
|
|
config = {
|
|
extra = {
|
|
slots = 4,
|
|
},
|
|
immutable = {
|
|
max_slots = 100,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = { cost = 16 },
|
|
},
|
|
rarity = "cry_epic",
|
|
cost = 10,
|
|
order = 70,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
return { vars = { number_format(center.ability.extra.slots) } }
|
|
end,
|
|
add_to_deck = function(self, card, from_debuff)
|
|
if card.ability.extra.slots > card.ability.immutable.max_slots then
|
|
card.ability.extra.slots = card.ability.immutable.max_slots
|
|
end
|
|
G.jokers.config.card_limit = lenient_bignum(G.jokers.config.card_limit + to_big(card.ability.extra.slots))
|
|
end,
|
|
remove_from_deck = function(self, card, from_debuff)
|
|
G.jokers.config.card_limit = lenient_bignum(G.jokers.config.card_limit - to_big(card.ability.extra.slots))
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Xero01",
|
|
},
|
|
art = {
|
|
"Linus Goof Balls",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Canvas
|
|
-- Retrigger all Jokers to the left once for every non-Common Joker to the right of this Joker
|
|
-- Still considering moving to Legendary - Jevonn
|
|
local canvas = {
|
|
object_type = "Joker",
|
|
name = "cry-Canvas",
|
|
key = "canvas",
|
|
immutable = true,
|
|
order = 4,
|
|
pos = { x = 2, y = 1 },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
rarity = "cry_epic",
|
|
cost = 18,
|
|
blueprint_compat = true,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
return { key = Cryptid.gameset_loc(self, { modest = "balanced" }) }
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.retrigger_joker_check and not context.retrigger_joker then
|
|
local num_retriggers = 0
|
|
for i = 1, #G.jokers.cards do
|
|
if
|
|
card.T.x + card.T.w / 2 < G.jokers.cards[i].T.x + G.jokers.cards[i].T.w / 2
|
|
and G.jokers.cards[i].config.center.rarity ~= 1
|
|
and (G.jokers.cards[i].config.center.rarity ~= "cry_candy" or Card.get_gameset(card) ~= "modest")
|
|
then
|
|
num_retriggers = num_retriggers + 1
|
|
end
|
|
end
|
|
if
|
|
card.T
|
|
and context.other_card.T
|
|
and (card.T.x + card.T.w / 2 > context.other_card.T.x + context.other_card.T.w / 2)
|
|
then
|
|
return {
|
|
message = localize("k_again_ex"),
|
|
repetitions = Card.get_gameset(card) ~= "modest" and num_retriggers or math.min(2, num_retriggers),
|
|
card = card,
|
|
}
|
|
end
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Mystic Misclick",
|
|
},
|
|
art = {
|
|
"Lil. Mr. Slipstream",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- ERROR
|
|
-- Displays a glitched message
|
|
-- While in shop, all cards are Glitched (fallback: Foil)
|
|
-- After a random number of rounds, duplicates all Jokers when sold
|
|
-- The glitched message can tell you what the next card rolled in the shop will be (similar to the Misprint easter egg)
|
|
local error_joker = {
|
|
object_type = "Joker",
|
|
name = "cry-Error",
|
|
key = "error",
|
|
pos = { x = 4, y = 2 },
|
|
config = {
|
|
extra = {
|
|
sell_rounds = 0,
|
|
active = false,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
-- Note: This currently does not have a dependency on Glitched because there's a fallback.
|
|
-- However I think this should be changed later...
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
immutable = true,
|
|
rarity = "cry_epic",
|
|
cost = 1,
|
|
order = 72,
|
|
blueprint_compat = false,
|
|
eternal_compat = false,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
local ok, ret = pcall(Cryptid.predict_card_for_shop)
|
|
if Cryptid.safe_get(G.GAME, "pseudorandom") and G.STAGE == G.STAGES.RUN and ok then
|
|
cry_error_msgs[#cry_error_msgs].string = "%%" .. ret
|
|
else
|
|
cry_error_msgs[#cry_error_msgs].string = "%%J6"
|
|
end
|
|
return {
|
|
main_start = {
|
|
{
|
|
n = G.UIT.O,
|
|
config = {
|
|
object = DynaText({
|
|
string = cry_error_operators,
|
|
colours = { G.C.DARK_EDITION },
|
|
pop_in_rate = 9999999,
|
|
silent = true,
|
|
random_element = true,
|
|
pop_delay = 0.30,
|
|
scale = 0.32,
|
|
min_cycle_time = 0,
|
|
}),
|
|
},
|
|
},
|
|
{
|
|
n = G.UIT.O,
|
|
config = {
|
|
object = DynaText({
|
|
string = cry_error_numbers,
|
|
colours = { G.C.DARK_EDITION },
|
|
pop_in_rate = 9999999,
|
|
silent = true,
|
|
random_element = true,
|
|
pop_delay = 0.33,
|
|
scale = 0.32,
|
|
min_cycle_time = 0,
|
|
}),
|
|
},
|
|
},
|
|
{
|
|
n = G.UIT.O,
|
|
config = {
|
|
object = DynaText({
|
|
string = cry_error_msgs,
|
|
colours = { G.C.UI.TEXT_DARK },
|
|
pop_in_rate = 9999999,
|
|
silent = true,
|
|
random_element = true,
|
|
pop_delay = 0.4011,
|
|
scale = 0.32,
|
|
min_cycle_time = 0,
|
|
}),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
end,
|
|
add_to_deck = function(self, card, from_debuff)
|
|
if G.GAME.modifiers.cry_force_edition and not G.GAME.modifiers.cry_force_edition_from_deck then
|
|
G.GAME.modifiers.cry_force_edition_from_deck = G.GAME.modifiers.cry_force_edition
|
|
elseif not G.GAME.modifiers.cry_force_edition_from_deck then
|
|
if G.P_CENTERS.e_cry_glitched then
|
|
G.GAME.modifiers.cry_force_edition = "cry_glitched"
|
|
else
|
|
G.GAME.modifiers.cry_force_edition = "foil"
|
|
end
|
|
G.GAME.modifiers.cry_force_edition_from_deck = "Nope!"
|
|
end
|
|
end,
|
|
remove_from_deck = function(self, card, from_debuff)
|
|
if G.GAME.modifiers.cry_force_edition_from_deck ~= "Nope!" then
|
|
G.GAME.modifiers.cry_force_edition = G.GAME.modifiers.cry_force_edition_from_deck
|
|
else
|
|
G.GAME.modifiers.cry_force_edition = nil
|
|
end
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if
|
|
context.end_of_round
|
|
and not context.blueprint
|
|
and not context.repetition
|
|
and not context.individual
|
|
and not card.ability.extra.active
|
|
then
|
|
if card.ability.extra.sell_rounds == 0 then
|
|
card.ability.extra.sell_rounds = math.floor(pseudorandom(pseudoseed("cry_error")) * 10 + 1)
|
|
end
|
|
card.ability.extra.sell_rounds = card.ability.extra.sell_rounds - 1
|
|
if card.ability.extra.sell_rounds == 0 then
|
|
card.ability.extra.active = true
|
|
local eval = function(card)
|
|
return not card.REMOVED
|
|
end
|
|
juice_card_until(card, eval, true)
|
|
else
|
|
return {
|
|
message = "???",
|
|
colour = G.C.BLACK,
|
|
}
|
|
end
|
|
end
|
|
if
|
|
context.selling_self
|
|
and card.ability.extra.active
|
|
and not context.retrigger_joker
|
|
and not context.blueprint
|
|
then
|
|
local eval = function(card)
|
|
return (Cryptid.safe_get(card, "ability", "loyalty_remaining") == 0) and not G.RESET_JIGGLES
|
|
end
|
|
juice_card_until(card, eval, true)
|
|
local jokers = {}
|
|
for i = 1, #G.jokers.cards do
|
|
if G.jokers.cards[i].ability.name ~= "cry-Error" then
|
|
jokers[#jokers + 1] = G.jokers.cards[i]
|
|
end
|
|
end
|
|
for i = 1, #jokers do
|
|
local card = copy_card(jokers[i])
|
|
card:add_to_deck()
|
|
G.jokers:emplace(card)
|
|
end
|
|
return nil, true
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Coronacht",
|
|
"Fetch",
|
|
},
|
|
art = {
|
|
"mold spores",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
init = function(self)
|
|
cry_error_operators = { "+", "-", "X", "/", "^", "=", ">", "<", "m" }
|
|
cry_error_numbers = {
|
|
"0",
|
|
"1",
|
|
"2",
|
|
"3",
|
|
"4",
|
|
"5",
|
|
"6",
|
|
"7",
|
|
"8",
|
|
"9",
|
|
"10",
|
|
"69",
|
|
"404",
|
|
"420",
|
|
"-1",
|
|
"0.5",
|
|
"m",
|
|
"nan",
|
|
"inf",
|
|
"nil",
|
|
"pi",
|
|
"1e9",
|
|
"???",
|
|
"114",
|
|
"leet",
|
|
"666",
|
|
"eee6",
|
|
"21",
|
|
"365",
|
|
"2024",
|
|
}
|
|
cry_error_msgs = {
|
|
{ string = "rand()", colour = G.C.RARITY["cry_exotic"] },
|
|
{ string = "m", colour = G.C.UI.TEXT_DARK },
|
|
{ string = "Chips", colour = G.C.CHIPS },
|
|
{ string = "Mult", colour = G.C.MULT },
|
|
{ string = "Jokers", colour = G.C.FILTER },
|
|
{ string = "dollars", colour = G.C.FILTER },
|
|
{ string = "hands", colour = G.C.FILTER },
|
|
{ string = "slots", colour = G.C.FILTER },
|
|
{ string = "Antes", colour = G.C.FILTER },
|
|
{ string = "ERROR", colour = G.C.UI.TEXT_INACTIVE },
|
|
{ string = "Tarots", colour = G.C.SECONDARY_SET.Tarot },
|
|
{ string = "Planets", colour = G.C.SECONDARY_SET.Planet },
|
|
{ string = "Codes", colour = G.C.SECONDARY_SET.Code },
|
|
{ string = "Specls", colour = G.C.SECONDARY_SET.Spectral },
|
|
{ string = "Jolly", colour = G.C.CRY_JOLLY },
|
|
{ string = "Tags", colour = G.C.RED },
|
|
{ string = "Cryptids", colour = G.C.SECONDARY_SET.Spectral },
|
|
{ string = "Glop", colour = G.C.CRY_ALTGREENGRADIENT },
|
|
{ string = "%%ERROR", colour = G.C.CRY_ASCENDANT }, --temp string, this will be modified
|
|
}
|
|
|
|
function Cryptid.predict_pseudoseed(key)
|
|
local M = G.GAME.pseudorandom[key] or pseudohash(key .. (G.GAME.pseudorandom.seed or ""))
|
|
local m = math.abs(tonumber(string.format("%.13f", (2.134453429141 + M * 1.72431234) % 1)))
|
|
return (m + (G.GAME.pseudorandom.hashed_seed or 0)) / 2
|
|
end
|
|
|
|
function Cryptid.predict_card_for_shop()
|
|
local total_rate = G.GAME.joker_rate + G.GAME.playing_card_rate
|
|
for _, v in ipairs(SMODS.ConsumableType.obj_buffer) do
|
|
total_rate = total_rate + (G.GAME[v:lower() .. "_rate"] or 0)
|
|
end
|
|
local polled_rate = pseudorandom(Cryptid.predict_pseudoseed("cdt" .. G.GAME.round_resets.ante)) * total_rate
|
|
local check_rate = 0
|
|
-- need to preserve order to leave RNG unchanged
|
|
local rates =
|
|
{
|
|
{ type = "Joker", val = G.GAME.joker_rate },
|
|
{ type = "Tarot", val = G.GAME.tarot_rate },
|
|
{ type = "Planet", val = G.GAME.planet_rate },
|
|
{
|
|
type = (G.GAME.used_vouchers["v_illusion"] and pseudorandom(
|
|
Cryptid.predict_pseudoseed("illusion")
|
|
) > 0.6) and "Enhanced" or "Base",
|
|
val = G.GAME.playing_card_rate,
|
|
},
|
|
{ type = "Spectral", val = G.GAME.spectral_rate },
|
|
}
|
|
for _, v in ipairs(SMODS.ConsumableType.obj_buffer) do
|
|
if not (v == "Tarot" or v == "Planet" or v == "Spectral") then
|
|
table.insert(rates, { type = v, val = G.GAME[v:lower() .. "_rate"] })
|
|
end
|
|
end
|
|
for _, v in ipairs(rates) do
|
|
if polled_rate > check_rate and polled_rate <= check_rate + v.val then
|
|
local c = create_card(v.type, "ERROR", nil, nil, nil, nil, nil, "sho")
|
|
if not c.set then
|
|
return v.type:sub(1, 1) .. c.suit:sub(1, 1) .. c.value:sub(1, 2)
|
|
else
|
|
for i = 1, #G.P_CENTER_POOLS[c.set] do
|
|
if G.P_CENTER_POOLS[c.set][i].key == c.key then
|
|
return c.set:sub(1, 1) .. i
|
|
end
|
|
end
|
|
end
|
|
end
|
|
check_rate = check_rate + v.val
|
|
end
|
|
end
|
|
end,
|
|
}
|
|
|
|
-- m
|
|
-- This Joker gains X13 Mult when Jolly Joker is sold
|
|
local m = {
|
|
object_type = "Joker",
|
|
discovered = true,
|
|
name = "cry-m",
|
|
key = "m",
|
|
pos = { x = 3, y = 1 },
|
|
config = {
|
|
extra = {
|
|
extra = 13,
|
|
x_mult = 1,
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = {
|
|
extra = {
|
|
extra = 1,
|
|
x_mult = 1,
|
|
},
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
"set_cry_meme",
|
|
-- Note: This isn't in the M Joker content set due to being added separately
|
|
},
|
|
},
|
|
pools = { ["Meme"] = true, ["M"] = true },
|
|
rarity = "cry_epic",
|
|
order = 1,
|
|
cost = 13,
|
|
effect = "M Joker",
|
|
perishable_compat = false,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
loc_vars = function(self, info_queue, center)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.j_jolly
|
|
return {
|
|
vars = {
|
|
number_format(center.ability.extra.extra),
|
|
number_format(center.ability.extra.x_mult),
|
|
},
|
|
}
|
|
end,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if context.joker_main and (to_big(card.ability.extra.x_mult) > to_big(1)) then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_xmult",
|
|
vars = { number_format(card.ability.extra.x_mult) },
|
|
}),
|
|
Xmult_mod = card.ability.extra.x_mult,
|
|
}
|
|
end
|
|
if context.selling_card and context.card:is_jolly() and not context.blueprint then
|
|
SMODS.scale_card(card, {
|
|
ref_table = card.ability.extra,
|
|
ref_value = "x_mult",
|
|
scalar_value = "extra",
|
|
message_key = "a_xmult",
|
|
message_colour = G.C.RED,
|
|
})
|
|
return nil, true
|
|
end
|
|
if context.forcetrigger then
|
|
SMODS.scale_card(card, {
|
|
ref_table = card.ability.extra,
|
|
ref_value = "x_mult",
|
|
scalar_value = "extra",
|
|
message_key = "a_xmult",
|
|
message_colour = G.C.RED,
|
|
})
|
|
return {
|
|
Xmult_mod = card.ability.extra.x_mult,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- M
|
|
-- Create a Negative Jolly Joker when Blind is selected
|
|
local M = {
|
|
object_type = "Joker",
|
|
name = "cry-M",
|
|
key = "M",
|
|
pos = { x = 0, y = 0 },
|
|
order = 250,
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
--Note: This isn't in the M Joker content set due to being added separately
|
|
},
|
|
},
|
|
rarity = "cry_epic",
|
|
effect = "M Joker",
|
|
cost = 13,
|
|
immutable = true,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
loc_vars = function(self, info_queue, center)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.j_jolly
|
|
if not center.edition or (center.edition and not center.edition.negative) then
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
|
|
end
|
|
end,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if (context.setting_blind and not (context.blueprint_card or self).getting_sliced) or context.forcetrigger then
|
|
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_jolly")
|
|
card:set_edition({
|
|
negative = true,
|
|
})
|
|
card:add_to_deck()
|
|
G.jokers:emplace(card)
|
|
return nil, true
|
|
end
|
|
end,
|
|
pools = { ["M"] = true },
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Boredom
|
|
-- 1 in 2 chance to retrigger each Joker or played card
|
|
local boredom = {
|
|
object_type = "Joker",
|
|
name = "cry-Boredom",
|
|
key = "boredom",
|
|
pos = { x = 1, y = 0 },
|
|
config = { extra = { odds = 2 } },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
"set_cry_meme",
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = { extra = { odds = 3 } },
|
|
},
|
|
pools = { ["Meme"] = true },
|
|
rarity = "cry_epic",
|
|
order = 32,
|
|
cost = 14,
|
|
blueprint_compat = true,
|
|
loc_vars = function(self, info_queue, card)
|
|
local num, denom = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, "Boredom")
|
|
|
|
return {
|
|
vars = {
|
|
num,
|
|
denom,
|
|
},
|
|
}
|
|
end,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if
|
|
context.retrigger_joker_check
|
|
and not context.retrigger_joker
|
|
and not (context.other_card.ability and context.other_card.ability.name == "cry-Boredom")
|
|
then
|
|
if SMODS.pseudorandom_probability(card, "cry_boredom_joker", 1, card.ability.extra.odds, "Boredom") then
|
|
return {
|
|
message = localize("k_again_ex"),
|
|
repetitions = 1,
|
|
card = card,
|
|
}
|
|
else
|
|
return nil, true
|
|
end
|
|
end
|
|
if
|
|
context.repetition
|
|
and context.cardarea == G.play
|
|
and SMODS.pseudorandom_probability(card, "cry_boredom_joker", 1, card.ability.extra.odds, "Boredom")
|
|
then
|
|
return {
|
|
message = localize("k_again_ex"),
|
|
repetitions = 1,
|
|
card = card,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Math",
|
|
},
|
|
art = {
|
|
"Saturn",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Number Blocks
|
|
-- Earn $1 at end of round; Increase payout by $1 for each [rank] held in hand (changes every round)
|
|
local number_blocks = {
|
|
object_type = "Joker",
|
|
name = "cry-Number Blocks",
|
|
key = "number_blocks",
|
|
config = {
|
|
extra = {
|
|
money_mod = 1,
|
|
money = 1,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
pos = { x = 0, y = 2 },
|
|
rarity = "cry_epic",
|
|
cost = 14,
|
|
order = 12,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
return {
|
|
vars = {
|
|
number_format(center.ability.extra.money),
|
|
number_format(center.ability.extra.money_mod),
|
|
localize(Cryptid.safe_get(G.GAME, "current_round", "cry_nb_card", "rank") or "Ace", "ranks"),
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if
|
|
context.individual
|
|
and not context.end_of_round
|
|
and context.cardarea == G.hand
|
|
and not context.blueprint
|
|
and not context.before
|
|
and not context.after
|
|
and context.other_card:get_id() == G.GAME.current_round.cry_nb_card.id
|
|
then
|
|
if context.other_card.debuff then
|
|
return {
|
|
message = localize("k_debuffed"),
|
|
colour = G.C.RED,
|
|
card = card,
|
|
}
|
|
else
|
|
SMODS.scale_card(card, {
|
|
ref_table = card.ability.extra,
|
|
ref_value = "money",
|
|
scalar_value = "money_mod",
|
|
})
|
|
return nil, true
|
|
end
|
|
end
|
|
end,
|
|
calc_dollar_bonus = function(self, card)
|
|
if to_big(card.ability.extra.money) > to_big(0) then
|
|
return lenient_bignum(card.ability.extra.money)
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"George The Rat",
|
|
},
|
|
code = {
|
|
"Math",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Double Scale
|
|
-- Scaling jokers scale quadratically
|
|
-- Most of the code for this lies in Card:cry_double_scale_calc in lib/calculate.lua
|
|
local double_scale = {
|
|
object_type = "Joker",
|
|
name = "cry-Double Scale",
|
|
key = "Double Scale",
|
|
pos = { x = 0, y = 3 },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = {
|
|
cost = 20,
|
|
center = { rarity = 4 },
|
|
},
|
|
exp_modest = { cost = 11 },
|
|
},
|
|
extra_gamesets = { "exp_modest" },
|
|
loc_vars = function(self, info_queue, center)
|
|
return { key = Cryptid.gameset_loc(self, { exp_modest = "modest" }) }
|
|
end,
|
|
order = 6,
|
|
rarity = "cry_epic",
|
|
cost = 18,
|
|
immutable = true,
|
|
atlas = "atlasepic",
|
|
calc_scaling = function(self, card, other, current_scaling, current_scalar, args)
|
|
if not G.GAME.cryptid_base_scales then
|
|
G.GAME.cryptid_base_scales = {}
|
|
end
|
|
if not G.GAME.cryptid_base_scales[other.config.center.key] then
|
|
G.GAME.cryptid_base_scales[other.config.center.key] = {}
|
|
end
|
|
if not G.GAME.cryptid_base_scales[other.config.center.key][args.scalar_value] then
|
|
G.GAME.cryptid_base_scales[other.config.center.key][args.scalar_value] = current_scalar
|
|
end
|
|
local true_base = G.GAME.cryptid_base_scales[other.config.center.key][args.scalar_value]
|
|
local orig_scale_scale = current_scaling
|
|
if Cryptid.gameset(self) == "exp_modest" then
|
|
return {
|
|
scalar_value = lenient_bignum(to_big(true_base) * 2),
|
|
message = localize("k_upgrade_ex"),
|
|
}
|
|
end
|
|
args.scalar_table[args.scalar_value] = new_scale
|
|
return {
|
|
message = localize("k_upgrade_ex"),
|
|
}
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Mystic Misclick",
|
|
},
|
|
art = {
|
|
"lord.ruby",
|
|
},
|
|
code = {
|
|
"Math",
|
|
"Mathguy",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Nostalgic Candy
|
|
-- Sell this card to permanently gain +3 hand size
|
|
local oldcandy = {
|
|
object_type = "Joker",
|
|
name = "cry_oldcandy",
|
|
key = "oldcandy",
|
|
pos = { x = 4, y = 1 },
|
|
order = 43,
|
|
config = {
|
|
extra = { hand_size = 3 },
|
|
immutable = { max_hand_size_mod = 1000 },
|
|
},
|
|
gameset_config = {
|
|
modest = { extra = { hand_size = 1 } },
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
pools = { ["Food"] = true },
|
|
loc_vars = function(self, info_queue, center)
|
|
return {
|
|
vars = {
|
|
math.min(
|
|
center.ability.immutable.max_hand_size_mod,
|
|
math.max(1, math.floor(center.ability.extra.hand_size))
|
|
),
|
|
},
|
|
}
|
|
end,
|
|
rarity = "cry_epic",
|
|
cost = 9,
|
|
blueprint_compat = true,
|
|
eternal_compat = false,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if context.selling_self or context.forcetrigger then
|
|
G.hand:change_size(
|
|
math.min(
|
|
card.ability.immutable.max_hand_size_mod,
|
|
math.max(1, math.floor(card.ability.extra.hand_size))
|
|
)
|
|
)
|
|
return nil, true
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Circus
|
|
-- Rare/Epic/Legendary/Exotic Jokers give X2/3/4/20 Mult
|
|
local circus = {
|
|
object_type = "Joker",
|
|
name = "cry-circus",
|
|
key = "circus",
|
|
pos = { x = 4, y = 4 },
|
|
config = {},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
atlas = "atlasepic",
|
|
order = 33,
|
|
|
|
loc_vars = function(self, info_queue, center)
|
|
local extra_rarities = {}
|
|
local mults = {}
|
|
Cryptid.circus_rarities["exotic"].colour = G.C.CRY_EXOTIC
|
|
for i, v in pairs(Cryptid.circus_rarities) do
|
|
extra_rarities[#extra_rarities + 1] = v
|
|
end
|
|
table.sort(extra_rarities, function(a, b)
|
|
return a.order < b.order
|
|
end)
|
|
mults.colours = {}
|
|
for i, v in pairs(extra_rarities) do
|
|
if not v.hidden then
|
|
mults[#mults + 1] = number_format(center.ability.extra[tostring(v.rarity) .. "_mult_mod"])
|
|
mults.colours[#mults.colours + 1] = v.colour
|
|
end
|
|
end
|
|
return {
|
|
vars = mults,
|
|
}
|
|
end,
|
|
set_ability = function(self, center)
|
|
local extra_rarities = {}
|
|
local mults = {}
|
|
local mult_numbers = {}
|
|
for i, v in pairs(Cryptid.circus_rarities) do
|
|
extra_rarities[#extra_rarities + 1] = v
|
|
end
|
|
table.sort(extra_rarities, function(a, b)
|
|
return a.order < b.order
|
|
end)
|
|
for i, v in pairs(extra_rarities) do
|
|
mult_numbers[tostring(v.rarity) .. "_mult_mod"] = v.base_mult
|
|
mults[v.rarity] = tostring(v.rarity) .. "_mult_mod"
|
|
end
|
|
if not self.config.extra then
|
|
self.config.extra = mult_numbers
|
|
center.ability.extra = mult_numbers
|
|
self.config.immutable = {
|
|
rarity_map = mults,
|
|
}
|
|
center.ability.immutable = {
|
|
rarity_map = mults,
|
|
}
|
|
end
|
|
end,
|
|
rarity = "cry_epic",
|
|
cost = 16,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
calculate = function(self, card, context)
|
|
if context.other_joker and card ~= context.other_joker then
|
|
local mod_key = card.ability.immutable.rarity_map[context.other_joker.config.center.rarity]
|
|
if mod_key and card.ability.extra[mod_key] and to_big(card.ability.extra[mod_key]) > to_big(1) then
|
|
if not Talisman.config_file.disable_anims then
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
context.other_joker:juice_up(0.5, 0.5)
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
local xmult = card.ability.extra[mod_key]
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_xmult",
|
|
vars = { number_format(xmult) },
|
|
}),
|
|
Xmult_mod = xmult,
|
|
}
|
|
end
|
|
end
|
|
if context.forcetrigger then
|
|
local total = 1
|
|
for i, v in pairs(card.ability.extra) do
|
|
if type(v) == "number" or (type(v) == "table" and v.tetrate) then
|
|
total = total * v
|
|
end
|
|
end
|
|
return {
|
|
Xmult_mod = total,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Ein13",
|
|
},
|
|
art = {
|
|
"Ein13",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
"BobJoe400",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Caramel
|
|
-- Each played card gives X1.75 Mult when scored for the next 11 rounds
|
|
local caramel = {
|
|
object_type = "Joker",
|
|
name = "cry-caramel",
|
|
key = "caramel",
|
|
config = {
|
|
extra = {
|
|
x_mult = 1.75,
|
|
rounds_remaining = 11,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
pos = { x = 0, y = 1 },
|
|
rarity = "cry_epic",
|
|
cost = 12,
|
|
order = 106,
|
|
gameset_config = {
|
|
modest = {
|
|
extra = {
|
|
x_mult = 1.5,
|
|
rounds_remaining = 6,
|
|
},
|
|
},
|
|
},
|
|
pools = { ["Food"] = true },
|
|
blueprint_compat = true,
|
|
eternal_compat = false,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
return {
|
|
vars = {
|
|
number_format(center.ability.extra.x_mult),
|
|
number_format(center.ability.extra.rounds_remaining),
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.individual then
|
|
if context.cardarea == G.play then
|
|
return {
|
|
x_mult = lenient_bignum(card.ability.extra.x_mult),
|
|
colour = G.C.RED,
|
|
card = card,
|
|
}
|
|
end
|
|
end
|
|
if
|
|
context.end_of_round
|
|
and not context.blueprint
|
|
and not context.individual
|
|
and not context.repetition
|
|
and not context.retrigger_joker
|
|
then
|
|
card.ability.extra.rounds_remaining = lenient_bignum(to_big(card.ability.extra.rounds_remaining) - 1)
|
|
if to_big(card.ability.extra.rounds_remaining) > to_big(0) then
|
|
return {
|
|
message = { localize("cry_minus_round") },
|
|
colour = G.C.FILTER,
|
|
}
|
|
else
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
play_sound("tarot1")
|
|
card.T.r = -0.2
|
|
card:juice_up(0.3, 0.4)
|
|
card.states.drag.is = true
|
|
card.children.center.pinch.x = true
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.3,
|
|
blockable = false,
|
|
func = function()
|
|
G.jokers:remove_card(card)
|
|
card:remove()
|
|
card = nil
|
|
return true
|
|
end,
|
|
}))
|
|
return true
|
|
end,
|
|
}))
|
|
return {
|
|
message = localize("k_eaten_ex"),
|
|
colour = G.C.FILTER,
|
|
}
|
|
end
|
|
end
|
|
if context.forcetrigger then
|
|
card.ability.extra.rounds_remaining = lenient_bignum(to_big(card.ability.extra.rounds_remaining) - 1)
|
|
card.ability.extra.rounds_remaining = math.max(card.ability.extra.rounds_remaining, 0)
|
|
return {
|
|
Xmult_mod = lenient_bignum(card.ability.extra.x_mult),
|
|
colour = G.C.RED,
|
|
card = card,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Sob
|
|
-- you cannot run... you cannot hide... you cannot escape...
|
|
-- Creates a Negative Absolute Eternal Obelisk when added
|
|
-- Creates Obelisks (if room) when doing just about anything
|
|
|
|
-- Still planning on making one more change to this later - Jevonn
|
|
local curse_sob = {
|
|
object_type = "Joker",
|
|
name = "cry_curse_sob",
|
|
key = "curse_sob",
|
|
pos = { x = 1, y = 1 },
|
|
pools = { ["Meme"] = true },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
"set_cry_meme",
|
|
},
|
|
},
|
|
gameset_config = {
|
|
modest = {
|
|
cost = 20,
|
|
center = { rarity = 4 },
|
|
},
|
|
},
|
|
rarity = "cry_epic",
|
|
cost = 9,
|
|
order = 82,
|
|
immutable = true,
|
|
perishable_compat = true,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if
|
|
context.selling_card
|
|
and context.card.ability.name == "Obelisk"
|
|
and not context.retrigger_joker
|
|
and not context.blueprint
|
|
then
|
|
return {}
|
|
elseif
|
|
( -- Compacting all the elseifs into one block for space and readability also maintablity
|
|
context.selling_self
|
|
or context.discard
|
|
or context.reroll_shop --Yes
|
|
or context.buying_card
|
|
or context.skip_blind
|
|
or context.using_consumeable
|
|
or context.selling_card
|
|
or context.setting_blind
|
|
or context.skipping_booster
|
|
or context.open_booster
|
|
or context.forcetrigger
|
|
)
|
|
and (#G.jokers.cards + G.GAME.joker_buffer < (context.selling_self and (G.jokers.config.card_limit + 1) or G.jokers.config.card_limit))
|
|
or context.forcetrigger and not context.retrigger_joker and not context.blueprint
|
|
then
|
|
local createjoker = math.min(1, G.jokers.config.card_limit - (#G.jokers.cards + G.GAME.joker_buffer))
|
|
G.GAME.joker_buffer = G.GAME.joker_buffer + createjoker
|
|
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_obelisk")
|
|
card:add_to_deck()
|
|
G.jokers:emplace(card)
|
|
G.GAME.joker_buffer = 0
|
|
return {
|
|
card_eval_status_text(card, "extra", nil, nil, nil, {
|
|
message = localize("cry_curse_ex"),
|
|
colour = G.C.FILTER,
|
|
}),
|
|
}
|
|
end
|
|
end,
|
|
add_to_deck = function(self, card, from_debuff)
|
|
if not from_debuff then
|
|
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_obelisk")
|
|
card:set_edition("e_negative", true, nil, true)
|
|
card.ability.cry_absolute = true
|
|
card:add_to_deck()
|
|
G.jokers:emplace(card)
|
|
return {
|
|
card_eval_status_text(card, "extra", nil, nil, nil, {
|
|
message = localize("cry_curse_ex"),
|
|
colour = G.C.DARK_EDITION,
|
|
}),
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
unlocked = false,
|
|
check_for_unlock = function(self, args)
|
|
if Cryptid.safe_get(G, "jokers") then
|
|
for i = 1, #G.jokers.cards do
|
|
if G.jokers.cards[i].config.center.key == "j_obelisk" and SMODS.is_eternal(G.jokers.cards[i]) then
|
|
unlock_card(self)
|
|
end
|
|
end
|
|
end
|
|
if args.type == "cry_lock_all" then
|
|
lock_card(self)
|
|
end
|
|
if args.type == "cry_unlock_all" then
|
|
unlock_card(self)
|
|
end
|
|
end,
|
|
}
|
|
|
|
-- Bonus Joker
|
|
-- 1 in 8 chance for each played Bonus Card to increase Joker or Consumable slots by 1 when scored
|
|
-- Works twice per round
|
|
local bonusjoker = {
|
|
object_type = "Joker",
|
|
name = "cry-Bonus Joker",
|
|
key = "bonusjoker",
|
|
pos = { x = 3, y = 2 },
|
|
config = {
|
|
extra = {
|
|
odds = 8,
|
|
add = 1,
|
|
},
|
|
immutable = { check = 0, max = 100 },
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
immutable = false,
|
|
rarity = "cry_epic",
|
|
cost = 11,
|
|
order = 75,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
enhancement_gate = "m_bonus",
|
|
loc_vars = function(self, info_queue, card)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.m_bonus
|
|
local aaa, bbb = SMODS.get_probability_vars(card, 1, card.ability.extra.odds, "Bonus Joker")
|
|
return {
|
|
vars = {
|
|
aaa,
|
|
bbb,
|
|
number_format(math.min(card.ability.extra.add, card.ability.immutable.max)),
|
|
},
|
|
}
|
|
end,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play then
|
|
if SMODS.has_enhancement(context.other_card, "m_bonus") then
|
|
if
|
|
SMODS.pseudorandom_probability(card, "bonusjoker", 1, card.ability.extra.odds, "Bonus Joker")
|
|
and card.ability.immutable.check < 2
|
|
and not context.retrigger_joker
|
|
then
|
|
local option = pseudorandom_element({ 1, 2 }, pseudoseed("bonusjoker"))
|
|
if option == 1 then
|
|
if not context.blueprint then
|
|
card.ability.immutable.check = lenient_bignum(card.ability.immutable.check + 1)
|
|
end
|
|
G.jokers.config.card_limit = lenient_bignum(
|
|
G.jokers.config.card_limit + math.min(card.ability.extra.add, card.ability.immutable.max)
|
|
)
|
|
else
|
|
if not context.blueprint then
|
|
card.ability.immutable.check = lenient_bignum(card.ability.immutable.check + 1)
|
|
end
|
|
G.consumeables.config.card_limit = lenient_bignum(
|
|
G.consumeables.config.card_limit
|
|
+ to_big(math.min(card.ability.extra.add, card.ability.immutable.max))
|
|
)
|
|
end
|
|
return {
|
|
extra = { focus = card, message = localize("k_upgrade_ex") },
|
|
card = card,
|
|
colour = G.C.MONEY,
|
|
}
|
|
end
|
|
end
|
|
end
|
|
if
|
|
context.end_of_round
|
|
and card.ability.immutable.check ~= 0
|
|
and not context.blueprint
|
|
and not context.retrigger_joker
|
|
and not context.individual
|
|
and not context.repetition
|
|
then
|
|
card.ability.immutable.check = 0
|
|
return {
|
|
message = localize("k_reset"),
|
|
card = card,
|
|
}
|
|
end
|
|
if context.forcetrigger then
|
|
local option = pseudorandom_element({ 1, 2 }, pseudoseed("bonusjoker"))
|
|
if option == 1 then
|
|
if not context.blueprint then
|
|
card.ability.immutable.check = lenient_bignum(card.ability.immutable.check + 1)
|
|
end
|
|
G.jokers.config.card_limit = lenient_bignum(
|
|
G.jokers.config.card_limit + cmath.min(card.ability.extra.add, card.ability.immutable.max)
|
|
)
|
|
else
|
|
if not context.blueprint then
|
|
card.ability.immutable.check = lenient_bignum(card.ability.immutable.check + 1)
|
|
end
|
|
G.consumeables.config.card_limit = lenient_bignum(
|
|
G.consumeables.config.card_limit
|
|
+ to_big(math.min(card.ability.extra.add, card.ability.immutable.max))
|
|
)
|
|
end
|
|
return {
|
|
extra = { focus = card, message = localize("k_upgrade_ex") },
|
|
card = card,
|
|
colour = G.C.MONEY,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Mult Joker
|
|
-- 1 in 3 chance for each played Mult Card to create a Cryptid when scored (Must have room)
|
|
local multjoker = {
|
|
object_type = "Joker",
|
|
name = "cry-Mult Joker",
|
|
key = "multjoker",
|
|
pos = { x = 2, y = 3 },
|
|
config = { extra = { odds = 3 } },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
rarity = "cry_epic",
|
|
order = 99,
|
|
cost = 11,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
enhancement_gate = "m_mult",
|
|
loc_vars = function(self, info_queue, card)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.m_mult
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.c_cryptid
|
|
return {
|
|
vars = { SMODS.get_probability_vars(card, 1, card.ability.extra.odds, "Mult Joker") },
|
|
}
|
|
end,
|
|
atlas = "atlasepic",
|
|
calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play then
|
|
if
|
|
SMODS.has_enhancement(context.other_card, "m_mult")
|
|
and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit
|
|
then
|
|
if SMODS.pseudorandom_probability(card, "multjoker", 1, card.ability.extra.odds, "Mult Joker") then
|
|
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
local new_card =
|
|
create_card("Spectral", G.consumeables, nil, nil, nil, nil, "c_cryptid", "multjoker")
|
|
new_card:add_to_deck()
|
|
G.consumeables:emplace(new_card)
|
|
G.GAME.consumeable_buffer = 0
|
|
return true
|
|
end,
|
|
}))
|
|
card_eval_status_text(
|
|
context.blueprint_card or card,
|
|
"extra",
|
|
nil,
|
|
nil,
|
|
nil,
|
|
{ message = localize("cry_plus_cryptid"), colour = G.C.SECONDARY_SET.Spectral }
|
|
)
|
|
return nil, true
|
|
end
|
|
end
|
|
end
|
|
if context.forcetrigger then
|
|
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer + 1
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
local new_card =
|
|
create_card("Spectral", G.consumeables, nil, nil, nil, nil, "c_cryptid", "multjoker")
|
|
new_card:add_to_deck()
|
|
G.consumeables:emplace(new_card)
|
|
G.GAME.consumeable_buffer = 0
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Gold Joker
|
|
-- Earn +2% at end of round when a Gold Card is scored
|
|
local goldjoker = {
|
|
object_type = "Joker",
|
|
name = "cry-gold Joker",
|
|
key = "goldjoker",
|
|
config = {
|
|
extra = {
|
|
percent_mod = 2,
|
|
percent = 0,
|
|
},
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
pos = { x = 0, y = 4 },
|
|
rarity = "cry_epic",
|
|
cost = 14,
|
|
order = 81,
|
|
enhancement_gate = "m_gold",
|
|
perishable_compat = false,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.m_gold
|
|
return {
|
|
vars = {
|
|
number_format(center.ability.extra.percent),
|
|
number_format(center.ability.extra.percent_mod),
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.cardarea == G.play and context.individual and not context.blueprint then
|
|
if SMODS.has_enhancement(context.other_card, "m_gold") then
|
|
SMODS.scale_card(card, {
|
|
ref_table = card.ability.extra,
|
|
ref_value = "percent",
|
|
scalar_value = "percent_mod",
|
|
})
|
|
end
|
|
end
|
|
if context.individual and context.cardarea == G.play then
|
|
if SMODS.has_enhancement(context.other_card, "m_gold") then
|
|
SMODS.scale_card(card, {
|
|
ref_table = card.ability.extra,
|
|
ref_value = "percent",
|
|
scalar_value = "percent_mod",
|
|
})
|
|
end
|
|
end
|
|
end,
|
|
calc_dollar_bonus = function(self, card)
|
|
local bonus =
|
|
lenient_bignum(math.max(0, math.floor(0.01 * to_big(card.ability.extra.percent) * (G.GAME.dollars or 0))))
|
|
if to_big(bonus) > to_big(0) then
|
|
return bonus
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- Nostalgic Googol Play Card
|
|
-- Sell this card to create 2 copies of the leftmost Joker
|
|
-- Still needs updated description
|
|
local altgoogol = {
|
|
object_type = "Joker",
|
|
name = "cry-altgoogol",
|
|
key = "altgoogol",
|
|
pos = { x = 4, y = 3 },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
immutable = true,
|
|
rarity = "cry_epic",
|
|
cost = 10,
|
|
order = 60,
|
|
blueprint_compat = false,
|
|
eternal_compat = false,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
soul_pos = { x = 10, y = 0, extra = { x = 5, y = 3 } },
|
|
config = { copies = 2 },
|
|
gameset_config = {
|
|
modest = {
|
|
cost = 15,
|
|
copies = 1,
|
|
},
|
|
mainline = { copies = 2 },
|
|
madness = {
|
|
center = { blueprint_compat = true },
|
|
copies = 2,
|
|
},
|
|
},
|
|
loc_vars = function(self, info_queue, center)
|
|
return { key = Cryptid.gameset_loc(self, { modest = "balanced" }), vars = { center.ability.copies } }
|
|
end,
|
|
calculate = function(self, card, context)
|
|
local gameset = Card.get_gameset(card)
|
|
if
|
|
(context.selling_self and not context.retrigger_joker and (gameset == "madness" or not context.blueprint))
|
|
or context.forcetrigger
|
|
then
|
|
local jokers = {}
|
|
for i = 1, #G.jokers.cards do
|
|
if G.jokers.cards[i] ~= card then
|
|
jokers[#jokers + 1] = G.jokers.cards[i]
|
|
end
|
|
end
|
|
if #jokers > 0 then
|
|
if not gameset == "modest" or #G.jokers.cards <= G.jokers.config.card_limit then
|
|
if G.jokers.cards[1].ability.name ~= "cry-altgoogol" then
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
for i = 1, card.ability.copies do
|
|
local chosen_joker = G.jokers.cards[1]
|
|
local card = copy_card(
|
|
chosen_joker,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
(
|
|
gameset == "modest"
|
|
and (Cryptid.safe_get(chosen_joker, "edition", "negative"))
|
|
or nil
|
|
)
|
|
)
|
|
card:add_to_deck()
|
|
G.jokers:emplace(card)
|
|
end
|
|
return true
|
|
end,
|
|
}))
|
|
card_eval_status_text(context.blueprint_card or card, "extra", nil, nil, nil, {
|
|
message = localize("k_duplicated_ex"),
|
|
colour = G.C.RARITY.cry_epic,
|
|
})
|
|
return nil, true
|
|
else
|
|
card_eval_status_text(context.blueprint_card or card, "extra", nil, nil, nil, {
|
|
message = localize("k_nope_ex"),
|
|
colour = G.C.RARITY.cry_epic,
|
|
})
|
|
return nil, true
|
|
end
|
|
else
|
|
card_eval_status_text(context.blueprint_card or card, "extra", nil, nil, nil, {
|
|
message = localize("k_no_room_ex"),
|
|
colour = G.C.RARITY.cry_epic,
|
|
})
|
|
return nil, true
|
|
end
|
|
else
|
|
card_eval_status_text(context.blueprint_card or card, "extra", nil, nil, nil, {
|
|
message = localize("k_no_other_jokers"),
|
|
colour = G.C.RARITY.cry_epic,
|
|
})
|
|
return nil, true
|
|
end
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Jevonn",
|
|
},
|
|
art = {
|
|
"Jevonn",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
}
|
|
|
|
-- One For All
|
|
-- +1 Joker slot, Booster Pack slot, hand size, consumable slot, shop slot
|
|
local soccer = {
|
|
object_type = "Joker",
|
|
name = "cry-soccer",
|
|
key = "soccer",
|
|
pos = { x = 1, y = 4 },
|
|
config = { extra = { holygrail = 1 } },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
immutable = true, -- i swear i changed this... whatever
|
|
rarity = "cry_epic",
|
|
order = 58,
|
|
cost = 20,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
return { key = Cryptid.gameset_loc(self, { modest = "balanced" }), vars = { center.ability.extra.holygrail } }
|
|
end,
|
|
add_to_deck = function(self, card, from_debuff)
|
|
card.ability.extra.holygrail = math.floor(card.ability.extra.holygrail)
|
|
local mod = card.ability.extra.holygrail
|
|
G.jokers.config.card_limit = G.jokers.config.card_limit + ((Card.get_gameset(card) == "modest") and 0 or mod)
|
|
G.consumeables.config.card_limit = G.consumeables.config.card_limit + mod
|
|
G.hand:change_size(mod)
|
|
SMODS.change_booster_limit(mod)
|
|
SMODS.change_voucher_limit(mod)
|
|
end,
|
|
remove_from_deck = function(self, card, from_debuff)
|
|
card.ability.extra.holygrail = math.floor(card.ability.extra.holygrail)
|
|
local mod = card.ability.extra.holygrail
|
|
G.jokers.config.card_limit = G.jokers.config.card_limit + ((Card.get_gameset(card) == "modest") and 0 or -mod)
|
|
G.consumeables.config.card_limit = G.consumeables.config.card_limit - mod
|
|
G.hand:change_size(-mod)
|
|
SMODS.change_booster_limit(-mod)
|
|
SMODS.change_voucher_limit(-mod)
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"Mjiojio",
|
|
},
|
|
art = {
|
|
"Ein13",
|
|
"George The Rat",
|
|
},
|
|
code = {
|
|
"Jevonn",
|
|
},
|
|
},
|
|
unlocked = false,
|
|
check_for_unlock = function(self, args)
|
|
if args.type == "win" then
|
|
for k, v in pairs(G.GAME.hands) do
|
|
if k ~= "High Card" and G.GAME.hands[k].played ~= 0 then
|
|
return
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
if args.type == "cry_lock_all" then
|
|
lock_card(self)
|
|
end
|
|
if args.type == "cry_unlock_all" then
|
|
unlock_card(self)
|
|
end
|
|
end,
|
|
}
|
|
|
|
-- Flesh Panopticon
|
|
-- X20 Boss Blind size; When Boss Blind defeated, self destructs and creates a Negative Gateway
|
|
local fleshpanopticon = {
|
|
object_type = "Joker",
|
|
name = "cry-fleshpanopticon",
|
|
key = "fleshpanopticon",
|
|
pos = { x = 0, y = 5 },
|
|
config = { extra = { boss_size = 20 } },
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
"c_cry_gateway",
|
|
},
|
|
},
|
|
immutable = true,
|
|
rarity = "cry_epic",
|
|
cost = 15,
|
|
order = 146,
|
|
atlas = "atlasepic",
|
|
loc_vars = function(self, info_queue, center)
|
|
info_queue[#info_queue + 1] = { set = "Spectral", key = "c_cry_gateway" }
|
|
if not center.edition or (center.edition and not center.edition.negative) then
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
|
|
end
|
|
return { vars = { center.ability.extra.boss_size } }
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.setting_blind and not context.blueprint and context.blind.boss and not card.getting_sliced then
|
|
local eval = function(card)
|
|
return not card.REMOVED and not G.RESET_JIGGLES
|
|
end
|
|
juice_card_until(card, eval, true)
|
|
card.gone = false
|
|
G.GAME.blind.chips = G.GAME.blind.chips * card.ability.extra.boss_size
|
|
G.GAME.blind.chip_text = number_format(G.GAME.blind.chips)
|
|
G.HUD_blind:recalculate()
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
play_sound("timpani")
|
|
delay(0.4)
|
|
return true
|
|
end,
|
|
}))
|
|
card_eval_status_text(card, "extra", nil, nil, nil, { message = localize("cry_good_luck_ex") })
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
if
|
|
context.end_of_round
|
|
and not context.individual
|
|
and not context.repetition
|
|
and not context.blueprint
|
|
and G.GAME.blind.boss
|
|
and not card.gone
|
|
then
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "before",
|
|
delay = 0.0,
|
|
func = function()
|
|
local card = create_card(
|
|
nil,
|
|
G.consumeables,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
Cryptid.enabled("c_cry_gateway") and "c_cry_gateway" or "c_soul",
|
|
"sup"
|
|
)
|
|
card:set_edition({ negative = true }, true)
|
|
card:add_to_deck()
|
|
G.consumeables:emplace(card)
|
|
return true
|
|
end,
|
|
}))
|
|
if not SMODS.is_eternal(card) then
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
play_sound("tarot1")
|
|
card.T.r = -0.2
|
|
card:juice_up(0.3, 0.4)
|
|
card.states.drag.is = true
|
|
card.children.center.pinch.x = true
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.3,
|
|
blockable = false,
|
|
func = function()
|
|
G.jokers:remove_card(card)
|
|
card:remove()
|
|
card = nil
|
|
return true
|
|
end,
|
|
}))
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
card.gone = true
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"notmario",
|
|
},
|
|
art = {
|
|
"notmario",
|
|
},
|
|
code = {
|
|
"notmario",
|
|
},
|
|
},
|
|
}
|
|
-- Spectrogram
|
|
-- Retrigger rightmost Joker once for every Echo Card played and scored
|
|
local spectrogram = {
|
|
object_type = "Joker",
|
|
name = "cry-Spectrogram",
|
|
key = "spectrogram",
|
|
pos = { x = 1, y = 5 },
|
|
config = {
|
|
extra = {},
|
|
immutable = { echonum = 0 },
|
|
},
|
|
rarity = "cry_epic",
|
|
cost = 9,
|
|
order = 133,
|
|
atlas = "atlasepic",
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
"m_cry_echo",
|
|
},
|
|
},
|
|
loc_vars = function(self, info_queue, center)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.m_cry_echo
|
|
return { vars = {} }
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.before and context.cardarea == G.jokers then
|
|
card.ability.immutable.echonum = 0
|
|
for i, v in pairs(context.scoring_hand) do
|
|
if v.config.center_key == "m_cry_echo" and not v.debuff then
|
|
card.ability.immutable.echonum = card.ability.immutable.echonum + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
if
|
|
context.retrigger_joker_check
|
|
and not context.retrigger_joker
|
|
and context.other_card == G.jokers.cards[#G.jokers.cards]
|
|
and context.other_card ~= self
|
|
then
|
|
if card.ability.immutable.echonum and card.ability.immutable.echonum > 0 then
|
|
return {
|
|
message = localize("k_again_ex"),
|
|
repetitions = card.ability.immutable.echonum,
|
|
card = card,
|
|
}
|
|
end
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"AlexZGreat",
|
|
},
|
|
art = {
|
|
"Ein13",
|
|
},
|
|
code = {
|
|
"AlexZGreat",
|
|
},
|
|
},
|
|
}
|
|
local jtron = {
|
|
object_type = "Joker",
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
name = "cry-jtron",
|
|
key = "jtron",
|
|
config = {
|
|
extra = { bonus = 1 },
|
|
immutable = { current = 0 },
|
|
},
|
|
rarity = "cry_epic",
|
|
cost = 14,
|
|
order = 64,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
pos = { x = 2, y = 5 },
|
|
loc_vars = function(self, info_queue, center)
|
|
info_queue[#info_queue + 1] = G.P_CENTERS.j_joker
|
|
center.ability.immutable.current =
|
|
lenient_bignum(1 + to_big(center.ability.extra.bonus) * #SMODS.find_card("j_joker"))
|
|
return {
|
|
vars = {
|
|
number_format(center.ability.extra.bonus),
|
|
number_format(center.ability.immutable.current),
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
card.ability.immutable.current =
|
|
lenient_bignum(1 + to_big(card.ability.extra.bonus) * #SMODS.find_card("j_joker"))
|
|
if context.cardarea == G.jokers and context.joker_main then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_powmult",
|
|
vars = {
|
|
number_format(card.ability.immutable.current),
|
|
},
|
|
}),
|
|
Emult_mod = lenient_bignum(card.ability.immutable.current),
|
|
colour = G.C.DARK_EDITION,
|
|
}
|
|
end
|
|
if context.forcetrigger then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_powmult",
|
|
vars = {
|
|
number_format(1 + to_big(card.ability.extra.bonus)),
|
|
},
|
|
}),
|
|
Emult_mod = lenient_bignum(1 + to_big(card.ability.extra.bonus)),
|
|
colour = G.C.DARK_EDITION,
|
|
}
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = { "AlexZGreat" },
|
|
art = { "Darren_The_Frog" },
|
|
code = { "candycanearter" },
|
|
},
|
|
}
|
|
-- Retriggers steels every 2nd hand, scaling xmult every 3rd hand, first card to steel every 5th hand, stronger steels every 7th hand
|
|
local clockwork = { -- Steel Support: The Joker
|
|
object_type = "Joker",
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
name = "cry-clockwork",
|
|
key = "clockwork",
|
|
pos = { x = 5, y = 5 },
|
|
config = {
|
|
extra = {
|
|
xmult = 1,
|
|
xmult_mod = 0.25,
|
|
steelenhc = 1,
|
|
steel_mod = 0.1,
|
|
},
|
|
immutable = {
|
|
limits = {
|
|
l1 = 2,
|
|
l2 = 3,
|
|
l3 = 5,
|
|
l4 = 7,
|
|
},
|
|
counters = {
|
|
c1 = 0,
|
|
c2 = 0,
|
|
c3 = 0,
|
|
c4 = 0,
|
|
},
|
|
},
|
|
},
|
|
order = 135,
|
|
immutable = false,
|
|
rarity = "cry_epic",
|
|
cost = 12,
|
|
blueprint_compat = true,
|
|
atlas = "atlasone",
|
|
enhancement_gate = "m_steel", -- lucky joker uses this? hopefully it works
|
|
loc_vars = function(self, info_queue, center)
|
|
local function process_var(m, cap)
|
|
if m >= cap - 1 then
|
|
return localize("k_active_ex")
|
|
end
|
|
return cap - m - 1
|
|
end
|
|
return {
|
|
vars = {
|
|
process_var(center.ability.immutable.counters.c1, center.ability.immutable.limits.l1),
|
|
process_var(center.ability.immutable.counters.c2, center.ability.immutable.limits.l2),
|
|
process_var(center.ability.immutable.counters.c3, center.ability.immutable.limits.l3),
|
|
process_var(center.ability.immutable.counters.c4, center.ability.immutable.limits.l4),
|
|
number_format(center.ability.extra.xmult),
|
|
number_format(center.ability.extra.xmult_mod),
|
|
number_format(center.ability.extra.steelenhc),
|
|
number_format(center.ability.extra.steel_mod),
|
|
center.ability.immutable.limits.l1,
|
|
center.ability.immutable.limits.l2,
|
|
center.ability.immutable.limits.l3,
|
|
center.ability.immutable.limits.l4,
|
|
},
|
|
}
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.before and context.cardarea == G.jokers and not context.blueprint and not context.retrigger then
|
|
local function clamp(c, l)
|
|
local m = c + 1
|
|
if c + 1 >= l then
|
|
return 0
|
|
end
|
|
return m
|
|
end
|
|
|
|
card.ability.immutable.counters.c1 =
|
|
clamp(card.ability.immutable.counters.c1, card.ability.immutable.limits.l1) -- ticker 1
|
|
|
|
card.ability.immutable.counters.c2 =
|
|
clamp(card.ability.immutable.counters.c2, card.ability.immutable.limits.l2) -- ticker 2
|
|
if card.ability.immutable.counters.c2 == 0 then
|
|
card.ability.extra.xmult =
|
|
lenient_bignum(to_big(card.ability.extra.xmult) + card.ability.extra.xmult_mod)
|
|
end
|
|
|
|
card.ability.immutable.counters.c3 =
|
|
clamp(card.ability.immutable.counters.c3, card.ability.immutable.limits.l3) -- ticker 3
|
|
|
|
card.ability.immutable.counters.c4 =
|
|
clamp(card.ability.immutable.counters.c4, card.ability.immutable.limits.l4) -- ticker 4
|
|
if card.ability.immutable.counters.c4 == 0 then
|
|
card.ability.extra.steelenhc =
|
|
lenient_bignum(to_big(card.ability.extra.steelenhc) + card.ability.extra.steel_mod)
|
|
end
|
|
end
|
|
if context.repetition and context.cardarea == G.hand and card.ability.immutable.counters.c1 == 0 then -- effect 1
|
|
if SMODS.has_enhancement(context.other_card, "m_steel") then
|
|
return {
|
|
message = localize("k_again_ex"),
|
|
repetitions = 1,
|
|
card = card,
|
|
}
|
|
end
|
|
end
|
|
if
|
|
context.joker_main and context.cardarea == G.jokers -- effect 2
|
|
then
|
|
return { xmult = card.ability.extra.xmult }
|
|
end
|
|
if
|
|
context.before
|
|
and context.cardarea == G.jokers
|
|
and not context.blueprint_card
|
|
and not context.retrigger_joker
|
|
and card.ability.immutable.counters.c3 == 0
|
|
and context.full_hand[1]
|
|
then -- effect 3
|
|
context.full_hand[1]:set_ability(G.P_CENTERS["m_steel"], nil, true)
|
|
end
|
|
if
|
|
context.individual
|
|
and context.cardarea == G.hand
|
|
and not context.end_of_round
|
|
and SMODS.has_enhancement(context.other_card, "m_steel")
|
|
and to_big(card.ability.extra.steelenhc) ~= to_big(1)
|
|
then
|
|
if context.other_card.debuff then
|
|
return {
|
|
message = localize("k_debuffed"),
|
|
colour = G.C.RED,
|
|
card = card,
|
|
}
|
|
else -- effect 4
|
|
return { xmult = lenient_bignum(card.ability.extra.steelenhc) }
|
|
end
|
|
end
|
|
--imo this secret effect can be madness only -Math
|
|
if
|
|
context.after
|
|
and context.cardarea == G.jokers
|
|
and not context.blueprint_card
|
|
and not context.retrigger_joker
|
|
then -- The Clockwork Joker is canonically a non-binary self-replicating machine amoeba, that self replicates every 21 minutes. Their pronouns are any/all; they are several billion tiny jokers
|
|
if -- in a trench coat, constantly ticking in an almost perfect yet flawed mechanism. Its only purpose is the strengthening and spreading of the steel world; everything else is meaningless to it.
|
|
card.ability.immutable.counters.c1 == 0 -- lore by nova :3
|
|
and card.ability.immutable.counters.c2 == 0
|
|
and card.ability.immutable.counters.c3 == 0
|
|
and card.ability.immutable.counters.c4 == 0
|
|
then
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
local m = copy_card(card)
|
|
m:add_to_deck()
|
|
G.jokers:emplace(m)
|
|
return true
|
|
end,
|
|
}))
|
|
return {
|
|
message = localize("k_duplicated_ex"),
|
|
card = card,
|
|
}
|
|
end
|
|
end
|
|
end,
|
|
set_ability = function(self, card, initial, delay_sprites)
|
|
card.ability.immutable.counters.c1 =
|
|
math.floor(pseudorandom("Clockwork1") * (card.ability.immutable.limits.l1 - 1) + 0.5)
|
|
card.ability.immutable.counters.c2 =
|
|
math.floor(pseudorandom("Clockwork2") * (card.ability.immutable.limits.l2 - 1) + 0.5)
|
|
card.ability.immutable.counters.c3 =
|
|
math.floor(pseudorandom("Clockwork3") * (card.ability.immutable.limits.l3 - 1) + 0.5)
|
|
card.ability.immutable.counters.c4 =
|
|
math.floor(pseudorandom("Clockwork4") * (card.ability.immutable.limits.l4 - 1) + 0.5)
|
|
end,
|
|
cry_credits = {
|
|
idea = {
|
|
"cassknows",
|
|
},
|
|
code = {
|
|
"Nova",
|
|
"Math",
|
|
},
|
|
art = {
|
|
"unexian",
|
|
},
|
|
},
|
|
}
|
|
-- Force-triggers the rightmost joker during context.joker_main
|
|
local demicolon = {
|
|
object_type = "Joker",
|
|
gameset_config = {
|
|
modest = { disabled = true },
|
|
mainline = { disabled = true },
|
|
madness = { disabled = false },
|
|
experimental = { disabled = false },
|
|
},
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
name = "cry-demicolon",
|
|
key = "demicolon",
|
|
rarity = "cry_epic",
|
|
cost = 14,
|
|
order = 299,
|
|
blueprint_compat = false,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
pos = { x = 3, y = 5 },
|
|
config = { check = nil },
|
|
immutable = true,
|
|
loc_vars = function(self, info_queue, card)
|
|
card.ability.demicoloncompat_ui = card.ability.demicoloncompat_ui or ""
|
|
card.ability.demicoloncompat_ui_check = nil
|
|
local check = card.ability.check
|
|
return {
|
|
main_end = (card.area and card.area == G.jokers)
|
|
and {
|
|
{
|
|
n = G.UIT.C,
|
|
config = { align = "bm", minh = 0.4 },
|
|
nodes = {
|
|
{
|
|
n = G.UIT.C,
|
|
config = {
|
|
ref_table = card,
|
|
align = "m",
|
|
-- colour = (check and G.C.cry_epic or G.C.JOKER_GREY),
|
|
colour = card.ability.colour,
|
|
r = 0.05,
|
|
padding = 0.08,
|
|
func = "blueprint_compat",
|
|
},
|
|
nodes = {
|
|
{
|
|
n = G.UIT.T,
|
|
config = {
|
|
ref_table = card.ability,
|
|
ref_value = "demicoloncompat",
|
|
colour = G.C.UI.TEXT_LIGHT,
|
|
scale = 0.32 * 0.8,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
or nil,
|
|
}
|
|
end,
|
|
update = function(self, card, front)
|
|
local other_joker = nil
|
|
if G.STAGE == G.STAGES.RUN then
|
|
for i = 1, #G.jokers.cards do
|
|
if G.jokers.cards[i] == card then
|
|
other_joker = G.jokers.cards[i + 1]
|
|
end
|
|
end
|
|
local m = Cryptid.demicolonGetTriggerable(other_joker)
|
|
if m[1] and not m[2] then
|
|
card.ability.demicoloncompat = "Compatible"
|
|
card.ability.check = true
|
|
card.ability.colour = G.C.SECONDARY_SET.Enhanced
|
|
elseif m[2] then
|
|
card.ability.demicoloncompat = "Dangerous!"
|
|
card.ability.check = true
|
|
card.ability.colour = G.C.MULT
|
|
else
|
|
card.ability.demicoloncompat = "Incompatible"
|
|
card.ability.check = false
|
|
card.ability.colour = G.C.SUITS.Spades
|
|
end
|
|
end
|
|
end,
|
|
calculate = function(self, card, context)
|
|
if context.joker_main and not context.blueprint then
|
|
for i = 1, #G.jokers.cards do
|
|
if G.jokers.cards[i] == card then
|
|
if Cryptid.demicolonGetTriggerable(G.jokers.cards[i + 1])[1] then
|
|
local results = Cryptid.forcetrigger(G.jokers.cards[i + 1], context)
|
|
if results and results.jokers then
|
|
results.jokers.message = localize("cry_demicolon")
|
|
results.jokers.colour = G.C.RARITY.cry_epic
|
|
results.jokers.sound = "cry_demitrigger"
|
|
return results.jokers
|
|
end
|
|
return {
|
|
message = localize("cry_demicolon"),
|
|
colour = G.C.RARITY.cry_epic,
|
|
sound = "cry_demitrigger",
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
cry_credits = {
|
|
idea = { "HexaCryonic" },
|
|
art = { "HexaCryonic" },
|
|
code = { "Nova" },
|
|
},
|
|
}
|
|
|
|
local starfruit = {
|
|
object_type = "Joker",
|
|
dependencies = {
|
|
items = {
|
|
"set_cry_epic",
|
|
},
|
|
},
|
|
name = "cry-starfruit",
|
|
key = "starfruit",
|
|
rarity = "cry_epic",
|
|
cost = 14,
|
|
order = 300,
|
|
blueprint_compat = true,
|
|
demicoloncompat = true,
|
|
atlas = "atlasepic",
|
|
pos = { x = 4, y = 5 },
|
|
config = { emult = 2, emult_mod = 0.2 },
|
|
pools = { ["Food"] = true },
|
|
calculate = function(self, card, context)
|
|
if context.joker_main or context.forcetrigger then
|
|
return {
|
|
message = localize({
|
|
type = "variable",
|
|
key = "a_powmult",
|
|
vars = {
|
|
number_format(card.ability.emult),
|
|
},
|
|
}),
|
|
Emult_mod = lenient_bignum(card.ability.emult),
|
|
colour = G.C.DARK_EDITION,
|
|
}
|
|
end
|
|
if context.reroll_shop or context.forcetrigger then
|
|
SMODS.scale_card(card, {
|
|
ref_table = card.ability,
|
|
ref_value = "emult",
|
|
scalar_value = "emult_mod",
|
|
operation = "-",
|
|
no_message = true,
|
|
})
|
|
--floating point precision can kiss my ass istg
|
|
if to_number(card.ability.emult) <= 1.00000001 then
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
play_sound("tarot1")
|
|
card.T.r = -0.2
|
|
card:juice_up(0.3, 0.4)
|
|
card.states.drag.is = true
|
|
card.children.center.pinch.x = true
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.3,
|
|
blockable = false,
|
|
func = function()
|
|
G.jokers:remove_card(card)
|
|
card:remove()
|
|
card = nil
|
|
return true
|
|
end,
|
|
}))
|
|
return true
|
|
end,
|
|
}))
|
|
return {
|
|
message = localize("k_eaten_ex"),
|
|
colour = G.C.RARITY.cry_epic,
|
|
}
|
|
else
|
|
if not msg or type(msg) == "string" then
|
|
return {
|
|
message = msg or localize({
|
|
type = "variable",
|
|
key = "a_powmult_minus",
|
|
vars = {
|
|
number_format(card.ability.emult_mod),
|
|
},
|
|
}),
|
|
colour = G.C.RARITY.cry_epic,
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
loc_vars = function(self, queue, card)
|
|
return {
|
|
vars = {
|
|
number_format(card.ability.emult),
|
|
number_format(card.ability.emult_mod),
|
|
},
|
|
}
|
|
end,
|
|
cry_credits = {
|
|
art = { "lord.ruby" },
|
|
code = { "lord.ruby" },
|
|
idea = { "NinjaBanana" },
|
|
},
|
|
check_for_unlock = function(self, args)
|
|
if args.type == "foods_destroyed" and to_big(args.destroyed) >= 2 then
|
|
unlock_card(self)
|
|
end
|
|
if args.type == "cry_lock_all" then
|
|
lock_card(self)
|
|
end
|
|
if args.type == "cry_unlock_all" then
|
|
unlock_card(self)
|
|
end
|
|
end,
|
|
init = function()
|
|
local card_remove_ref = Card.remove
|
|
function Card:remove(...)
|
|
if self:is_food() and self.area == G.jokers and not G.SETTINGS.paused then
|
|
G.cry_foods_eaten = (G.cry_foods_eaten or 0) + 1
|
|
check_for_unlock({ type = "foods_destroyed", destroyed = G.cry_foods_eaten })
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
G.cry_foods_eaten = nil
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
return card_remove_ref(self, ...)
|
|
end
|
|
end,
|
|
}
|
|
|
|
return {
|
|
name = "Epic Jokers",
|
|
items = {
|
|
supercell,
|
|
membershipcardtwo,
|
|
googol_play,
|
|
sync_catalyst,
|
|
negative,
|
|
canvas,
|
|
error_joker,
|
|
M,
|
|
m,
|
|
boredom,
|
|
double_scale,
|
|
number_blocks,
|
|
oldcandy,
|
|
circus,
|
|
caramel,
|
|
curse_sob,
|
|
bonusjoker,
|
|
multjoker,
|
|
goldjoker,
|
|
altgoogol,
|
|
soccer,
|
|
fleshpanopticon,
|
|
spectrogram,
|
|
jtron,
|
|
clockwork,
|
|
demicolon,
|
|
starfruit,
|
|
},
|
|
}
|