balatro-mods/Cryptid/Items/Spectrals.lua
2025-01-19 15:01:49 +08:00

1275 lines
34 KiB
Lua

local white_hole = {
object_type = "Consumable",
set = "Spectral",
name = "cry-White Hole",
key = "white_hole",
pos = { x = 1, y = 4 },
cost = 4,
order = 40,
atlas = "atlasnotjokers",
hidden = true, --default soul_rate of 0.3% in spectral packs is used
soul_set = "Planet",
can_use = function(self, card)
return true
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
--Get most played hand type (logic yoinked from Telescope)
local _planet, _hand, _tally = nil, nil, -1
for k, v in ipairs(G.handlist) do
if G.GAME.hands[v].visible and G.GAME.hands[v].played > _tally then
_hand = v
_tally = G.GAME.hands[v].played
end
end
if _hand then
for k, v in pairs(G.P_CENTER_POOLS.Planet) do
if v.config.hand_type == _hand then
_planet = v.key
end
end
end
local removed_levels = 0
for k, v in ipairs(G.handlist) do
if G.GAME.hands[v].level > 1 then
local this_removed_levels = G.GAME.hands[v].level - 1
removed_levels = removed_levels + this_removed_levels
level_up_hand(used_consumable, v, true, -this_removed_levels)
end
end
update_hand_text(
{ sound = "button", volume = 0.7, pitch = 0.8, delay = 0.3 },
{
handname = localize(_hand, "poker_hands"),
chips = G.GAME.hands[_hand].chips,
mult = G.GAME.hands[_hand].mult,
level = G.GAME.hands[_hand].level,
}
)
level_up_hand(used_consumable, _hand, false, 3 * removed_levels)
update_hand_text(
{ sound = "button", volume = 0.7, pitch = 1.1, delay = 0 },
{ mult = 0, chips = 0, handname = "", level = "" }
)
end,
--Incantation compat
can_stack = true,
can_divide = true,
can_bulk_use = true,
bulk_use = function(self, card, area, copier, number)
local used_consumable = copier or card
--Get most played hand type (logic yoinked from Telescope)
local _planet, _hand, _tally = nil, nil, -1
for k, v in ipairs(G.handlist) do
if G.GAME.hands[v].visible and G.GAME.hands[v].played > _tally then
_hand = v
_tally = G.GAME.hands[v].played
end
end
if _hand then
for k, v in pairs(G.P_CENTER_POOLS.Planet) do
if v.config.hand_type == _hand then
_planet = v.key
end
end
end
local removed_levels = 0
for k, v in ipairs(G.handlist) do
if G.GAME.hands[v].level > 1 then
local this_removed_levels = G.GAME.hands[v].level - 1
removed_levels = removed_levels + this_removed_levels
level_up_hand(used_consumable, v, true, -this_removed_levels)
end
end
update_hand_text(
{ sound = "button", volume = 0.7, pitch = 0.8, delay = 0.3 },
{
handname = localize(_hand, "poker_hands"),
chips = G.GAME.hands[_hand].chips,
mult = G.GAME.hands[_hand].mult,
level = G.GAME.hands[_hand].level,
}
)
level_up_hand(used_consumable, _hand, false, removed_levels * 3 ^ number)
update_hand_text(
{ sound = "button", volume = 0.7, pitch = 1.1, delay = 0 },
{ mult = 0, chips = 0, handname = "", level = "" }
)
end,
}
local vacuum = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Vacuum",
key = "vacuum",
pos = { x = 3, y = 1 },
config = { extra = 4 },
cost = 4,
order = 2,
atlas = "atlasnotjokers",
loc_vars = function(self, info_queue, center)
return { vars = { center.ability.extra } }
end,
can_use = function(self, card)
return #G.hand.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local earnings = 0
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.hand.cards do
local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("card1", percent)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.2)
for i = 1, #G.hand.cards do
local CARD = G.hand.cards[i]
if CARD.config.center ~= G.P_CENTERS.c_base then
earnings = earnings + 1
end
if CARD.edition then
earnings = earnings + 1
end
if CARD.seal then
earnings = earnings + 1
end
local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
CARD:flip()
CARD:set_ability(G.P_CENTERS.c_base, true, nil)
CARD:set_edition(nil, true)
CARD:set_seal(nil, true)
play_sound("tarot2", percent)
CARD:juice_up(0.3, 0.3)
return true
end,
}))
end
ease_dollars(earnings * card.ability.extra)
end,
}
local hammerspace = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Hammerspace",
key = "hammerspace",
pos = { x = 4, y = 3 },
config = {},
cost = 4,
order = 3,
atlas = "atlasnotjokers",
can_use = function(self, card)
return #G.hand.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.hand.cards do
local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("card1", percent)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.2)
for i = 1, #G.hand.cards do
local CARD = G.hand.cards[i]
local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
CARD:flip()
CARD:set_ability(get_random_consumable("cry_hammerspace", nil, "c_cry_hammerspace", nil, true))
play_sound("tarot2", percent)
CARD:juice_up(0.3, 0.3)
return true
end,
}))
end
end,
}
local lock = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Lock",
key = "lock",
pos = { x = 0, y = 1 },
config = {},
cost = 4,
order = 1,
atlas = "atlasnotjokers",
can_use = function(self, card)
return #G.jokers.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local target = #G.jokers.cards == 1 and G.jokers.cards[1] or G.jokers.cards[math.random(#G.jokers.cards)]
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.jokers.cards do
local percent = 1.15 - (i - 0.999) / (#G.jokers.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.jokers.cards[i]:flip()
play_sound("card1", percent)
G.jokers.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.2)
for i = 1, #G.jokers.cards do
local CARD = G.jokers.cards[i]
local percent = 0.85 + (i - 0.999) / (#G.jokers.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
CARD:flip()
CARD.ability.perishable = nil
CARD.pinned = nil
CARD:set_rental(nil)
if not CARD.sob then
CARD:set_eternal(nil)
end
CARD.ability.banana = nil
if Cryptid.enabled["Spooky"] then
CARD.ability.cry_possessed = nil
SMODS.Stickers.cry_flickering:apply(CARD, nil)
end
play_sound("card1", percent)
CARD:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot2")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
play_sound("card1", 0.9)
target:flip()
return true
end,
}))
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.3,
func = function()
play_sound("gold_seal", 1.2, 0.4)
target:juice_up(0.3, 0.3)
return true
end,
}))
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
play_sound("card1", 1.1)
target:flip()
target:set_eternal(true)
return true
end,
}))
end,
}
local trade = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Trade",
key = "trade",
pos = { x = 2, y = 1 },
config = {},
cost = 4,
order = 4,
atlas = "atlasnotjokers",
can_use = function(self, card)
local usable_count = 0
for _, v in pairs(G.GAME.used_vouchers) do
if v then
usable_count = usable_count + 1
end
end
if G.GAME.voucher_sticker_index and G.GAME.voucher_sticker_index.eternal then
for _, v in pairs(G.GAME.voucher_sticker_index.eternal) do
if v then
usable_count = usable_count - 1
end
end
end
if usable_count > 0 then
return true
else
return false
end
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local usable_vouchers = {}
for k, _ in pairs(G.GAME.used_vouchers) do
local can_use = true
for kk, __ in pairs(G.GAME.used_vouchers) do
local v = G.P_CENTERS[kk]
if v.requires then
for _, vv in pairs(v.requires) do
if vv == k then
can_use = false
break
end
end
end
if
G.GAME.voucher_sticker_index
and G.GAME.voucher_sticker_index.eternal
and G.GAME.voucher_sticker_index.eternal[v.name]
then
can_use = false
end
end
if can_use then
usable_vouchers[#usable_vouchers + 1] = k
end
end
local unredeemed_voucher = pseudorandom_element(usable_vouchers, pseudoseed("cry_trade"))
--redeem extra voucher code based on Betmma's Vouchers
local area
if G.STATE == G.STATES.HAND_PLAYED then
if not G.redeemed_vouchers_during_hand then
G.redeemed_vouchers_during_hand =
CardArea(G.play.T.x, G.play.T.y, G.play.T.w, G.play.T.h, { type = "play", card_limit = 5 })
end
area = G.redeemed_vouchers_during_hand
else
area = G.play
end
local card = create_card("Voucher", area, nil, nil, nil, nil, unredeemed_voucher)
if G.GAME.voucher_edition_index[card.ability.name] then
local edition = cry_edition_to_table(G.GAME.voucher_edition_index[card.ability.name])
if edition then
card:set_edition(edition, true, true)
end
end
if G.GAME.voucher_sticker_index.eternal[card.ability.name] then
card:set_eternal(true)
card.ability.eternal = true
end
if G.GAME.voucher_sticker_index.perishable[card.ability.name] then
card:set_perishable(true)
card.ability.perish_tally = G.GAME.voucher_sticker_index.perishable[card.ability.name]
card.ability.perishable = true
if G.GAME.voucher_sticker_index.perishable[card.ability.name] == 0 then
card.debuff = true
end
end
if G.GAME.voucher_sticker_index.rental[card.ability.name] then
card:set_rental(true)
card.ability.rental = true
end
if G.GAME.voucher_sticker_index.pinned[card.ability.name] then
card.pinned = true
end
if G.GAME.voucher_sticker_index.banana[card.ability.name] then
card.ability.banana = true
end
card:start_materialize()
area:emplace(card)
card.cost = 0
card.shop_voucher = false
local current_round_voucher = G.GAME.current_round.voucher
card:unredeem()
G.GAME.current_round.voucher = current_round_voucher
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0,
func = function()
card:start_dissolve()
return true
end,
}))
for i = 1, 2 do
local area
if G.STATE == G.STATES.HAND_PLAYED then
if not G.redeemed_vouchers_during_hand then
G.redeemed_vouchers_during_hand =
CardArea(G.play.T.x, G.play.T.y, G.play.T.w, G.play.T.h, { type = "play", card_limit = 5 })
end
area = G.redeemed_vouchers_during_hand
else
area = G.play
end
local _pool = get_current_pool("Voucher", nil, nil, nil, true)
local center = pseudorandom_element(_pool, pseudoseed("cry_trade_redeem"))
local it = 1
while center == "UNAVAILABLE" do
it = it + 1
center = pseudorandom_element(_pool, pseudoseed("cry_trade_redeem_resample" .. it))
end
local card = create_card("Voucher", area, nil, nil, nil, nil, center)
card:start_materialize()
area:emplace(card)
card.cost = 0
card.shop_voucher = false
local current_round_voucher = G.GAME.current_round.voucher
card:redeem()
G.GAME.current_round.voucher = current_round_voucher
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0,
func = function()
card:start_dissolve()
return true
end,
}))
end
end,
}
local analog = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Analog",
key = "analog",
pos = { x = 3, y = 0 },
config = { copies = 2, ante = 1 },
loc_vars = function(self, info_queue, center)
return { vars = { center.ability.copies, center.ability.ante } }
end,
cost = 4,
order = 7,
atlas = "atlasnotjokers",
can_use = function(self, card)
return #G.jokers.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local deletable_jokers = {}
for k, v in pairs(G.jokers.cards) do
if not v.ability.eternal then
deletable_jokers[#deletable_jokers + 1] = v
end
end
local chosen_joker = pseudorandom_element(G.jokers.cards, pseudoseed("cry_analog_choice"))
local _first_dissolve = nil
G.E_MANAGER:add_event(Event({
trigger = "before",
delay = 0.75,
func = function()
for k, v in pairs(deletable_jokers) do
if v ~= chosen_joker then
v:start_dissolve(nil, _first_dissolve)
_first_dissolve = true
end
end
return true
end,
}))
for i = 1, card.ability.copies do
G.E_MANAGER:add_event(Event({
trigger = "before",
delay = 0.4,
func = function()
local card = copy_card(chosen_joker)
card:start_materialize()
card:add_to_deck()
G.jokers:emplace(card)
return true
end,
}))
end
ease_ante(card.ability.ante)
end,
}
local summoning = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Summoning",
key = "summoning",
pos = { x = 3, y = 4 },
cost = 4,
order = 5,
atlas = "atlasnotjokers",
can_use = function(self, card)
return #G.jokers.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local deletable_jokers = {}
for k, v in pairs(G.jokers.cards) do
if not v.ability.eternal then
deletable_jokers[#deletable_jokers + 1] = v
end
end
local chosen_joker = pseudorandom_element(G.jokers.cards, pseudoseed("cry_summoning"))
local _first_dissolve = nil
G.E_MANAGER:add_event(Event({
trigger = "before",
delay = 0.75,
func = function()
for k, v in pairs(deletable_jokers) do
if v == chosen_joker then
v:start_dissolve(nil, _first_dissolve)
_first_dissolve = true
end
end
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("timpani")
local card = create_card("Joker", G.jokers, nil, "cry_epic", nil, nil, nil, "cry_summoning")
card:add_to_deck()
G.jokers:emplace(card)
card:juice_up(0.3, 0.5)
return true
end,
}))
delay(0.6)
end,
}
local replica = {
object_type = "Consumable",
set = "Spectral",
name = "cry-Replica",
key = "replica",
pos = { x = 1, y = 1 },
config = {},
cost = 4,
order = 6,
atlas = "atlasnotjokers",
can_use = function(self, card)
return #G.hand.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local chosen_card = pseudorandom_element(G.hand.cards, pseudoseed("cry_replica_choice"))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.hand.cards do
local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("card1", percent)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
for i = 1, #G.hand.cards do
if not G.hand.cards[i].ability.eternal then
G.E_MANAGER:add_event(Event({
func = function()
copy_card(chosen_card, G.hand.cards[i])
return true
end,
}))
end
end
for i = 1, #G.hand.cards do
local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.hand.cards[i]:flip()
play_sound("tarot2", percent, 0.6)
G.hand.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.5)
end,
}
local ritual = {
cry_credits = {
idea = {"Mystic Misclick"},
art = {"spire_winder"},
code = {"spire_winder"}
},
object_type = "Consumable",
set = "Spectral",
name = "cry-Ritual",
key = "ritual",
order = 9,
config = {
max_highlighted = 1,
},
loc_vars = function(self, info_queue, center)
if not center.edition or (center.edition and not center.edition.cry_mosaic) then
info_queue[#info_queue + 1] = G.P_CENTERS.e_cry_mosaic
end
if not center.edition or (center.edition and not center.edition.negative) then
info_queue[#info_queue + 1] = G.P_CENTERS.e_negative
end
if not center.edition or (center.edition and not center.edition.cry_astral) then
info_queue[#info_queue + 1] = G.P_CENTERS.e_cry_astral
end
return { vars = { center.ability.max_highlighted } }
end,
cost = 5,
atlas = "atlasnotjokers",
pos = { x = 5, y = 1 },
use = function(self, card, area, copier)
local used_consumable = copier or card
for i = 1, #G.hand.highlighted do
local highlighted = G.hand.highlighted[i]
G.E_MANAGER:add_event(Event({
func = function()
play_sound("tarot1")
highlighted:juice_up(0.3, 0.5)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.1,
func = function()
if highlighted then
local random_result = pseudorandom(pseudoseed("cry-Ritual"))
if random_result >= 5 / 6 then
highlighted:set_edition({cry_astral = true})
else
if random_result >= 1 / 2 then
highlighted:set_edition({cry_mosaic = true})
else
highlighted:set_edition({negative = true})
end
end
end
return true
end,
}))
delay(0.5)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.2,
func = function()
G.hand:unhighlight_all()
return true
end,
}))
end
end,
}
local adversary = {
cry_credits = {
idea = {"y_not_tony"},
art = {"Pyrocreep"},
code = {"spire_winder"}
},
object_type = "Consumable",
set = "Spectral",
name = "cry-Adversary",
key = "adversary",
pos = { x = 6, y = 1 },
config = {},
cost = 4,
order = 10,
atlas = "atlasnotjokers",
loc_vars = function(self, info_queue, center)
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,
can_use = function(self, card)
return #G.jokers.cards > 0
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local target = #G.jokers.cards == 1 and G.jokers.cards[1] or G.jokers.cards[math.random(#G.jokers.cards)]
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
for i = 1, #G.jokers.cards do
local percent = 1.15 - (i - 0.999) / (#G.jokers.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
G.jokers.cards[i]:flip()
play_sound("card1", percent)
G.jokers.cards[i]:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.2)
for i = 1, #G.jokers.cards do
local CARD = G.jokers.cards[i]
local percent = 0.85 + (i - 0.999) / (#G.jokers.cards - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
CARD:flip()
if not CARD.edition then CARD:set_edition({negative = true}) end
play_sound("card1", percent)
CARD:juice_up(0.3, 0.3)
return true
end,
}))
end
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot2")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.cry_shop_joker_price_modifier = G.GAME.cry_shop_joker_price_modifier * 2
for k, v in pairs(G.I.CARD) do
if v.set_cost then
v:set_cost()
end
end
return true
end,
}))
end,
}
local chambered = {
cry_credits = {
idea = {"y_not_tony"},
art = {"Pyrocreep"},
code = {"spire_winder"}
},
object_type = "Consumable",
set = "Spectral",
name = "cry-Chambered",
key = "chambered",
pos = { x = 5, y = 0 },
config = { extra = {num_copies = 3}},
loc_vars = function(self, info_queue, card)
info_queue[#info_queue + 1] = { key = "e_negative_consumable", set = "Edition", config = { extra = 1 } }
return { vars = { card.ability.extra.num_copies } }
end,
cost = 4,
order = 11,
atlas = "atlasnotjokers",
can_use = function(self, card)
local filteredCons = {}
-- Copy consumables that aren't Chambered
for _, item in ipairs(G.consumeables.cards) do
if item.ability.name ~= "cry-Chambered" then
table.insert(filteredCons, item)
end
end
return #filteredCons > 0
end,
use = function(self, card, area, copier)
local filteredCons = {}
-- Copy consumables that aren't Chambered
for _, item in ipairs(G.consumeables.cards) do
if item.ability.name ~= "cry-Chambered" then
table.insert(filteredCons, item)
end
end
target = pseudorandom_element(filteredCons, pseudoseed('chambered'))
for i=1,card.ability.extra.num_copies do
G.E_MANAGER:add_event(Event({
func = function()
local card_copy = copy_card(target, nil)
if Incantation then
card_copy:setQty(1)
end
card_copy:set_edition({negative = true}, true)
card_copy:add_to_deck()
G.consumeables:emplace(card_copy)
return true
end}))
card_eval_status_text(target, 'extra', nil, nil, nil, {message = localize('k_duplicated_ex'), colour = G.C.SECONDARY_SET.Spectral})
end
end,
}
local conduit = {
cry_credits = {
idea = {"Knockback1 (Oiiman)"},
art = {"Knockback1 (Oiiman)"},
code = {"spire_winder"}
},
object_type = "Consumable",
set = "Spectral",
name = "cry-conduit",
key = "conduit",
pos = { x = 6, y = 0 },
config = { },
cost = 4,
order = 12,
atlas = "atlasnotjokers",
can_use = function(self, card)
local combinedTable = {}
for _, value in ipairs(G.hand.highlighted) do
if value ~= card then
table.insert(combinedTable, value)
end
end
for _, value in ipairs(G.jokers.highlighted) do
if value ~= card then
table.insert(combinedTable, value)
end
end
return (#combinedTable == 2)
end,
use = function(self, card, area, copier)
local used_consumable = copier or card
local combinedTable = {}
for _, value in ipairs(G.hand.highlighted) do
if value ~= card then
table.insert(combinedTable, value)
end
end
for _, value in ipairs(G.jokers.highlighted) do
if value ~= card then
table.insert(combinedTable, value)
end
end
local highlighted_1 = combinedTable[1]
local highlighted_2 = combinedTable[2]
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot1")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
local percent = 1.15 - (1 - 0.999) / (1 - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
highlighted_1:flip()
highlighted_2:flip()
play_sound("card1", percent)
highlighted_1:juice_up(0.3, 0.3)
highlighted_2:juice_up(0.3, 0.3)
return true
end,
}))
delay(0.2)
local percent = 0.85 + (1 - 0.999) / (1 - 0.998) * 0.3
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.15,
func = function()
local one_edition = highlighted_1.edition
highlighted_1:flip()
highlighted_1:set_edition(highlighted_2.edition)
highlighted_2:flip()
highlighted_2:set_edition(one_edition)
play_sound("card1", percent)
highlighted_1:juice_up(0.3, 0.3)
highlighted_2:juice_up(0.3, 0.3)
return true
end,
}))
delay(0.2)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
play_sound("tarot2")
used_consumable:juice_up(0.3, 0.5)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.2,
func = function()
G.hand:unhighlight_all()
G.jokers:unhighlight_all()
return true
end,
}))
end,
}
local spectrals = {
white_hole,
vacuum,
hammerspace,
lock,
trade,
analog,
replica,
adversary,
chambered,
conduit,
}
if Cryptid.enabled["Epic Jokers"] then
spectrals[#spectrals + 1] = summoning
end
if Cryptid.enabled["Misc."] then
spectrals[#spectrals + 1] = ritual
end
return {
name = "Spectrals",
init = function()
--Trade - undo redeeming vouchers
function Card:unredeem()
if self.ability.set == "Voucher" then
stop_use()
if not self.config.center.discovered then
discover_card(self.config.center)
end
self.states.hover.can = false
if G.GAME.used_vouchers[self.config.center_key] then
G.GAME.used_vouchers[self.config.center_key] = nil
end
G.GAME.cry_owned_vouchers[self.config.center_key] = nil
local top_dynatext = nil
local bot_dynatext = nil
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.4,
func = function()
top_dynatext = DynaText({
string = localize({
type = "name_text",
set = self.config.center.set,
key = self.config.center.key,
}),
colours = { G.C.RED },
rotate = 1,
shadow = true,
bump = true,
float = true,
scale = 0.9,
pop_in = 0.6 / G.SPEEDFACTOR,
pop_in_rate = 1.5 * G.SPEEDFACTOR,
})
bot_dynatext = DynaText({
string = localize("cry_unredeemed"),
colours = { G.C.RED },
rotate = 2,
shadow = true,
bump = true,
float = true,
scale = 0.9,
pop_in = 1.4 / G.SPEEDFACTOR,
pop_in_rate = 1.5 * G.SPEEDFACTOR,
pitch_shift = 0.25,
})
self:juice_up(0.3, 0.5)
play_sound("card1")
play_sound("timpani")
self.children.top_disp = UIBox({
definition = {
n = G.UIT.ROOT,
config = { align = "tm", r = 0.15, colour = G.C.CLEAR, padding = 0.15 },
nodes = {
{ n = G.UIT.O, config = { object = top_dynatext } },
},
},
config = { align = "tm", offset = { x = 0, y = 0 }, parent = self },
})
self.children.bot_disp = UIBox({
definition = {
n = G.UIT.ROOT,
config = { align = "tm", r = 0.15, colour = G.C.CLEAR, padding = 0.15 },
nodes = {
{ n = G.UIT.O, config = { object = bot_dynatext } },
},
},
config = { align = "bm", offset = { x = 0, y = 0 }, parent = self },
})
return true
end,
}))
G.GAME.current_round.voucher = nil
self:unapply_to_run()
delay(0.6)
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 2.6,
func = function()
top_dynatext:pop_out(4)
bot_dynatext:pop_out(4)
return true
end,
}))
G.E_MANAGER:add_event(Event({
trigger = "after",
delay = 0.5,
func = function()
self.children.top_disp:remove()
self.children.top_disp = nil
self.children.bot_disp:remove()
self.children.bot_disp = nil
return true
end,
}))
end
end
function Card:unapply_to_run(center)
local center_table = {
name = center and center.name or self and self.ability.name,
extra = self and G.GAME.cry_voucher_centers[self.config.center_key].config.extra,
}
local obj = center or self.config.center
if obj.unredeem and type(obj.unredeem) == "function" then
obj:unredeem(self)
return
end
local is_debuffed = false
if
G.GAME.voucher_sticker_index.perishable[center_table.name]
and G.GAME.voucher_sticker_index.perishable[center_table.name] == 0
then
is_debuffed = true
end
if G.GAME.voucher_sticker_index.eternal[center_table.name] then
G.GAME.voucher_sticker_index.eternal[center_table.name] = nil
end
if G.GAME.voucher_sticker_index.perishable[center_table.name] then
G.GAME.voucher_sticker_index.perishable[center_table.name] = nil
end
if G.GAME.voucher_sticker_index.rental[center_table.name] then
G.GAME.voucher_sticker_index.rental[center_table.name] = nil
end
if G.GAME.voucher_sticker_index.pinned[center_table.name] then
G.GAME.voucher_sticker_index.pinned[center_table.name] = nil
end
if G.GAME.voucher_sticker_index.banana[center_table.name] then
G.GAME.voucher_sticker_index.banana[center_table.name] = nil
end
if is_debuffed == false then
if center_table.name == "Overstock" or center_table.name == "Overstock Plus" then
G.E_MANAGER:add_event(Event({
func = function()
change_shop_size(-center_table.extra)
return true
end,
}))
end
if center_table.name == "Tarot Merchant" or center_table.name == "Tarot Tycoon" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.tarot_rate = G.GAME.tarot_rate / center_table.extra
return true
end,
}))
end
if center_table.name == "Planet Merchant" or center_table.name == "Planet Tycoon" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.planet_rate = G.GAME.planet_rate / center_table.extra
return true
end,
}))
end
if center_table.name == "Hone" or center_table.name == "Glow Up" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.edition_rate = G.GAME.edition_rate / center_table.extra
return true
end,
}))
end
if center_table.name == "Magic Trick" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.playing_card_rate = 0
return true
end,
}))
end
if center_table.name == "Crystal Ball" then
G.E_MANAGER:add_event(Event({
func = function()
G.consumeables.config.card_limit = G.consumeables.config.card_limit - center_table.extra
return true
end,
}))
end
if center_table.name == "Clearance Sale" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.discount_percent = 0
for k, v in pairs(G.I.CARD) do
if v.set_cost then
v:set_cost()
end
end
return true
end,
}))
end
if center_table.name == "Liquidation" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.discount_percent = 25 -- no idea why the below returns nil, so it's hardcoded now
-- G.GAME.discount_percent = G.P_CENTERS.v_clearance_sale.extra
for k, v in pairs(G.I.CARD) do
if v.set_cost then
v:set_cost()
end
end
return true
end,
}))
end
if center_table.name == "Reroll Surplus" or center_table.name == "Reroll Glut" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.round_resets.reroll_cost = G.GAME.round_resets.reroll_cost + self.ability.extra
G.GAME.current_round.reroll_cost =
math.max(0, G.GAME.current_round.reroll_cost + self.ability.extra)
return true
end,
}))
end
if center_table.name == "Seed Money" then
G.E_MANAGER:add_event(Event({
func = function()
G.GAME.interest_cap = 25 --note: does not account for potential deck effects
return true
end,
}))
end
if center_table.name == "Money Tree" then
G.E_MANAGER:add_event(Event({
func = function()
if G.GAME.used_vouchers.v_seed_money then
G.GAME.interest_cap = 50
else
G.GAME.interest_cap = 25
end
return true
end,
}))
end
if center_table.name == "Grabber" or center_table.name == "Nacho Tong" then
G.GAME.round_resets.hands = G.GAME.round_resets.hands - center_table.extra
ease_hands_played(-center_table.extra)
end
if center_table.name == "Paint Brush" or center_table.name == "Palette" then
G.hand:change_size(-center_table.extra)
end
if center_table.name == "Wasteful" or center_table.name == "Recyclomancy" then
G.GAME.round_resets.discards = G.GAME.round_resets.discards - center_table.extra
ease_discard(-center_table.extra)
end
if center_table.name == "Antimatter" then
G.E_MANAGER:add_event(Event({
func = function()
if G.jokers then
G.jokers.config.card_limit = G.jokers.config.card_limit - center_table.extra
end
return true
end,
}))
end
if center_table.name == "Hieroglyph" or center_table.name == "Petroglyph" then
ease_ante(center_table.extra)
G.GAME.round_resets.blind_ante = G.GAME.round_resets.blind_ante or G.GAME.round_resets.ante
G.GAME.round_resets.blind_ante = G.GAME.round_resets.blind_ante + center_table.extra
if center_table.name == "Hieroglyph" then
G.GAME.round_resets.hands = G.GAME.round_resets.hands + center_table.extra
ease_hands_played(center_table.extra)
end
if center_table.name == "Petroglyph" then
G.GAME.round_resets.discards = G.GAME.round_resets.discards + center_table.extra
ease_discard(center_table.extra)
end
end
end
end
end,
items = spectrals,
}