From de85e1d7b2545cde8b025505edf820f7dc2cf3e2 Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:33:23 -0700 Subject: [PATCH 1/7] Add files via upload --- Items/Items/Blinds.lua | 755 +++++++++++++ Items/Items/Decks.lua | 293 +++++ Items/Items/Enhanced.lua | 535 +++++++++ Items/Items/MiscJokers.lua | 1973 ++++++++++++++++++++++++++++++++++ Items/Items/Planets.lua | 142 +++ Items/Items/Spectrals.lua | 272 +++++ Items/Items/Stakes.lua | 672 ++++++++++++ Items/Items/yEpicJokers.lua | 1026 ++++++++++++++++++ Items/Items/zAntimatter.lua | 67 ++ Items/Items/zExotic.lua | 515 +++++++++ Items/Items/zzChallenges.lua | 71 ++ 11 files changed, 6321 insertions(+) create mode 100644 Items/Items/Blinds.lua create mode 100644 Items/Items/Decks.lua create mode 100644 Items/Items/Enhanced.lua create mode 100644 Items/Items/MiscJokers.lua create mode 100644 Items/Items/Planets.lua create mode 100644 Items/Items/Spectrals.lua create mode 100644 Items/Items/Stakes.lua create mode 100644 Items/Items/yEpicJokers.lua create mode 100644 Items/Items/zAntimatter.lua create mode 100644 Items/Items/zExotic.lua create mode 100644 Items/Items/zzChallenges.lua diff --git a/Items/Items/Blinds.lua b/Items/Items/Blinds.lua new file mode 100644 index 000000000..84cc09a35 --- /dev/null +++ b/Items/Items/Blinds.lua @@ -0,0 +1,755 @@ +--extra blind functions for use by bosses +function Blind:cry_ante_base_mod(dt) + if not self.disabled then + local obj = self.config.blind + if obj.cry_ante_base_mod and type(obj.cry_ante_base_mod) == 'function' then + return obj:cry_ante_base_mod(self, dt) + end + end + return 0 +end +function Blind:cry_round_base_mod(dt) + if not self.disabled then + local obj = self.config.blind + if obj.cry_round_base_mod and type(obj.cry_round_base_mod) == 'function' then + return obj:cry_round_base_mod(self, dt) + end + end + return 1 +end +function Blind:cry_cap_score(score) + if not self.disabled then + local obj = self.config.blind + if obj.cry_cap_score and type(obj.cry_cap_score) == 'function' then + return obj:cry_cap_score(self, score) + end + end + return score +end +function Blind:cry_after_play() + if not self.disabled then + local obj = self.config.blind + if obj.cry_after_play and type(obj.cry_after_play) == 'function' then + return obj:cry_after_play(self) + end + end +end +function Blind:cry_before_play() + if not self.disabled then + local obj = self.config.blind + if obj.cry_before_play and type(obj.cry_before_play) == 'function' then + return obj:cry_before_play(self) + end + end +end + +local tax = { + object_type = "Blind", + name = "cry-Tax", + key = "tax", + pos = {x = 0, y = 0}, + boss = { + min = 1, + max = 10 + }, + loc_txt = { + name = 'The Tax', + text = { + "Score per hand capped at", + "0.4X blind requirements" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('40ff40'), + cry_cap_score = function(self, blind, score) + return math.floor(math.min(0.4*blind.chips,score)+0.5) + end +} + +local clock = { + object_type = "Blind", + name = "cry-Clock", + key = "clock", + pos = {x = 0, y = 1}, + mult = 0, + boss = { + min = 1, + max = 10 + }, + loc_txt = { + name = 'The Clock', + text = { + "+0.1X blind requirements every", + "3 seconds spent this ante" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('853455'), + defeat = function(self, blind, silent) + G.P_BLINDS.bl_cry_clock.mult = 0 + end, + disable = function(self, blind, silent) + G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling*2 + G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + end, + cry_ante_base_mod = function(self, blind, dt) + return 0.1*dt/3 + end +} +local trick = { + object_type = "Blind", + name = "cry-Trick", + key = "trick", + pos = {x = 0, y = 3}, + boss = { + min = 1, + max = 10 + }, + loc_txt = { + name = 'The Trick', + text = { + "After each hand, flip all", + "face-up cards held in hand" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('babd24'), + cry_after_play = function(self, blind) + --flip and shuffle all cards held in hand + for k, v in ipairs(G.hand.cards) do + if v.facing == "front" then + v:flip() + end + end + --[[if #G.hand.cards > 1 then + G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 0.2, func = function() + G.E_MANAGER:add_event(Event({ func = function() G.hand:shuffle('cry_trick'); play_sound('cardSlide1', 0.85);return true end })) + delay(0.15) + G.E_MANAGER:add_event(Event({ func = function() G.hand:shuffle('cry_trick'); play_sound('cardSlide1', 1.15);return true end })) + delay(0.15) + G.E_MANAGER:add_event(Event({ func = function() G.hand:shuffle('cry_trick'); play_sound('cardSlide1', 1);return true end })) + delay(0.5) + return true end })) + end--]] + end +} + +local joke = { + object_type = "Blind", + name = "cry-Joke", + key = "joke", + pos = {x = 0, y = 4}, + boss = { + min = 1, + max = 10 + }, + loc_txt = { + name = 'The Joke', + text = { + "If score is >2X requirements,", + "set ante to multiple of 8" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('00ffaa') +} +local lavender_loop = { + object_type = "Blind", + name = "cry-Lavender Loop", + key = "lavender_loop", + pos = {x = 0, y = 2}, + mult = 1, + dollars = 8, + boss = { + min = 3, + max = 10, + showdown = true + }, + loc_txt = { + name = 'Lavender Loop', + text = { + "1.25X blind requirements every", + "1.5 seconds spent this round" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('ae00ff'), + disable = function(self, blind, silent) + G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling*2 + G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + end, + cry_round_base_mod = function(self, blind, dt) + return 1.25^(dt/1.5) + end +} +local vermillion_virus = { + object_type = "Blind", + name = "cry-Vermillion Virus", + key = "vermillion_virus", + pos = {x = 0, y = 5}, + dollars = 8, + boss = { + min = 3, + max = 10, + showdown = true + }, + loc_txt = { + name = 'Vermillion Virus', + text = { + "One random Joker", + "replaced every hand" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('f65d34'), + cry_before_play = function(self, blind) + if G.jokers.cards[1] then + local idx = pseudorandom(pseudoseed('cry_vermillion_virus'),1,#G.jokers.cards) + if G.jokers.cards[idx] then + _card = create_card('Joker', G.jokers, nil, nil, nil, nil, nil, 'cry_vermillion_virus_gen') + G.jokers.cards[idx]:remove_from_deck() + _card:add_to_deck() + _card:start_materialize() + G.jokers.cards[idx] = _card + _card:set_card_area(G.jokers) + G.jokers:set_ranks() + G.jokers:align_cards() + end + end + end +} + +local sapphire_stamp = { + object_type = "Blind", + name = "cry-Sapphire Stamp", + key = "sapphire_stamp", + pos = {x = 0, y = 6}, + dollars = 8, + boss = { + min = 3, + max = 10, + showdown = true + }, + loc_txt = { + name = 'Sapphire Stamp', + text = { + "Select an extra card, deselect", + "random card before scoring" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('4057d6'), + cry_before_play = function(self, blind) + local idx = pseudorandom(pseudoseed("cry_sapphire_stamp"), 1, #G.hand.highlighted) + G.hand:remove_from_highlighted(G.hand.highlighted[idx]) + end, + set_blind = function(self, blind, reset, silent) + if not reset then + G.hand.config.highlighted_limit = G.hand.config.highlighted_limit + 1 + end + end, + defeat = function(self, blind, silent) + if not self.disabled then + G.hand.config.highlighted_limit = G.hand.config.highlighted_limit - 1 + end + end, + disable = function(self, blind, silent) + G.hand.config.highlighted_limit = G.hand.config.highlighted_limit - 1 + end, +} + +local obsidian_orb = { + object_type = "Blind", + name = "cry-Obsidian Orb", + key = "obsidian_orb", + pos = {x = 0, y = 7}, + dollars = 8, + boss = { + min = 3, + max = 10, + showdown = true + }, + loc_txt = { + name = 'Obsidian Orb', + text = { + "Applies abilities of", + "all defeated bosses" + } + }, + atlas = "blinds", + discovered = true, + boss_colour = HEX('290759'), + set_blind = function(self, blind, reset, silent) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.set_blind then s:set_blind(blind,reset,silent) end + if s.name == 'The Eye' and not reset then + blind.hands = { + ["Flush Five"] = false, + ["Flush House"] = false, + ["Five of a Kind"] = false, + ["Straight Flush"] = false, + ["Four of a Kind"] = false, + ["Full House"] = false, + ["Flush"] = false, + ["Straight"] = false, + ["Three of a Kind"] = false, + ["Two Pair"] = false, + ["Pair"] = false, + ["High Card"] = false, + } + end + if s.name == 'The Mouth' and not reset then + blind.only_hand = false + end + if s.name == 'The Fish' and not reset then + blind.prepped = nil + end + if s.name == 'The Water' and not reset then + blind.discards_sub = G.GAME.current_round.discards_left + ease_discard(-blind.discards_sub) + end + if s.name == 'The Needle' and not reset then + blind.hands_sub = G.GAME.round_resets.hands - 1 + ease_hands_played(-blind.hands_sub) + end + if s.name == 'The Manacle' and not reset then + G.hand:change_size(-1) + end + if s.name == 'Amber Acorn' and not reset and #G.jokers.cards > 0 then + G.jokers:unhighlight_all() + for k, v in ipairs(G.jokers.cards) do + v:flip() + end + if #G.jokers.cards > 1 then + G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 0.2, func = function() + G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 0.85);return true end })) + delay(0.15) + G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 1.15);return true end })) + delay(0.15) + G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 1);return true end })) + delay(0.5) + return true end })) + end + end + + --add new debuffs + for _, v in ipairs(G.playing_cards) do + self:debuff_card(v) + end + for _, v in ipairs(G.jokers.cards) do + if not reset then self:debuff_card(v, true) end + end + end + end, + defeat = function(self, blind, silent) + for k, _ in pairs(G.GAME.defeated_blinds) do + if G.P_BLINDS[k].defeat then G.P_BLINDS[k]:defeat(blind, silent) end + if G.P_BLINDS[k].name == "The Manacle" and not self.disabled then + G.hand:change_size(1) + end + end + end, + disable = function(self, blind, silent) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.disable then s:disable(blind, silent) end + if s.name == 'The Water' then + ease_discard(blind.discards_sub) + end + if s.name == 'The Wheel' or s.name == 'The House' or s.name == 'The Mark' or s.name == 'The Fish' then + for i = 1, #G.hand.cards do + if G.hand.cards[i].facing == 'back' then + G.hand.cards[i]:flip() + end + end + for k, v in pairs(G.playing_cards) do + v.ability.wheel_flipped = nil + end + end + if s.name == 'The Needle' then + ease_hands_played(blind.hands_sub) + end + if s.name == 'The Wall' then + blind.chips = blind.chips/2 + blind.chip_text = number_format(blind.chips) + end + if s.name == 'Cerulean Bell' then + for k, v in ipairs(G.playing_cards) do + v.ability.forced_selection = nil + end + end + if s.name == 'The Manacle' then + G.hand:change_size(1) + + G.FUNCS.draw_from_deck_to_hand(1) + end + if s.name == 'Violet Vessel' then + blind.chips = blind.chips/3 + blind.chip_text = number_format(blind.chips) + end + end + end, + press_play = function(self, blind) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.press_play then s:press_play(blind) end + if s.name == "The Hook" then + G.E_MANAGER:add_event(Event({ func = function() + local any_selected = nil + local _cards = {} + for k, v in ipairs(G.hand.cards) do + _cards[#_cards+1] = v + end + for i = 1, 2 do + if G.hand.cards[i] then + local selected_card, card_key = pseudorandom_element(_cards, pseudoseed('hook')) + G.hand:add_to_highlighted(selected_card, true) + table.remove(_cards, card_key) + any_selected = true + play_sound('card1', 1) + end + end + if any_selected then G.FUNCS.discard_cards_from_highlighted(nil, true) end + return true end })) + blind.triggered = true + delay(0.7) + end + if s.name == 'Crimson Heart' then + if G.jokers.cards[1] then + blind.triggered = true + blind.prepped = true + end + end + if s.name == 'The Fish' then + blind.prepped = true + end + if s.name == "The Tooth" then + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2, func = function() + for i = 1, #G.play.cards do + G.E_MANAGER:add_event(Event({func = function() G.play.cards[i]:juice_up(); return true end })) + ease_dollars(-1) + delay(0.23) + end + return true end })) + blind.triggered = true + end + end + end, + modify_hand = function(self, blind, cards, poker_hands, text, mult, hand_chips) + local new_mult = mult + local new_chips = chips + local trigger = false + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.modify_hand then + local this_trigger = false + new_mult, new_chips, this_trigger = s:modify_hand(blind, cards, poker_hands, text, new_mult, new_chips) + trigger = trigger or this_trigger + end + if s.name == "The Flint" then + blind.triggered = true + new_mult = math.max(math.floor(new_mult*0.5 + 0.5), 1) + new_chips = math.max(math.floor(new_chips*0.5 + 0.5), 0) + trigger = true + end + end + return new_mult or mult, new_chips or hand_chips, trigger + end, + debuff_hand = function(self, blind, cards, hand, handname, check) + blind.debuff_boss = nil + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.debuff_hand and s:debuff_hand(blind, cards, hand, handname, check) then + blind.debuff_boss = s + return true + end + if s.debuff then + blind.triggered = false + if s.debuff.hand and next(hand[s.debuff.hand]) then + blind.triggered = true + blind.debuff_boss = s + return true + end + if s.debuff.h_size_ge and #cards < s.debuff.h_size_ge then + blind.triggered = true + blind.debuff_boss = s + return true + end + if s.debuff.h_size_le and #cards > s.debuff.h_size_le then + blind.triggered = true + blind.debuff_boss = s + return true + end + if s.name == "The Eye" then + if blind.hands[handname] then + blind.triggered = true + blind.debuff_boss = s + return true + end + if not check then blind.hands[handname] = true end + end + if s.name == "The Mouth" then + if s.only_hand and s.only_hand ~= handname then + blind.triggered = true + blind.debuff_boss = s + return true + end + if not check then s.only_hand = handname end + end + end + if s.name == 'The Arm' then + blind.triggered = false + if G.GAME.hands[handname].level > 1 then + blind.triggered = true + if not check then + level_up_hand(self.children.animatedSprite, handname, nil, -1) + blind:wiggle() + end + end + end + if s.name == 'The Ox' then + blind.triggered = false + if handname == G.GAME.current_round.most_played_poker_hand then + blind.triggered = true + if not check then + ease_dollars(-G.GAME.dollars, true) + blind:wiggle() + end + end + end + end + return false + end, + drawn_to_hand = function(self, blind) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.drawn_to_hand then s:drawn_to_hand(blind) end + if s.name == 'Cerulean Bell' then + local any_forced = nil + for k, v in ipairs(G.hand.cards) do + if v.ability.forced_selection then + any_forced = true + end + end + if not any_forced then + G.hand:unhighlight_all() + local forced_card = pseudorandom_element(G.hand.cards, pseudoseed('cerulean_bell')) + forced_card.ability.forced_selection = true + G.hand:add_to_highlighted(forced_card) + end + end + if s.name == 'Crimson Heart' and blind.prepped and G.jokers.cards[1] then + local jokers = {} + for i = 1, #G.jokers.cards do + if not G.jokers.cards[i].debuff or #G.jokers.cards < 2 then jokers[#jokers+1] =G.jokers.cards[i] end + G.jokers.cards[i]:set_debuff(false) + end + local _card = pseudorandom_element(jokers, pseudoseed('crimson_heart')) + if _card then + _card:set_debuff(true) + _card:juice_up() + self:wiggle() + end + end + end + end, + stay_flipped = function(self, blind, area, card) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.stay_flipped and s:stay_flipped(blind, area, card) then return true end + if area == G.hand then + if s.name == 'The Wheel' and pseudorandom(pseudoseed('wheel')) < G.GAME.probabilities.normal/7 then + return true + end + if s.name == 'The House' and G.GAME.current_round.hands_played == 0 and G.GAME.current_round.discards_used == 0 then + return true + end + if s.name == 'The Mark' and card:is_face(true) then + return true + end + if s.name == 'The Fish' and blind.prepped then + return true + end + end + end + end, + debuff_card = function(self, blind, card, from_blind) + if card and type(card) == 'table' and card.area then + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.debuff_card then s:debuff_card(blind, card, from_blind) end + if s.debuff and not G.GAME.blind.disabled and card.area ~= G.jokers then + --this part is buggy for some reason + if s.debuff.suit and Card.is_suit(card, s.debuff.suit, true) then + card:set_debuff(true) + return + end + if s.debuff.is_face =='face' and Card.is_face(card, true) then + card:set_debuff(true) + return + end + if s.name == 'The Pillar' and card.ability.played_this_ante then + card:set_debuff(true) + return + end + if s.debuff.value and s.debuff.value == card.base.value then + card:set_debuff(true) + return + end + if s.debuff.nominal and s.debuff.nominal == card.base.nominal then + card:set_debuff(true) + return + end + end + if s.name == 'Crimson Heart' and not G.GAME.blind.disabled and card.area == G.jokers then + return + end + if s.name == 'Verdant Leaf' and not G.GAME.blind.disabled and card.area ~= G.jokers then card:set_debuff(true); return end + end + end + end, + cry_ante_base_mod = function(self, blind, dt) + local mod = 0 + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.cry_ante_base_mod then + mod = mod + s:cry_ante_base_mod(blind, dt) + end + end + return mod + end, + cry_round_base_mod = function(self, blind, dt) + local mod = 1 + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.cry_round_base_mod then + mod = mod * s:cry_round_base_mod(blind, dt) + end + end + return mod + end, + cry_cap_score = function(self, blind, score) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.cry_cap_score then + score = s:cry_cap_score(blind, score) + end + end + return score + end, + cry_before_play = function(self, blind) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.cry_before_play then s:cry_before_play(blind) end + end + end, + cry_after_play = function(self, blind) + for k, _ in pairs(G.GAME.defeated_blinds) do + s = G.P_BLINDS[k] + if s.cry_after_play then s:cry_after_play(blind) end + end + end, + get_loc_debuff_text = function(self, blind) + if not blind.debuff_boss then return "Applies abilities of all defeated bosses" end + local loc_vars = nil + if blind.debuff_boss.name == 'The Ox' then + loc_vars = {localize(G.GAME.current_round.most_played_poker_hand, 'poker_hands')} + end + local loc_target = localize{type = 'raw_descriptions', key = blind.debuff_boss.key, set = 'Blind', vars = loc_vars} + local loc_debuff_text = '' + for k, v in ipairs(loc_target) do + loc_debuff_text = loc_debuff_text..v..(k <= #loc_target and ' ' or '') + end + local disp_text = (blind.debuff_boss.name == 'The Wheel' and G.GAME.probabilities.normal or '')..loc_debuff_text + if (blind.debuff_boss.name == 'The Mouth') and blind.only_hand then disp_text = disp_text..' ['..localize(blind.only_hand, 'poker_hands')..']' end + return disp_text + end +} + +local blind_sprites = { + object_type = "Atlas", + key = "blinds", + atlas_table = "ANIMATION_ATLAS", + path = "bl_cry.png", + px = 34, + py = 34, + frames = 21 +} + +return {name = "Blinds", + init = function() + --Clock Patches + local upd = Game.update + function Game:update(dt) + upd(self,dt) + if G.GAME and G.GAME.round_resets and G.GAME.round_resets.blind_choices and G.GAME.round_resets.blind_choices.Boss and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].cry_ante_base_mod then + if G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult ~= 0 and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult_ante ~= G.GAME.round_resets.ante then + if G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].name == "cry-Obsidian Orb" then + for i = 1, #G.GAME.defeated_blinds do + G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult * G.P_BLINDS[G.GAME.defeated_blinds[i]]/2 + end + else + G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = 0 + end + G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult_ante = G.GAME.round_resets.ante + end + if G.GAME.round_resets.blind_states.Boss ~= "Current" then + G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult + (G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].cry_ante_base_mod and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss]:cry_ante_base_mod(nil, dt) or 0) + --Update UI + if G.blind_select_opts then + local blind_UI = G.blind_select_opts.boss.definition.nodes[1].nodes[1].nodes[1].nodes[1] + local chip_text_node = blind_UI.nodes[1].nodes[3].nodes[1].nodes[2].nodes[2].nodes[3] + chip_text_node.config.text = number_format(get_blind_amount(G.GAME.round_resets.blind_ante)*G.GAME.starting_params.ante_scaling*G.P_BLINDS.bl_cry_clock.mult) + chip_text_node.config.scale = score_number_scale(0.9, get_blind_amount(G.GAME.round_resets.blind_ante)*G.GAME.starting_params.ante_scaling*G.P_BLINDS.bl_cry_clock.mult) + G.blind_select_opts.boss:recalculate() + end + elseif not G.GAME.blind.disabled and to_big(G.GAME.chips) < to_big(G.GAME.blind.chips) then + G.GAME.blind.chips = G.GAME.blind.chips + G.GAME.blind:cry_ante_base_mod(dt)*get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling + G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + end + end + if G.GAME and G.GAME.blind and not G.GAME.blind.disabled and to_big(G.GAME.chips) < to_big(G.GAME.blind.chips) then + G.GAME.blind.chips = G.GAME.blind.chips * G.GAME.blind:cry_round_base_mod(dt) + G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + end + end + --Trick Patches + local gfep = G.FUNCS.evaluate_play + function G.FUNCS.evaluate_play(e) + gfep(e) + G.GAME.blind:cry_after_play() + end + --Sapphire Stamp Patches + local pcfh = G.FUNCS.play_cards_from_highlighted + function G.FUNCS.play_cards_from_highlighted(e) + G.GAME.blind:cry_before_play() + pcfh(e) + end + --Obsidian Orb Patches + local dft = Blind.defeat + function Blind:defeat(s) + dft(self, s) + if self.name ~= "cry-Obsidian Orb" and + (self.name ~= "The Eye" or not G.GAME.defeated_blinds["bl_mouth"]) and + (self.name ~= "The Mouth" or not G.GAME.defeated_blinds["bl_eye"]) and + (self.name ~= "The Needle" or not G.GAME.defeated_blinds["bl_cry_tax"]) and + (self.name ~= "cry-Tax" or not G.GAME.defeated_blinds["bl_needle"]) + then + G.GAME.defeated_blinds[self.config.blind.key] = true + end + end + local sr = Game.start_run + function Game:start_run(args) + sr(self, args) + if not G.GAME.defeated_blinds then G.GAME.defeated_blinds = {} end + end + end, + items = {tax, clock, trick, joke, lavender_loop, vermillion_virus, sapphire_stamp, obsidian_orb, blind_sprites}} \ No newline at end of file diff --git a/Items/Items/Decks.lua b/Items/Items/Decks.lua new file mode 100644 index 000000000..3fd8348da --- /dev/null +++ b/Items/Items/Decks.lua @@ -0,0 +1,293 @@ +local very_fair = { + object_type = "Back", + name = "Very Fair Deck", + key = "very_fair", + config = {hands = -2, discards = -2, cry_no_vouchers = true}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Very Fair Deck", + text = { + "{C:blue}-2{} hands, {C:red}-2{} discards", + "every round", + "{C:attention}Vouchers{} no longer", + "appear in the shop" + } + }, + --[[loc_vars = function(self, info_queue, center) + return {vars = {center.effect.config.hands, center.effect.config.discards}} + end,--]] --this doesn't work, will fix later + atlas = "very_fair" +} + +-- Thanks to many members of the community for contributing to all of these quips! +-- There's too many to credit so just go here: https://discord.com/channels/1116389027176787968/1209506360987877408/1237971471146553406 +-- And here: https://discord.com/channels/1116389027176787968/1219749193204371456/1240468252325318667 +very_fair_quips = { + {"L", "NO VOUCHERS", "FOR YOU"}, + {"BOZO", "DID YOU THINK I WOULD", "GIVE YOU A VOUCHER?"}, + {"NOPE!", "NO VOUCHERS HERE!", "(SLUMPAGE EDITION)"}, + {"SKILL ISSUE", "IMAGINE BEING GOOD ENOUGH", "FOR A VOUCHER"}, + {"JIMBO", "FROM MANAGEMENT", "FORGOT TO RESTOCK"}, + {"OOPS!", "NO VOUCHERS", ""}, + {"YOU JOKER,", "WHY ARE YOU LOOKING", "OVER HERE? LOL"}, + {"THE VOUCHER", "IS IN", "ANOTHER CASTLE"}, + {"$0", "BLANK VOUCHER", "(GET IT?)"}, + {"ERROR", "CANNOT DO ARITHMETIC ON A NIL VALUE", "(tier4vouchers.lua)"}, + {"100% OFF", "ON ALL VOUCHERS", "(SOMEONE ALREADY BOUGHT THEM)"}, + {"TRY AGAIN LATER", "HINT: YOU WON'T HAVE", "ENOUGH MONEY ANYWAYS"}, + {"HUH?", "\"VOUCHER\"?", "THAT'S NOT EVEN A WORD..."}, + {"HOLD \"R\"", "TO RESTOCK", "ALL VOUCHERS"}, + {"DID YOU KNOW?", "PRESSING ALT+F4", "GIVES FREE VOUCHERS!"}, + {"SORRY,", "THERE ARE NO VOUCHERS", "DUE TO BUDGET CUTS"}, + {"CALL 1-600-JIMBO", "TO RATE YOUR", "VOUCHER EXPERIENCE"}, + {"DEFEAT", "ANTE 39 BOSS BLIND", "TO RESTOCK"}, + {"MAGIC TRICK", "I MADE THIS VOUCHER", "DISAPPEAR"}, + {"WHY IS A", "VOUCHER LIKE", "A WRITING DESK?"}, + {"WE HAVE RETRACTED", "YOUR VOUCHERS, THEY WOULD BE", "BETTER USED IN OTHER RUNS"}, + {"WHY DO THEY CALL IT VOUCHER", "WHEN MULT OUT THE HOT", "IN COLD EAT EAT THE CHIP"}, + {"SORRY", "THE VOUCHERS ARE EXPERIENCING", "VOUCHIFIA ABORTUS"}, + {"UNFORTUNATELY", "THE VOUCHRX REWRITE UPDATE", "HAS BEEN CANCELLED"}, + {"DEFEAT", "BOSS BLIND", "TO CHANGE NOTHING"}, + {"BIRDS ARE SINGING", "FLOWERS ARE BLOOMING", "KIDS LIKE YOU..."}, + {"WE ARE SORRY TO SAY", "ALL VOUCHERS HAVE BEEN RECALLED", "DUE TO SALMONELLA EXPOSURE"}, + {"VOUCHERS COULDN'T ARRIVE", "DUE TO SHOP LAYOUT BEING", "200% OVERBUDGET"}, + {"YOU LIKE", "BUYING VOUCHERS, DON'T YOU", "YOU'RE A VOUCHERBUYER"}, + {"VOUCHERS", "!E", "VOUCHER POOL"}, + {"THERE", "IS NO", "VOUCHER"}, + {"THERE IS", "NO SANTA", "AND THERE ARE NO VOUCHERS"}, + {"", "VOUCHERN'T", ""}, + {"YOU", "JUST LOST", "THE GAME"}, + {"CAN I OFFER YOU", "A NICE EGG", "IN THESE TRYING TIMES?"}, + {"GO TOUCH GRASS", "INSTEAD OF USING", "THIS DECK"}, + {"YOU COULD BE", "PLAYING ON BLUE DECK", "RIGHT NOW"}, + {"FREE EXOTICS", "GET THEM BEFORE ITS", "TOO LATE (sold out)"}, + {"PROVE THEM WRONG", "BUY BUYING AN INVISIBLE", "VOUCHER FOR $10"}, + {"", "no vouchers?", ""}, + {"see this ad?", "if you are, then it's working", "and you could have it for your own"}, + {"YOU'RE MISSING OUT ON", "AT LEAST 5 VOUCHERS RIGHT NOW", "tonktonktonktonktonk"}, + {"10", "20 NO VOUCHER XD", "30 GOTO 10"}, + {"VOUCHERS", "ARE A PREMIUM FEATURE", "$199.99 JOLLARS TO UNLOCK"}, + {"TRUE VOUCHERLESS!?!?", "ASCENDANT STAKE ONLY", "VERY FAIR DECK"}, + {"ENJOYING YOUR", "VOUCHER EXPERIENCE? GIVE US A", "FIVE STAR RATING ON JESTELP"}, + {"FREE VOUCHERS", "HOT VOUCHERS NEAR YOU", "GET VOUCHERS QUICK WITH THIS ONE TRICK"}, + {"INTRODUCING", "THE VERY FIRST TIER 0 VOUCHER!", "(coming to Cryptid 1.0 soon)"}, + {"A VOUCHER!", "IT'S JUST IMAGINARY", "WE IMAGINED YOU WOULD WANT IT, THAT IS"}, + {"TURN OFF ADBLOCKER", "WITHOUT ADS, WE WOULDN'T", "BE ABLE TO SELL YOU VOUCHERS"}, + {"IF YOU HAVE", "A PROBLEM WITH THIS", "EMAIL IT TO US AT NORESPONSE@JMAIL.COM"}, + {"NOT ENOUGH MONEY", "TO BUY THIS VOUCHER", "SO WHY WOULD WE PUT IT HERE?"}, + {"WANT A VOUCHER?", "WELL SHUT UP", "YOU CAN'T HAVE ANY LOL"}, + {"^$%& NO", "VOUCHERS ^%&% %&$^% FOR", "$%&%%$ %&$&*%$^ YOU"}, + {"A VOUCHER (TRUST)", "|\\/|", "|/\\|"}, + {"... --- ...", ".--. .-.. .- -.-- . .-. -.. . -.-. --- -.. . -.. -- --- .-. ... .", "-.-. --- -.. . - --- ..-. .. -. -.. .- ...- --- ..- -.-. .... . .-."}, + {"RUN > NEW", "STARE AT NOTHING", "FOR AN HOUR OR TWO"}, + {"WE'RE VERY SORRY", "THE LAST GUY PANIC BOUGHT", "ALL THE VOUCHERS"}, + {"HOW IT FEELS", "TO BUY NO", "VOUCHERS"}, + {"JIMBO GOT A NAT 1", "AND DUMPED ALL THE", "VOUCHERS IN A DITCH"}, + {"ATTEMPT TO INDEX", "FIELD 'VOUCHER'", "(A NIL VALUE)"}, + {"OH YOU REALLY THOUGHT THAT READING ALL THESE LINES WOULD BRING YOUR VOUCHERS BACK?", "SORRY TO TELL YOU, BUT THIS DECK DOESN'T CONTAIN THE VOUCHERS YOU SEEK.", "THIS ABNORMALLY LONG TEXT IS HERE AND DESIGNED TO WASTE YOUR TIME AND EFFORT WHILE YOU READ IT."}, + {"GO TO", "https://youtu.be/p7YXXieghto", "FOR FREE VOUCHERS"} +} +very_fair_quip = {} + +local very_fair_sprite = { + object_type = "Atlas", + key = "very_fair", + + path = "b_cry_very_fair.png", + px = 71, + py = 95 +} + +local equilibrium = { + object_type = "Back", + name = "cry-Equilibrium", + key = "equilibrium", + config = {vouchers = {'v_overstock_norm','v_overstock_plus'}, cry_equilibrium = true}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deck of Equilibrium", + text = { + "All cards have the", + "{C:attention}same chance{} of", + "appearing in shops,", + "start run with", + "{C:attention,T:v_overstock_plus}Overstock Plus" + } + }, + atlas = "equilibrium" +} +local equilibrium_sprite = { + object_type = "Atlas", + key = "equilibrium", + path = "b_cry_equilibrium.png", + px = 71, + py = 95 +} +local misprint = { + object_type = "Back", + name = "cry-Misprint", + key = "misprint", + config = {cry_misprint_min = 0.1, cry_misprint_max = 10}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Misprint Deck", + text = { + "Values of cards", + "and poker hands", + "are {C:attention}randomized" + } + }, + atlas = "misprint" +} +local misprint_sprite = { + object_type = "Atlas", + key = "misprint", + path = "b_cry_misprint.png", + px = 71, + py = 95 +} +local infinite = { + object_type = "Back", + name = "cry-Infinite", + key = "infinite", + config = {cry_highlight_limit = 1e20}, + pos = {x = 0, y = 0}, + atlas = "infinite", + loc_txt = { + name = "Infinite Deck", + text = { + "You can select {C:attention}any", + "number of cards" + } + }, +} +local infinite_sprite = { + object_type = "Atlas", + key = "infinite", + path = "b_cry_infinite.png", + px = 71, + py = 95 +} +local conveyor = { + object_type = "Back", + name = "cry-Conveyor", + key = "conveyor", + config = {cry_conveyor = true}, + pos = {x = 0, y = 0}, + atlas = "conveyor", + loc_txt = { + name = "Conveyor Deck", + text = { + "Jokers may {C:attention}not{} be moved", + "At start of round,", + "{C:attention}duplicate{} rightmost Joker", + "and {C:attention}destroy{} leftmost Joker" + } + } +} +local conveyor_sprite = { + object_type = "Atlas", + key = "conveyor", + path = "b_cry_conveyor.png", + px = 71, + py = 95 +} +local CCD = { + object_type = "Back", + name = "cry-CCD", + key = "CCD", + config = {cry_ccd = true}, + pos = {x = 0, y = 0}, + atlas = "CCD", + loc_txt = { + name = "CCD Deck", + text = { + "Every card is also", + "a {C:attention}random{} consumable" + } + } +} +local ccd_sprite = { + object_type = "Atlas", + key = "CCD", + path = "b_cry_ccd.png", + px = 71, + py = 95 +} +return {name = "Misc. Decks", + init = function() + local Backapply_to_runRef = Back.apply_to_run + function Back.apply_to_run(self) + Backapply_to_runRef(self) + if self.effect.config.cry_no_vouchers then + G.GAME.modifiers.cry_no_vouchers = true + end + if self.effect.config.cry_equilibrium then + G.GAME.modifiers.cry_equilibrium = true + end + if self.effect.config.cry_conveyor then + G.GAME.modifiers.cry_conveyor = true + end + if self.effect.config.cry_misprint_min then + G.GAME.modifiers.cry_misprint_min = self.effect.config.cry_misprint_min + G.GAME.modifiers.cry_misprint_max = self.effect.config.cry_misprint_max + end + if self.effect.config.cry_highlight_limit then + G.GAME.modifiers.cry_highlight_limit = self.effect.config.cry_highlight_limit + end + if self.effect.config.cry_ccd then + G.GAME.modifiers.cry_ccd = true + end + end + --equilibrium deck patches + local gcp = get_current_pool + function get_current_pool(t, r, l, a, override_equilibrium_effect) + if G.GAME.modifiers.cry_equilibrium and not override_equilibrium_effect and (a == 'sho' or t == 'Voucher' or t == 'Booster') then + if t ~= "Enhanced" and t ~= "Edition" and t ~= "Back" and t ~= "Tag" and t ~= "Seal" and t ~= "Stake" then + if not P_CRY_ITEMS then + P_CRY_ITEMS = {} + local valid_pools = {"Joker", "Consumeables", "Voucher", "Booster"} + for _, id in ipairs(valid_pools) do + for k, v in pairs(G.P_CENTER_POOLS[id]) do + P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key + end + end + for k, v in pairs(G.P_CARDS) do + P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key + end + end + return P_CRY_ITEMS, "cry_equilibrium"..G.GAME.round_resets.ante + end + end + return gcp(t,r,l,a) + end + local gp = get_pack + function get_pack(k, t) + if G.GAME.modifiers.cry_equilibrium then + if not P_CRY_ITEMS then + P_CRY_ITEMS = {} + local valid_pools = {"Joker", "Consumeables", "Voucher", "Booster"} + for _, id in ipairs(valid_pools) do + for k, v in pairs(G.P_CENTER_POOLS[id]) do + P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key + end + end + for k, v in pairs(G.P_CARDS) do + P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key + end + end + return G.P_CENTERS[pseudorandom_element(P_CRY_ITEMS,pseudoseed('cry_equipackbrium'..G.GAME.round_resets.ante))] + end + return gp(k,t) + end + --Misprint Deck patches + function cry_log_random(seed,min,max) + math.randomseed(seed) + local lmin = math.log(min,2.718281828459045) + local lmax = math.log(max,2.718281828459045) + local poll = math.random()*(lmax-lmin)+lmin + return math.exp(poll) + end + end, + items = {very_fair_sprite, equilibrium_sprite, misprint_sprite, infinite_sprite, conveyor_sprite, ccd_sprite, + very_fair, equilibrium, misprint, infinite, conveyor, CCD}} diff --git a/Items/Items/Enhanced.lua b/Items/Items/Enhanced.lua new file mode 100644 index 000000000..14189b1f3 --- /dev/null +++ b/Items/Items/Enhanced.lua @@ -0,0 +1,535 @@ +local hierophant_deck = {object_type = "Back", + name = "cry-The Hierophant's Deck", + key = "hierophant_deck", + config = {cry_force_enhancement = "m_bonus"}, + pos = {x = 0, y = 0}, + atlas = "hierophant", + loc_txt = { + name = "The Hierophant's Deck", + text = { + "Start with a deck", + "of {C:attention}Bonus Cards{}", + "Cards cannot change enhancements" + } + }, +} +local hierophant_sprite = { + object_type = "Atlas", + key = "hierophant", + path = "b_cry_hierophant.png", + px = 71, + py = 95 +} +local empress_deck = {object_type = "Back", + name = "cry-The Empress's Deck", + key = "empress_deck", + config = {cry_force_enhancement = "m_mult"}, + atlas = "empress", + pos = {x = 0, y = 0}, + loc_txt = { + name = "The Empress's Deck", + text = { + "Start with a deck", + "of {C:attention}Mult Cards{}", + "Cards cannot change enhancements" + } + }, +} +local empress_sprite = { + object_type = "Atlas", + key = "empress", + path = "b_cry_empress.png", + px = 71, + py = 95 +} +local lovers_deck = {object_type = "Back", + name = "cry-The Lovers' Deck", + key = "lovers_deck", + config = {cry_force_enhancement = "m_wild"}, + pos = {x = 0, y = 0}, + atlas = "lovers", + loc_txt = { + name = "The Lovers' Deck", + text = { + "Start with a deck", + "of {C:attention}Wild Cards{}", + "Cards cannot change enhancements" + } + }, +} +local lovers_sprite = { + object_type = "Atlas", + key = "lovers", + path = "b_cry_lovers.png", + px = 71, + py = 95 +} +local justice_deck = {object_type = "Back", + name = "cry-Deck of Justice", + key = "justice_deck", + config = {cry_force_enhancement = "m_glass"}, + pos = {x = 0, y = 0}, + atlas = "justice", + loc_txt = { + name = "Deck of Justice", + text = { + "Start with a deck", + "of {C:attention}Glass Cards{}", + "Cards cannot change enhancements" + } + }, +} +local justice_sprite = { + object_type = "Atlas", + key = "justice", + path = "b_cry_justice.png", + px = 71, + py = 95 +} +local chariot_deck = {object_type = "Back", + name = "cry-The Chariot's Deck", + key = "chariot_deck", + config = {cry_force_enhancement = "m_steel"}, + pos = {x = 6, y = 1}, + loc_txt = { + name = "The Chariot's Deck", + text = { + "Start with a deck", + "of {C:attention}Steel Cards{}", + "Cards cannot change enhancements" + } + }, + +} +local tower_deck = {object_type = "Back", + name = "cry-Stoner's Deck", + key = "tower_deck", + config = {cry_force_enhancement = "m_stone"}, + pos = {x = 5, y = 0}, + loc_txt = { + name = "Stoner's Deck", + text = { + "Start with a deck", + "of {C:attention}Stone Cards{}", + "Cards cannot change enhancements" + } + }, + +} +local devil_deck = {object_type = "Back", + name = "cry-The Devil's Deck", + key = "devil_deck", + config = {cry_force_enhancement = "m_gold"}, + pos = {x = 6, y = 0}, + loc_txt = { + name = "The Devil's Deck", + text = { + "Start with a deck", + "of {C:attention}Gold Cards{}", + "Cards cannot change enhancements" + } + }, + +} +local magician_deck = {object_type = "Back", + name = "cry-The Magician's Deck", + key = "magician_deck", + config = {cry_force_enhancement = "m_lucky"}, + pos = {x = 4, y = 1}, + loc_txt = { + name = "The Magician's Deck", + text = { + "Start with a deck", + "of {C:attention}Lucky Cards{}", + "Cards cannot change enhancements" + } + }, + +} +local foil_deck = {object_type = "Back", + name = "cry-Deck of Chips", + key = "foil_deck", + config = {cry_force_edition = 'foil'}, + pos = {x = 0, y = 2}, + loc_txt = { + name = "Deck of Chips", + text = { + "Start with a deck", + "of {C:attention}Foil Cards{}", + "Cards cannot change editions" + } + }, + +} +local holo_deck = {object_type = "Back", + name = "cry-Deck of Mult", + key = "holo_deck", + config = {cry_force_edition = 'holo'}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deck of Mult", + text = { + "Start with a deck", + "of {C:attention}Holographic Cards{}", + "Cards cannot change editions" + } + }, + +} +local poly_deck = {object_type = "Back", + name = "cry-Deck of XMult", + key = "poly_deck", + config = {cry_force_edition = 'polychrome'}, + pos = {x = 5, y = 2}, + loc_txt = { + name = "Deck of XMult", + text = { + "Start with a deck", + "of {C:attention}Polychrome Cards{}", + "Cards cannot change editions" + } + }, + +} +local talisman_deck = {object_type = "Back", + name = "cry-Talisman Deck", + key = "talisman_deck", + config = {cry_force_seal = 'Gold'}, + pos = {x = 1, y = 2}, + loc_txt = { + name = "Talisman Deck", + text = { + "Start with a deck", + "of {C:attention}Gold Seal Cards{}", + "Cards cannot change seals" + } + }, + +} +local deja_vu_deck = {object_type = "Back", + name = "cry-Deja Vu Deck", + key = "deja_vu_deck", + config = {cry_force_seal = 'Red'}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deja Vu Deck", + text = { + "Start with a deck", + "of {C:attention}Red Seal Cards{}", + "Cards cannot change seals" + } + }, + +} +local trance_deck = {object_type = "Back", + name = "cry-Trance Deck", + key = "trance_deck", + config = {cry_force_seal = 'Blue', hide_seal = true}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Trance Deck", + text = { + "Start with a deck", + "of {C:attention}Blue Seal Cards{}", + "Cards cannot change seals" + } + }, + atlas = "trance" +} +local trance_sprite = { + object_type = "Atlas", + key = "trance", + path = "b_cry_trance.png", + px = 71, + py = 95 +} +local medium_deck = {object_type = "Back", + name = "cry-Medium Deck", + key = "medium_deck", + config = {cry_force_seal = 'Purple', hide_seal = true}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Medium Deck", + text = { + "Start with a deck", + "of {C:attention}Purple Seal Cards{}", + "Cards cannot change seals" + } + }, + atlas = "medium" +} +local medium_sprite = { + object_type = "Atlas", + key = "medium", + path = "b_cry_medium.png", + px = 71, + py = 95 +} +local eternal_deck = {object_type = "Back", + name = "cry-Eternal Deck", + key = "eternal_deck", + config = {cry_force_sticker = 'eternal'}, + pos = {x = 0, y = 0}, + atlas = "eternal", + loc_txt = { + name = "Eternal Deck", + text = { + "Start with a deck", + "of {C:attention}Eternal Cards{}" + } + }, +} +local eternal_sprite = { + object_type = "Atlas", + key = "eternal", + path = "b_cry_eternal.png", + px = 71, + py = 95 +} +local perishable_deck = {object_type = "Back", + name = "cry-Perishable Deck", + key = "perishable_deck", + config = {cry_force_sticker = 'perishable'}, + pos = {x = 0, y = 0}, + atlas = "perishable", + loc_txt = { + name = "Perishable Deck", + text = { + "Start with a deck", + "of {C:attention}Perishable Cards{}" + } + }, +} +local perishable_sprite = { + object_type = "Atlas", + key = "perishable", + path = "b_cry_perishable.png", + px = 71, + py = 95 +} +local rental_deck = {object_type = "Back", + name = "cry-Rental Deck", + key = "rental_deck", + config = {cry_force_sticker = 'rental'}, + pos = {x = 0, y = 0}, + atlas = "rental", + loc_txt = { + name = "Rental Deck", + text = { + "Start with a deck", + "of {C:attention}Rental Cards{}" + } + }, +} +local rental_sprite = { + object_type = "Atlas", + key = "rental", + path = "b_cry_rental.png", + px = 71, + py = 95 +} +local world_deck = {object_type = "Back", + name = "cry-World Deck", + key = "world_deck", + config = {cry_force_suit = 'Spades', cry_boss_blocked = {'bl_goad'}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deck of The World", + text = { + "All cards in deck are {C:spade}Spades{}", + "and cannot change suits", + "{C:attention}The Goad{} cannot appear" + } + }, + atlas = "world_deck" +} +local star_deck = {object_type = "Back", + name = "cry-Star Deck", + key = "star_deck", + config = {cry_force_suit = 'Diamonds', cry_boss_blocked = {'bl_window'}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deck of The Stars", + text = { + "All cards in deck are {C:diamond}Diamonds{}", + "and cannot change suits", + "{C:attention}The Window{} cannot appear" + } + }, + atlas = "star_deck" +} +local sun_deck = {object_type = "Back", + name = "cry-Sun Deck", + key = "sun_deck", + config = {cry_force_suit = 'Hearts', cry_boss_blocked = {'bl_head'}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deck of The Sun", + text = { + "All cards in deck are {C:heart}Hearts{}", + "and cannot change suits", + "{C:attention}The Head{} cannot appear" + } + }, + atlas = "sun_deck" +} +local moon_deck = {object_type = "Back", + name = "cry-Moon Deck", + key = "moon_deck", + config = {cry_force_suit = 'Clubs', cry_boss_blocked = {'bl_club'}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Deck of The Moon", + text = { + "All cards in deck are {C:club}Clubs{}", + "and cannot change suits", + "{C:attention}The Club{} cannot appear" + } + }, + atlas = "moon_deck" +} +local world_sprite = { + object_type = "Atlas", + key = "world_deck", + path = "b_cry_world.png", + px = 71, + py = 95 +} +local star_sprite = { + object_type = "Atlas", + key = "star_deck", + path = "b_cry_star.png", + px = 71, + py = 95 +} +local sun_sprite = { + object_type = "Atlas", + key = "sun_deck", + path = "b_cry_sun.png", + px = 71, + py = 95 +} +local moon_sprite = { + object_type = "Atlas", + key = "moon_deck", + path = "b_cry_moon.png", + px = 71, + py = 95 +} + +return {name = "Enhanced Decks", + init = function() + local Backapply_to_runRef = Back.apply_to_run + function Back.apply_to_run(self) + Backapply_to_runRef(self) + + if self.effect.config.cry_force_enhancement then + if self.effect.config.cry_force_enhancement ~= 'random' then G.GAME.modifiers.cry_force_enhancement = self.effect.config.cry_force_enhancement end + G.E_MANAGER:add_event(Event({ + func = function() + for c = #G.playing_cards, 1, -1 do + if self.effect.config.cry_force_enhancement == 'random' then + local random_enhancement = pseudorandom_element(G.P_CENTER_POOLS.Enhanced, pseudoseed('cry_ant_enhancement')) + G.playing_cards[c]:set_ability(G.P_CENTERS[random_enhancement.key]); + else + G.playing_cards[c]:set_ability(G.P_CENTERS[self.effect.config.cry_force_enhancement]); + end + end + + return true + end + })) + end + if self.effect.config.cry_force_edition then + if self.effect.config.cry_force_edition ~= 'random' then G.GAME.modifiers.cry_force_edition = self.effect.config.cry_force_edition end + G.E_MANAGER:add_event(Event({ + func = function() + for c = #G.playing_cards, 1, -1 do + local ed_table = {} + if self.effect.config.cry_force_edition == 'random' then + local editions = {"foil", "holo", "polychrome"} --todo: modded edition support + local random_edition = pseudorandom_element(editions, pseudoseed('cry_ant_edition')) + ed_table[random_edition] = true + G.playing_cards[c]:set_edition(ed_table, true, true); + else + ed_table[self.effect.config.cry_force_edition] = true + G.playing_cards[c]:set_edition(ed_table, true, true); + end + end + + return true + end + })) + end + if self.effect.config.cry_force_seal then + if self.effect.config.cry_force_seal ~= 'random' then G.GAME.modifiers.cry_force_seal = self.effect.config.cry_force_seal end + G.E_MANAGER:add_event(Event({ + func = function() + for c = #G.playing_cards, 1, -1 do + if self.effect.config.cry_force_seal == 'random' then + local random_seal = pseudorandom_element(G.P_CENTER_POOLS.Seal, pseudoseed('cry_ant_seal')) + G.playing_cards[c]:set_seal(random_seal.key, true); + else + G.playing_cards[c]:set_seal(self.effect.config.cry_force_seal, true); + end + end + return true + end + })) + end + if self.effect.config.cry_force_sticker then + G.E_MANAGER:add_event(Event({ + func = function() + for c = #G.playing_cards, 1, -1 do + G.playing_cards[c].config.center.eternal_compat = true + G.playing_cards[c].config.center.perishable_compat = true + G.playing_cards[c]["set_"..self.effect.config.cry_force_sticker](G.playing_cards[c],true); + end + return true + end + })) + end + if self.effect.config.cry_force_suit then + G.GAME.modifiers.cry_force_suit = self.effect.config.cry_force_suit + G.E_MANAGER:add_event(Event({ + func = function() + for c = #G.playing_cards, 1, -1 do + G.playing_cards[c]:change_suit(self.effect.config.cry_force_suit) + end + return true + end + })) + end + if self.effect.config.cry_boss_blocked then + for _, v in pairs(self.effect.config.cry_boss_blocked) do + G.GAME.bosses_used[v] = 1e308 + end + end + end + local sa = Card.set_ability + function Card:set_ability(center, y, z) + if center.set == "Enhanced" then + return sa(self, G.GAME.modifiers.cry_force_enhancement and G.P_CENTERS[G.GAME.modifiers.cry_force_enhancement] or center, y, z) + else + return sa(self, center, y, z) + end + end + local se = Card.set_edition + function Card:set_edition(edition, y, z) + return se(self, G.GAME.modifiers.cry_force_edition and {[G.GAME.modifiers.cry_force_edition]=true} or edition, y, z) + end + local ss = Card.set_seal + function Card:set_seal(seal, y, z) + return ss(self, G.GAME.modifiers.cry_force_seal or seal, y, z) + end + local cs = Card.change_suit + function Card:change_suit(new_suit) + return cs(self, G.GAME.modifiers.cry_force_suit or new_suit) + end + end, + items = {trance_sprite, medium_sprite, world_sprite, star_sprite, sun_sprite, moon_sprite, perishable_sprite, eternal_sprite, rental_sprite, lovers_sprite, hierophant_sprite, empress_sprite, justice_sprite, +hierophant_deck, empress_deck, lovers_deck, justice_deck, chariot_deck, tower_deck, devil_deck, magician_deck, +foil_deck, holo_deck, poly_deck, +talisman_deck, deja_vu_deck, trance_deck, medium_deck, +eternal_deck, perishable_deck, rental_deck, +star_deck, moon_deck, sun_deck, world_deck}} \ No newline at end of file diff --git a/Items/Items/MiscJokers.lua b/Items/Items/MiscJokers.lua new file mode 100644 index 000000000..8fe43cc12 --- /dev/null +++ b/Items/Items/MiscJokers.lua @@ -0,0 +1,1973 @@ +local dropshot = { + object_type = "Joker", + name = "cry-Dropshot", + key = "dropshot", + config = {extra = {Xmult_mod = 0.2, x_mult = 1}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Dropshot', + text = { + "This Joker gains {X:mult,C:white} X#1# {} Mult", + "per played, {C:attention}nonscoring{} {V:1}#2#{} card,", + "suit changes every round", + "{C:inactive}(Currently {X:mult,C:white} X#3# {C:inactive} Mult)" + } + }, + rarity = 3, + cost = 8, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = "dropshot", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.Xmult_mod, localize(G.GAME.current_round.cry_dropshot_card and G.GAME.current_round.cry_dropshot_card.suit or "Spades", 'suits_singular'), center.ability.extra.x_mult, colours = {G.C.SUITS[G.GAME.current_round.cry_dropshot_card and G.GAME.current_round.cry_dropshot_card.suit or "Spades"]}}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and context.before and not context.blueprint then + cards = 0 + for k, v in ipairs(context.scoring_hand) do + v.cry_dropshot_incompat = true + end + for k, v in ipairs(context.full_hand) do + if not v.cry_dropshot_incompat and v:is_suit(G.GAME.current_round.cry_dropshot_card.suit)then + cards = cards + 1 + G.E_MANAGER:add_event(Event({ + func = function() + v:juice_up() + return true + end + })) + end + end + for k, v in ipairs(context.scoring_hand) do + v.cry_dropshot_incompat = nil + end + if cards > 0 then + card.ability.extra.x_mult = card.ability.extra.x_mult + cards * card.ability.extra.Xmult_mod + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) + return {calculated = true} + end + end + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + end +} +local dropshot_sprite = { + object_type = "Atlas", + key = "dropshot", + + path = "j_cry_dropshot.png", + px = 71, + py = 95 +} +local maximized = { + object_type = "Joker", + name = "cry-Maximized", + key = "maximized", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Maximized', + text = { + "All {C:attention}face{} cards", + "are considered {C:attention}Kings{},", + "all {C:attention}numbered{} cards", + "are considered {C:attention}10s{}" + } + }, + rarity = 3, + cost = 10, + discovered = true, + atlas = "maximized" +} +local maximized_sprite = { + object_type = "Atlas", + key = "maximized", + + path = "j_cry_maximized.png", + px = 71, + py = 95 +} +local potofjokes = { + object_type = "Joker", + name = "cry-Pot of Jokes", + key = "pot_of_jokes", + config = {extra = {h_size = -2, h_mod = 1}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Pot of Jokes', + text = { + "{C:attention}#1#{} hand size,", + "increases by", + "{C:blue}#2#{} every round"} + }, + rarity = 3, + cost = 10, + discovered = true, + perishable_compat = false, + atlas = 'pot_of_jokes', + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.h_size<0 and center.ability.extra.h_size or "+"..center.ability.extra.h_size,center.ability.extra.h_mod}} + end, + calculate = function(self, card, context) + if context.end_of_round and not context.individual and not context.repetition and not context.blueprint then + card.ability.extra.h_size = card.ability.extra.h_size + card.ability.extra.h_mod + G.hand:change_size(card.ability.extra.h_mod) + return { + message = localize{type='variable',key='a_handsize',vars={card.ability.extra.h_mod}}, + colour = G.C.FILTER, + card = card + } + end + end, + add_to_deck = function(self, card, from_debuff) + G.hand:change_size(card.ability.extra.h_size) + end, + remove_from_deck = function(self, card, from_debuff) + G.hand:change_size(-card.ability.extra.h_size) + end +} +local potofjokes_sprite = { + object_type = "Atlas", + key = "pot_of_jokes", + + path = "j_cry_pot_of_jokes.png", + px = 71, + py = 95 +} +local queensgambit = { + object_type = "Joker", + name = "cry-Queen's Gambit", + key = "queens_gambit", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Queen\'s Gambit', + text = { "If {C:attention}poker hand{} is a", + "{C:attention}Royal Flush{}, destroy scored", + "{C:attention}Queen{} and create a", + "{C:dark_edition}Negative {}{C:red}Rare{}{C:attention} Joker{}"} + }, + rarity = 3, + cost = 10, + discovered = true, + atlas = "queens_gambit", + config = {extra = {type = "Straight Flush"}}, + calculate = function(self, card, context) + if context.destroying_card and not context.blueprint then + if G.GAME.current_round.current_hand.handname == "Royal Flush" and SMODS.Ranks[context.destroying_card.base.value].key == "Queen" then + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_plus_joker'), colour = G.C.FILTER}) + G.E_MANAGER:add_event(Event({ + trigger = 'after', + func = function() + local card = create_card("Joker", G.jokers, nil, 0.99, nil, nil, nil, "cry_gambit") + card:set_edition({ + negative = true + }) + card:add_to_deck() + G.jokers:emplace(card) + card:start_materialize() + return true + end + })) + return true + end + end + end +} +local queensgambit_sprite = { + object_type = "Atlas", + key = "queens_gambit", + + path = "j_cry_queens_gambit.png", + px = 71, + py = 95 +} +local wee_fib = { + object_type = "Joker", + name = "cry-Wee Fibonacci", + key = "wee_fib", + config = {extra = {mult = 0, mult_mod = 3}}, + pos = {x = 1, y = 5}, + loc_txt = { + name = 'Wee Fibonacci', + text = { + "This Joker gains", + "{C:mult}+#2#{} Mult for each scored", + "{C:attention}Ace{}, {C:attention}2{}, {C:attention}3{}, {C:attention}5{}, or {C:attention}8{}", + "{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)"} + }, + rarity = 3, + cost = 12, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.mult,center.ability.extra.mult_mod}} + end, + calculate = function(self, card, context) + if context.cardarea == G.play and context.individual and not context.blueprint then + local rank = SMODS.Ranks[context.other_card.base.value].key + if rank == "Ace" or rank == "2" or rank == "3" or rank == "5" or rank == "8" then + card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_mod + + return { + extra = {focus = self, message = localize('k_upgrade_ex')}, + card = card, + colour = G.C.MULT + } + end + end + if context.cardarea == G.jokers and (card.ability.extra.mult > 0) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_mult',vars={card.ability.extra.mult}}, + mult_mod = card.ability.extra.mult, + colour = G.C.MULT + } + end + end, +} +local whip = { + object_type = "Joker", + name = "cry-The WHIP", + key = "whip", + pos = {x = 0, y = 0}, + config = {extra = {Xmult_mod = 0.5, x_mult = 1}}, + loc_txt = { + name = 'The WHIP', + text = { "This Joker gains {X:mult,C:white} X#1# {} Mult", + "if {C:attention}played hand{} contains a", + "{C:attention}2{} and {C:attention}7{} of different suits", + "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)"} + }, + rarity = 2, + cost = 6, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = "whip", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.Xmult_mod, center.ability.extra.x_mult}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and context.before and not context.blueprint then + for i = 1, #context.full_hand do + if SMODS.Ranks[context.full_hand[i].base.value].key == "2" then + for j = 1, #context.full_hand do + if SMODS.Ranks[context.full_hand[j].base.value].key == "7" then + --Different suits + for k, v in pairs(SMODS.Suits) do + if context.full_hand[i]:is_suit(k, nil, true) and context.full_hand[j]:is_suit(k, nil, true) then return end + end + card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.Xmult_mod + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) + return {calculated = true} + end + end + end + end + end + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + end +} +local whip_sprite = { + object_type = "Atlas", + key = "whip", + path = "j_cry_whip.png", + px = 71, + py = 95 +} +local lucky_joker = { + object_type = "Joker", + name = "cry-Lucky Joker", + key = "lucky_joker", + config = {extra = { dollars = 5}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Lucky Joker', + text = { + "Earn {C:money}$#1#{} every time a", + "{C:attention}Lucky{} card {C:green}successfully{}", + "triggers" + } + }, + rarity = 1, + cost = 5, + discovered = true, + blueprint_compat = true, + atlas = "lucky_joker", + enhancement_gate = 'm_lucky', + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.dollars}} + end, + calculate = function(self, card, context) + if context.individual and context.other_card.lucky_trigger then + G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.dollars + G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)})) + return { + dollars = card.ability.extra.dollars, + card = card + } + end + end +} +local lucky_joker_sprite = { + object_type = "Atlas", + key = "lucky_joker", + + path = "j_cry_lucky_joker.png", + px = 71, + py = 95 +} + +local cursor = { + object_type = "Joker", + name = "cry-Cursor", + key = "cursor", + config = {extra = {chips = 0, chip_mod = 5}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Cursor', + text = { + "This Joker gains {C:chips}+#2#{} Chips", + "for each card {C:attention}purchased{}", + "{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips)" + } + }, + rarity = 1, + cost = 5, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = "cursor", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.chips, center.ability.extra.chip_mod}} + end, + calculate = function(self, card, context) + if context.buying_card and not context.blueprint then + card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}, colour = G.C.CHIPS}) + return {calculated = true} + end + if context.cardarea == G.jokers and (card.ability.extra.chips > 0) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips}}, + chip_mod = card.ability.extra.chips + } + end + end +} +local cursor_sprite = { + object_type = "Atlas", + key = "cursor", + path = "j_cry_cursor.png", + px = 71, + py = 95 +} +local pickle = { + object_type = "Joker", + name = "cry-Pickle", + key = "pickle", + config = {extra = {tags = 3, tags_mod = 1}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Pickle', + text = { + "When {C:attention}Blind{} is skipped, create", + "{C:attention}#1#{} Tags, reduced by", + "{C:red}#2#{} when {C:attention}Blind{} is selected" + } + }, + rarity = 2, + cost = 5, + discovered = true, + blueprint_compat = true, + eternal_compat = false, + atlas = "pickle", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.tags, center.ability.extra.tags_mod}} + end, + calculate = function(self, card, context) + if context.skip_blind then + for i = 1, card.ability.extra.tags do + local tag = Tag(get_next_tag_key("cry_pickle")) + if tag.name == 'Orbital Tag' then + local _poker_hands = {} + for k, v in pairs(G.GAME.hands) do + if v.visible then _poker_hands[#_poker_hands+1] = k end + end + tag.ability.orbital_hand = pseudorandom_element(_poker_hands, pseudoseed('cry_pickle_orbital')) + end + if tag.name == 'Boss Tag' then + i = i - 1 --skip these, as they can cause bugs with pack opening from other tags + else + add_tag(tag) + end + end + card_eval_status_text(card, 'extra', nil, nil, nil, {message = "+"..card.ability.extra.tags.." Tag"..(card.ability.extra.tags>1 and "s" or ""), colour = G.C.FILTER}) + return {calculated = true} + end + if context.setting_blind and not context.blueprint then + card.ability.extra.tags = card.ability.extra.tags - card.ability.extra.tags_mod + if card.ability.extra.tags > 0 then + card_eval_status_text(card, 'extra', nil, nil, nil, {message = "-"..card.ability.extra.tags_mod.." Tag"..(card.ability.extra.tags_mod>1 and "s" or ""), colour = G.C.FILTER}) + return {calculated = true} + 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 + end +} +local pickle_sprite = { + object_type = "Atlas", + key = "pickle", + path = "j_cry_pickle.png", + px = 71, + py = 95 +} + +local cube = { + object_type = "Joker", + name = "cry-Cube", + key = "cube", + config = {extra = {chips = 6}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Cube', + text = { + "{C:chips}+#1#{} Chips" + } + }, + rarity = 1, + cost = -25, + discovered = true, + blueprint_compat = true, + atlas = "cube", + source_gate = "sho", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.chips}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and not context.before and not context.after then + return { + message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips}}, + chip_mod = card.ability.extra.chips + } + end + end +} +local cube_sprite = { + object_type = "Atlas", + key = "cube", + path = "j_cry_cube.png", + px = 71, + py = 95 +} + +local triplet_rhythm = { + object_type = "Joker", + name = "cry-Triplet Rhythm", + key = "triplet_rhythm", + config = {extra = {Xmult = 3}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Triplet Rhythm', + text = { + "{X:mult,C:white} X#1# {} Mult if scoring hand", + "contains {C:attention}exactly{} three {C:attention}3s" + } + }, + rarity = 2, + cost = 7, + discovered = true, + blueprint_compat = true, + atlas = "triplet_rhythm", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.Xmult}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and not context.before and not context.after and context.scoring_hand then + local threes = 0 + for i = 1, #context.scoring_hand do + if SMODS.Ranks[context.scoring_hand[i].base.value].key == "3" then + threes = threes + 1 + end + end + if threes == 3 then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, + Xmult_mod = card.ability.extra.Xmult + } + end + end + end +} +local triplet_rhythm_sprite = { + object_type = "Atlas", + key = "triplet_rhythm", + path = "j_cry_triplet_rhythm.png", + px = 71, + py = 95 +} +local booster = { + object_type = "Joker", + name = "cry-Booster Joker", + key = "booster", + config = {extra = {booster_slots = 1}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Booster Joker', + text = { + "{C:attention}+#1#{} Booster Pack slot", + } + }, + rarity = 2, + cost = 7, + discovered = true, + blueprint_compat = false, + atlas = "booster_joker", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.booster_slots}} + end, + add_to_deck = function(self, card, from_debuff) + if not G.GAME.modifiers.cry_booster_packs then G.GAME.modifiers.cry_booster_packs = 2 end + G.GAME.modifiers.cry_booster_packs = G.GAME.modifiers.cry_booster_packs + card.ability.extra.booster_slots + end, + remove_from_deck = function(self, card, from_debuff) + if not G.GAME.modifiers.cry_booster_packs then G.GAME.modifiers.cry_booster_packs = 2 end + G.GAME.modifiers.cry_booster_packs = G.GAME.modifiers.cry_booster_packs - card.ability.extra.booster_slots + end +} +local booster_sprite = { + object_type = "Atlas", + key = "booster_joker", + path = "j_cry_booster.png", + px = 71, + py = 95 +} +local chili_pepper = { + object_type = "Joker", + name = "cry-Chili Pepper", + key = "chili_pepper", + config = {extra = {Xmult = 1, Xmult_mod = 0.5, rounds_remaining = 8}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Chili Pepper', + text = { + "This joker gains {X:mult,C:white} X#2# {} Mult at end of round,", + "{C:red}self destructs{} after {C:attention}#3#{} rounds", + "{C:inactive}currently{} {X:mult,C:white} X#1# {} {C:inactive}Mult{}" + } + }, + rarity = 2, + cost = 6, + discovered = true, + blueprint_compat = false, + eternal_compat = false, + perishable_compat = false, + atlas = "chili_pepper", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.Xmult, center.ability.extra.Xmult_mod, center.ability.extra.rounds_remaining}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and not context.before and not context.after and card.ability.extra.Xmult > 1 then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, + Xmult_mod = card.ability.extra.Xmult + } + 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.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_mod + card.ability.extra.rounds_remaining = card.ability.extra.rounds_remaining - 1 + if card.ability.extra.rounds_remaining > 0 then + return { + message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.Xmult}}, + 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 + end +} +local chili_pepper_sprite = { + object_type = "Atlas", + key = "chili_pepper", + path = "j_cry_chili_pepper.png", + px = 71, + py = 95 +} +local compound_interest = { + object_type = "Joker", + name = "cry-Compound Interest", + key = "compound_interest", + config = {extra = {percent_mod = 2, percent = 10}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Compound Interest', + text = { + "Earn {C:money}#1#%{} of total money", + "at end of round,", + "increases by {C:money}#2#%{} per", + "consecutive payout" + } + }, + rarity = 3, + cost = 8, + discovered = true, + perishable_compat = false, + atlas = "compound_interest", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.percent, center.ability.extra.percent_mod}} + end, + calc_dollar_bonus = function(self, card) + local bonus = math.max(0,math.floor(0.01*card.ability.extra.percent*G.GAME.dollars)) + card.ability.extra.percent = card.ability.extra.percent + card.ability.extra.percent_mod + if bonus > 0 then return bonus end + end +} +local compound_interest_sprite = { + object_type = "Atlas", + key = "compound_interest", + path = "j_cry_compound_interest.png", + px = 71, + py = 95 +} + +local big_cube = { + object_type = "Joker", + name = "cry-Big Cube", + key = "big_cube", + joker_gate = "cry-Cube", + config = {extra = {Xchips = 6}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Big Cube', + text = { + "{X:chips,C:white} X#1# {} Chips" + } + }, + rarity = 1, + cost = 25, + discovered = true, + atlas = "big_cube", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.Xchips}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and not context.before and not context.after then + return { + message = "X"..card.ability.extra.Xchips, + Xchip_mod = card.ability.extra.Xchips, + colour = G.C.CHIPS + } + end + end +} +local big_cube_sprite = { + object_type = "Atlas", + key = "big_cube", + path = "j_cry_big_cube.png", + px = 71, + py = 95 +} + +local eternalflame = { + object_type = "Joker", + name = "cry-eternalflame", + key = "eternalflame", + pos = {x = 0, y = 0}, + config = {extra = {extra = 0.1, x_mult = 1}}, + loc_txt = { + name = 'Eternal Flame', + text = { + "This Joker gains {X:mult,C:white} X#1# {} Mult", + "for each card {C:attention}sold{}", + "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" + } + }, + rarity = 3, + cost = 9, + discovered = true, + perishable_compat = false, + blueprint_compat = true,loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.extra, center.ability.extra.x_mult}} + end, + atlas = "eternalflame", + calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + if context.selling_card and not context.blueprint then + card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) + return {calculated = true} + end + end +} +local eternalflame_sprite = { + object_type = "Atlas", + key = "eternalflame", + + path = "j_cry_eternalflame.png", + px = 71, + py = 95 +} + +local nice = { + object_type = "Joker", + name = "cry-Nice", + key = "nice", + config = {extra = {chips = 420, sixcount = 0, ninecount = 0}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Nice', + text = { + "{C:chips}+#1#{} Chips if played hand", + "contains a {C:attention}6{} and a {C:attention}9" + } + }, + rarity = 3, + cost = 6.9, + discovered = true, + atlas = "nice", + blueprint_compat = true,loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.chips}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and context.before and not context.after then + card.ability.extra.sixcount = 0 + card.ability.extra.ninecount = 0 + for i, v in pairs (context.full_hand) do + if v:get_id() == 6 then + card.ability.extra.sixcount = card.ability.extra.sixcount + 1 + elseif v:get_id() == 9 then + card.ability.extra.ninecount = card.ability.extra.ninecount + 1 + end + end + elseif context.cardarea == G.jokers and not context.before and not context.after then + if card.ability.extra.sixcount > 0 and card.ability.extra.ninecount > 0 then + return { + message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips or 0}}, + chip_mod = card.ability.extra.chips or 0 + } + end + end + end +} +local seal_the_deal = { + object_type = "Joker", + name = "cry-Seal The Deal", + key = "seal_the_deal", + config = {extra = {Xchips = 6}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Seal the Deal', + text = { + "Add a {C:attention}random seal{} to all", + "cards scored on {C:attention}last hand{} played" + } + }, + rarity = 2, + cost = 6, + discovered = true, + atlas = "seal_the_deal", + calculate = function(self, card, context) + if context.individual and context.cardarea == G.play then + if G.GAME.current_round.hands_left == 0 then + G.E_MANAGER:add_event(Event({ + func = function() + local seal_type = pseudorandom(pseudoseed("seal_the_deal")) + if seal_type > 0.75 then context.other_card:set_seal("Red", true) + elseif seal_type > 0.5 then context.other_card:set_seal("Blue", true) + elseif seal_type > 0.25 then context.other_card:set_seal("Gold", true) + else context.other_card:set_seal("Purple", true) + end + card:juice_up(0.3,0.4) + context.other_card:juice_up(0.3,0.3) + play_sound('gold_seal', 1.2, 0.4) + return true + end + })) + delay(0.5) + return true + end + end + end +} +local nice_sprite = { + object_type = "Atlas", + key = "nice", + path = "j_cry_nice.png", + px = 71, + py = 95 +} + +local seal_the_deal_sprite = { + object_type = "Atlas", + key = "seal_the_deal", + path = "j_cry_seal_the_deal.png", + px = 71, + py = 95 +} + +local chad = { + object_type = "Joker", + name = "cry-Chad", + key = "chad", + pos = {x = 0, y = 0}, + config = {extra = {retriggers = 2}}, + loc_txt = { + name = 'Chad', + text = { + "Retrigger {C:attention}leftmost{} Joker", + "{C:attention}#1#{} additional time(s)" + } + }, + rarity = 3, + cost = 10, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.retriggers}} + end, + atlas = "chad", + calculate = function(self, card, context) + if context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= self then + if context.other_card == G.jokers.cards[1] then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.retriggers, + card = card + } + else return {calculated = true} end + end + end +} +local chad_sprite = { + object_type = "Atlas", + key = "chad", + path = "j_cry_chad.png", + px = 71, + py = 95 +} +local jimball = { + object_type = "Joker", + name = "cry-Jimball", + key = "jimball", + pos = {x = 0, y = 0}, + config = {x_mult = 1, extra = 0.15}, + loc_txt = { + name = 'Jimball', + text = { + "This Joker gains {X:mult,C:white} X#1# {} Mult", + "per {C:attention}consecutive{} hand played", + "while playing your", + "most played {C:attention}poker hand", + "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" + } + }, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra, center.ability.x_mult}} + end, + rarity = 3, + cost = 10, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + calculate = function(self, card, context) + if context.before and not context.blueprint then + local reset = false + local play_more_than = (G.GAME.hands[context.scoring_name].played or 0) + for k, v in pairs(G.GAME.hands) do + if k ~= context.scoring_name and v.played >= play_more_than and v.visible then + reset = true + end + end + if reset then + if card.ability.x_mult > 1 then + card.ability.x_mult = 1 + return { + card = self, + message = localize('k_reset') + } + end + else + card.ability.x_mult = card.ability.x_mult + card.ability.extra + end + end + end, + atlas = "jimball", +} +local jimball_sprite = { + object_type = "Atlas", + key = "jimball", + path = "j_cry_jimball.png", + px = 71, + py = 95 +} + +local sus = { + object_type = "Joker", + name = "cry-SUS", + key = "sus", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'SUS', + text = { + "At end of round, create", + "a {C:attention}copy{} of a random", + "card {C:attention}held in hand{},", + "destroy all others" + } + }, + rarity = 3, + cost = 9, + discovered = true, + blueprint_compat = true, + atlas = "sus", + calculate = function(self, card, context) + if context.end_of_round and not context.cardarea then + if not card.ability.used_round or card.ability.used_round ~= G.GAME.round then + card.ability.chosen_card = nil + end + local choosable_cards = {} + for i = 1, #G.hand.cards do + if not G.hand.cards[i].murdered_by_impostor then + choosable_cards[#choosable_cards+1] = G.hand.cards[i] + end + end + card.ability.chosen_card = card.ability.chosen_card or pseudorandom_element(choosable_cards, pseudoseed('cry_sus')) + if not card.ability.used_round or card.ability.used_round ~= G.GAME.round then + card.ability.used_round = G.GAME.round + local deletable_cards = {} + for k, v in pairs(G.hand.cards) do + if not v.ability.eternal then deletable_cards[#deletable_cards + 1] = v end + end + local _first_dissolve = nil + G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.75, func = function() + for k, v in pairs(deletable_cards) do + if v ~= card.ability.chosen_card then + v.murdered_by_impostor = true + v:start_dissolve(nil, _first_dissolve) + _first_dissolve = true + end + end + return true end })) + end + G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.4, func = function() + card:juice_up(0.3, 0.4) + G.playing_card = (G.playing_card and G.playing_card + 1) or 1 + local _c = copy_card(card.ability.chosen_card, nil, nil, G.playing_card) + _c:start_materialize() + _c:add_to_deck() + G.deck.config.card_limit = G.deck.config.card_limit + 1 + table.insert(G.playing_cards, _c) + G.hand:emplace(_c) + playing_card_joker_effects({_c}) + return true end })) + return {message = "Impostor!"} + end + end +} +local sus_sprite = { + object_type = "Atlas", + key = "sus", + path = "j_cry_sus.png", + px = 71, + py = 95 +} +local fspinner = { + object_type = "Joker", + name = "cry-fspinner", + key = "fspinner", + pos = {x = 0, y = 0}, + config = {extra = {chips = 0, chip_mod = 14}}, + loc_txt = { + name = 'Fidget Spinner', + text = { + "This Joker gains {C:chips}+#2#{} Chips", + "if hand played is {C:attention}not{}", + "most played {C:attention}poker hand{}", + "{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips)" + } + }, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.chips, center.ability.extra.chip_mod}} + end, + rarity = 2, + cost = 6, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = 'fspinner', + calculate = function(self, card, context) + if context.before and not context.blueprint then + local play_more_than = (G.GAME.hands[context.scoring_name].played or 0) + for k, v in pairs(G.GAME.hands) do + if k ~= context.scoring_name and v.played >= play_more_than and v.visible then + card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod + return { + message = localize('k_upgrade_ex'), + card = card, + } + end + end + + end + if context.cardarea == G.jokers and (card.ability.extra.chips > 0) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips}}, + chip_mod = card.ability.extra.chips + } + end + end, + atlas = "fspinner", +} +local fspinner_sprite = { + object_type = "Atlas", + key = "fspinner", + path = "j_cry_fspinner.png", + px = 71, + py = 95 +} +local waluigi = { + object_type = "Joker", + name = "cry-Waluigi", + key = "waluigi", + pos = {x = 0, y = 0}, + soul_pos = {x = 1, y = 0}, + config = {extra = {Xmult = 2.5}}, + loc_txt = { + name = 'Waluigi', + text = { + "All Jokers give", + "{X:mult,C:white} X#1# {} Mult" + } + }, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.Xmult}} + end, + rarity = 4, + cost = 20, + discovered = true, + blueprint_compat = true, + calculate = function(self, card, context) + if context.other_joker and context.other_joker.ability.set == "Joker" 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 + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, + Xmult_mod = card.ability.extra.Xmult + } + end + end, + atlas = "waluigi", +} +local waluigi_sprite = { + object_type = "Atlas", + key = "waluigi", + path = "j_cry_waluigi.png", + px = 71, + py = 95 +} +local krustytheclown = { + object_type = "Joker", + name = "cry-krustytheclown", + key = "krustytheclown", + pos = {x = 0, y = 0}, + config = {extra = {extra = 0.02, x_mult = 1}}, + loc_txt = { + name = 'Krusty the Clown', + text = { + "This Joker gains {X:mult,C:white} X#1# {} Mult", + "per {C:attention}card{} scored", + "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" + } + }, + rarity = 2, + cost = 7, + discovered = true, + perishable_compat = false, + blueprint_compat = true,loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.extra, center.ability.extra.x_mult}} + end, + atlas = "krustytheclown", + calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + if context.cardarea == G.play and context.individual and not context.blueprint then + card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra + return { + extra = {focus = card, message = localize('k_upgrade_ex')}, + card = card, + colour = G.C.MULT + } + end + end +} +local krustytheclown_sprite = { + object_type = "Atlas", + key = "krustytheclown", + + path = "j_cry_krustytheclown.png", + px = 71, + py = 95 +} +local blurred = { + object_type = "Joker", + name = "cry-blurred", + key = "blurred", + pos = {x = 0, y = 0}, + config = {extra = {hands = 1}}, + loc_txt = { + name = 'Blurred Joker', + text = { + "{C:blue}+#1#{} hand(s) when", + "{C:attention}Blind{} is selected" + } + }, + rarity = 1, + cost = 4, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.hands}} + end, + atlas = "blurred", + calculate = function(self, card, context) + if context.setting_blind and not (context.blueprint_card or card).getting_sliced then + return { + message = localize('k_hand'), --make this actually work in the future + ease_hands_played(card.ability.extra.hands), + delay(0.6), + } + end + end +} +local blurred_sprite = { + object_type = "Atlas", + key = "blurred", + path = "j_cry_blurred.png", + px = 71, + py = 95 +} +local gardenfork = { + object_type = "Joker", + name = "cry-gardenfork", + key = "gardenfork", + pos = {x = 0, y = 0}, + config = {extra = {money = 7}}, + loc_txt = { + name = 'Garden of Forking Paths', + text = { "Earn {C:money}$#1#{} if {C:attention}played hand{}", + "contains an {C:attention}Ace{} and a {C:attention}7{}", + } + }, + rarity = 3, + cost = 7, + discovered = true, + blueprint_compat = true, + atlas = "gardenfork", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.money}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and context.before and not context.blueprint then + for i = 1, #context.full_hand do + if SMODS.Ranks[context.full_hand[i].base.value].key == "Ace" then + for j = 1, #context.full_hand do + if SMODS.Ranks[context.full_hand[j].base.value].key == "7" then + ease_dollars(card.ability.extra.money) + return {message = "$" .. card.ability.extra.money, colour = G.C.MONEY} + end + end + end + end + end + end +} +local gardenfork_sprite = { + object_type = "Atlas", + key = "gardenfork", + path = "j_cry_gardenfork.png", + px = 71, + py = 95 +} +local lightupthenight = { + object_type = "Joker", + name = "cry-lightupthenight", + key = "lightupthenight", + config = {extra = {xmult = 1.75}}, + pos = {x = 0, y = 0}, + atlas = 'lightupthenight', + loc_txt = { + name = 'Light Up the Night', + text = { + "Each played {C:attention}7{} or {C:attention}2{}", + "gives {X:mult,C:white}X#1#{} Mult when scored", + } + }, + rarity = 3, + cost = 7, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.xmult}} + end, + calculate = function(self, card, context) + if context.cardarea == G.play and context.individual then + local rank = SMODS.Ranks[context.other_card.base.value].key + if rank == "2" or rank == "7" then + return { + x_mult = card.ability.extra.xmult, + colour = G.C.RED, + card = card + } + end + end + end +} +local lightupthenight_sprite = { + object_type = "Atlas", + key = "lightupthenight", + path = "j_cry_lightupthenight.png", + px = 71, + py = 95 +} +local nosound = { + object_type = "Joker", + name = "cry-nosound", + key = "nosound", + config = {extra = {retriggers = 3}}, + pos = {x = 0, y = 0}, + atlas = 'nosound', + loc_txt = { + name = 'No Sound, No Memory', + text = { + "Retrigger each played {C:attention}7{}", + "{C:attention:}#1#{} additional time(s)", + } + }, + rarity = 3, + cost = 7, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = { center.ability.extra.retriggers}} + end, + calculate = function(self, card, context) + if context.repetition then + if context.cardarea == G.play then + local rank = SMODS.Ranks[context.other_card.base.value].key + if rank == "7" then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.retriggers, + card = card + } + end + end + end + end +} +local nosound_sprite = { + object_type = "Atlas", + key = "nosound", + path = "j_cry_nosound.png", + px = 71, + py = 95 +} +local antennastoheaven = { + object_type = "Joker", + name = "cry-antennastoheaven", + key = "antennastoheaven", + pos = {x = 0, y = 0}, + config = {extra = {bonus = 0.1, Xchips = 1}}, + loc_txt = { + name = '...Like Antennas to Heaven', + text = { + "This Joker gains {X:chips,C:white} X#1# {} Chips", + "per {C:attention}7{} or {C:attention}4{} scored", + "{C:inactive}(Currently {X:chips,C:white} X#2# {C:inactive} Chips)" + } + }, + rarity = 3, + cost = 7, + discovered = true, + perishable_compat = false, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.bonus, center.ability.extra.Xchips}} + end, + atlas = "antennastoheaven", + calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.Xchips > 1) and not context.before and not context.after then + return { + message = "X"..card.ability.extra.Xchips, + Xchip_mod = card.ability.extra.Xchips, + colour = G.C.CHIPS + } + end + if context.cardarea == G.play and context.individual and not context.blueprint then + local rank = SMODS.Ranks[context.other_card.base.value].key + if rank == "4" or rank == "7" then + card.ability.extra.Xchips = card.ability.extra.Xchips + card.ability.extra.bonus + return { + extra = {focus = card, message = localize('k_upgrade_ex')}, + card = card, + colour = G.C.CHIPS + } + end + end + end +} +local antennastoheaven_sprite = { + object_type = "Atlas", + key = "antennastoheaven", + path = "j_cry_antennastoheaven.png", + px = 71, + py = 95 +} +local hunger = { + object_type = "Joker", + name = "cry-hunger", + key = "hunger", + config = {extra = {money = 3}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Consume-able', + text = { + "Earn {C:money}$#1#{} when", + "using a {C:attention}consumable{}", + } + }, + rarity = 2, + cost = 6, + discovered = true, + blueprint_compat = true, + atlas = "hunger", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.money}} + end, + calculate = function(self, card, context) --This didn't work for Jevonn for some reason but it works for me :joker: + if context.using_consumeable then + ease_dollars(card.ability.extra.money) + return {calculated = true} + end + end +} +local hunger_sprite = { + object_type = "Atlas", + key = "hunger", + path = "j_cry_hunger.png", + px = 71, + py = 95 +} +local weegaming = { + object_type = "Joker", + name = "cry-weegaming", + key = "weegaming", + config = {extra = {retriggers = 2}}, + pos = {x = 0, y = 0}, + atlas = 'weegaming', + loc_txt = { + name = '2D', + text = { + "Retrigger each played {C:attention}2{}", --wee gaming + "{C:attention:}#1#{} additional time(s) when scored", --wee gaming? + } + }, + rarity = 1, + cost = 5, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = { center.ability.extra.retriggers}} + end, + calculate = function(self, card, context) + if context.repetition then + if context.cardarea == G.play then + local rank = SMODS.Ranks[context.other_card.base.value].key + if rank == "2" then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.retriggers, + card = card + } + end + end + end + end +} +local weegaming_sprite = { + object_type = "Atlas", + key = "weegaming", + path = "j_placeholder.png", + px = 71, + py = 95 +} +local redbloon = { + object_type = "Joker", + name = "cry-redbloon", + key = "redbloon", + config = {extra = {money = 20, rounds_remaining = 2, text = "s"}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Red Bloon', + text = { + "Earn {C:money}$#1#{} in {C:attention}#2#{} round#3#", + "{C:red}self destructs{}" + } + }, + rarity = 1, + cost = 2, + discovered = true, + blueprint_compat = false, + eternal_compat = false, + perishable_compat = false, + atlas = "redbloon", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.money, center.ability.extra.rounds_remaining, center.ability.extra.text}} + end, + calculate = function(self, card, context) + 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 = card.ability.extra.rounds_remaining - 1 + if card.ability.extra.rounds_remaining > 0 then + return { + message = {"-1 Round"}, + colour = G.C.FILTER + } + else + ease_dollars(card.ability.extra.money) + 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 = "$" .. card.ability.extra.money, colour = G.C.MONEY + } + end + end + if card.ability.extra.rounds_remaining == 1 then + card.ability.extra.text = "" + end + end +} +local redbloon_sprite = { + object_type = "Atlas", + key = "redbloon", + path = "j_cry_redbloon.png", + px = 71, + py = 95 +} +local apjoker = { + object_type = "Joker", + name = "cry-apjoker", + key = "apjoker", + pos = {x = 0, y = 0}, + config = {extra = {x_mult = 4}}, + loc_txt = { + name = 'AP Joker', + text = { "{X:mult,C:white} X#1# {} Mult against {C:attention}Boss Blinds{}"} + }, + rarity = 2, + cost = 6, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = "apjoker", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.x_mult}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and G.GAME.blind.boss and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + end +} +local apjoker_sprite = { + object_type = "Atlas", + key = "apjoker", + path = "j_cry_apjoker.png", + px = 71, + py = 95 +} +local maze = { + object_type = "Joker", + name = "cry-maze", + key = "maze", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Labyrinth', + text = { + "All hands are considered the", + "{C:attention}first hand{} of each round,", + "all discards are considered the", + "{C:attention}first discard{} of each round" + } + }, + rarity = 1, + cost = 3, + discovered = true, + atlas = "maze", + calculate = function(self, card, context) + if (context.before or context.after or context.pre_discard or context.discard or context.cardarea == G.hand) and not context.blueprint and not context.retrigger_joker then + G.GAME.current_round.hands_played = 0 + G.GAME.current_round.discards_used = 0 + end + end, + add_to_deck = function(self, card, from_debuff) + G.GAME.current_round.hands_played = 0 + G.GAME.current_round.discards_used = 0 + end +} + +local maze_sprite = { + object_type = "Atlas", + key = "maze", + path = "j_cry_labyrinth.png", + px = 71, + py = 95 +} + +--Notes from my testing +-- I've found that DNA and Burnt Joker work SOMEWHAT but can be jank at times (ESPECIALLY so with retrigger jokers). i can only assume other modded jokers will behave in a similar way. Trading card and sixth sense work without any issues tho so yey +local unjust_dagger = { +object_type = "Joker", +name = "cry-Unjust Dagger", +key = "unjust_dagger", +pos = {x = 0, y = 0}, +config = {extra = {x_mult = 1}}, +loc_txt = { +name = 'Unjust Dagger', +text = { +"When {C:attention}Blind{} is selected,", +"destroy Joker to the left", +"and gain {C:attention}one-fifth{} of", +"its sell value as {X:mult,C:white} XMult {}", +"{C:inactive}(Currently {X:mult,C:white} X#1# {C:inactive} Mult)" +} +}, +rarity = 2, +cost = 7, +discovered = true, +perishable_compat = false, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.x_mult}} + end, +atlas = "unjust_dagger", +calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + local my_pos = nil + for i = 1, #G.jokers.cards do + if G.jokers.cards[i] == card then my_pos = i; break end +end + if context.setting_blind and not (context.blueprint_card or self).getting_sliced and my_pos and G.jokers.cards[my_pos-1] and not G.jokers.cards[my_pos-1].ability.eternal and not G.jokers.cards[my_pos-1].getting_sliced then + local sliced_card = G.jokers.cards[my_pos-1] + sliced_card.getting_sliced = true + G.GAME.joker_buffer = G.GAME.joker_buffer - 1 + G.E_MANAGER:add_event(Event({func = function() + G.GAME.joker_buffer = 0 + card.ability.extra.x_mult = card.ability.extra.x_mult + sliced_card.sell_cost*0.2 + card:juice_up(0.8, 0.8) + sliced_card:start_dissolve({HEX("57ecab")}, nil, 1.6) + play_sound('slice1', 0.96+math.random()*0.08) + return true end })) + card_eval_status_text(self, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult+0.2*sliced_card.sell_cost}}, colour = G.C.RED, no_juice = true}) +return {calculated = true} + end + end +} +local unjust_dagger_sprite = { +object_type = "Atlas", + key = "unjust_dagger", + path = "j_cry_unjust_dagger.png", + px = 71, + py = 95 +} +local jollysus = { + object_type = "Joker", + name = "cry-jollysus", + key = "jollysus", + pos = {x = 0, y = 0}, + config = {extra = {spawn = true, active = "Active!", inactive = ""}, jolly = {t_mult = 8, type = 'Pair'}}, + loc_txt = { + name = 'Jolly Joker?', + text = { + "Create a {C:attention}Jolly Joker{}", + "when a joker is {C:attention}sold{}", + "{C:red}Works 1 time per round{}", + "{C:inactive}#1##2#{}" + } + }, + rarity = 2, + cost = 5, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + return {vars = {center.ability.extra.active, center.ability.extra.inactive}} + end, + atlas = "jollysus", + calculate = function(self, card, context) + if context.end_of_round and not context.retrigger_joker and not context.blueprint then + if not card.ability.extra.spawn then + card.ability.extra.active = "Active!" + card.ability.extra.inactive = "" + card.ability.extra.spawn = true + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "Reset", + colour = G.C.FILTER, + }) + } + end + end + if ((context.selling_card and context.card.ability.name == "cry-jollysus") or context.selling_self) and card.ability.extra.spawn and not context.retrigger_joker then --add support for selling itself (Blueprint compatible) + if not context.blueprint and not context.retrigger_joker then --ok tested this and making it sell itself next to blueprints doesn't make the blueprints create jokers, but it creates copies correctly when selling itself or blueprint so good enough for me + card.ability.extra.active = "" --also this doesn't work with brainstorm either (what is this jank????) + card.ability.extra.inactive = "No triggers left!" + card.ability.extra.spawn = false + end + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') + card:add_to_deck() + G.jokers:emplace(card) --man, now that I think about it this is probably the most complicated joker i've done so far + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "M!", + colour = G.C.FILTER, + }) + } + end + if context.selling_card and card.ability.extra.spawn and not context.retrigger_joker then + if context.card.ability.set == 'Joker' then + if not context.blueprint and not context.retrigger_joker then + card.ability.extra.active = "" + card.ability.extra.inactive = "No triggers left!" + card.ability.extra.spawn = false + end + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') + card:add_to_deck() + G.jokers:emplace(card) + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "M!", + colour = G.C.FILTER, + }) + } + end + end + end +} +local jollysus_sprite = { + object_type = "Atlas", + key = "jollysus", + path = "j_cry_jollysus.png", + px = 71, + py = 95 +} +local bubblem = { + object_type = "Joker", + name = "cry-bubblem", + key = "bubblem", + pos = {x = 0, y = 0}, + config = {extra = {spawn = false}, jolly = {t_mult = 8, type = 'Pair'}}, + loc_txt = { + name = 'Bubble M', + text = { + "Create a {C:dark_edition}Foil {C:attention}Jolly Joker{}", + "if hand played contains", + "a {C:attention}Four of a kind{}", + "{C:red}self destructs{}", + } + }, + rarity = 1, + cost = 2, + discovered = true, + loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + info_queue[#info_queue+1] = G.P_CENTERS.e_foil + end, + atlas = "bubblem", + calculate = function(self, card, context) + if context.scoring_name and (context.scoring_name == 'Five of a Kind' or context.scoring_name == 'Four of a Kind' or context.scoring_name == 'Flush Five') then + card.ability.extra.spawn = true + end + + if context.cardarea == G.jokers and card.ability.extra.spawn and context.before and not context.blueprint and not context.retrigger_joker 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(self) + card:remove() + card = nil + return true + end + })) + return true + end + })) + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') + card:set_edition({ + foil = true + }) + card:add_to_deck() + G.jokers:emplace(card) + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "M!", + colour = G.C.FILTER, + }) + } + end + end +} + +local bubblem_sprite = { + object_type = "Atlas", + key = "bubblem", + path = "j_cry_bubblem.png", + px = 71, + py = 95 +} +local mstack = { + object_type = "Joker", + name = "cry-mstack", + key = "mstack", + config = {extra = {sell = 0, retriggers = 0, text = ""}, jolly = {t_mult = 8, type = 'Pair'}}, + pos = {x = 0, y = 0}, + atlas = 'mstack', + loc_txt = { + name = 'M Stack', + text = { + "Retrigger all cards played", + "once for every {C:attention}2 Jolly Jokers{}", + "{C:attention}sold{}, up to {C:attention}8 sold{}", + "{C:inactive}Currently{}{C:attention:} #1#{}{C:inactive} retriggers #2#{}", + } + }, + rarity = 2, + cost = 7, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + return {vars = {center.ability.extra.retriggers, center.ability.extra.text}} + end, + calculate = function(self, card, context) --note: hardcoded like this intentionally + if context.repetition then + if context.cardarea == G.play then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.retriggers, + card = card + } + end + end + + if context.selling_card and context.card.ability.name == "Jolly Joker" and card.ability.extra.retriggers < 4 and not context.blueprint and not context.retrigger_joker then + if card.ability.extra.sell == 1 then + if not context.blueprint or context.retrigger_joker then + card.ability.extra.retriggers = card.ability.extra.retriggers + 1 + end + card.ability.extra.sell = 0 + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "Upgrade!", + colour = G.C.FILTER, + }) + } + else + card.ability.extra.sell = card.ability.extra.sell + 1 + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "1/2", + colour = G.C.FILTER, + }) + } + end + end + + if card.ability.extra.retriggers == 4 then + card.ability.extra.text = "(MAX)" + end + end, +} + +local mstack_sprite = { + object_type = "Atlas", + key = "mstack", + path = "j_cry_mstack.png", + px = 71, + py = 95 +} +return {name = "Misc. Jokers", + init = function() + --Dropshot Patches + local gigo = Game.init_game_object; + function Game:init_game_object() + local g = gigo(self) + g.current_round.cry_dropshot_card = {suit = 'Spades'} + return g + end + local rcc = reset_castle_card; + function reset_castle_card() + rcc() + G.GAME.current_round.cry_dropshot_card.suit = 'Spades' + local valid_castle_cards = {} + for k, v in ipairs(G.playing_cards) do + if v.ability.effect ~= 'Stone Card' then + valid_castle_cards[#valid_castle_cards+1] = v + end + end + if valid_castle_cards[1] then + local castle_card = pseudorandom_element(valid_castle_cards, pseudoseed('cry_dro'..G.GAME.round_resets.ante)) + if not G.GAME.current_round.cry_dropshot_card then + G.GAME.current_round.cry_dropshot_card = {} + end + G.GAME.current_round.cry_dropshot_card.suit = castle_card.base.suit + end + end + + --Maximized Patches + local cgi_ref = Card.get_id + override_maximized = false + function Card:get_id() + local id = cgi_ref(self) + if (next(find_joker("cry-Maximized")) and not override_maximized) then + if (id >= 2 and id <= 10) then id = 10 end + if (id >= 11 and id <= 13 or next(find_joker("Pareidolia"))) then id = 13 end + end + return id + end + --Fix issues with View Deck and Maximized + local gui_vd = G.UIDEF.view_deck + function G.UIDEF.view_deck(unplayed_only) + override_maximized = true + local ret_value = gui_vd(unplayed_only) + override_maximized = false + return ret_value + end + + --Cube Patches + local sc = Card.set_cost + function Card:set_cost() + sc(self) + if self.ability.name == "cry-Cube" then + self.cost = -25 + end + if self.ability.name == "cry-Big Cube" then + self.cost = 25 + end + end + + --Jimball Patches + local upd = Game.update + cry_jimball_dt = 0 + function Game:update(dt) + upd(self,dt) + cry_jimball_dt = cry_jimball_dt + dt + if G.P_CENTERS and G.P_CENTERS.j_cry_jimball and cry_jimball_dt > 0.1 then + cry_jimball_dt = 0 + local obj = G.P_CENTERS.j_cry_jimball + if (obj.pos.x == 5 and obj.pos.y == 6) then + obj.pos.x = 0 + obj.pos.y = 0 + elseif (obj.pos.x < 8) then obj.pos.x = obj.pos.x + 1 + elseif (obj.pos.y < 6) then + obj.pos.x = 0 + obj.pos.y = obj.pos.y + 1 + end + end + end + + end, + items = {dropshot_sprite, maximized_sprite, potofjokes_sprite, queensgambit_sprite, whip_sprite, lucky_joker_sprite, cursor_sprite, pickle_sprite, cube_sprite, triplet_rhythm_sprite, booster_sprite, chili_pepper_sprite, compound_interest_sprite, big_cube_sprite, eternalflame_sprite, nice_sprite, sus_sprite, chad_sprite, waluigi_sprite, seal_the_deal_sprite, jimball_sprite, fspinner_sprite, krustytheclown_sprite, blurred_sprite, gardenfork_sprite, lightupthenight_sprite, nosound_sprite, antennastoheaven_sprite, hunger_sprite, weegaming_sprite, redbloon_sprite, apjoker_sprite, maze_sprite, unjust_dagger_sprite, jollysus_sprite, bubblem_sprite, mstack_sprite, dropshot, maximized, potofjokes, queensgambit, wee_fib, compound_interest, whip, pickle, triplet_rhythm, booster, chili_pepper, lucky_joker, cursor, cube, big_cube, nice, sus, chad, jimball, waluigi, eternalflame, seal_the_deal, fspinner, krustytheclown, blurred, gardenfork, lightupthenight, nosound, antennastoheaven, hunger, weegaming, redbloon, apjoker, maze, unjust_dagger, jollysus, bubblem, mstack,}} diff --git a/Items/Items/Planets.lua b/Items/Items/Planets.lua new file mode 100644 index 000000000..4ffaa0f9a --- /dev/null +++ b/Items/Items/Planets.lua @@ -0,0 +1,142 @@ +local timantti = { + object_type = "Consumable", + set = "Planet", + name = "cry-Timantti", + key = "Timantti", + pos = {x=0,y=0}, + config = {hand_types = {'High Card', 'Pair', 'Two Pair'}}, + loc_txt = { + name = 'Timantti', + text = { + "Level up {C:attention}#1#{},", + "{C:attention}#2#{}, and {C:attention}#3#" + } + }, + cost = 4, + discovered = true, + atlas = "c_suits", + can_use = function(self, card) + return true + end, + loc_vars = function(self, info_queue, center) + return {vars = self.config.hand_types} + end, + use = function(self, card, area, copier) + suit_level_up(self, card, area, copier) + end, + bulk_use = function(self, card, area, copier, number) + suit_level_up(self, card, area, copier, number) + end +} +local klubi = { + object_type = "Consumable", + set = "Planet", + name = "cry-Klubi", + key = "Klubi", + pos = {x=1,y=0}, + config = {hand_types = {'Three of a Kind', 'Straight', 'Flush'}}, + loc_txt = { + name = 'Klubi', + text = { + "Level up {C:attention}#1#{},", + "{C:attention}#2#{}, and {C:attention}#3#" + } + }, + cost = 4, + discovered = true, + atlas = "c_suits", + can_use = function(self, card) + return true + end, + loc_vars = function(self, info_queue, center) + return {vars = self.config.hand_types} + end, + use = function(self, card, area, copier) + suit_level_up(self, card, area, copier) + end, + bulk_use = function(self, card, area, copier, number) + suit_level_up(self, card, area, copier, number) + end +} +local sydan = { + object_type = "Consumable", + set = "Planet", + name = "cry-Sydan", + key = "Sydan", + pos = {x=2,y=0}, + config = {hand_types = {'Four of a Kind', 'Straight Flush', 'Full House'}}, + loc_txt = { + name = 'Sydan', + text = { + "Level up {C:attention}#1#{},", + "{C:attention}#2#{}, and {C:attention}#3#" + } + }, + cost = 4, + discovered = true, + atlas = "c_suits", + can_use = function(self, card) + return true + end, + loc_vars = function(self, info_queue, center) + return {vars = self.config.hand_types} + end, + use = function(self, card, area, copier) + suit_level_up(self, card, area, copier) + end, + bulk_use = function(self, card, area, copier, number) + suit_level_up(self, card, area, copier, number) + end +} +local lapio = { + object_type = "Consumable", + set = "Planet", + name = "cry-Lapio", + key = "Lapio", + pos = {x=3,y=0}, + config = {hand_types = {'Five of a Kind', 'Flush House', 'Flush Five'}, softlock = true}, + loc_txt = { + name = 'Lapio', + text = { + "Level up {C:attention}#1#{},", + "{C:attention}#2#{}, and {C:attention}#3#" + } + }, + cost = 4, + discovered = true, + atlas = "c_suits", + can_use = function(self, card) + return true + end, + loc_vars = function(self, info_queue, center) + return {vars = self.config.hand_types} + end, + use = function(self, card, area, copier) + suit_level_up(self, card, area, copier) + end, + bulk_use = function(self, card, area, copier, number) + suit_level_up(self, card, area, copier, number) + end +} + +function suit_level_up(center, card, area, copier, number) + for _, v in pairs(card.config.center.config.hand_types) do + update_hand_text({sound = 'button', volume = 0.7, pitch = 0.8, delay = 0.3}, {handname=localize(v, 'poker_hands'),chips = G.GAME.hands[v].chips, mult = G.GAME.hands[v].mult, level=G.GAME.hands[v].level}) + level_up_hand(card, v, nil, number) + update_hand_text({sound = 'button', volume = 0.7, pitch = 1.1, delay = 0}, {mult = 0, chips = 0, handname = '', level = ''}) + end +end + +local suits_sprite = { + object_type = "Atlas", + key = "c_suits", + path = "c_cry_suits.png", + px = 71, + py = 95 +} + +return {name = "Planets", + init = function() + + end, + items = {suits_sprite, sydan, klubi, lapio, timantti}} \ No newline at end of file diff --git a/Items/Items/Spectrals.lua b/Items/Items/Spectrals.lua new file mode 100644 index 000000000..2ae68c6a1 --- /dev/null +++ b/Items/Items/Spectrals.lua @@ -0,0 +1,272 @@ +local white_hole = { + object_type = "Consumable", + set = "Spectral", + name = "cry-White Hole", + key = "white_hole", + pos = {x=0,y=0}, + loc_txt = { + name = 'White Hole', + text = { "{C:attention}Remove{} all hand levels,", + "upgrade {C:legendary,E:1}most played{} poker hand", + "by {C:attention}3{} for each removed level" + } + }, + cost = 4, + atlas = "white_hole", + discovered = true, + 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) + --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(card, 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(card, _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) + --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(card, 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(card, _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 white_hole_sprite = { + object_type = "Atlas", + key = "white_hole", + path = "c_cry_white_hole.png", + px = 71, + py = 95 +} + +local vacuum = { + object_type = "Consumable", + set = "Spectral", + name = "cry-Vacuum", + key = "vacuum", + pos = {x=0,y=0}, + config = {extra = 4}, + loc_txt = { + name = 'Vacuum', + text = { + "Removes {C:red}all {C:green}modifications{}", + "from {C:red}all{} cards in your hand,", + "Earn {C:money}$#1#{} per {C:green}modification{} removed", + "{C:inactive,s:0.7}(ex. Enhancements, Seals, Editions)" + } + }, + cost = 15, + atlas = "vacuum", + discovered = true, + 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 earnings = 0 + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() + play_sound('tarot1') + card: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 vacuum_sprite = { + object_type = "Atlas", + key = "vacuum", + + path = "c_cry_vacuum.png", + px = 71, + py = 95 +} + +local hammerspace = { + object_type = "Consumable", + set = "Spectral", + name = "cry-Hammerspace", + key = "hammerspace", + pos = {x=0,y=0}, + config = {}, + loc_txt = { + name = 'Hammerspace', + text = { + "Apply random {C:attention}consumables{}", + "as if they were {C:dark_edition}Enhancements{}", + "to your {C:attention}entire hand{}", + "{C:red}-1{} hand size" + } + }, + cost = 4, + atlas = "hammerspace", + discovered = true, + can_use = function(self, card) + return #G.hand.cards > 0 + end, + use = function(self, card, area, copier) + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() + play_sound('tarot1') + card: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(G.P_CENTERS[pseudorandom_element(G.P_CENTER_POOLS.Consumeables, pseudoseed('cry_hammerspace')).key], true, nil);play_sound('tarot2', percent);CARD:juice_up(0.3, 0.3);return true end })) + end + G.hand:change_size(-1) + end +} +local hammerspace_sprite = { + object_type = "Atlas", + key = "hammerspace", + path = "s_hammerspace.png", + px = 71, + py = 95 +} + +local lock = { + object_type = "Consumable", + set = "Spectral", + name = "cry-Lock", + key = "lock", + pos = {x=0,y=0}, + config = {}, + loc_txt = { + name = 'Lock', + text = { + "Remove {C:red}all{} stickers from {C:red}all {C:attention}Jokers{},", + "then apply {C:purple,E:1}Eternal{} to a random {C:attention}Joker{}" + } + }, + cost = 4, + atlas = "lock", + discovered = true, + can_use = function(self, card) + return #G.jokers.cards > 0 + end, + use = function(self, card, area, copier) + 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') + card: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);CARD:set_eternal(nil);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') + card: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 lock_sprite = { + object_type = "Atlas", + key = "lock", + + path = "c_cry_lock.png", + px = 71, + py = 95 +} + +return {name = "Spectrals", + init = function() + + end, + items = {white_hole_sprite, vacuum_sprite, hammerspace_sprite, lock_sprite, white_hole, vacuum, hammerspace, lock}} diff --git a/Items/Items/Stakes.lua b/Items/Items/Stakes.lua new file mode 100644 index 000000000..ba68d3f79 --- /dev/null +++ b/Items/Items/Stakes.lua @@ -0,0 +1,672 @@ +local pink = {object_type = "Stake", + name = "cry-Pink Stake", + key = "pink", + pos = {x = 0, y = 0}, + atlas = "stake", + applied_stakes = {"gold"}, + loc_txt = { + name = "Pink Stake", + text = { + "Required score scales", + "faster for each {C:attention}Ante" + } + }, + modifiers = function() + G.GAME.modifiers.scaling = math.max(G.GAME.modifiers.scaling or 0, 4) + end, + color = HEX("ff5ee6") +} +local brown = {object_type = "Stake", + name = "cry-Brown Stake", + key = "brown", + pos = {x = 1, y = 0}, + atlas = "stake", + applied_stakes = {"cry_pink"}, + modifiers = function() + G.GAME.modifiers.cry_eternal_perishable_compat = true + end, + loc_txt = { + name = "Brown Stake", + text = { + "All {C:attention}stickers{} are compatible", + "with each other" + } + }, + color = HEX("883200") +} +local yellow = {object_type = "Stake", + name = "cry-Yellow Stake", + key = "yellow", + pos = {x = 2, y = 0}, + atlas = "stake", + applied_stakes = {"cry_brown"}, + modifiers = function() + G.GAME.modifiers.cry_any_stickers = true + end, + loc_txt = { + name = "Yellow Stake", + text = { + "{C:attention}Stickers{} can appear on", + "all purchasable items" + } + }, + color = HEX("f7ff1f") +} +local jade = {object_type = "Stake", + name = "cry-Jade Stake", + key = "jade", + pos = {x = 3, y = 0}, + atlas = "stake", + applied_stakes = {"cry_yellow"}, + modifiers = function() + G.GAME.modifiers.flipped_cards = 20 + end, + loc_txt = { + name = "Jade Stake", + text = { + "Cards can be drawn {C:attention}face down{}", + } + }, + shiny = true, + color = HEX("78953c") +} +local cyan = {object_type = "Stake", + name = "cry-Cyan Stake", + key = "cyan", + pos = {x = 4, y = 0}, + atlas = "stake", + applied_stakes = {"cry_jade"}, + modifiers = function() + G.GAME.modifiers.cry_rarer_jokers = true + end, + loc_txt = { + name = "Cyan Stake", + text = { + "{C:green}Uncommon{} and {C:red}Rare{} Jokers are", + "less likely to appear", + } + }, + color = HEX("39ffcc") +} +local gray = {object_type = "Stake", + name = "cry-Gray Stake", + key = "gray", + pos = {x = 0, y = 1}, + atlas = "stake", + applied_stakes = {"cry_cyan"}, + modifiers = function() + G.GAME.modifiers.cry_reroll_scaling = 2 + end, + loc_txt = { + name = "Gray Stake", + text = { + "Rerolls increase by {C:attention}$2{} each" + } + }, + color = HEX("999999") +} +local crimson = {object_type = "Stake", + name = "cry-Crimson Stake", + key = "crimson", + pos = {x = 1, y = 1}, + atlas = "stake", + applied_stakes = {"cry_gray"}, + modifiers = function() + G.GAME.modifiers.cry_voucher_restock_antes = 2 + end, + loc_txt = { + name = "Crimson Stake", + text = { + "Vouchers restock on {C:attention}even{} Antes", + } + }, + color = HEX("800000") +} +local diamond = {object_type = "Stake", + name = "cry-Diamond Stake", + key = "diamond", + pos = {x = 2, y = 1}, + atlas = "stake", + applied_stakes = {"cry_crimson"}, + modifiers = function() + G.GAME.win_ante = 10 + end, + loc_txt = { + name = "Diamond Stake", + text = { + "Must beat Ante {C:attention}10{} to win", + } + }, + shiny = true, + color = HEX("88e5d9") +} +local amber = {object_type = "Stake", + name = "cry-Amber Stake", + key = "amber", + pos = {x = 3, y = 1}, + atlas = "stake", + applied_stakes = {"cry_diamond"}, + modifiers = function() + G.GAME.modifiers.cry_booster_packs = 1 + end, + loc_txt = { + name = "Amber Stake", + text = { + "{C:attention}-1{} Booster Pack slot", + } + }, + shiny = true, + color = HEX("feb900") +} +local bronze = {object_type = "Stake", + name = "cry-Bronze Stake", + key = "bronze", + pos = {x = 4, y = 1}, + atlas = "stake", + applied_stakes = {"cry_amber"}, + modifiers = function() + G.GAME.modifiers.cry_voucher_price_hike = 1.5 + end, + loc_txt = { + name = "Bronze Stake", + text = { + "Vouchers are {C:attention}50%{} more expensive", + } + }, + shiny = true, + color = HEX("d27c37") +} +local quartz = {object_type = "Stake", + name = "cry-Quartz Stake", + key = "quartz", + pos = {x = 0, y = 2}, + atlas = "stake", + applied_stakes = {"cry_bronze"}, + modifiers = function() + G.GAME.modifiers.cry_enable_pinned_in_shop = true + end, + loc_txt = { + name = "Quartz Stake", + text = { + "Jokers can be {C:attention}Pinned{}", + "{s:0.8,C:inactive}(Stays pinned to the leftmost position){}", + } + }, + shiny = true, + color = HEX("e8e8e8") +} +local ruby = {object_type = "Stake", + name = "cry-Ruby Stake", + key = "ruby", + pos = {x = 1, y = 2}, + atlas = "stake", + applied_stakes = {"cry_quartz"}, + modifiers = function() + G.GAME.modifiers.cry_big_boss_rate = 0.3 + end, + loc_txt = { + name = "Ruby Stake", + text = { + "{C:attention}Big{} Blinds can become", + "{C:attention}Boss{} Blinds", + } + }, + shiny = true, + color = HEX("fc5f55") +} +local glass = {object_type = "Stake", + name = "cry-Glass Stake", + key = "glass", + pos = {x = 2, y = 2}, + atlas = "stake", + applied_stakes = {"cry_ruby"}, + modifiers = function() + G.GAME.modifiers.cry_shatter_rate = 30 + end, + loc_txt = { + name = "Glass Stake", + text = { + "Cards can {C:attention}shatter{} when scored", + } + }, + shiny = true, + color = HEX("ffffff") +} +local sapphire = {object_type = "Stake", + name = "cry-Sapphire Stake", + key = "sapphire", + pos = {x = 3, y = 2}, + atlas = "stake", + applied_stakes = {"cry_glass"}, + modifiers = function() + G.GAME.modifiers.cry_ante_tax = 0.25 + G.GAME.modifiers.cry_ante_tax_max = 10 + end, + loc_txt = { + name = "Sapphire Stake", + text = { + "Lose {C:attention}25%{} of current money", + "at end of Ante", + "{s:0.8,C:inactive}(Up to $10){}", + } + }, + shiny = true, + color = HEX("3551fc") +} +local emerald = {object_type = "Stake", + name = "cry-Emerald Stake", + key = "emerald", + pos = {x = 4, y = 2}, + atlas = "stake", + applied_stakes = {"cry_sapphire"}, + modifiers = function() + G.GAME.modifiers.cry_enable_flipped_in_shop = true + end, + loc_txt = { + name = "Emerald Stake", + text = { + "Cards, packs, and vouchers", + "can be {C:attention}face down{}", + "{s:0.8,C:inactive}(Unable to be viewed until purchased){}", + } + }, + shiny = true, + color = HEX("06fc2c") +} +local platinum = {object_type = "Stake", + name = "cry-Platinum Stake", + key = "platinum", + pos = {x = 0, y = 3}, + atlas = "stake", + applied_stakes = {"cry_emerald"}, + modifiers = function() + G.GAME.modifiers.cry_no_small_blind = true + G.GAME.round_resets.blind_states['Small'] = 'Hide' + end, + loc_txt = { + name = "Platinum Stake", + text = { + "Small Blinds are {C:attention}removed{}", + } + }, + shiny = true, + color = HEX("b0f6ff") +} +local twilight = {object_type = "Stake", + name = "cry-Twilight Stake", + key = "twilight", + pos = {x = 1, y = 3}, + atlas = "stake", + applied_stakes = {"cry_platinum"}, + loc_txt = { + name = "Twilight Stake", + text = { + "Cards can be {C:attention}Banana{}", + "{s:0.8,C:inactive}(1 in 10 chance of being destroyed each round){}", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local verdant = {object_type = "Stake", + name = "cry-Verdant Stake", + key = "verdant", + pos = {x = 2, y = 3}, + atlas = "stake", + applied_stakes = {"cry_twilight"}, + loc_txt = { + name = "Verdant Stake", + text = { + "Required score scales", + "faster for each {C:attention}Ante", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local ember = {object_type = "Stake", + name = "cry-Ember Stake", + key = "ember", + pos = {x = 3, y = 3}, + atlas = "stake", + applied_stakes = {"cry_verdant"}, + loc_txt = { + name = "Ember Stake", + text = { + "All items have no sell value", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local dawn = {object_type = "Stake", + name = "cry-Dawn Stake", + key = "dawn", + pos = {x = 4, y = 3}, + atlas = "stake", + applied_stakes = {"cry_ember"}, + loc_txt = { + name = "Dawn Stake", + text = { + "Tarots and Spectrals target {C:attention}1", + "fewer card", + "{s:0.8,C:inactive}(Minimum of 1){}", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local horizon = {object_type = "Stake", + name = "cry-Horizon Stake", + key = "horizon", + pos = {x = 0, y = 4}, + atlas = "stake", + applied_stakes = {"cry_dawn"}, + loc_txt = { + name = "Horizon Stake", + text = { + "When blind selected, add a", + "{C:attention}random card{} to deck", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local blossom = {object_type = "Stake", + name = "cry-Blossom Stake", + key = "blossom", + pos = {x = 1, y = 4}, + atlas = "stake", + applied_stakes = {"cry_horizon"}, + loc_txt = { + name = "Blossom Stake", + text = { + "{C:attention}Final{} Boss Blinds can appear", + "after Ante 1", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local azure = {object_type = "Stake", + name = "cry-Azure Stake", + key = "azure", + pos = {x = 2, y = 4}, + atlas = "stake", + applied_stakes = {"cry_blossom"}, + loc_txt = { + name = "Azure Stake", + text = { + "Values on Jokers are reduced", + "by {C:attention}20%{}", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local ascendant = {object_type = "Stake", + name = "cry-Ascendant Stake", + key = "ascendant", + pos = {x = 3, y = 4}, + atlas = "stake", + applied_stakes = {"cry_azure"}, + loc_txt = { + name = "Ascendant Stake", + text = { + "{C:attention}-1{} Joker slot", + "{s:0.8,C:inactive}(Not yet implemented){}", + } + }, + shiny = true, + color = HEX("ffffff") --temporary before gradients +} +local stake_atlas = {object_type = "Atlas", + key = "stake", + + path = "stake_cry.png", + px = 29, + py = 29 +} +return {name = "More Stakes", + init = function(self) + -- Ante scaling changes + local gba = get_blind_amount + function get_blind_amount(ante) + local k = to_big(0.7) + if G.GAME.modifiers.scaling == 4 then + local amounts = { + to_big(300), to_big(1200), to_big(4000), to_big(11000), to_big(30000), to_big(100000), to_big(180000), to_big(300000) + } + if ante < 1 then return to_big(100) end + if ante <= 8 then return amounts[ante] end + local a, b, c, d = amounts[8],1.6,ante-8, 1 + 0.2*(ante-8) + local amount = a*(b+(k*c)^d)^c + amount.m = math.floor(10*amount.m)/10 + amount:normalize() + return amount + else return gba(ante) + end + end + -- Disallow use of Debuffed Perishable consumables + local cuc = Card.can_use_consumeable + function Card:can_use_consumeable(any_state, skip_check) + if self.ability.perishable and self.ability.perish_tally <= 0 then + return false + end + return cuc(self, any_state, skip_check) + end + -- Overriding Steamodded's registering of Incantation/Familiar/Grim + local function random_destroy(used_tarot) + local destroyed_cards = {} + local temp_hand = {} + local hasHand = false + for k, v in ipairs(G.hand.cards) do + if not v.ability.eternal then + temp_hand[#temp_hand+1] = v + hasHand = true + end + end + if hasHand then destroyed_cards[#destroyed_cards + 1] = pseudorandom_element(temp_hand, pseudoseed('random_destroy')) end + G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.4, + func = function() + play_sound('tarot1') + if used_tarot and used_tarot.juice_up then used_tarot:juice_up(0.3, 0.5) end + return true + end + })) + G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.1, + func = function() + for i = #destroyed_cards, 1, -1 do + local card = destroyed_cards[i] + if card.ability.name == 'Glass Card' then + card:shatter() + else + card:start_dissolve(nil, i ~= #destroyed_cards) + end + end + return true + end + })) + return destroyed_cards + end + SMODS.Consumable:take_ownership('grim', { + use = function(self, card, area, copier) + local used_tarot = copier or card + local destroyed_cards = random_destroy(used_tarot) + G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.7, + func = function() + local cards = {} + for i = 1, card.ability.extra do + cards[i] = true + local suit_list = {} + for i = #SMODS.Suit.obj_buffer, 1, -1 do + suit_list[#suit_list + 1] = SMODS.Suit.obj_buffer[i] + end + local _suit, _rank = + SMODS.Suits[pseudorandom_element(suit_list, pseudoseed('grim_create'))].card_key, 'A' + local cen_pool = {} + for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do + if v.key ~= 'm_stone' then + cen_pool[#cen_pool + 1] = v + end + end + create_playing_card({ + front = G.P_CARDS[_suit .. '_' .. _rank], + center = pseudorandom_element(cen_pool, pseudoseed('spe_card')) + }, G.hand, nil, i ~= 1, { G.C.SECONDARY_SET.Spectral }) + end + playing_card_joker_effects(cards) + return true + end + })) + delay(0.3) + for i = 1, #G.jokers.cards do + G.jokers.cards[i]:calculate_joker({ remove_playing_cards = true, removed = destroyed_cards }) + end + end, + }) + SMODS.Consumable:take_ownership('familiar', { + use = function(self, card, area, copier) + local used_tarot = copier or card + local destroyed_cards = random_destroy(used_tarot) + G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.7, + func = function() + local cards = {} + for i = 1, card.ability.extra do + cards[i] = true + local suit_list = {} + for i = #SMODS.Suit.obj_buffer, 1, -1 do + suit_list[#suit_list + 1] = SMODS.Suit.obj_buffer[i] + end + local faces = {} + for _, v in ipairs(SMODS.Rank.obj_buffer) do + local r = SMODS.Ranks[v] + if r.face then table.insert(faces, r.card_key) end + end + local _suit, _rank = + SMODS.Suits[pseudorandom_element(suit_list, pseudoseed('familiar_create'))].card_key, + pseudorandom_element(faces, pseudoseed('familiar_create')) + local cen_pool = {} + for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do + if v.key ~= 'm_stone' then + cen_pool[#cen_pool + 1] = v + end + end + create_playing_card({ + front = G.P_CARDS[_suit .. '_' .. _rank], + center = pseudorandom_element(cen_pool, pseudoseed('spe_card')) + }, G.hand, nil, i ~= 1, { G.C.SECONDARY_SET.Spectral }) + end + playing_card_joker_effects(cards) + return true + end + })) + delay(0.3) + for i = 1, #G.jokers.cards do + G.jokers.cards[i]:calculate_joker({ remove_playing_cards = true, removed = destroyed_cards }) + end + end, + }) + SMODS.Consumable:take_ownership('incantation', { + use = function(self, card, area, copier) + local used_tarot = copier or card + local destroyed_cards = random_destroy(used_tarot) + G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.7, + func = function() + local cards = {} + for i = 1, card.ability.extra do + cards[i] = true + local suit_list = {} + for i = #SMODS.Suit.obj_buffer, 1, -1 do + suit_list[#suit_list + 1] = SMODS.Suit.obj_buffer[i] + end + local numbers = {} + for _RELEASE_MODE, v in ipairs(SMODS.Rank.obj_buffer) do + local r = SMODS.Ranks[v] + if v ~= 'Ace' and not r.face then table.insert(numbers, r.card_key) end + end + local _suit, _rank = + SMODS.Suits[pseudorandom_element(suit_list, pseudoseed('incantation_create'))].card_key, + pseudorandom_element(numbers, pseudoseed('incantation_create')) + local cen_pool = {} + for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do + if v.key ~= 'm_stone' then + cen_pool[#cen_pool + 1] = v + end + end + create_playing_card({ + front = G.P_CARDS[_suit .. '_' .. _rank], + center = pseudorandom_element(cen_pool, pseudoseed('spe_card')) + }, G.hand, nil, i ~= 1, { G.C.SECONDARY_SET.Spectral }) + end + playing_card_joker_effects(cards) + return true + end + })) + delay(0.3) + for i = 1, #G.jokers.cards do + G.jokers.cards[i]:calculate_joker({ remove_playing_cards = true, removed = destroyed_cards }) + end + end, + }) + + -- This is short enough that I'm fine overriding it + function calculate_reroll_cost(skip_increment) + if G.GAME.current_round.free_rerolls < 0 then G.GAME.current_round.free_rerolls = 0 end + if G.GAME.current_round.free_rerolls > 0 then G.GAME.current_round.reroll_cost = 0; return end + G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase or 0 + if not skip_increment then G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase + (G.GAME.modifiers.cry_reroll_scaling or 1) end + G.GAME.current_round.reroll_cost = (G.GAME.round_resets.temp_reroll_cost or G.GAME.round_resets.reroll_cost) + G.GAME.current_round.reroll_cost_increase + end + + local sc = Card.set_cost + function Card:set_cost() + sc(self) + if self.ability.set == 'Voucher' and G.GAME.modifiers.cry_voucher_price_hike then + self.cost = math.floor(self.cost * G.GAME.modifiers.cry_voucher_price_hike) + --Update related costs + self.sell_cost = math.max(1, math.floor(self.cost/2)) + (self.ability.extra_value or 0) + if self.area and self.ability.couponed and (self.area == G.shop_jokers or self.area == G.shop_booster) then self.cost = 0 end + self.sell_cost_label = self.facing == 'back' and '?' or self.sell_cost + end + end + + for _, v in pairs(self.items) do + if v.object_type == "Stake" then + v.sticker_pos = v.pos + v.sticker_atlas = "sticker" + local words = {} + words[1], words[2] = v.loc_txt.name:match("(%w+)(.+)") + local stakeName = words[1] + v.loc_txt = {description = v.loc_txt} + v.loc_txt.sticker = { + name = stakeName.." Sticker", + text = { + "Used this Joker", + "to win on {C:attention}"..stakeName, + "{C:attention}Stake{} difficulty" + } + } + end + end + end, + items = {stake_atlas, pink, brown, yellow, jade, cyan, gray, crimson, diamond, + amber, bronze, quartz, ruby, glass, sapphire, emerald, platinum, + twilight, verdant, ember, dawn, horizon, blossom, azure, ascendant}} \ No newline at end of file diff --git a/Items/Items/yEpicJokers.lua b/Items/Items/yEpicJokers.lua new file mode 100644 index 000000000..e2ec1d77d --- /dev/null +++ b/Items/Items/yEpicJokers.lua @@ -0,0 +1,1026 @@ +cry_enable_epics = false +local googol_play = { + object_type = "Joker", + name = "cry-Googol Play Card", + key = "googol_play", + config = {extra = {Xmult = 1e100, odds = 10}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Googol Play Card', + text = { + "{C:green}#1# in #2#{} chance for", + "{X:red,C:white} X1e100 {} Mult" + } + }, + rarity = "cry_epic", + cost = 10, + discovered = true, + blueprint_compat = true, + atlas = "googol_play", + soul_pos = {x = 2, y = 0, extra = {x = 1, y = 0}}, + loc_vars = function(self, info_queue, center) + return {vars = {''..(G.GAME and G.GAME.probabilities.normal or 1), center.ability.extra.odds}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and not context.before and not context.after then + if pseudorandom('cry_googol_play') < G.GAME.probabilities.normal/card.ability.extra.odds then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, + Xmult_mod = card.ability.extra.Xmult + } + else return {calculated = true} end + end + end, +} +local googol_play_sprite = { + object_type = "Atlas", + key = "googol_play", + + path = "j_cry_googol_play.png", + px = 71, + py = 95 +} +local sync_catalyst = { + object_type = "Joker", + name = "cry-Sync Catalyst", + key = "sync_catalyst", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Sync Catalyst', + text = { + "Balance {C:blue}Chips{} and", + "{C:red}Mult{} when this Joker", + "is triggered" + } + }, + rarity = "cry_epic", + cost = 11, + discovered = true, + blueprint_compat = true, + atlas = "sync_catalyst", + calculate = function(self, card, context) + if context.cardarea == G.jokers and not context.before and not context.after then + local tot = hand_chips + mult + hand_chips = mod_chips(math.floor(tot/2)) + mult = mod_mult(math.floor(tot/2)) + update_hand_text({delay = 0}, {mult = mult, chips = hand_chips}) + return { + message = localize('k_balanced'), + colour = {0.8, 0.45, 0.85, 1} + } + end + end, +} +local sync_catalyst_sprite = { + object_type = "Atlas", + key = "sync_catalyst", + + path = "j_cry_sync_catalyst.png", + px = 71, + py = 95 +} +local negative = { + object_type = "Joker", + name = "cry-Negative Joker", + key = "negative", + pos = {x = 0, y = 0}, + config = {extra = 3}, + loc_txt = { + name = 'Negative Joker', + text = { + "{C:dark_edition}+#1#{C:attention} Joker{} slots" + } + }, + rarity = "cry_epic", + cost = 12, + discovered = true, + atlas = "negative", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra}} + end, + add_to_deck = function(self, card, from_debuff) + G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra + end, + remove_from_deck = function(self, card, from_debuff) + G.jokers.config.card_limit = G.jokers.config.card_limit - card.ability.extra + end +} +local negative_sprite = { + object_type = "Atlas", + key = "negative", + + path = "j_cry_negative.png", + px = 71, + py = 95 +} +local canvas = { + object_type = "Joker", + name = "cry-Canvas", + key = "canvas", + pos = {x = 0, y = 0}, + config = {num_retriggers = 0}, + loc_txt = { + name = 'Canvas', + text = { + "{C:attention}Retrigger{} all {C:attention}Jokers{} to the left", + "once for {C:attention}every{} non-{C:blue}Common{C:attention} Joker{}", + "to the right of this Joker" + } + }, + rarity = "cry_epic", + cost = 15, + discovered = true, + blueprint_compat = true, + atlas = "canvas", + calculate = function(self, card, context) + if context.retrigger_joker_check and not context.retrigger_joker then + self.config.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 then + self.config.num_retriggers = self.config.num_retriggers + 1 + end + end + if 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 = self.config.num_retriggers, + card = card + } + end + end + end, +} +local canvas_sprite = { + object_type = "Atlas", + key = "canvas", + + path = "j_cry_canvas.png", + px = 71, + py = 95 +} +local error_joker = { + object_type = "Joker", + name = "cry-Error", + key = "error", + pos = {x = 0, y = 0}, + config = {extra = {sell_rounds = 0, active = false}}, + loc_txt = { + name = '{C:red}ERR{}{C:dark_edition}O{}{C:red}R{}', + text = { + "" + } + }, + rarity = "cry_epic", + cost = 1, + discovered = true, + blueprint_compat = false, + eternal_compat = false, + atlas = "error", + calculate = function(self, card, context) + if context.end_of_round and not context.blueprint and not context.repetition 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(self, eval, true) + end + return { + message = "???", + colour = G.C.BLACK + } + 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 (card and card.ability and card.ability.loyalty_remaining == 0) and not G.RESET_JIGGLES end + juice_card_until(self, 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 + end + end +} +local error_sprite = { + object_type = "Atlas", + key = "error", + + path = "j_cry_error.png", + px = 71, + py = 95 +} +local m = { + object_type = "Joker", + name = "cry-m", + key = "m", + pos = {x = 0, y = 0}, + config = {extra = {extra = 13, x_mult = 1}, jolly = {t_mult = 8, type = 'Pair'}}, + loc_txt = { + name = 'm', + text = { + "This Joker gains {X:mult,C:white} X#1# {} Mult", + "when {C:attention}Jolly Joker{} is sold", + "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" + } + }, + rarity = "cry_epic", + cost = 13, + discovered = true, + perishable_compat = false, + blueprint_compat = true,loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + return {vars = {center.ability.extra.extra, center.ability.extra.x_mult}} + end, + atlas = "m", + calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + if context.selling_card and context.card.ability.name == "Jolly Joker" and not context.blueprint then + card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) + return {calculated = true} + end + end +} +local m_sprite = { + object_type = "Atlas", + key = "m", + + path = "j_cry_m.png", + px = 71, + py = 95 +} +local M = { + object_type = "Joker", + name = "cry-M", + key = "M", + pos = {x = 0, y = 0}, + config = {jolly = {t_mult = 8, type = 'Pair'}}, + loc_txt = { + name = 'M', + text = { + "When {C:attention}Blind{} is selected,", + "create a {C:dark_edition}Negative{}", + "{C:attention}Jolly Joker{}" + } + }, + rarity = "cry_epic", + cost = 13, + discovered = true, + blueprint_compat = true,loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + info_queue[#info_queue+1] = G.P_CENTERS.e_negative + end, + atlas = "M", + calculate = function(self, card, context) + if context.setting_blind and not (context.blueprint_card or self).getting_sliced 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 {completed=true} + end + end +} +local M_sprite = { + object_type = "Atlas", + key = "M", + path = "j_cry_big_m.png", + px = 71, + py = 95 +} +local boredom = { + object_type = "Joker", + name = "cry-Boredom", + key = "boredom", + pos = {x = 0, y = 0}, + config = {extra = {odds = 2}}, + loc_txt = { + name = 'Boredom', + text = { + "{C:green}#1# in #2#{} chance to", + "{C:attention}retrigger{} each {C:attention}Joker{}", + "or {C:attention}played card{}", + "{C:inactive,s:0.8}(Excludes itself){}" + } + }, + rarity = "cry_epic", + cost = 12, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = {''..(G.GAME and G.GAME.probabilities.normal or 1), center.ability.extra.odds}} + end, + atlas = "boredom", + calculate = function(self, card, context) + if context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= self then + if pseudorandom("cry_boredom_joker") < G.GAME.probabilities.normal/card.ability.extra.odds then + return { + message = localize('k_again_ex'), + repetitions = 1, + card = card + } + else return {calculated = true} end + end + if context.repetition and context.cardarea == G.play then + if pseudorandom("cry_boredom_card") < G.GAME.probabilities.normal/card.ability.extra.odds then + return { + message = localize('k_again_ex'), + repetitions = 1, + card = card + } + else + return {calculated = true} + end + end + end +} +local boredom_sprite = { + object_type = "Atlas", + key = "boredom", + + path = "j_cry_boredom.png", + px = 71, + py = 95 +} +local number_blocks = { + object_type = "Joker", + name = "cry-Number Blocks", + key = "number_blocks", + config = {extra = {money_mod = 1, money = 0}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Number Blocks', + text = { + "Earn {C:money}$#1#{} at end of round,", + "permanently increase payout by", + "{C:money}$#2#{} for each {C:attention}#3#{} held in hand,", + "rank changes every round" + } + }, + rarity = "cry_epic", + cost = 12, + discovered = true, + atlas = "number_blocks", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.money, center.ability.extra.money_mod, localize(G.GAME.current_round.cry_nb_card and 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 + card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')}) + return {calculated = true} + end + end, + calc_dollar_bonus = function(self, card) + if card.ability.extra.money > 0 then + return card.ability.extra.money + end + end +} +local number_blocks_sprite = { + object_type = "Atlas", + key = "number_blocks", + path = "j_cry_number_blocks.png", + px = 71, + py = 95 +} + +local double_scale = { + object_type = "Joker", + name = "cry-Double Scale", + key = "Double Scale", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Double Scale', + text = { + "Scaling {C:attention}Jokers{}", + "scale {C:attention}quadratically", + "{C:inactive,s:0.8}(ex. +1, +3, +6, +10)", + "{C:inactive,s:0.8}(grows by +1, +2, +3)" + } + }, + rarity = "cry_epic", + cost = 13, + discovered = true, + atlas = "double_scale", + --todo: support jokers that scale multiple variables + calculate = function(self, card, context) + --initialize tracking object + if not G.GAME.cry_double_scale then + G.GAME.cry_double_scale = {double_scale = true} --doesn't really matter what's in here as long as there's something + end + for i = 1, #G.jokers.cards do + --sort_id is a unique ID for each Joker + local jkr = G.jokers.cards[i] + if jkr.ability and type(jkr.ability) == 'table' then + if not G.GAME.cry_double_scale[jkr.sort_id] then + G.GAME.cry_double_scale[jkr.sort_id] = {ability = {double_scale = true}} + for k, v in pairs(jkr.ability) do + if type(jkr.ability[k]) ~= 'table' then + G.GAME.cry_double_scale[jkr.sort_id].ability[k] = v + else + G.GAME.cry_double_scale[jkr.sort_id].ability[k] = {} + for _k, _v in pairs(jkr.ability[k]) do + G.GAME.cry_double_scale[jkr.sort_id].ability[k][_k] = _v + end + end + end + elseif not G.GAME.cry_double_scale[jkr.sort_id].scaler then + dbl_info = G.GAME.cry_double_scale[jkr.sort_id] + if jkr.ability.name == "cry-Exponentia" then + dbl_info.base = {"extra", "pow_mult"} + dbl_info.scaler = {"extra", "pow_mult_mod"} + dbl_info.scaler_base = jkr.ability.extra.pow_mult_mod + dbl_info.offset = 1 + return + end + if jkr.ability.name == "cry-Redeo" then + dbl_info.base = {"extra", "money_req"} + dbl_info.scaler = {"extra", "money_mod"} + dbl_info.scaler_base = jkr.ability.extra.money_mod + dbl_info.offset = 1 + return + end + if jkr.ability.name == "cry-Chili Pepper" then + dbl_info.base = {"extra", "Xmult"} + dbl_info.scaler = {"extra", "Xmult_mod"} + dbl_info.scaler_base = jkr.ability.extra.Xmult_mod + dbl_info.offset = 1 + return + end + if jkr.ability.name == "Yorick" then + dbl_info.base = {"x_mult"} + dbl_info.scaler = {"extra", "xmult"} --not kidding + dbl_info.scaler_base = 1 + dbl_info.offset = 1 + return + end + if jkr.ability.name == "Hologram" then + dbl_info.base = {"x_mult"} + dbl_info.scaler = {"extra"} + dbl_info.scaler_base = jkr.ability.extra + dbl_info.offset = 1 + return + end + if jkr.ability.name == "Gift Card" then + dbl_info.base = {"extra_value"} + dbl_info.scaler = {"extra"} + dbl_info.scaler_base = jkr.ability.extra + dbl_info.offset = 1 + return + end + if jkr.ability.name == "Throwback" then + dbl_info.base = {"x_mult"} + dbl_info.scaler = {"extra"} + dbl_info.scaler_base = jkr.ability.x_mult or 1 + dbl_info.offset = 1 + return + end + if jkr.ability.name == "Egg" then + dbl_info.base = {"extra_value"} + dbl_info.scaler = {"extra"} + dbl_info.scaler_base = jkr.ability.extra + dbl_info.offset = 1 + return + end + for k, v in pairs(jkr.ability) do + --extra_value is ignored because it can be scaled by Gift Card + if k ~= "extra_value" and dbl_info.ability[k] ~= v and is_number(v) and is_number(dbl_info.ability[k]) then + dbl_info.base = {k} + local predicted_mod = math.abs(v-dbl_info.ability[k]) + local best_key = {""} + local best_coeff = 10^100 + for l, u in pairs(jkr.ability) do + if l ~= k and is_number(u) then + if predicted_mod/u >= 0.999 and predicted_mod/u < best_coeff then + best_coeff = predicted_mod/u + best_key = {l} + end + end + if type(jkr.ability[l]) == 'table' then + for _l, _u in pairs(jkr.ability[l]) do + if is_number(_u) and predicted_mod/_u >= 0.999 and predicted_mod/_u < best_coeff then + best_coeff = predicted_mod/_u + best_key = {l,_l} + end + end + end + end + dbl_info.scaler = best_key + end + if type(jkr.ability[k]) == 'table' then + for _k, _v in pairs(jkr.ability[k]) do + if dbl_info.ability[k][_k] ~= _v and is_number(_v) and is_number(dbl_info.ability[k][_k]) then + dbl_info.base = {k,_k} + local predicted_mod = math.abs(_v-dbl_info.ability[k][_k]) + local best_key = {""} + local best_coeff = 10^100 + for l, u in pairs(jkr.ability) do + if is_number(u) and predicted_mod/u >= 0.999 then + if predicted_mod/u < best_coeff then + best_coeff = predicted_mod/u + best_key = {l} + end + end + if type(jkr.ability[l]) == 'table' then + for _l, _u in pairs(jkr.ability[l]) do + if (l ~= k or _l ~= _k) and is_number(_u) and predicted_mod/_u >= 0.999 then + if predicted_mod/_u < best_coeff then + best_coeff = predicted_mod/_u + best_key = {l,_l} + end + end + end + end + end + dbl_info.scaler = best_key + end + end + end + end + if dbl_info.scaler then + dbl_info.scaler_base = #dbl_info.scaler == 2 and dbl_info.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] or dbl_info.ability[dbl_info.scaler[1]] + dbl_info.offset = 1 + end + end + if G.GAME.cry_double_scale[jkr.sort_id] and G.GAME.cry_double_scale[jkr.sort_id].scaler then + --update scaling metadata + dbl_info = G.GAME.cry_double_scale[jkr.sort_id] + local current_val, last_val, scale = 0, 0, 0 + if #dbl_info.base == 2 then + if not jkr.ability[dbl_info.base[1]] or not jkr.ability[dbl_info.base[1]][dbl_info.base[2]] then return end + current_val = jkr.ability[dbl_info.base[1]][dbl_info.base[2]] + last_val = dbl_info.ability[dbl_info.base[1]] and dbl_info.ability[dbl_info.base[1]][dbl_info.base[2]] or 1 + else + if not jkr.ability[dbl_info.base[1]] then return end + current_val = jkr.ability[dbl_info.base[1]] + last_val = dbl_info.ability[dbl_info.base[1]] or 1 + end + if #dbl_info.scaler == 2 then + if not jkr.ability[dbl_info.scaler[1]] or not jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] then return end + scale = jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] + else + if not jkr.ability[dbl_info.scaler[1]] then return end + scale = jkr.ability[dbl_info.scaler[1]] + end + scale_amt = math.abs((current_val-last_val)/scale) + if scale_amt > 0 then + dbl_info.offset = dbl_info.offset + scale_amt + local new_scale = dbl_info.scaler_base * dbl_info.offset + if #dbl_info.base == 2 then + if not jkr.ability[dbl_info.base[1]] or not jkr.ability[dbl_info.base[1]][dbl_info.base[2]] then return end + dbl_info.ability[dbl_info.base[1]][dbl_info.base[2]] = jkr.ability[dbl_info.base[1]][dbl_info.base[2]] + else + if not jkr.ability[dbl_info.base[1]] then return end + dbl_info.ability[dbl_info.base[1]] = jkr.ability[dbl_info.base[1]] + end + if #dbl_info.scaler == 2 then + if not jkr.ability[dbl_info.scaler[1]] or not jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] then return end + jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] = new_scale + else + if not jkr.ability[dbl_info.scaler[1]] then return end + jkr.ability[dbl_info.scaler[1]] = new_scale + end + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')}) + end + end + end + end + return + end +} + +local double_scale_sprite = { + object_type = "Atlas", + key = "double_scale", + path = "j_cry_double_scale.png", + px = 71, + py = 95 +} +local oldcandy = { + object_type = "Joker", + name = "cry_oldcandy", + key = "oldcandy", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Nostalgic Candy', + text = { + "Permanently gain", + "{C:attention}+3{} hand size", + "when sold" + } + }, + rarity = "cry_epic", + cost = 10, + discovered = true, + eternal_compat = false, + atlas = "oldcandy", + calculate = function(self, card, context) --hardcoded, unfortunately + if context.selling_self and not context.blueprint then + G.hand:change_size(3) + end +end +} + +local oldcandy_sprite = { + object_type = "Atlas", + key = "oldcandy", + path = "j_cry_oldcandy.png", + px = 71, + py = 95 +} +local caramel = { + object_type = "Joker", + name = "cry-caramel", + key = "caramel", + config = {extra = {x_mult = 1.75, rounds_remaining = 11}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Caramel', + text = { + "All cards scored give {X:mult,C:white}X#1#{} Mult", + "for the next {C:attention}#2#{} rounds", + } + }, + rarity = "cry_epic", + cost = 11, + discovered = true, + blueprint_compat = true, + eternal_compat = false, + atlas = 'caramel', + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.x_mult, center.ability.extra.rounds_remaining}} + end, + calculate = function(self, card, context) + if context.individual then + if context.cardarea == G.play then + return { + x_mult = 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 = card.ability.extra.rounds_remaining - 1 + if card.ability.extra.rounds_remaining > 0 then + return { + message = {"-1 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 + end +} +local caramel_sprite = { + object_type = "Atlas", + key = "caramel", + + path = "j_cry_caramel.png", + px = 71, + py = 95 +} + +local curse = { + object_type = "Joker", + name = "cry_curse", + key = "curse", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Sob', + text = { + "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}run...{}", + "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}hide...{}", + "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}escape...{}", + "{C:inactive}(Must have room){}" + } + }, + rarity = "cry_epic", + cost = 4, + discovered = true, + perishable_compat = true, + atlas = "curse", + calculate = function(self, card, context) -- hardcoded, unfortunately + if context.selling_self and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.discard and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.pre_discard and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.reroll_shop and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.destroying_card and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.buying_card and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.skip_blind and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.cardarea == G.jokers and context.before and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.using_consumable and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.selling_card and context.card.ability.name ~= "Obelisk" and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.setting_blind and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.skipping_booster and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + end, + add_to_deck = function(self, card, from_debuff) + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_obelisk') + card:set_edition({ + negative = true + }) + card:set_eternal(true) + card:add_to_deck() + G.jokers:emplace(card) + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "Curse!", + colour = G.C.DARK_EDITION, + }) + } + end +} + +local curse_sprite = { + object_type = "Atlas", + key = "curse", + path = "j_cry_curse.png", + px = 71, + py = 95 +} + + +G.P_JOKER_RARITY_POOLS["cry_epic"] = {googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel, curse} + + +return {name = "Epic Jokers", + init = function() + + --Error Patches + 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","???"} + 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 = 'Specls', colour = G.C.SECONDARY_SET.Spectral}, + {string = "#@"..(G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11)..(G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.suit:sub(1,1) or 'D'), colour = G.C.RED}, + } + + cry_enable_epics = true + --Number Blocks Patches + local gigo = Game.init_game_object; + function Game:init_game_object() + local g = gigo(self) + g.current_round.cry_nb_card = {rank = 'Ace'} + return g + end + local rcc = reset_castle_card; + function reset_castle_card() + rcc() + G.GAME.current_round.cry_nb_card = {rank = 'Ace'} + local valid_castle_cards = {} + for k, v in ipairs(G.playing_cards) do + if v.ability.effect ~= 'Stone Card' then + valid_castle_cards[#valid_castle_cards+1] = v + end + end + if valid_castle_cards[1] then + local castle_card = pseudorandom_element(valid_castle_cards, pseudoseed('cry_nb'..G.GAME.round_resets.ante)) + if not G.GAME.current_round.cry_nb_card then + G.GAME.current_round.cry_nb_card = {} + end + G.GAME.current_round.cry_nb_card.rank = castle_card.base.value + G.GAME.current_round.cry_nb_card.id = castle_card.base.id + end + end + + --For Double Scale, modify Green Joker to use one variable + SMODS.Joker:take_ownership('green_joker', { + config = {extra = 1, mult = 0}, + name = "cry-Green Joker", --will prevent old calculation code from working + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra,center.ability.extra,center.ability.mult}} + end, + calculate = function(self, card, context) + if context.discard and not context.blueprint and context.other_card == context.full_hand[#context.full_hand] then + local prev_mult = card.ability.mult + card.ability.mult = math.max(0, card.ability.mult - card.ability.extra) + if card.ability.mult ~= prev_mult then + return { + message = localize{type='variable',key='a_mult_minus',vars={card.ability.extra}}, + colour = G.C.RED, + card = card + } + end + end + if context.cardarea == G.jokers and context.before and not context.blueprint then + card.ability.mult = card.ability.mult + card.ability.extra + return { + card = card, + message = localize{type='variable',key='a_mult',vars={card.ability.extra}} + } + end + if context.cardarea == G.jokers and not context.before and not context.after then + return { + message = localize{type='variable',key='a_mult',vars={card.ability.mult}}, + mult_mod = card.ability.mult + } + end + end, + loc_txt = {} + }) + end, + items = {googol_play_sprite, sync_catalyst_sprite, negative_sprite, canvas_sprite, error_sprite, M_sprite, m_sprite, boredom_sprite, double_scale_sprite, number_blocks_sprite, oldcandy_sprite, caramel_sprite, curse_sprite, googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel, curse}} diff --git a/Items/Items/zAntimatter.lua b/Items/Items/zAntimatter.lua new file mode 100644 index 000000000..1b72ce8e4 --- /dev/null +++ b/Items/Items/zAntimatter.lua @@ -0,0 +1,67 @@ + +local blank = { + object_type = "Back", + name = "cry-Blank", + key = "blank", + pos = {x = 0, y = 0}, + loc_txt = { + name = "Blank Deck", + text = { + "{C:inactive,E:1}Does nothing?" + } + }, + atlas = "blank" +} +local blank_sprite = { + object_type = "Atlas", + key = "blank", + path = "b_cry_blank.png", + px = 71, + py = 95 +} +local antimatter = { + object_type = "Back", + name = "cry-Antimatter", + key = "antimatter", + config = {cry_antimatter = true, + discards = 1, --Red Deck: 1 + hands = 1, --Blue Deck: 1 + dollars = 10, --Yellow Deck + extra_hand_bonus = 2, extra_discard_bonus = 1, --Green Deck + joker_slot = 1, --Black Deck: 1 + vouchers = {'v_crystal_ball', 'v_telescope', 'v_tarot_merchant', 'v_planet_merchant', 'v_overstock_norm', 'v_overstock_plus'}, --Vouchers from all decks + consumables = {'c_fool', 'c_fool', 'c_hex'}, --Consumables from all decks + spectral_rate = 2, --Ghost Deck + remove_faces = true, --Abandoned Deck + hand_size = 2, --Painted Deck + randomize_rank_suit = true, --Erratic Deck + cry_equilibrium = true, --Deck of Equilibrium + cry_misprint_min = 1, cry_misprint_max = 10, --Misprint Deck + cry_highlight_limit = 1e20, --Infinite Deck + -- Enhanced Decks + cry_force_enhancement = 'random', + cry_force_edition = 'random', + cry_force_seal = 'random', + cry_boss_blocked = {"bl_goad", "bl_window", "bl_club", "bl_head"} + }, + pos = {x = 0, y = 0}, + loc_txt = { + name = "Antimatter Deck", + text = { + "Applies the {C:legendary,E:1}upsides{}", + "of {C:attention}every{} deck" + } + }, + atlas = "antimatter" +} +local antimatter_sprite = { + object_type = "Atlas", + key = "antimatter", + path = "b_cry_antimatter.png", + px = 71, + py = 95 +} +return {name = "Antimatter Deck", + init = function() + end, + items = {blank_sprite, antimatter_sprite, blank, antimatter}} \ No newline at end of file diff --git a/Items/Items/zExotic.lua b/Items/Items/zExotic.lua new file mode 100644 index 000000000..08af3c9fc --- /dev/null +++ b/Items/Items/zExotic.lua @@ -0,0 +1,515 @@ +local gateway = { + object_type = "Consumable", + set = "Spectral", + name = "cry-Gateway", + key = "gateway", + pos = {x=0,y=0}, + loc_txt = { + name = 'Gateway', + text = { "Create a random", + "{C:cry_exotic,E:1}Exotic{C:attention} Joker{}, destroy", + 'all other Jokers' } + }, + cost = 4, + atlas = "gateway", + hidden = true, --default soul_set and soul_rate of 0.3% in spectral packs is used + can_use = function(self, card) + return true + end, + use = function(self, card, area, copier) + 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 _first_dissolve = nil + G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.75, func = function() + for k, v in pairs(deletable_jokers) do + v:start_dissolve(nil, _first_dissolve) + _first_dissolve = true + 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_exotic", nil, nil, nil, 'cry_gateway') + card:add_to_deck() + G.jokers:emplace(card) + card:juice_up(0.3, 0.5) + return true end })) + delay(0.6) + end +} +local gateway_sprite = { + object_type = "Atlas", + key = "gateway", + + path = "c_cry_gateway.png", + px = 71, + py = 95 +} +local iterum = { + object_type = "Joker", + name = "cry-Iterum", + key = "iterum", + config = {extra = {x_mult = 2, repetitions = 1}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Iterum', + text = { + "Retrigger all cards played {C:attention}#2#{} time(s),", + "each played card gives", + "{X:mult,C:white} X#1# {} Mult when scored"} + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + blueprint_compat = true, + atlas = 'iterum', + soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.x_mult,center.ability.extra.repetitions}} + end, + calculate = function(self, card, context) + if context.repetition then + if context.cardarea == G.play then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.repetitions, + card = card + } + end + elseif context.individual then + if context.cardarea == G.play then + return { + x_mult = card.ability.extra.x_mult, + colour = G.C.RED, + card = card + } + end + end + end +} +local iterum_sprite = { + object_type = "Atlas", + key = "iterum", + + path = "j_cry_iterum.png", + px = 71, + py = 95 +} +local universum = { + object_type = "Joker", + name = "cry-Universum", + key = "universum", + config = {extra = 2}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Universum', + text = { + "{C:attention}Poker hands{} gain", + "{X:red,C:white} X#1# {} Mult and {X:blue,C:white} X#1# {} Chips", + "when leveled up", + } + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + blueprint_compat = true, + atlas = "universum", + soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra}} + end, + calculate = function(self, card, context) + if context.cry_universum then + return {mod = card.ability.extra} + end + end +} +local universum_sprite = { + object_type = "Atlas", + key = "universum", + + path = "j_cry_universum.png", + px = 71, + py = 95 +} +local exponentia = { + object_type = "Joker", + name = "cry-Exponentia", + key = "exponentia", + config = {extra = {pow_mult = 1.1, pow_mult_mod = 0.01}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Exponentia', + text = { + "This Joker gains {X:dark_edition,C:white} ^#1# {} Mult", + "when {X:red,C:white} XMult {} is triggered", + "{C:inactive}(Currently {X:dark_edition,C:white} ^#2# {C:inactive} Mult)" + } + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = "exponentia", + soul_pos = {x = 2, y = 0, extra = {x = 1, y = 0}}, + calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.pow_mult > 1) and not context.before and not context.after then + return { + message = "^"..card.ability.extra.pow_mult.." Mult", + pow_mult_mod = card.ability.extra.pow_mult, + colour = G.C.MULT + } + end + end, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.pow_mult_mod, center.ability.extra.pow_mult}} + end +} +local exponentia_sprite = { + object_type = "Atlas", + key = "exponentia", + path = "j_cry_exponentia.png", + px = 71, + py = 95 +} +local speculo = { + object_type = "Joker", + name = "cry-Speculo", + key = "speculo", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Speculo', + text = { + "Creates a {C:dark_edition}Negative{} copy", + "of a random {C:attention}Joker{}", + "at the end of the {C:attention}shop", + } + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + blueprint_compat = true, + atlas = "speculo", + soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, + calculate = function(self, card, context) + if context.ending_shop then + local eligibleJokers = {} + for i = 1, #G.jokers.cards do + if G.jokers.cards[i].ability.name ~= card.ability.name then eligibleJokers[#eligibleJokers+1] = G.jokers.cards[i] end + end + if #eligibleJokers > 0 then + G.E_MANAGER:add_event(Event({ + func = function() + local card = copy_card(pseudorandom_element(eligibleJokers, pseudoseed('cry_speculo')), nil) + card:set_edition({negative = true}, true) + card:add_to_deck() + G.jokers:emplace(card) + return true + end})) + card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_duplicated_ex')}) + return {calculated = true} + end + return + end + end +} +local speculo_sprite = { + object_type = "Atlas", + key = "speculo", + path = "j_cry_speculo.png", + px = 71, + py = 95 +} +local redeo = { + object_type = "Joker", + name = "cry-Redeo", + key = "redeo", + config = {extra = {ante_reduction = 1, money_req = 10, money_remaining = 0, money_mod = 10}}, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.ante_reduction, center.ability.extra.money_req, center.ability.extra.money_remaining, center.ability.extra.money_mod}} + end, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Redeo', + text = { + "{C:attention}-#1#{} Ante when", + "{C:money}$#2#{} {C:inactive}($#3#){} spent", + "{C:inactive,s:0.8}Requirements increase by", + "{C:money,s:0.8}$#4#{C:inactive,s:0.8} after each use" + } + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + atlas = "redeo", + soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, + calculate = function(self, card, context) + if context.cry_ease_dollars and context.cry_ease_dollars < 0 and not context.blueprint then + card.ability.extra.money_remaining = card.ability.extra.money_remaining - context.cry_ease_dollars + local ante_mod = 0 + while card.ability.extra.money_remaining >= card.ability.extra.money_req do + card.ability.extra.money_remaining = card.ability.extra.money_remaining - card.ability.extra.money_req + card.ability.extra.money_req = card.ability.extra.money_req + card.ability.extra.money_mod + ante_mod = ante_mod - card.ability.extra.ante_reduction + end + if ante_mod < 0 then + ease_ante(ante_mod) + end + return {calculated = true} + end + end +} +local redeo_sprite = { + object_type = "Atlas", + key = "redeo", + path = "j_cry_redeo.png", + px = 71, + py = 95 +} + +local tenebris = { + object_type = "Joker", + name = "cry-Tenebris", + key = "tenebris", + pos = {x = 0, y = 0}, + soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, + config = {extra = {slots = 25, money = 25}}, + loc_txt = { + name = 'Tenebris', + text = { + "{C:dark_edition}+#1#{C:attention} Joker{} slots", + "Earn {C:money}$#2#{} at end of round" + } + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + atlas = "tenebris", + calc_dollar_bonus = function(self, card) + return card.ability.extra.money + end, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.slots, center.ability.extra.money}} + end, + add_to_deck = function(self, card, from_debuff) + G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra.slots + end, + remove_from_deck = function(self, card, from_debuff) + G.jokers.config.card_limit = G.jokers.config.card_limit - card.ability.extra.slots + end +} + +local tenebris_sprite = { + object_type = "Atlas", + key = "tenebris", + path = "j_cry_tenebris.png", + px = 71, + py = 95 +} + +local effarcire = { + object_type = "Joker", + name = "cry-Effarcire", + key = "effarcire", + config = {}, + pos = {x = 0, y = 0}, + soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, + loc_txt = { + name = 'Effarcire', + text = { + "Always draw {C:green}full deck{} to hand", + "when {C:attention}Blind{} is selected" + } + }, + rarity = 3, + cost = 50, + discovered = true, + atlas = 'effarcire', + rarity = "cry_exotic", + calculate = function(self, card, context) + if not context.blueprint then + if context.first_hand_drawn then + G.FUNCS.draw_from_deck_to_hand(#G.deck.cards) + elseif G.hand.config.card_limit < 1 then + G.hand.config.card_limit = 1 + end + end + end +} + +local effarcire_sprite = { + object_type = "Atlas", + key = "effarcire", + path = "j_cry_effarcire.png", + px = 71, + py = 95 +} +local crustulum = { + object_type = "Joker", + name = "cry-crustulum", + key = "crustulum", + config = {extra = {chips = 0, chip_mod = 4,}}, + pos = {x = 0, y = 0}, + soul_pos = {x = 2, y = 0, extra = {x = 1, y = 0}}, + loc_txt = { + name = 'Crustulum', + text = { + "This Joker gains {C:chips}+#2#{} Chips", + "per {C:attention}reroll{} in the shop,", + "{C:green}all rerolls are free{}", + "{C:inactive}(Currently {C:chips}+#1#{C:inactive} chips)" + } + }, + rarity = "cry_exotic", + cost = 50, + discovered = true, + atlas = "crustulum", + blueprint_compat = true, + perishable_compat = false, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.chips, center.ability.extra.chip_mod}} + end, + calculate = function(self, card, context) --Warning, implementation is extremely scuffed ;-; + if context.reroll_shop and not context.blueprint then + card.ability.extra.chips = (card.ability.extra.chips) + card.ability.extra.chip_mod + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}, colour = G.C.CHIPS}) + G.GAME.current_round.free_rerolls = 1 + calculate_reroll_cost(true) + return {calculated = true} + end + if context.end_of_round then + G.GAME.current_round.free_rerolls = 1 + calculate_reroll_cost(true) + end + if context.cardarea == G.jokers and (card.ability.extra.chips) > 0 and not context.before and not context.after then + return { + message = localize{type='variable', key='a_chips', vars={card.ability.extra.chips}}, + chip_mod = card.ability.extra.chips + } + end + end, + add_to_deck = function(self, card, from_debuff) + G.GAME.current_round.free_rerolls = 1 + calculate_reroll_cost(true) + end +} +local crustulum_sprite = { + object_type = "Atlas", + key = "crustulum", + path = "j_cry_crustulum.png", + px = 71, + py = 95 +} + + +G.P_JOKER_RARITY_POOLS["cry_exotic"] = {iterum, universum, exponentia, speculo, redeo, tenebris, effarcire, crustulum} + +return {name = "Exotic Jokers", + init = function() + --Universum Patches + local uht = update_hand_text + function update_hand_text(config, vals) + if next(find_joker("cry-Universum")) then + G.E_MANAGER:add_event(Event({--This is the Hand name text for the poker hand + trigger = 'before', + blockable = not config.immediate, + delay = config.delay or 0.8, + func = function() + local col = G.C.GREEN + if vals.chips and G.GAME.current_round.current_hand.chips ~= vals.chips then + local delta = vals.chips + if is_number(vals.chips) and is_number(G.GAME.current_round.current_hand.chips) then delta = 'X'..number_format(vals.chips / G.GAME.current_round.current_hand.chips) end + G.GAME.current_round.current_hand.chips = vals.chips + G.hand_text_area.chips:update(0) + if vals.StatusText then + attention_text({ + text = delta, + scale = 0.8, + hold = 1, + cover = G.hand_text_area.chips.parent, + cover_colour = mix_colours(G.C.CHIPS, col, 0.1), + emboss = 0.05, + align = 'cm', + cover_align = 'cr' + }) + end + end + if vals.mult and G.GAME.current_round.current_hand.mult ~= vals.mult then + local delta = vals.mult + if is_number(vals.mult) and is_number(G.GAME.current_round.current_hand.mult) then delta = 'X'..number_format(vals.mult / G.GAME.current_round.current_hand.mult) end + G.GAME.current_round.current_hand.mult = vals.mult + G.hand_text_area.mult:update(0) + if vals.StatusText then + attention_text({ + text = delta, + scale = 0.8, + hold = 1, + cover = G.hand_text_area.mult.parent, + cover_colour = mix_colours(G.C.MULT, col, 0.1), + emboss = 0.05, + align = 'cm', + cover_align = 'cl' + }) + end + if not G.TAROT_INTERRUPT then G.hand_text_area.mult:juice_up() end + end + if vals.handname and G.GAME.current_round.current_hand.handname ~= vals.handname then + G.GAME.current_round.current_hand.handname = vals.handname + if not config.nopulse then + G.hand_text_area.handname.config.object:pulse(0.2) + end + end + if vals.chip_total then G.GAME.current_round.current_hand.chip_total = vals.chip_total;G.hand_text_area.chip_total.config.object:pulse(0.5) end + if vals.level and G.GAME.current_round.current_hand.hand_level ~= ' '..localize('k_lvl')..tostring(vals.level) then + if vals.level == '' then + G.GAME.current_round.current_hand.hand_level = vals.level + else + G.GAME.current_round.current_hand.hand_level = ' '..localize('k_lvl')..tostring(vals.level) + if is_number(vals.level) then + G.hand_text_area.hand_level.config.colour = G.C.HAND_LEVELS[math.min(vals.level, 7)] + else + G.hand_text_area.hand_level.config.colour = G.C.HAND_LEVELS[1] + end + G.hand_text_area.hand_level:juice_up() + end + end + if config.sound and not config.modded then play_sound(config.sound, config.pitch or 1, config.volume or 1) end + if config.modded then + G.HUD_blind:get_UIE_by_ID('HUD_blind_debuff_1'):juice_up(0.3, 0) + G.HUD_blind:get_UIE_by_ID('HUD_blind_debuff_2'):juice_up(0.3, 0) + G.GAME.blind:juice_up() + G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.06*G.SETTINGS.GAMESPEED, blockable = false, blocking = false, func = function() + play_sound('tarot2', 0.76, 0.4);return true end})) + play_sound('tarot2', 1, 0.4) + end + return true + end})) + else + uht(config, vals) + end + end + + --Redeo Patches + local ed = ease_dollars + function ease_dollars(mod, x) + ed(mod,x) + for i = 1, #G.jokers.cards do + local effects = G.jokers.cards[i]:calculate_joker({cry_ease_dollars = mod}) + if effects and effects.joker_repetitions then + rep_list = effects.joker_repetitions + for z=1, #rep_list do + if type(rep_list[z]) == 'table' and rep_list[z].repetitions then + for r=1, rep_list[z].repetitions do + card_eval_status_text(rep_list[z].card, 'jokers', nil, nil, nil, rep_list[z]) + if percent then percent = percent+percent_delta end + G.jokers.cards[i]:calculate_joker({cry_ease_dollars = mod, retrigger_joker = true}) + end + end + end + end + end + end + end, + items = {gateway_sprite, iterum_sprite, universum_sprite, exponentia_sprite, speculo_sprite, redeo_sprite, tenebris_sprite, effarcire_sprite, crustulum_sprite, gateway, iterum, universum, exponentia, speculo, redeo, tenebris, effarcire, crustulum,}} diff --git a/Items/Items/zzChallenges.lua b/Items/Items/zzChallenges.lua new file mode 100644 index 000000000..bf725bc33 --- /dev/null +++ b/Items/Items/zzChallenges.lua @@ -0,0 +1,71 @@ +local sticker_sheet = { + object_type = "Challenge", + key = "sticker_sheet", + rules = { + custom = { + {id = 'all_eternal'}, + {id = 'cry_all_perishable'}, + {id = 'cry_all_rental'}, + {id = 'cry_all_pinned'}, + {id = 'cry_eternal_perishable_compat'}, + {id = 'cry_any_stickers'}, + {id = 'cry_sticker_sheet'}, + }, + modifiers = {} + }, + restrictions = { + banned_cards = {}, + banned_other = {} + }, + loc_txt = "Sticker Sheet" +} +local ballin = { + object_type = "Challenge", + key = "ballin", + rules = { + custom = {}, + modifiers = { + {id = 'joker_slots', value = 3} + } + }, + jokers = { + {id = 'j_cry_jimball',eternal=true} + }, + deck = {enhancement = 'm_stone'}, + loc_txt = "Ballin'" +} +local rush_hour = { + object_type = "Challenge", + key = "rush_hour", + loc_txt = "Rush Hour", + rules = { + custom = { + {id = 'cry_rush_hour'} --this just explains the rule + }, + modifiers = {} + }, + restrictions = { + banned_cards = { + {id = 'j_luchador'}, + {id = 'j_chicot'} + }, + banned_other = {} + } +} + +local challenges = {sticker_sheet} +if Cryptid_config["Misc. Jokers"] then challenges[#challenges+1] = ballin end +if Cryptid_config["Blinds"] then challenges[#challenges+1] = rush_hour end + +for k, v in pairs(G.P_CENTERS) do + if v.set == "Joker" then + if not v.perishable_compat or not v.eternal_compat then + sticker_sheet.restrictions.banned_cards[#sticker_sheet.restrictions.banned_cards+1] = {id = k} + end + end +end + +return {name = "Challenges", + init = function() + end, + items = challenges} \ No newline at end of file From 2384485036da165c2631f1872f8415d71a41f2f8 Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:34:09 -0700 Subject: [PATCH 2/7] Delete Items/Items directory --- Items/Items/Blinds.lua | 755 ------------- Items/Items/Decks.lua | 293 ----- Items/Items/Enhanced.lua | 535 --------- Items/Items/MiscJokers.lua | 1973 ---------------------------------- Items/Items/Planets.lua | 142 --- Items/Items/Spectrals.lua | 272 ----- Items/Items/Stakes.lua | 672 ------------ Items/Items/yEpicJokers.lua | 1026 ------------------ Items/Items/zAntimatter.lua | 67 -- Items/Items/zExotic.lua | 515 --------- Items/Items/zzChallenges.lua | 71 -- 11 files changed, 6321 deletions(-) delete mode 100644 Items/Items/Blinds.lua delete mode 100644 Items/Items/Decks.lua delete mode 100644 Items/Items/Enhanced.lua delete mode 100644 Items/Items/MiscJokers.lua delete mode 100644 Items/Items/Planets.lua delete mode 100644 Items/Items/Spectrals.lua delete mode 100644 Items/Items/Stakes.lua delete mode 100644 Items/Items/yEpicJokers.lua delete mode 100644 Items/Items/zAntimatter.lua delete mode 100644 Items/Items/zExotic.lua delete mode 100644 Items/Items/zzChallenges.lua diff --git a/Items/Items/Blinds.lua b/Items/Items/Blinds.lua deleted file mode 100644 index 84cc09a35..000000000 --- a/Items/Items/Blinds.lua +++ /dev/null @@ -1,755 +0,0 @@ ---extra blind functions for use by bosses -function Blind:cry_ante_base_mod(dt) - if not self.disabled then - local obj = self.config.blind - if obj.cry_ante_base_mod and type(obj.cry_ante_base_mod) == 'function' then - return obj:cry_ante_base_mod(self, dt) - end - end - return 0 -end -function Blind:cry_round_base_mod(dt) - if not self.disabled then - local obj = self.config.blind - if obj.cry_round_base_mod and type(obj.cry_round_base_mod) == 'function' then - return obj:cry_round_base_mod(self, dt) - end - end - return 1 -end -function Blind:cry_cap_score(score) - if not self.disabled then - local obj = self.config.blind - if obj.cry_cap_score and type(obj.cry_cap_score) == 'function' then - return obj:cry_cap_score(self, score) - end - end - return score -end -function Blind:cry_after_play() - if not self.disabled then - local obj = self.config.blind - if obj.cry_after_play and type(obj.cry_after_play) == 'function' then - return obj:cry_after_play(self) - end - end -end -function Blind:cry_before_play() - if not self.disabled then - local obj = self.config.blind - if obj.cry_before_play and type(obj.cry_before_play) == 'function' then - return obj:cry_before_play(self) - end - end -end - -local tax = { - object_type = "Blind", - name = "cry-Tax", - key = "tax", - pos = {x = 0, y = 0}, - boss = { - min = 1, - max = 10 - }, - loc_txt = { - name = 'The Tax', - text = { - "Score per hand capped at", - "0.4X blind requirements" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('40ff40'), - cry_cap_score = function(self, blind, score) - return math.floor(math.min(0.4*blind.chips,score)+0.5) - end -} - -local clock = { - object_type = "Blind", - name = "cry-Clock", - key = "clock", - pos = {x = 0, y = 1}, - mult = 0, - boss = { - min = 1, - max = 10 - }, - loc_txt = { - name = 'The Clock', - text = { - "+0.1X blind requirements every", - "3 seconds spent this ante" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('853455'), - defeat = function(self, blind, silent) - G.P_BLINDS.bl_cry_clock.mult = 0 - end, - disable = function(self, blind, silent) - G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling*2 - G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) - end, - cry_ante_base_mod = function(self, blind, dt) - return 0.1*dt/3 - end -} -local trick = { - object_type = "Blind", - name = "cry-Trick", - key = "trick", - pos = {x = 0, y = 3}, - boss = { - min = 1, - max = 10 - }, - loc_txt = { - name = 'The Trick', - text = { - "After each hand, flip all", - "face-up cards held in hand" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('babd24'), - cry_after_play = function(self, blind) - --flip and shuffle all cards held in hand - for k, v in ipairs(G.hand.cards) do - if v.facing == "front" then - v:flip() - end - end - --[[if #G.hand.cards > 1 then - G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 0.2, func = function() - G.E_MANAGER:add_event(Event({ func = function() G.hand:shuffle('cry_trick'); play_sound('cardSlide1', 0.85);return true end })) - delay(0.15) - G.E_MANAGER:add_event(Event({ func = function() G.hand:shuffle('cry_trick'); play_sound('cardSlide1', 1.15);return true end })) - delay(0.15) - G.E_MANAGER:add_event(Event({ func = function() G.hand:shuffle('cry_trick'); play_sound('cardSlide1', 1);return true end })) - delay(0.5) - return true end })) - end--]] - end -} - -local joke = { - object_type = "Blind", - name = "cry-Joke", - key = "joke", - pos = {x = 0, y = 4}, - boss = { - min = 1, - max = 10 - }, - loc_txt = { - name = 'The Joke', - text = { - "If score is >2X requirements,", - "set ante to multiple of 8" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('00ffaa') -} -local lavender_loop = { - object_type = "Blind", - name = "cry-Lavender Loop", - key = "lavender_loop", - pos = {x = 0, y = 2}, - mult = 1, - dollars = 8, - boss = { - min = 3, - max = 10, - showdown = true - }, - loc_txt = { - name = 'Lavender Loop', - text = { - "1.25X blind requirements every", - "1.5 seconds spent this round" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('ae00ff'), - disable = function(self, blind, silent) - G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling*2 - G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) - end, - cry_round_base_mod = function(self, blind, dt) - return 1.25^(dt/1.5) - end -} -local vermillion_virus = { - object_type = "Blind", - name = "cry-Vermillion Virus", - key = "vermillion_virus", - pos = {x = 0, y = 5}, - dollars = 8, - boss = { - min = 3, - max = 10, - showdown = true - }, - loc_txt = { - name = 'Vermillion Virus', - text = { - "One random Joker", - "replaced every hand" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('f65d34'), - cry_before_play = function(self, blind) - if G.jokers.cards[1] then - local idx = pseudorandom(pseudoseed('cry_vermillion_virus'),1,#G.jokers.cards) - if G.jokers.cards[idx] then - _card = create_card('Joker', G.jokers, nil, nil, nil, nil, nil, 'cry_vermillion_virus_gen') - G.jokers.cards[idx]:remove_from_deck() - _card:add_to_deck() - _card:start_materialize() - G.jokers.cards[idx] = _card - _card:set_card_area(G.jokers) - G.jokers:set_ranks() - G.jokers:align_cards() - end - end - end -} - -local sapphire_stamp = { - object_type = "Blind", - name = "cry-Sapphire Stamp", - key = "sapphire_stamp", - pos = {x = 0, y = 6}, - dollars = 8, - boss = { - min = 3, - max = 10, - showdown = true - }, - loc_txt = { - name = 'Sapphire Stamp', - text = { - "Select an extra card, deselect", - "random card before scoring" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('4057d6'), - cry_before_play = function(self, blind) - local idx = pseudorandom(pseudoseed("cry_sapphire_stamp"), 1, #G.hand.highlighted) - G.hand:remove_from_highlighted(G.hand.highlighted[idx]) - end, - set_blind = function(self, blind, reset, silent) - if not reset then - G.hand.config.highlighted_limit = G.hand.config.highlighted_limit + 1 - end - end, - defeat = function(self, blind, silent) - if not self.disabled then - G.hand.config.highlighted_limit = G.hand.config.highlighted_limit - 1 - end - end, - disable = function(self, blind, silent) - G.hand.config.highlighted_limit = G.hand.config.highlighted_limit - 1 - end, -} - -local obsidian_orb = { - object_type = "Blind", - name = "cry-Obsidian Orb", - key = "obsidian_orb", - pos = {x = 0, y = 7}, - dollars = 8, - boss = { - min = 3, - max = 10, - showdown = true - }, - loc_txt = { - name = 'Obsidian Orb', - text = { - "Applies abilities of", - "all defeated bosses" - } - }, - atlas = "blinds", - discovered = true, - boss_colour = HEX('290759'), - set_blind = function(self, blind, reset, silent) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.set_blind then s:set_blind(blind,reset,silent) end - if s.name == 'The Eye' and not reset then - blind.hands = { - ["Flush Five"] = false, - ["Flush House"] = false, - ["Five of a Kind"] = false, - ["Straight Flush"] = false, - ["Four of a Kind"] = false, - ["Full House"] = false, - ["Flush"] = false, - ["Straight"] = false, - ["Three of a Kind"] = false, - ["Two Pair"] = false, - ["Pair"] = false, - ["High Card"] = false, - } - end - if s.name == 'The Mouth' and not reset then - blind.only_hand = false - end - if s.name == 'The Fish' and not reset then - blind.prepped = nil - end - if s.name == 'The Water' and not reset then - blind.discards_sub = G.GAME.current_round.discards_left - ease_discard(-blind.discards_sub) - end - if s.name == 'The Needle' and not reset then - blind.hands_sub = G.GAME.round_resets.hands - 1 - ease_hands_played(-blind.hands_sub) - end - if s.name == 'The Manacle' and not reset then - G.hand:change_size(-1) - end - if s.name == 'Amber Acorn' and not reset and #G.jokers.cards > 0 then - G.jokers:unhighlight_all() - for k, v in ipairs(G.jokers.cards) do - v:flip() - end - if #G.jokers.cards > 1 then - G.E_MANAGER:add_event(Event({ trigger = 'after', delay = 0.2, func = function() - G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 0.85);return true end })) - delay(0.15) - G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 1.15);return true end })) - delay(0.15) - G.E_MANAGER:add_event(Event({ func = function() G.jokers:shuffle('aajk'); play_sound('cardSlide1', 1);return true end })) - delay(0.5) - return true end })) - end - end - - --add new debuffs - for _, v in ipairs(G.playing_cards) do - self:debuff_card(v) - end - for _, v in ipairs(G.jokers.cards) do - if not reset then self:debuff_card(v, true) end - end - end - end, - defeat = function(self, blind, silent) - for k, _ in pairs(G.GAME.defeated_blinds) do - if G.P_BLINDS[k].defeat then G.P_BLINDS[k]:defeat(blind, silent) end - if G.P_BLINDS[k].name == "The Manacle" and not self.disabled then - G.hand:change_size(1) - end - end - end, - disable = function(self, blind, silent) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.disable then s:disable(blind, silent) end - if s.name == 'The Water' then - ease_discard(blind.discards_sub) - end - if s.name == 'The Wheel' or s.name == 'The House' or s.name == 'The Mark' or s.name == 'The Fish' then - for i = 1, #G.hand.cards do - if G.hand.cards[i].facing == 'back' then - G.hand.cards[i]:flip() - end - end - for k, v in pairs(G.playing_cards) do - v.ability.wheel_flipped = nil - end - end - if s.name == 'The Needle' then - ease_hands_played(blind.hands_sub) - end - if s.name == 'The Wall' then - blind.chips = blind.chips/2 - blind.chip_text = number_format(blind.chips) - end - if s.name == 'Cerulean Bell' then - for k, v in ipairs(G.playing_cards) do - v.ability.forced_selection = nil - end - end - if s.name == 'The Manacle' then - G.hand:change_size(1) - - G.FUNCS.draw_from_deck_to_hand(1) - end - if s.name == 'Violet Vessel' then - blind.chips = blind.chips/3 - blind.chip_text = number_format(blind.chips) - end - end - end, - press_play = function(self, blind) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.press_play then s:press_play(blind) end - if s.name == "The Hook" then - G.E_MANAGER:add_event(Event({ func = function() - local any_selected = nil - local _cards = {} - for k, v in ipairs(G.hand.cards) do - _cards[#_cards+1] = v - end - for i = 1, 2 do - if G.hand.cards[i] then - local selected_card, card_key = pseudorandom_element(_cards, pseudoseed('hook')) - G.hand:add_to_highlighted(selected_card, true) - table.remove(_cards, card_key) - any_selected = true - play_sound('card1', 1) - end - end - if any_selected then G.FUNCS.discard_cards_from_highlighted(nil, true) end - return true end })) - blind.triggered = true - delay(0.7) - end - if s.name == 'Crimson Heart' then - if G.jokers.cards[1] then - blind.triggered = true - blind.prepped = true - end - end - if s.name == 'The Fish' then - blind.prepped = true - end - if s.name == "The Tooth" then - G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2, func = function() - for i = 1, #G.play.cards do - G.E_MANAGER:add_event(Event({func = function() G.play.cards[i]:juice_up(); return true end })) - ease_dollars(-1) - delay(0.23) - end - return true end })) - blind.triggered = true - end - end - end, - modify_hand = function(self, blind, cards, poker_hands, text, mult, hand_chips) - local new_mult = mult - local new_chips = chips - local trigger = false - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.modify_hand then - local this_trigger = false - new_mult, new_chips, this_trigger = s:modify_hand(blind, cards, poker_hands, text, new_mult, new_chips) - trigger = trigger or this_trigger - end - if s.name == "The Flint" then - blind.triggered = true - new_mult = math.max(math.floor(new_mult*0.5 + 0.5), 1) - new_chips = math.max(math.floor(new_chips*0.5 + 0.5), 0) - trigger = true - end - end - return new_mult or mult, new_chips or hand_chips, trigger - end, - debuff_hand = function(self, blind, cards, hand, handname, check) - blind.debuff_boss = nil - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.debuff_hand and s:debuff_hand(blind, cards, hand, handname, check) then - blind.debuff_boss = s - return true - end - if s.debuff then - blind.triggered = false - if s.debuff.hand and next(hand[s.debuff.hand]) then - blind.triggered = true - blind.debuff_boss = s - return true - end - if s.debuff.h_size_ge and #cards < s.debuff.h_size_ge then - blind.triggered = true - blind.debuff_boss = s - return true - end - if s.debuff.h_size_le and #cards > s.debuff.h_size_le then - blind.triggered = true - blind.debuff_boss = s - return true - end - if s.name == "The Eye" then - if blind.hands[handname] then - blind.triggered = true - blind.debuff_boss = s - return true - end - if not check then blind.hands[handname] = true end - end - if s.name == "The Mouth" then - if s.only_hand and s.only_hand ~= handname then - blind.triggered = true - blind.debuff_boss = s - return true - end - if not check then s.only_hand = handname end - end - end - if s.name == 'The Arm' then - blind.triggered = false - if G.GAME.hands[handname].level > 1 then - blind.triggered = true - if not check then - level_up_hand(self.children.animatedSprite, handname, nil, -1) - blind:wiggle() - end - end - end - if s.name == 'The Ox' then - blind.triggered = false - if handname == G.GAME.current_round.most_played_poker_hand then - blind.triggered = true - if not check then - ease_dollars(-G.GAME.dollars, true) - blind:wiggle() - end - end - end - end - return false - end, - drawn_to_hand = function(self, blind) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.drawn_to_hand then s:drawn_to_hand(blind) end - if s.name == 'Cerulean Bell' then - local any_forced = nil - for k, v in ipairs(G.hand.cards) do - if v.ability.forced_selection then - any_forced = true - end - end - if not any_forced then - G.hand:unhighlight_all() - local forced_card = pseudorandom_element(G.hand.cards, pseudoseed('cerulean_bell')) - forced_card.ability.forced_selection = true - G.hand:add_to_highlighted(forced_card) - end - end - if s.name == 'Crimson Heart' and blind.prepped and G.jokers.cards[1] then - local jokers = {} - for i = 1, #G.jokers.cards do - if not G.jokers.cards[i].debuff or #G.jokers.cards < 2 then jokers[#jokers+1] =G.jokers.cards[i] end - G.jokers.cards[i]:set_debuff(false) - end - local _card = pseudorandom_element(jokers, pseudoseed('crimson_heart')) - if _card then - _card:set_debuff(true) - _card:juice_up() - self:wiggle() - end - end - end - end, - stay_flipped = function(self, blind, area, card) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.stay_flipped and s:stay_flipped(blind, area, card) then return true end - if area == G.hand then - if s.name == 'The Wheel' and pseudorandom(pseudoseed('wheel')) < G.GAME.probabilities.normal/7 then - return true - end - if s.name == 'The House' and G.GAME.current_round.hands_played == 0 and G.GAME.current_round.discards_used == 0 then - return true - end - if s.name == 'The Mark' and card:is_face(true) then - return true - end - if s.name == 'The Fish' and blind.prepped then - return true - end - end - end - end, - debuff_card = function(self, blind, card, from_blind) - if card and type(card) == 'table' and card.area then - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.debuff_card then s:debuff_card(blind, card, from_blind) end - if s.debuff and not G.GAME.blind.disabled and card.area ~= G.jokers then - --this part is buggy for some reason - if s.debuff.suit and Card.is_suit(card, s.debuff.suit, true) then - card:set_debuff(true) - return - end - if s.debuff.is_face =='face' and Card.is_face(card, true) then - card:set_debuff(true) - return - end - if s.name == 'The Pillar' and card.ability.played_this_ante then - card:set_debuff(true) - return - end - if s.debuff.value and s.debuff.value == card.base.value then - card:set_debuff(true) - return - end - if s.debuff.nominal and s.debuff.nominal == card.base.nominal then - card:set_debuff(true) - return - end - end - if s.name == 'Crimson Heart' and not G.GAME.blind.disabled and card.area == G.jokers then - return - end - if s.name == 'Verdant Leaf' and not G.GAME.blind.disabled and card.area ~= G.jokers then card:set_debuff(true); return end - end - end - end, - cry_ante_base_mod = function(self, blind, dt) - local mod = 0 - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.cry_ante_base_mod then - mod = mod + s:cry_ante_base_mod(blind, dt) - end - end - return mod - end, - cry_round_base_mod = function(self, blind, dt) - local mod = 1 - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.cry_round_base_mod then - mod = mod * s:cry_round_base_mod(blind, dt) - end - end - return mod - end, - cry_cap_score = function(self, blind, score) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.cry_cap_score then - score = s:cry_cap_score(blind, score) - end - end - return score - end, - cry_before_play = function(self, blind) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.cry_before_play then s:cry_before_play(blind) end - end - end, - cry_after_play = function(self, blind) - for k, _ in pairs(G.GAME.defeated_blinds) do - s = G.P_BLINDS[k] - if s.cry_after_play then s:cry_after_play(blind) end - end - end, - get_loc_debuff_text = function(self, blind) - if not blind.debuff_boss then return "Applies abilities of all defeated bosses" end - local loc_vars = nil - if blind.debuff_boss.name == 'The Ox' then - loc_vars = {localize(G.GAME.current_round.most_played_poker_hand, 'poker_hands')} - end - local loc_target = localize{type = 'raw_descriptions', key = blind.debuff_boss.key, set = 'Blind', vars = loc_vars} - local loc_debuff_text = '' - for k, v in ipairs(loc_target) do - loc_debuff_text = loc_debuff_text..v..(k <= #loc_target and ' ' or '') - end - local disp_text = (blind.debuff_boss.name == 'The Wheel' and G.GAME.probabilities.normal or '')..loc_debuff_text - if (blind.debuff_boss.name == 'The Mouth') and blind.only_hand then disp_text = disp_text..' ['..localize(blind.only_hand, 'poker_hands')..']' end - return disp_text - end -} - -local blind_sprites = { - object_type = "Atlas", - key = "blinds", - atlas_table = "ANIMATION_ATLAS", - path = "bl_cry.png", - px = 34, - py = 34, - frames = 21 -} - -return {name = "Blinds", - init = function() - --Clock Patches - local upd = Game.update - function Game:update(dt) - upd(self,dt) - if G.GAME and G.GAME.round_resets and G.GAME.round_resets.blind_choices and G.GAME.round_resets.blind_choices.Boss and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].cry_ante_base_mod then - if G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult ~= 0 and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult_ante ~= G.GAME.round_resets.ante then - if G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].name == "cry-Obsidian Orb" then - for i = 1, #G.GAME.defeated_blinds do - G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult * G.P_BLINDS[G.GAME.defeated_blinds[i]]/2 - end - else - G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = 0 - end - G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult_ante = G.GAME.round_resets.ante - end - if G.GAME.round_resets.blind_states.Boss ~= "Current" then - G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult + (G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].cry_ante_base_mod and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss]:cry_ante_base_mod(nil, dt) or 0) - --Update UI - if G.blind_select_opts then - local blind_UI = G.blind_select_opts.boss.definition.nodes[1].nodes[1].nodes[1].nodes[1] - local chip_text_node = blind_UI.nodes[1].nodes[3].nodes[1].nodes[2].nodes[2].nodes[3] - chip_text_node.config.text = number_format(get_blind_amount(G.GAME.round_resets.blind_ante)*G.GAME.starting_params.ante_scaling*G.P_BLINDS.bl_cry_clock.mult) - chip_text_node.config.scale = score_number_scale(0.9, get_blind_amount(G.GAME.round_resets.blind_ante)*G.GAME.starting_params.ante_scaling*G.P_BLINDS.bl_cry_clock.mult) - G.blind_select_opts.boss:recalculate() - end - elseif not G.GAME.blind.disabled and to_big(G.GAME.chips) < to_big(G.GAME.blind.chips) then - G.GAME.blind.chips = G.GAME.blind.chips + G.GAME.blind:cry_ante_base_mod(dt)*get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling - G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) - end - end - if G.GAME and G.GAME.blind and not G.GAME.blind.disabled and to_big(G.GAME.chips) < to_big(G.GAME.blind.chips) then - G.GAME.blind.chips = G.GAME.blind.chips * G.GAME.blind:cry_round_base_mod(dt) - G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) - end - end - --Trick Patches - local gfep = G.FUNCS.evaluate_play - function G.FUNCS.evaluate_play(e) - gfep(e) - G.GAME.blind:cry_after_play() - end - --Sapphire Stamp Patches - local pcfh = G.FUNCS.play_cards_from_highlighted - function G.FUNCS.play_cards_from_highlighted(e) - G.GAME.blind:cry_before_play() - pcfh(e) - end - --Obsidian Orb Patches - local dft = Blind.defeat - function Blind:defeat(s) - dft(self, s) - if self.name ~= "cry-Obsidian Orb" and - (self.name ~= "The Eye" or not G.GAME.defeated_blinds["bl_mouth"]) and - (self.name ~= "The Mouth" or not G.GAME.defeated_blinds["bl_eye"]) and - (self.name ~= "The Needle" or not G.GAME.defeated_blinds["bl_cry_tax"]) and - (self.name ~= "cry-Tax" or not G.GAME.defeated_blinds["bl_needle"]) - then - G.GAME.defeated_blinds[self.config.blind.key] = true - end - end - local sr = Game.start_run - function Game:start_run(args) - sr(self, args) - if not G.GAME.defeated_blinds then G.GAME.defeated_blinds = {} end - end - end, - items = {tax, clock, trick, joke, lavender_loop, vermillion_virus, sapphire_stamp, obsidian_orb, blind_sprites}} \ No newline at end of file diff --git a/Items/Items/Decks.lua b/Items/Items/Decks.lua deleted file mode 100644 index 3fd8348da..000000000 --- a/Items/Items/Decks.lua +++ /dev/null @@ -1,293 +0,0 @@ -local very_fair = { - object_type = "Back", - name = "Very Fair Deck", - key = "very_fair", - config = {hands = -2, discards = -2, cry_no_vouchers = true}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Very Fair Deck", - text = { - "{C:blue}-2{} hands, {C:red}-2{} discards", - "every round", - "{C:attention}Vouchers{} no longer", - "appear in the shop" - } - }, - --[[loc_vars = function(self, info_queue, center) - return {vars = {center.effect.config.hands, center.effect.config.discards}} - end,--]] --this doesn't work, will fix later - atlas = "very_fair" -} - --- Thanks to many members of the community for contributing to all of these quips! --- There's too many to credit so just go here: https://discord.com/channels/1116389027176787968/1209506360987877408/1237971471146553406 --- And here: https://discord.com/channels/1116389027176787968/1219749193204371456/1240468252325318667 -very_fair_quips = { - {"L", "NO VOUCHERS", "FOR YOU"}, - {"BOZO", "DID YOU THINK I WOULD", "GIVE YOU A VOUCHER?"}, - {"NOPE!", "NO VOUCHERS HERE!", "(SLUMPAGE EDITION)"}, - {"SKILL ISSUE", "IMAGINE BEING GOOD ENOUGH", "FOR A VOUCHER"}, - {"JIMBO", "FROM MANAGEMENT", "FORGOT TO RESTOCK"}, - {"OOPS!", "NO VOUCHERS", ""}, - {"YOU JOKER,", "WHY ARE YOU LOOKING", "OVER HERE? LOL"}, - {"THE VOUCHER", "IS IN", "ANOTHER CASTLE"}, - {"$0", "BLANK VOUCHER", "(GET IT?)"}, - {"ERROR", "CANNOT DO ARITHMETIC ON A NIL VALUE", "(tier4vouchers.lua)"}, - {"100% OFF", "ON ALL VOUCHERS", "(SOMEONE ALREADY BOUGHT THEM)"}, - {"TRY AGAIN LATER", "HINT: YOU WON'T HAVE", "ENOUGH MONEY ANYWAYS"}, - {"HUH?", "\"VOUCHER\"?", "THAT'S NOT EVEN A WORD..."}, - {"HOLD \"R\"", "TO RESTOCK", "ALL VOUCHERS"}, - {"DID YOU KNOW?", "PRESSING ALT+F4", "GIVES FREE VOUCHERS!"}, - {"SORRY,", "THERE ARE NO VOUCHERS", "DUE TO BUDGET CUTS"}, - {"CALL 1-600-JIMBO", "TO RATE YOUR", "VOUCHER EXPERIENCE"}, - {"DEFEAT", "ANTE 39 BOSS BLIND", "TO RESTOCK"}, - {"MAGIC TRICK", "I MADE THIS VOUCHER", "DISAPPEAR"}, - {"WHY IS A", "VOUCHER LIKE", "A WRITING DESK?"}, - {"WE HAVE RETRACTED", "YOUR VOUCHERS, THEY WOULD BE", "BETTER USED IN OTHER RUNS"}, - {"WHY DO THEY CALL IT VOUCHER", "WHEN MULT OUT THE HOT", "IN COLD EAT EAT THE CHIP"}, - {"SORRY", "THE VOUCHERS ARE EXPERIENCING", "VOUCHIFIA ABORTUS"}, - {"UNFORTUNATELY", "THE VOUCHRX REWRITE UPDATE", "HAS BEEN CANCELLED"}, - {"DEFEAT", "BOSS BLIND", "TO CHANGE NOTHING"}, - {"BIRDS ARE SINGING", "FLOWERS ARE BLOOMING", "KIDS LIKE YOU..."}, - {"WE ARE SORRY TO SAY", "ALL VOUCHERS HAVE BEEN RECALLED", "DUE TO SALMONELLA EXPOSURE"}, - {"VOUCHERS COULDN'T ARRIVE", "DUE TO SHOP LAYOUT BEING", "200% OVERBUDGET"}, - {"YOU LIKE", "BUYING VOUCHERS, DON'T YOU", "YOU'RE A VOUCHERBUYER"}, - {"VOUCHERS", "!E", "VOUCHER POOL"}, - {"THERE", "IS NO", "VOUCHER"}, - {"THERE IS", "NO SANTA", "AND THERE ARE NO VOUCHERS"}, - {"", "VOUCHERN'T", ""}, - {"YOU", "JUST LOST", "THE GAME"}, - {"CAN I OFFER YOU", "A NICE EGG", "IN THESE TRYING TIMES?"}, - {"GO TOUCH GRASS", "INSTEAD OF USING", "THIS DECK"}, - {"YOU COULD BE", "PLAYING ON BLUE DECK", "RIGHT NOW"}, - {"FREE EXOTICS", "GET THEM BEFORE ITS", "TOO LATE (sold out)"}, - {"PROVE THEM WRONG", "BUY BUYING AN INVISIBLE", "VOUCHER FOR $10"}, - {"", "no vouchers?", ""}, - {"see this ad?", "if you are, then it's working", "and you could have it for your own"}, - {"YOU'RE MISSING OUT ON", "AT LEAST 5 VOUCHERS RIGHT NOW", "tonktonktonktonktonk"}, - {"10", "20 NO VOUCHER XD", "30 GOTO 10"}, - {"VOUCHERS", "ARE A PREMIUM FEATURE", "$199.99 JOLLARS TO UNLOCK"}, - {"TRUE VOUCHERLESS!?!?", "ASCENDANT STAKE ONLY", "VERY FAIR DECK"}, - {"ENJOYING YOUR", "VOUCHER EXPERIENCE? GIVE US A", "FIVE STAR RATING ON JESTELP"}, - {"FREE VOUCHERS", "HOT VOUCHERS NEAR YOU", "GET VOUCHERS QUICK WITH THIS ONE TRICK"}, - {"INTRODUCING", "THE VERY FIRST TIER 0 VOUCHER!", "(coming to Cryptid 1.0 soon)"}, - {"A VOUCHER!", "IT'S JUST IMAGINARY", "WE IMAGINED YOU WOULD WANT IT, THAT IS"}, - {"TURN OFF ADBLOCKER", "WITHOUT ADS, WE WOULDN'T", "BE ABLE TO SELL YOU VOUCHERS"}, - {"IF YOU HAVE", "A PROBLEM WITH THIS", "EMAIL IT TO US AT NORESPONSE@JMAIL.COM"}, - {"NOT ENOUGH MONEY", "TO BUY THIS VOUCHER", "SO WHY WOULD WE PUT IT HERE?"}, - {"WANT A VOUCHER?", "WELL SHUT UP", "YOU CAN'T HAVE ANY LOL"}, - {"^$%& NO", "VOUCHERS ^%&% %&$^% FOR", "$%&%%$ %&$&*%$^ YOU"}, - {"A VOUCHER (TRUST)", "|\\/|", "|/\\|"}, - {"... --- ...", ".--. .-.. .- -.-- . .-. -.. . -.-. --- -.. . -.. -- --- .-. ... .", "-.-. --- -.. . - --- ..-. .. -. -.. .- ...- --- ..- -.-. .... . .-."}, - {"RUN > NEW", "STARE AT NOTHING", "FOR AN HOUR OR TWO"}, - {"WE'RE VERY SORRY", "THE LAST GUY PANIC BOUGHT", "ALL THE VOUCHERS"}, - {"HOW IT FEELS", "TO BUY NO", "VOUCHERS"}, - {"JIMBO GOT A NAT 1", "AND DUMPED ALL THE", "VOUCHERS IN A DITCH"}, - {"ATTEMPT TO INDEX", "FIELD 'VOUCHER'", "(A NIL VALUE)"}, - {"OH YOU REALLY THOUGHT THAT READING ALL THESE LINES WOULD BRING YOUR VOUCHERS BACK?", "SORRY TO TELL YOU, BUT THIS DECK DOESN'T CONTAIN THE VOUCHERS YOU SEEK.", "THIS ABNORMALLY LONG TEXT IS HERE AND DESIGNED TO WASTE YOUR TIME AND EFFORT WHILE YOU READ IT."}, - {"GO TO", "https://youtu.be/p7YXXieghto", "FOR FREE VOUCHERS"} -} -very_fair_quip = {} - -local very_fair_sprite = { - object_type = "Atlas", - key = "very_fair", - - path = "b_cry_very_fair.png", - px = 71, - py = 95 -} - -local equilibrium = { - object_type = "Back", - name = "cry-Equilibrium", - key = "equilibrium", - config = {vouchers = {'v_overstock_norm','v_overstock_plus'}, cry_equilibrium = true}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deck of Equilibrium", - text = { - "All cards have the", - "{C:attention}same chance{} of", - "appearing in shops,", - "start run with", - "{C:attention,T:v_overstock_plus}Overstock Plus" - } - }, - atlas = "equilibrium" -} -local equilibrium_sprite = { - object_type = "Atlas", - key = "equilibrium", - path = "b_cry_equilibrium.png", - px = 71, - py = 95 -} -local misprint = { - object_type = "Back", - name = "cry-Misprint", - key = "misprint", - config = {cry_misprint_min = 0.1, cry_misprint_max = 10}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Misprint Deck", - text = { - "Values of cards", - "and poker hands", - "are {C:attention}randomized" - } - }, - atlas = "misprint" -} -local misprint_sprite = { - object_type = "Atlas", - key = "misprint", - path = "b_cry_misprint.png", - px = 71, - py = 95 -} -local infinite = { - object_type = "Back", - name = "cry-Infinite", - key = "infinite", - config = {cry_highlight_limit = 1e20}, - pos = {x = 0, y = 0}, - atlas = "infinite", - loc_txt = { - name = "Infinite Deck", - text = { - "You can select {C:attention}any", - "number of cards" - } - }, -} -local infinite_sprite = { - object_type = "Atlas", - key = "infinite", - path = "b_cry_infinite.png", - px = 71, - py = 95 -} -local conveyor = { - object_type = "Back", - name = "cry-Conveyor", - key = "conveyor", - config = {cry_conveyor = true}, - pos = {x = 0, y = 0}, - atlas = "conveyor", - loc_txt = { - name = "Conveyor Deck", - text = { - "Jokers may {C:attention}not{} be moved", - "At start of round,", - "{C:attention}duplicate{} rightmost Joker", - "and {C:attention}destroy{} leftmost Joker" - } - } -} -local conveyor_sprite = { - object_type = "Atlas", - key = "conveyor", - path = "b_cry_conveyor.png", - px = 71, - py = 95 -} -local CCD = { - object_type = "Back", - name = "cry-CCD", - key = "CCD", - config = {cry_ccd = true}, - pos = {x = 0, y = 0}, - atlas = "CCD", - loc_txt = { - name = "CCD Deck", - text = { - "Every card is also", - "a {C:attention}random{} consumable" - } - } -} -local ccd_sprite = { - object_type = "Atlas", - key = "CCD", - path = "b_cry_ccd.png", - px = 71, - py = 95 -} -return {name = "Misc. Decks", - init = function() - local Backapply_to_runRef = Back.apply_to_run - function Back.apply_to_run(self) - Backapply_to_runRef(self) - if self.effect.config.cry_no_vouchers then - G.GAME.modifiers.cry_no_vouchers = true - end - if self.effect.config.cry_equilibrium then - G.GAME.modifiers.cry_equilibrium = true - end - if self.effect.config.cry_conveyor then - G.GAME.modifiers.cry_conveyor = true - end - if self.effect.config.cry_misprint_min then - G.GAME.modifiers.cry_misprint_min = self.effect.config.cry_misprint_min - G.GAME.modifiers.cry_misprint_max = self.effect.config.cry_misprint_max - end - if self.effect.config.cry_highlight_limit then - G.GAME.modifiers.cry_highlight_limit = self.effect.config.cry_highlight_limit - end - if self.effect.config.cry_ccd then - G.GAME.modifiers.cry_ccd = true - end - end - --equilibrium deck patches - local gcp = get_current_pool - function get_current_pool(t, r, l, a, override_equilibrium_effect) - if G.GAME.modifiers.cry_equilibrium and not override_equilibrium_effect and (a == 'sho' or t == 'Voucher' or t == 'Booster') then - if t ~= "Enhanced" and t ~= "Edition" and t ~= "Back" and t ~= "Tag" and t ~= "Seal" and t ~= "Stake" then - if not P_CRY_ITEMS then - P_CRY_ITEMS = {} - local valid_pools = {"Joker", "Consumeables", "Voucher", "Booster"} - for _, id in ipairs(valid_pools) do - for k, v in pairs(G.P_CENTER_POOLS[id]) do - P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key - end - end - for k, v in pairs(G.P_CARDS) do - P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key - end - end - return P_CRY_ITEMS, "cry_equilibrium"..G.GAME.round_resets.ante - end - end - return gcp(t,r,l,a) - end - local gp = get_pack - function get_pack(k, t) - if G.GAME.modifiers.cry_equilibrium then - if not P_CRY_ITEMS then - P_CRY_ITEMS = {} - local valid_pools = {"Joker", "Consumeables", "Voucher", "Booster"} - for _, id in ipairs(valid_pools) do - for k, v in pairs(G.P_CENTER_POOLS[id]) do - P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key - end - end - for k, v in pairs(G.P_CARDS) do - P_CRY_ITEMS[#P_CRY_ITEMS+1] = v.key - end - end - return G.P_CENTERS[pseudorandom_element(P_CRY_ITEMS,pseudoseed('cry_equipackbrium'..G.GAME.round_resets.ante))] - end - return gp(k,t) - end - --Misprint Deck patches - function cry_log_random(seed,min,max) - math.randomseed(seed) - local lmin = math.log(min,2.718281828459045) - local lmax = math.log(max,2.718281828459045) - local poll = math.random()*(lmax-lmin)+lmin - return math.exp(poll) - end - end, - items = {very_fair_sprite, equilibrium_sprite, misprint_sprite, infinite_sprite, conveyor_sprite, ccd_sprite, - very_fair, equilibrium, misprint, infinite, conveyor, CCD}} diff --git a/Items/Items/Enhanced.lua b/Items/Items/Enhanced.lua deleted file mode 100644 index 14189b1f3..000000000 --- a/Items/Items/Enhanced.lua +++ /dev/null @@ -1,535 +0,0 @@ -local hierophant_deck = {object_type = "Back", - name = "cry-The Hierophant's Deck", - key = "hierophant_deck", - config = {cry_force_enhancement = "m_bonus"}, - pos = {x = 0, y = 0}, - atlas = "hierophant", - loc_txt = { - name = "The Hierophant's Deck", - text = { - "Start with a deck", - "of {C:attention}Bonus Cards{}", - "Cards cannot change enhancements" - } - }, -} -local hierophant_sprite = { - object_type = "Atlas", - key = "hierophant", - path = "b_cry_hierophant.png", - px = 71, - py = 95 -} -local empress_deck = {object_type = "Back", - name = "cry-The Empress's Deck", - key = "empress_deck", - config = {cry_force_enhancement = "m_mult"}, - atlas = "empress", - pos = {x = 0, y = 0}, - loc_txt = { - name = "The Empress's Deck", - text = { - "Start with a deck", - "of {C:attention}Mult Cards{}", - "Cards cannot change enhancements" - } - }, -} -local empress_sprite = { - object_type = "Atlas", - key = "empress", - path = "b_cry_empress.png", - px = 71, - py = 95 -} -local lovers_deck = {object_type = "Back", - name = "cry-The Lovers' Deck", - key = "lovers_deck", - config = {cry_force_enhancement = "m_wild"}, - pos = {x = 0, y = 0}, - atlas = "lovers", - loc_txt = { - name = "The Lovers' Deck", - text = { - "Start with a deck", - "of {C:attention}Wild Cards{}", - "Cards cannot change enhancements" - } - }, -} -local lovers_sprite = { - object_type = "Atlas", - key = "lovers", - path = "b_cry_lovers.png", - px = 71, - py = 95 -} -local justice_deck = {object_type = "Back", - name = "cry-Deck of Justice", - key = "justice_deck", - config = {cry_force_enhancement = "m_glass"}, - pos = {x = 0, y = 0}, - atlas = "justice", - loc_txt = { - name = "Deck of Justice", - text = { - "Start with a deck", - "of {C:attention}Glass Cards{}", - "Cards cannot change enhancements" - } - }, -} -local justice_sprite = { - object_type = "Atlas", - key = "justice", - path = "b_cry_justice.png", - px = 71, - py = 95 -} -local chariot_deck = {object_type = "Back", - name = "cry-The Chariot's Deck", - key = "chariot_deck", - config = {cry_force_enhancement = "m_steel"}, - pos = {x = 6, y = 1}, - loc_txt = { - name = "The Chariot's Deck", - text = { - "Start with a deck", - "of {C:attention}Steel Cards{}", - "Cards cannot change enhancements" - } - }, - -} -local tower_deck = {object_type = "Back", - name = "cry-Stoner's Deck", - key = "tower_deck", - config = {cry_force_enhancement = "m_stone"}, - pos = {x = 5, y = 0}, - loc_txt = { - name = "Stoner's Deck", - text = { - "Start with a deck", - "of {C:attention}Stone Cards{}", - "Cards cannot change enhancements" - } - }, - -} -local devil_deck = {object_type = "Back", - name = "cry-The Devil's Deck", - key = "devil_deck", - config = {cry_force_enhancement = "m_gold"}, - pos = {x = 6, y = 0}, - loc_txt = { - name = "The Devil's Deck", - text = { - "Start with a deck", - "of {C:attention}Gold Cards{}", - "Cards cannot change enhancements" - } - }, - -} -local magician_deck = {object_type = "Back", - name = "cry-The Magician's Deck", - key = "magician_deck", - config = {cry_force_enhancement = "m_lucky"}, - pos = {x = 4, y = 1}, - loc_txt = { - name = "The Magician's Deck", - text = { - "Start with a deck", - "of {C:attention}Lucky Cards{}", - "Cards cannot change enhancements" - } - }, - -} -local foil_deck = {object_type = "Back", - name = "cry-Deck of Chips", - key = "foil_deck", - config = {cry_force_edition = 'foil'}, - pos = {x = 0, y = 2}, - loc_txt = { - name = "Deck of Chips", - text = { - "Start with a deck", - "of {C:attention}Foil Cards{}", - "Cards cannot change editions" - } - }, - -} -local holo_deck = {object_type = "Back", - name = "cry-Deck of Mult", - key = "holo_deck", - config = {cry_force_edition = 'holo'}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deck of Mult", - text = { - "Start with a deck", - "of {C:attention}Holographic Cards{}", - "Cards cannot change editions" - } - }, - -} -local poly_deck = {object_type = "Back", - name = "cry-Deck of XMult", - key = "poly_deck", - config = {cry_force_edition = 'polychrome'}, - pos = {x = 5, y = 2}, - loc_txt = { - name = "Deck of XMult", - text = { - "Start with a deck", - "of {C:attention}Polychrome Cards{}", - "Cards cannot change editions" - } - }, - -} -local talisman_deck = {object_type = "Back", - name = "cry-Talisman Deck", - key = "talisman_deck", - config = {cry_force_seal = 'Gold'}, - pos = {x = 1, y = 2}, - loc_txt = { - name = "Talisman Deck", - text = { - "Start with a deck", - "of {C:attention}Gold Seal Cards{}", - "Cards cannot change seals" - } - }, - -} -local deja_vu_deck = {object_type = "Back", - name = "cry-Deja Vu Deck", - key = "deja_vu_deck", - config = {cry_force_seal = 'Red'}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deja Vu Deck", - text = { - "Start with a deck", - "of {C:attention}Red Seal Cards{}", - "Cards cannot change seals" - } - }, - -} -local trance_deck = {object_type = "Back", - name = "cry-Trance Deck", - key = "trance_deck", - config = {cry_force_seal = 'Blue', hide_seal = true}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Trance Deck", - text = { - "Start with a deck", - "of {C:attention}Blue Seal Cards{}", - "Cards cannot change seals" - } - }, - atlas = "trance" -} -local trance_sprite = { - object_type = "Atlas", - key = "trance", - path = "b_cry_trance.png", - px = 71, - py = 95 -} -local medium_deck = {object_type = "Back", - name = "cry-Medium Deck", - key = "medium_deck", - config = {cry_force_seal = 'Purple', hide_seal = true}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Medium Deck", - text = { - "Start with a deck", - "of {C:attention}Purple Seal Cards{}", - "Cards cannot change seals" - } - }, - atlas = "medium" -} -local medium_sprite = { - object_type = "Atlas", - key = "medium", - path = "b_cry_medium.png", - px = 71, - py = 95 -} -local eternal_deck = {object_type = "Back", - name = "cry-Eternal Deck", - key = "eternal_deck", - config = {cry_force_sticker = 'eternal'}, - pos = {x = 0, y = 0}, - atlas = "eternal", - loc_txt = { - name = "Eternal Deck", - text = { - "Start with a deck", - "of {C:attention}Eternal Cards{}" - } - }, -} -local eternal_sprite = { - object_type = "Atlas", - key = "eternal", - path = "b_cry_eternal.png", - px = 71, - py = 95 -} -local perishable_deck = {object_type = "Back", - name = "cry-Perishable Deck", - key = "perishable_deck", - config = {cry_force_sticker = 'perishable'}, - pos = {x = 0, y = 0}, - atlas = "perishable", - loc_txt = { - name = "Perishable Deck", - text = { - "Start with a deck", - "of {C:attention}Perishable Cards{}" - } - }, -} -local perishable_sprite = { - object_type = "Atlas", - key = "perishable", - path = "b_cry_perishable.png", - px = 71, - py = 95 -} -local rental_deck = {object_type = "Back", - name = "cry-Rental Deck", - key = "rental_deck", - config = {cry_force_sticker = 'rental'}, - pos = {x = 0, y = 0}, - atlas = "rental", - loc_txt = { - name = "Rental Deck", - text = { - "Start with a deck", - "of {C:attention}Rental Cards{}" - } - }, -} -local rental_sprite = { - object_type = "Atlas", - key = "rental", - path = "b_cry_rental.png", - px = 71, - py = 95 -} -local world_deck = {object_type = "Back", - name = "cry-World Deck", - key = "world_deck", - config = {cry_force_suit = 'Spades', cry_boss_blocked = {'bl_goad'}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deck of The World", - text = { - "All cards in deck are {C:spade}Spades{}", - "and cannot change suits", - "{C:attention}The Goad{} cannot appear" - } - }, - atlas = "world_deck" -} -local star_deck = {object_type = "Back", - name = "cry-Star Deck", - key = "star_deck", - config = {cry_force_suit = 'Diamonds', cry_boss_blocked = {'bl_window'}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deck of The Stars", - text = { - "All cards in deck are {C:diamond}Diamonds{}", - "and cannot change suits", - "{C:attention}The Window{} cannot appear" - } - }, - atlas = "star_deck" -} -local sun_deck = {object_type = "Back", - name = "cry-Sun Deck", - key = "sun_deck", - config = {cry_force_suit = 'Hearts', cry_boss_blocked = {'bl_head'}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deck of The Sun", - text = { - "All cards in deck are {C:heart}Hearts{}", - "and cannot change suits", - "{C:attention}The Head{} cannot appear" - } - }, - atlas = "sun_deck" -} -local moon_deck = {object_type = "Back", - name = "cry-Moon Deck", - key = "moon_deck", - config = {cry_force_suit = 'Clubs', cry_boss_blocked = {'bl_club'}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Deck of The Moon", - text = { - "All cards in deck are {C:club}Clubs{}", - "and cannot change suits", - "{C:attention}The Club{} cannot appear" - } - }, - atlas = "moon_deck" -} -local world_sprite = { - object_type = "Atlas", - key = "world_deck", - path = "b_cry_world.png", - px = 71, - py = 95 -} -local star_sprite = { - object_type = "Atlas", - key = "star_deck", - path = "b_cry_star.png", - px = 71, - py = 95 -} -local sun_sprite = { - object_type = "Atlas", - key = "sun_deck", - path = "b_cry_sun.png", - px = 71, - py = 95 -} -local moon_sprite = { - object_type = "Atlas", - key = "moon_deck", - path = "b_cry_moon.png", - px = 71, - py = 95 -} - -return {name = "Enhanced Decks", - init = function() - local Backapply_to_runRef = Back.apply_to_run - function Back.apply_to_run(self) - Backapply_to_runRef(self) - - if self.effect.config.cry_force_enhancement then - if self.effect.config.cry_force_enhancement ~= 'random' then G.GAME.modifiers.cry_force_enhancement = self.effect.config.cry_force_enhancement end - G.E_MANAGER:add_event(Event({ - func = function() - for c = #G.playing_cards, 1, -1 do - if self.effect.config.cry_force_enhancement == 'random' then - local random_enhancement = pseudorandom_element(G.P_CENTER_POOLS.Enhanced, pseudoseed('cry_ant_enhancement')) - G.playing_cards[c]:set_ability(G.P_CENTERS[random_enhancement.key]); - else - G.playing_cards[c]:set_ability(G.P_CENTERS[self.effect.config.cry_force_enhancement]); - end - end - - return true - end - })) - end - if self.effect.config.cry_force_edition then - if self.effect.config.cry_force_edition ~= 'random' then G.GAME.modifiers.cry_force_edition = self.effect.config.cry_force_edition end - G.E_MANAGER:add_event(Event({ - func = function() - for c = #G.playing_cards, 1, -1 do - local ed_table = {} - if self.effect.config.cry_force_edition == 'random' then - local editions = {"foil", "holo", "polychrome"} --todo: modded edition support - local random_edition = pseudorandom_element(editions, pseudoseed('cry_ant_edition')) - ed_table[random_edition] = true - G.playing_cards[c]:set_edition(ed_table, true, true); - else - ed_table[self.effect.config.cry_force_edition] = true - G.playing_cards[c]:set_edition(ed_table, true, true); - end - end - - return true - end - })) - end - if self.effect.config.cry_force_seal then - if self.effect.config.cry_force_seal ~= 'random' then G.GAME.modifiers.cry_force_seal = self.effect.config.cry_force_seal end - G.E_MANAGER:add_event(Event({ - func = function() - for c = #G.playing_cards, 1, -1 do - if self.effect.config.cry_force_seal == 'random' then - local random_seal = pseudorandom_element(G.P_CENTER_POOLS.Seal, pseudoseed('cry_ant_seal')) - G.playing_cards[c]:set_seal(random_seal.key, true); - else - G.playing_cards[c]:set_seal(self.effect.config.cry_force_seal, true); - end - end - return true - end - })) - end - if self.effect.config.cry_force_sticker then - G.E_MANAGER:add_event(Event({ - func = function() - for c = #G.playing_cards, 1, -1 do - G.playing_cards[c].config.center.eternal_compat = true - G.playing_cards[c].config.center.perishable_compat = true - G.playing_cards[c]["set_"..self.effect.config.cry_force_sticker](G.playing_cards[c],true); - end - return true - end - })) - end - if self.effect.config.cry_force_suit then - G.GAME.modifiers.cry_force_suit = self.effect.config.cry_force_suit - G.E_MANAGER:add_event(Event({ - func = function() - for c = #G.playing_cards, 1, -1 do - G.playing_cards[c]:change_suit(self.effect.config.cry_force_suit) - end - return true - end - })) - end - if self.effect.config.cry_boss_blocked then - for _, v in pairs(self.effect.config.cry_boss_blocked) do - G.GAME.bosses_used[v] = 1e308 - end - end - end - local sa = Card.set_ability - function Card:set_ability(center, y, z) - if center.set == "Enhanced" then - return sa(self, G.GAME.modifiers.cry_force_enhancement and G.P_CENTERS[G.GAME.modifiers.cry_force_enhancement] or center, y, z) - else - return sa(self, center, y, z) - end - end - local se = Card.set_edition - function Card:set_edition(edition, y, z) - return se(self, G.GAME.modifiers.cry_force_edition and {[G.GAME.modifiers.cry_force_edition]=true} or edition, y, z) - end - local ss = Card.set_seal - function Card:set_seal(seal, y, z) - return ss(self, G.GAME.modifiers.cry_force_seal or seal, y, z) - end - local cs = Card.change_suit - function Card:change_suit(new_suit) - return cs(self, G.GAME.modifiers.cry_force_suit or new_suit) - end - end, - items = {trance_sprite, medium_sprite, world_sprite, star_sprite, sun_sprite, moon_sprite, perishable_sprite, eternal_sprite, rental_sprite, lovers_sprite, hierophant_sprite, empress_sprite, justice_sprite, -hierophant_deck, empress_deck, lovers_deck, justice_deck, chariot_deck, tower_deck, devil_deck, magician_deck, -foil_deck, holo_deck, poly_deck, -talisman_deck, deja_vu_deck, trance_deck, medium_deck, -eternal_deck, perishable_deck, rental_deck, -star_deck, moon_deck, sun_deck, world_deck}} \ No newline at end of file diff --git a/Items/Items/MiscJokers.lua b/Items/Items/MiscJokers.lua deleted file mode 100644 index 8fe43cc12..000000000 --- a/Items/Items/MiscJokers.lua +++ /dev/null @@ -1,1973 +0,0 @@ -local dropshot = { - object_type = "Joker", - name = "cry-Dropshot", - key = "dropshot", - config = {extra = {Xmult_mod = 0.2, x_mult = 1}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Dropshot', - text = { - "This Joker gains {X:mult,C:white} X#1# {} Mult", - "per played, {C:attention}nonscoring{} {V:1}#2#{} card,", - "suit changes every round", - "{C:inactive}(Currently {X:mult,C:white} X#3# {C:inactive} Mult)" - } - }, - rarity = 3, - cost = 8, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - atlas = "dropshot", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.Xmult_mod, localize(G.GAME.current_round.cry_dropshot_card and G.GAME.current_round.cry_dropshot_card.suit or "Spades", 'suits_singular'), center.ability.extra.x_mult, colours = {G.C.SUITS[G.GAME.current_round.cry_dropshot_card and G.GAME.current_round.cry_dropshot_card.suit or "Spades"]}}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and context.before and not context.blueprint then - cards = 0 - for k, v in ipairs(context.scoring_hand) do - v.cry_dropshot_incompat = true - end - for k, v in ipairs(context.full_hand) do - if not v.cry_dropshot_incompat and v:is_suit(G.GAME.current_round.cry_dropshot_card.suit)then - cards = cards + 1 - G.E_MANAGER:add_event(Event({ - func = function() - v:juice_up() - return true - end - })) - end - end - for k, v in ipairs(context.scoring_hand) do - v.cry_dropshot_incompat = nil - end - if cards > 0 then - card.ability.extra.x_mult = card.ability.extra.x_mult + cards * card.ability.extra.Xmult_mod - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) - return {calculated = true} - end - end - if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - end -} -local dropshot_sprite = { - object_type = "Atlas", - key = "dropshot", - - path = "j_cry_dropshot.png", - px = 71, - py = 95 -} -local maximized = { - object_type = "Joker", - name = "cry-Maximized", - key = "maximized", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Maximized', - text = { - "All {C:attention}face{} cards", - "are considered {C:attention}Kings{},", - "all {C:attention}numbered{} cards", - "are considered {C:attention}10s{}" - } - }, - rarity = 3, - cost = 10, - discovered = true, - atlas = "maximized" -} -local maximized_sprite = { - object_type = "Atlas", - key = "maximized", - - path = "j_cry_maximized.png", - px = 71, - py = 95 -} -local potofjokes = { - object_type = "Joker", - name = "cry-Pot of Jokes", - key = "pot_of_jokes", - config = {extra = {h_size = -2, h_mod = 1}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Pot of Jokes', - text = { - "{C:attention}#1#{} hand size,", - "increases by", - "{C:blue}#2#{} every round"} - }, - rarity = 3, - cost = 10, - discovered = true, - perishable_compat = false, - atlas = 'pot_of_jokes', - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.h_size<0 and center.ability.extra.h_size or "+"..center.ability.extra.h_size,center.ability.extra.h_mod}} - end, - calculate = function(self, card, context) - if context.end_of_round and not context.individual and not context.repetition and not context.blueprint then - card.ability.extra.h_size = card.ability.extra.h_size + card.ability.extra.h_mod - G.hand:change_size(card.ability.extra.h_mod) - return { - message = localize{type='variable',key='a_handsize',vars={card.ability.extra.h_mod}}, - colour = G.C.FILTER, - card = card - } - end - end, - add_to_deck = function(self, card, from_debuff) - G.hand:change_size(card.ability.extra.h_size) - end, - remove_from_deck = function(self, card, from_debuff) - G.hand:change_size(-card.ability.extra.h_size) - end -} -local potofjokes_sprite = { - object_type = "Atlas", - key = "pot_of_jokes", - - path = "j_cry_pot_of_jokes.png", - px = 71, - py = 95 -} -local queensgambit = { - object_type = "Joker", - name = "cry-Queen's Gambit", - key = "queens_gambit", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Queen\'s Gambit', - text = { "If {C:attention}poker hand{} is a", - "{C:attention}Royal Flush{}, destroy scored", - "{C:attention}Queen{} and create a", - "{C:dark_edition}Negative {}{C:red}Rare{}{C:attention} Joker{}"} - }, - rarity = 3, - cost = 10, - discovered = true, - atlas = "queens_gambit", - config = {extra = {type = "Straight Flush"}}, - calculate = function(self, card, context) - if context.destroying_card and not context.blueprint then - if G.GAME.current_round.current_hand.handname == "Royal Flush" and SMODS.Ranks[context.destroying_card.base.value].key == "Queen" then - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_plus_joker'), colour = G.C.FILTER}) - G.E_MANAGER:add_event(Event({ - trigger = 'after', - func = function() - local card = create_card("Joker", G.jokers, nil, 0.99, nil, nil, nil, "cry_gambit") - card:set_edition({ - negative = true - }) - card:add_to_deck() - G.jokers:emplace(card) - card:start_materialize() - return true - end - })) - return true - end - end - end -} -local queensgambit_sprite = { - object_type = "Atlas", - key = "queens_gambit", - - path = "j_cry_queens_gambit.png", - px = 71, - py = 95 -} -local wee_fib = { - object_type = "Joker", - name = "cry-Wee Fibonacci", - key = "wee_fib", - config = {extra = {mult = 0, mult_mod = 3}}, - pos = {x = 1, y = 5}, - loc_txt = { - name = 'Wee Fibonacci', - text = { - "This Joker gains", - "{C:mult}+#2#{} Mult for each scored", - "{C:attention}Ace{}, {C:attention}2{}, {C:attention}3{}, {C:attention}5{}, or {C:attention}8{}", - "{C:inactive}(Currently {C:mult}+#1#{C:inactive} Mult)"} - }, - rarity = 3, - cost = 12, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.mult,center.ability.extra.mult_mod}} - end, - calculate = function(self, card, context) - if context.cardarea == G.play and context.individual and not context.blueprint then - local rank = SMODS.Ranks[context.other_card.base.value].key - if rank == "Ace" or rank == "2" or rank == "3" or rank == "5" or rank == "8" then - card.ability.extra.mult = card.ability.extra.mult + card.ability.extra.mult_mod - - return { - extra = {focus = self, message = localize('k_upgrade_ex')}, - card = card, - colour = G.C.MULT - } - end - end - if context.cardarea == G.jokers and (card.ability.extra.mult > 0) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_mult',vars={card.ability.extra.mult}}, - mult_mod = card.ability.extra.mult, - colour = G.C.MULT - } - end - end, -} -local whip = { - object_type = "Joker", - name = "cry-The WHIP", - key = "whip", - pos = {x = 0, y = 0}, - config = {extra = {Xmult_mod = 0.5, x_mult = 1}}, - loc_txt = { - name = 'The WHIP', - text = { "This Joker gains {X:mult,C:white} X#1# {} Mult", - "if {C:attention}played hand{} contains a", - "{C:attention}2{} and {C:attention}7{} of different suits", - "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)"} - }, - rarity = 2, - cost = 6, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - atlas = "whip", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.Xmult_mod, center.ability.extra.x_mult}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and context.before and not context.blueprint then - for i = 1, #context.full_hand do - if SMODS.Ranks[context.full_hand[i].base.value].key == "2" then - for j = 1, #context.full_hand do - if SMODS.Ranks[context.full_hand[j].base.value].key == "7" then - --Different suits - for k, v in pairs(SMODS.Suits) do - if context.full_hand[i]:is_suit(k, nil, true) and context.full_hand[j]:is_suit(k, nil, true) then return end - end - card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.Xmult_mod - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) - return {calculated = true} - end - end - end - end - end - if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - end -} -local whip_sprite = { - object_type = "Atlas", - key = "whip", - path = "j_cry_whip.png", - px = 71, - py = 95 -} -local lucky_joker = { - object_type = "Joker", - name = "cry-Lucky Joker", - key = "lucky_joker", - config = {extra = { dollars = 5}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Lucky Joker', - text = { - "Earn {C:money}$#1#{} every time a", - "{C:attention}Lucky{} card {C:green}successfully{}", - "triggers" - } - }, - rarity = 1, - cost = 5, - discovered = true, - blueprint_compat = true, - atlas = "lucky_joker", - enhancement_gate = 'm_lucky', - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.dollars}} - end, - calculate = function(self, card, context) - if context.individual and context.other_card.lucky_trigger then - G.GAME.dollar_buffer = (G.GAME.dollar_buffer or 0) + card.ability.extra.dollars - G.E_MANAGER:add_event(Event({func = (function() G.GAME.dollar_buffer = 0; return true end)})) - return { - dollars = card.ability.extra.dollars, - card = card - } - end - end -} -local lucky_joker_sprite = { - object_type = "Atlas", - key = "lucky_joker", - - path = "j_cry_lucky_joker.png", - px = 71, - py = 95 -} - -local cursor = { - object_type = "Joker", - name = "cry-Cursor", - key = "cursor", - config = {extra = {chips = 0, chip_mod = 5}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Cursor', - text = { - "This Joker gains {C:chips}+#2#{} Chips", - "for each card {C:attention}purchased{}", - "{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips)" - } - }, - rarity = 1, - cost = 5, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - atlas = "cursor", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.chips, center.ability.extra.chip_mod}} - end, - calculate = function(self, card, context) - if context.buying_card and not context.blueprint then - card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}, colour = G.C.CHIPS}) - return {calculated = true} - end - if context.cardarea == G.jokers and (card.ability.extra.chips > 0) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips}}, - chip_mod = card.ability.extra.chips - } - end - end -} -local cursor_sprite = { - object_type = "Atlas", - key = "cursor", - path = "j_cry_cursor.png", - px = 71, - py = 95 -} -local pickle = { - object_type = "Joker", - name = "cry-Pickle", - key = "pickle", - config = {extra = {tags = 3, tags_mod = 1}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Pickle', - text = { - "When {C:attention}Blind{} is skipped, create", - "{C:attention}#1#{} Tags, reduced by", - "{C:red}#2#{} when {C:attention}Blind{} is selected" - } - }, - rarity = 2, - cost = 5, - discovered = true, - blueprint_compat = true, - eternal_compat = false, - atlas = "pickle", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.tags, center.ability.extra.tags_mod}} - end, - calculate = function(self, card, context) - if context.skip_blind then - for i = 1, card.ability.extra.tags do - local tag = Tag(get_next_tag_key("cry_pickle")) - if tag.name == 'Orbital Tag' then - local _poker_hands = {} - for k, v in pairs(G.GAME.hands) do - if v.visible then _poker_hands[#_poker_hands+1] = k end - end - tag.ability.orbital_hand = pseudorandom_element(_poker_hands, pseudoseed('cry_pickle_orbital')) - end - if tag.name == 'Boss Tag' then - i = i - 1 --skip these, as they can cause bugs with pack opening from other tags - else - add_tag(tag) - end - end - card_eval_status_text(card, 'extra', nil, nil, nil, {message = "+"..card.ability.extra.tags.." Tag"..(card.ability.extra.tags>1 and "s" or ""), colour = G.C.FILTER}) - return {calculated = true} - end - if context.setting_blind and not context.blueprint then - card.ability.extra.tags = card.ability.extra.tags - card.ability.extra.tags_mod - if card.ability.extra.tags > 0 then - card_eval_status_text(card, 'extra', nil, nil, nil, {message = "-"..card.ability.extra.tags_mod.." Tag"..(card.ability.extra.tags_mod>1 and "s" or ""), colour = G.C.FILTER}) - return {calculated = true} - 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 - end -} -local pickle_sprite = { - object_type = "Atlas", - key = "pickle", - path = "j_cry_pickle.png", - px = 71, - py = 95 -} - -local cube = { - object_type = "Joker", - name = "cry-Cube", - key = "cube", - config = {extra = {chips = 6}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Cube', - text = { - "{C:chips}+#1#{} Chips" - } - }, - rarity = 1, - cost = -25, - discovered = true, - blueprint_compat = true, - atlas = "cube", - source_gate = "sho", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.chips}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and not context.before and not context.after then - return { - message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips}}, - chip_mod = card.ability.extra.chips - } - end - end -} -local cube_sprite = { - object_type = "Atlas", - key = "cube", - path = "j_cry_cube.png", - px = 71, - py = 95 -} - -local triplet_rhythm = { - object_type = "Joker", - name = "cry-Triplet Rhythm", - key = "triplet_rhythm", - config = {extra = {Xmult = 3}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Triplet Rhythm', - text = { - "{X:mult,C:white} X#1# {} Mult if scoring hand", - "contains {C:attention}exactly{} three {C:attention}3s" - } - }, - rarity = 2, - cost = 7, - discovered = true, - blueprint_compat = true, - atlas = "triplet_rhythm", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.Xmult}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and not context.before and not context.after and context.scoring_hand then - local threes = 0 - for i = 1, #context.scoring_hand do - if SMODS.Ranks[context.scoring_hand[i].base.value].key == "3" then - threes = threes + 1 - end - end - if threes == 3 then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, - Xmult_mod = card.ability.extra.Xmult - } - end - end - end -} -local triplet_rhythm_sprite = { - object_type = "Atlas", - key = "triplet_rhythm", - path = "j_cry_triplet_rhythm.png", - px = 71, - py = 95 -} -local booster = { - object_type = "Joker", - name = "cry-Booster Joker", - key = "booster", - config = {extra = {booster_slots = 1}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Booster Joker', - text = { - "{C:attention}+#1#{} Booster Pack slot", - } - }, - rarity = 2, - cost = 7, - discovered = true, - blueprint_compat = false, - atlas = "booster_joker", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.booster_slots}} - end, - add_to_deck = function(self, card, from_debuff) - if not G.GAME.modifiers.cry_booster_packs then G.GAME.modifiers.cry_booster_packs = 2 end - G.GAME.modifiers.cry_booster_packs = G.GAME.modifiers.cry_booster_packs + card.ability.extra.booster_slots - end, - remove_from_deck = function(self, card, from_debuff) - if not G.GAME.modifiers.cry_booster_packs then G.GAME.modifiers.cry_booster_packs = 2 end - G.GAME.modifiers.cry_booster_packs = G.GAME.modifiers.cry_booster_packs - card.ability.extra.booster_slots - end -} -local booster_sprite = { - object_type = "Atlas", - key = "booster_joker", - path = "j_cry_booster.png", - px = 71, - py = 95 -} -local chili_pepper = { - object_type = "Joker", - name = "cry-Chili Pepper", - key = "chili_pepper", - config = {extra = {Xmult = 1, Xmult_mod = 0.5, rounds_remaining = 8}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Chili Pepper', - text = { - "This joker gains {X:mult,C:white} X#2# {} Mult at end of round,", - "{C:red}self destructs{} after {C:attention}#3#{} rounds", - "{C:inactive}currently{} {X:mult,C:white} X#1# {} {C:inactive}Mult{}" - } - }, - rarity = 2, - cost = 6, - discovered = true, - blueprint_compat = false, - eternal_compat = false, - perishable_compat = false, - atlas = "chili_pepper", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.Xmult, center.ability.extra.Xmult_mod, center.ability.extra.rounds_remaining}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and not context.before and not context.after and card.ability.extra.Xmult > 1 then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, - Xmult_mod = card.ability.extra.Xmult - } - 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.Xmult = card.ability.extra.Xmult + card.ability.extra.Xmult_mod - card.ability.extra.rounds_remaining = card.ability.extra.rounds_remaining - 1 - if card.ability.extra.rounds_remaining > 0 then - return { - message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.Xmult}}, - 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 - end -} -local chili_pepper_sprite = { - object_type = "Atlas", - key = "chili_pepper", - path = "j_cry_chili_pepper.png", - px = 71, - py = 95 -} -local compound_interest = { - object_type = "Joker", - name = "cry-Compound Interest", - key = "compound_interest", - config = {extra = {percent_mod = 2, percent = 10}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Compound Interest', - text = { - "Earn {C:money}#1#%{} of total money", - "at end of round,", - "increases by {C:money}#2#%{} per", - "consecutive payout" - } - }, - rarity = 3, - cost = 8, - discovered = true, - perishable_compat = false, - atlas = "compound_interest", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.percent, center.ability.extra.percent_mod}} - end, - calc_dollar_bonus = function(self, card) - local bonus = math.max(0,math.floor(0.01*card.ability.extra.percent*G.GAME.dollars)) - card.ability.extra.percent = card.ability.extra.percent + card.ability.extra.percent_mod - if bonus > 0 then return bonus end - end -} -local compound_interest_sprite = { - object_type = "Atlas", - key = "compound_interest", - path = "j_cry_compound_interest.png", - px = 71, - py = 95 -} - -local big_cube = { - object_type = "Joker", - name = "cry-Big Cube", - key = "big_cube", - joker_gate = "cry-Cube", - config = {extra = {Xchips = 6}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Big Cube', - text = { - "{X:chips,C:white} X#1# {} Chips" - } - }, - rarity = 1, - cost = 25, - discovered = true, - atlas = "big_cube", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.Xchips}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and not context.before and not context.after then - return { - message = "X"..card.ability.extra.Xchips, - Xchip_mod = card.ability.extra.Xchips, - colour = G.C.CHIPS - } - end - end -} -local big_cube_sprite = { - object_type = "Atlas", - key = "big_cube", - path = "j_cry_big_cube.png", - px = 71, - py = 95 -} - -local eternalflame = { - object_type = "Joker", - name = "cry-eternalflame", - key = "eternalflame", - pos = {x = 0, y = 0}, - config = {extra = {extra = 0.1, x_mult = 1}}, - loc_txt = { - name = 'Eternal Flame', - text = { - "This Joker gains {X:mult,C:white} X#1# {} Mult", - "for each card {C:attention}sold{}", - "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" - } - }, - rarity = 3, - cost = 9, - discovered = true, - perishable_compat = false, - blueprint_compat = true,loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.extra, center.ability.extra.x_mult}} - end, - atlas = "eternalflame", - calculate = function(self, card, context) - if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - if context.selling_card and not context.blueprint then - card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) - return {calculated = true} - end - end -} -local eternalflame_sprite = { - object_type = "Atlas", - key = "eternalflame", - - path = "j_cry_eternalflame.png", - px = 71, - py = 95 -} - -local nice = { - object_type = "Joker", - name = "cry-Nice", - key = "nice", - config = {extra = {chips = 420, sixcount = 0, ninecount = 0}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Nice', - text = { - "{C:chips}+#1#{} Chips if played hand", - "contains a {C:attention}6{} and a {C:attention}9" - } - }, - rarity = 3, - cost = 6.9, - discovered = true, - atlas = "nice", - blueprint_compat = true,loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.chips}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and context.before and not context.after then - card.ability.extra.sixcount = 0 - card.ability.extra.ninecount = 0 - for i, v in pairs (context.full_hand) do - if v:get_id() == 6 then - card.ability.extra.sixcount = card.ability.extra.sixcount + 1 - elseif v:get_id() == 9 then - card.ability.extra.ninecount = card.ability.extra.ninecount + 1 - end - end - elseif context.cardarea == G.jokers and not context.before and not context.after then - if card.ability.extra.sixcount > 0 and card.ability.extra.ninecount > 0 then - return { - message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips or 0}}, - chip_mod = card.ability.extra.chips or 0 - } - end - end - end -} -local seal_the_deal = { - object_type = "Joker", - name = "cry-Seal The Deal", - key = "seal_the_deal", - config = {extra = {Xchips = 6}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Seal the Deal', - text = { - "Add a {C:attention}random seal{} to all", - "cards scored on {C:attention}last hand{} played" - } - }, - rarity = 2, - cost = 6, - discovered = true, - atlas = "seal_the_deal", - calculate = function(self, card, context) - if context.individual and context.cardarea == G.play then - if G.GAME.current_round.hands_left == 0 then - G.E_MANAGER:add_event(Event({ - func = function() - local seal_type = pseudorandom(pseudoseed("seal_the_deal")) - if seal_type > 0.75 then context.other_card:set_seal("Red", true) - elseif seal_type > 0.5 then context.other_card:set_seal("Blue", true) - elseif seal_type > 0.25 then context.other_card:set_seal("Gold", true) - else context.other_card:set_seal("Purple", true) - end - card:juice_up(0.3,0.4) - context.other_card:juice_up(0.3,0.3) - play_sound('gold_seal', 1.2, 0.4) - return true - end - })) - delay(0.5) - return true - end - end - end -} -local nice_sprite = { - object_type = "Atlas", - key = "nice", - path = "j_cry_nice.png", - px = 71, - py = 95 -} - -local seal_the_deal_sprite = { - object_type = "Atlas", - key = "seal_the_deal", - path = "j_cry_seal_the_deal.png", - px = 71, - py = 95 -} - -local chad = { - object_type = "Joker", - name = "cry-Chad", - key = "chad", - pos = {x = 0, y = 0}, - config = {extra = {retriggers = 2}}, - loc_txt = { - name = 'Chad', - text = { - "Retrigger {C:attention}leftmost{} Joker", - "{C:attention}#1#{} additional time(s)" - } - }, - rarity = 3, - cost = 10, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.retriggers}} - end, - atlas = "chad", - calculate = function(self, card, context) - if context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= self then - if context.other_card == G.jokers.cards[1] then - return { - message = localize('k_again_ex'), - repetitions = card.ability.extra.retriggers, - card = card - } - else return {calculated = true} end - end - end -} -local chad_sprite = { - object_type = "Atlas", - key = "chad", - path = "j_cry_chad.png", - px = 71, - py = 95 -} -local jimball = { - object_type = "Joker", - name = "cry-Jimball", - key = "jimball", - pos = {x = 0, y = 0}, - config = {x_mult = 1, extra = 0.15}, - loc_txt = { - name = 'Jimball', - text = { - "This Joker gains {X:mult,C:white} X#1# {} Mult", - "per {C:attention}consecutive{} hand played", - "while playing your", - "most played {C:attention}poker hand", - "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" - } - }, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra, center.ability.x_mult}} - end, - rarity = 3, - cost = 10, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - calculate = function(self, card, context) - if context.before and not context.blueprint then - local reset = false - local play_more_than = (G.GAME.hands[context.scoring_name].played or 0) - for k, v in pairs(G.GAME.hands) do - if k ~= context.scoring_name and v.played >= play_more_than and v.visible then - reset = true - end - end - if reset then - if card.ability.x_mult > 1 then - card.ability.x_mult = 1 - return { - card = self, - message = localize('k_reset') - } - end - else - card.ability.x_mult = card.ability.x_mult + card.ability.extra - end - end - end, - atlas = "jimball", -} -local jimball_sprite = { - object_type = "Atlas", - key = "jimball", - path = "j_cry_jimball.png", - px = 71, - py = 95 -} - -local sus = { - object_type = "Joker", - name = "cry-SUS", - key = "sus", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'SUS', - text = { - "At end of round, create", - "a {C:attention}copy{} of a random", - "card {C:attention}held in hand{},", - "destroy all others" - } - }, - rarity = 3, - cost = 9, - discovered = true, - blueprint_compat = true, - atlas = "sus", - calculate = function(self, card, context) - if context.end_of_round and not context.cardarea then - if not card.ability.used_round or card.ability.used_round ~= G.GAME.round then - card.ability.chosen_card = nil - end - local choosable_cards = {} - for i = 1, #G.hand.cards do - if not G.hand.cards[i].murdered_by_impostor then - choosable_cards[#choosable_cards+1] = G.hand.cards[i] - end - end - card.ability.chosen_card = card.ability.chosen_card or pseudorandom_element(choosable_cards, pseudoseed('cry_sus')) - if not card.ability.used_round or card.ability.used_round ~= G.GAME.round then - card.ability.used_round = G.GAME.round - local deletable_cards = {} - for k, v in pairs(G.hand.cards) do - if not v.ability.eternal then deletable_cards[#deletable_cards + 1] = v end - end - local _first_dissolve = nil - G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.75, func = function() - for k, v in pairs(deletable_cards) do - if v ~= card.ability.chosen_card then - v.murdered_by_impostor = true - v:start_dissolve(nil, _first_dissolve) - _first_dissolve = true - end - end - return true end })) - end - G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.4, func = function() - card:juice_up(0.3, 0.4) - G.playing_card = (G.playing_card and G.playing_card + 1) or 1 - local _c = copy_card(card.ability.chosen_card, nil, nil, G.playing_card) - _c:start_materialize() - _c:add_to_deck() - G.deck.config.card_limit = G.deck.config.card_limit + 1 - table.insert(G.playing_cards, _c) - G.hand:emplace(_c) - playing_card_joker_effects({_c}) - return true end })) - return {message = "Impostor!"} - end - end -} -local sus_sprite = { - object_type = "Atlas", - key = "sus", - path = "j_cry_sus.png", - px = 71, - py = 95 -} -local fspinner = { - object_type = "Joker", - name = "cry-fspinner", - key = "fspinner", - pos = {x = 0, y = 0}, - config = {extra = {chips = 0, chip_mod = 14}}, - loc_txt = { - name = 'Fidget Spinner', - text = { - "This Joker gains {C:chips}+#2#{} Chips", - "if hand played is {C:attention}not{}", - "most played {C:attention}poker hand{}", - "{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips)" - } - }, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.chips, center.ability.extra.chip_mod}} - end, - rarity = 2, - cost = 6, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - atlas = 'fspinner', - calculate = function(self, card, context) - if context.before and not context.blueprint then - local play_more_than = (G.GAME.hands[context.scoring_name].played or 0) - for k, v in pairs(G.GAME.hands) do - if k ~= context.scoring_name and v.played >= play_more_than and v.visible then - card.ability.extra.chips = card.ability.extra.chips + card.ability.extra.chip_mod - return { - message = localize('k_upgrade_ex'), - card = card, - } - end - end - - end - if context.cardarea == G.jokers and (card.ability.extra.chips > 0) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_chips',vars={card.ability.extra.chips}}, - chip_mod = card.ability.extra.chips - } - end - end, - atlas = "fspinner", -} -local fspinner_sprite = { - object_type = "Atlas", - key = "fspinner", - path = "j_cry_fspinner.png", - px = 71, - py = 95 -} -local waluigi = { - object_type = "Joker", - name = "cry-Waluigi", - key = "waluigi", - pos = {x = 0, y = 0}, - soul_pos = {x = 1, y = 0}, - config = {extra = {Xmult = 2.5}}, - loc_txt = { - name = 'Waluigi', - text = { - "All Jokers give", - "{X:mult,C:white} X#1# {} Mult" - } - }, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.Xmult}} - end, - rarity = 4, - cost = 20, - discovered = true, - blueprint_compat = true, - calculate = function(self, card, context) - if context.other_joker and context.other_joker.ability.set == "Joker" 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 - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, - Xmult_mod = card.ability.extra.Xmult - } - end - end, - atlas = "waluigi", -} -local waluigi_sprite = { - object_type = "Atlas", - key = "waluigi", - path = "j_cry_waluigi.png", - px = 71, - py = 95 -} -local krustytheclown = { - object_type = "Joker", - name = "cry-krustytheclown", - key = "krustytheclown", - pos = {x = 0, y = 0}, - config = {extra = {extra = 0.02, x_mult = 1}}, - loc_txt = { - name = 'Krusty the Clown', - text = { - "This Joker gains {X:mult,C:white} X#1# {} Mult", - "per {C:attention}card{} scored", - "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" - } - }, - rarity = 2, - cost = 7, - discovered = true, - perishable_compat = false, - blueprint_compat = true,loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.extra, center.ability.extra.x_mult}} - end, - atlas = "krustytheclown", - calculate = function(self, card, context) - if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - if context.cardarea == G.play and context.individual and not context.blueprint then - card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra - return { - extra = {focus = card, message = localize('k_upgrade_ex')}, - card = card, - colour = G.C.MULT - } - end - end -} -local krustytheclown_sprite = { - object_type = "Atlas", - key = "krustytheclown", - - path = "j_cry_krustytheclown.png", - px = 71, - py = 95 -} -local blurred = { - object_type = "Joker", - name = "cry-blurred", - key = "blurred", - pos = {x = 0, y = 0}, - config = {extra = {hands = 1}}, - loc_txt = { - name = 'Blurred Joker', - text = { - "{C:blue}+#1#{} hand(s) when", - "{C:attention}Blind{} is selected" - } - }, - rarity = 1, - cost = 4, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.hands}} - end, - atlas = "blurred", - calculate = function(self, card, context) - if context.setting_blind and not (context.blueprint_card or card).getting_sliced then - return { - message = localize('k_hand'), --make this actually work in the future - ease_hands_played(card.ability.extra.hands), - delay(0.6), - } - end - end -} -local blurred_sprite = { - object_type = "Atlas", - key = "blurred", - path = "j_cry_blurred.png", - px = 71, - py = 95 -} -local gardenfork = { - object_type = "Joker", - name = "cry-gardenfork", - key = "gardenfork", - pos = {x = 0, y = 0}, - config = {extra = {money = 7}}, - loc_txt = { - name = 'Garden of Forking Paths', - text = { "Earn {C:money}$#1#{} if {C:attention}played hand{}", - "contains an {C:attention}Ace{} and a {C:attention}7{}", - } - }, - rarity = 3, - cost = 7, - discovered = true, - blueprint_compat = true, - atlas = "gardenfork", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.money}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and context.before and not context.blueprint then - for i = 1, #context.full_hand do - if SMODS.Ranks[context.full_hand[i].base.value].key == "Ace" then - for j = 1, #context.full_hand do - if SMODS.Ranks[context.full_hand[j].base.value].key == "7" then - ease_dollars(card.ability.extra.money) - return {message = "$" .. card.ability.extra.money, colour = G.C.MONEY} - end - end - end - end - end - end -} -local gardenfork_sprite = { - object_type = "Atlas", - key = "gardenfork", - path = "j_cry_gardenfork.png", - px = 71, - py = 95 -} -local lightupthenight = { - object_type = "Joker", - name = "cry-lightupthenight", - key = "lightupthenight", - config = {extra = {xmult = 1.75}}, - pos = {x = 0, y = 0}, - atlas = 'lightupthenight', - loc_txt = { - name = 'Light Up the Night', - text = { - "Each played {C:attention}7{} or {C:attention}2{}", - "gives {X:mult,C:white}X#1#{} Mult when scored", - } - }, - rarity = 3, - cost = 7, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.xmult}} - end, - calculate = function(self, card, context) - if context.cardarea == G.play and context.individual then - local rank = SMODS.Ranks[context.other_card.base.value].key - if rank == "2" or rank == "7" then - return { - x_mult = card.ability.extra.xmult, - colour = G.C.RED, - card = card - } - end - end - end -} -local lightupthenight_sprite = { - object_type = "Atlas", - key = "lightupthenight", - path = "j_cry_lightupthenight.png", - px = 71, - py = 95 -} -local nosound = { - object_type = "Joker", - name = "cry-nosound", - key = "nosound", - config = {extra = {retriggers = 3}}, - pos = {x = 0, y = 0}, - atlas = 'nosound', - loc_txt = { - name = 'No Sound, No Memory', - text = { - "Retrigger each played {C:attention}7{}", - "{C:attention:}#1#{} additional time(s)", - } - }, - rarity = 3, - cost = 7, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = { center.ability.extra.retriggers}} - end, - calculate = function(self, card, context) - if context.repetition then - if context.cardarea == G.play then - local rank = SMODS.Ranks[context.other_card.base.value].key - if rank == "7" then - return { - message = localize('k_again_ex'), - repetitions = card.ability.extra.retriggers, - card = card - } - end - end - end - end -} -local nosound_sprite = { - object_type = "Atlas", - key = "nosound", - path = "j_cry_nosound.png", - px = 71, - py = 95 -} -local antennastoheaven = { - object_type = "Joker", - name = "cry-antennastoheaven", - key = "antennastoheaven", - pos = {x = 0, y = 0}, - config = {extra = {bonus = 0.1, Xchips = 1}}, - loc_txt = { - name = '...Like Antennas to Heaven', - text = { - "This Joker gains {X:chips,C:white} X#1# {} Chips", - "per {C:attention}7{} or {C:attention}4{} scored", - "{C:inactive}(Currently {X:chips,C:white} X#2# {C:inactive} Chips)" - } - }, - rarity = 3, - cost = 7, - discovered = true, - perishable_compat = false, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.bonus, center.ability.extra.Xchips}} - end, - atlas = "antennastoheaven", - calculate = function(self, card, context) - if context.cardarea == G.jokers and (card.ability.extra.Xchips > 1) and not context.before and not context.after then - return { - message = "X"..card.ability.extra.Xchips, - Xchip_mod = card.ability.extra.Xchips, - colour = G.C.CHIPS - } - end - if context.cardarea == G.play and context.individual and not context.blueprint then - local rank = SMODS.Ranks[context.other_card.base.value].key - if rank == "4" or rank == "7" then - card.ability.extra.Xchips = card.ability.extra.Xchips + card.ability.extra.bonus - return { - extra = {focus = card, message = localize('k_upgrade_ex')}, - card = card, - colour = G.C.CHIPS - } - end - end - end -} -local antennastoheaven_sprite = { - object_type = "Atlas", - key = "antennastoheaven", - path = "j_cry_antennastoheaven.png", - px = 71, - py = 95 -} -local hunger = { - object_type = "Joker", - name = "cry-hunger", - key = "hunger", - config = {extra = {money = 3}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Consume-able', - text = { - "Earn {C:money}$#1#{} when", - "using a {C:attention}consumable{}", - } - }, - rarity = 2, - cost = 6, - discovered = true, - blueprint_compat = true, - atlas = "hunger", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.money}} - end, - calculate = function(self, card, context) --This didn't work for Jevonn for some reason but it works for me :joker: - if context.using_consumeable then - ease_dollars(card.ability.extra.money) - return {calculated = true} - end - end -} -local hunger_sprite = { - object_type = "Atlas", - key = "hunger", - path = "j_cry_hunger.png", - px = 71, - py = 95 -} -local weegaming = { - object_type = "Joker", - name = "cry-weegaming", - key = "weegaming", - config = {extra = {retriggers = 2}}, - pos = {x = 0, y = 0}, - atlas = 'weegaming', - loc_txt = { - name = '2D', - text = { - "Retrigger each played {C:attention}2{}", --wee gaming - "{C:attention:}#1#{} additional time(s) when scored", --wee gaming? - } - }, - rarity = 1, - cost = 5, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = { center.ability.extra.retriggers}} - end, - calculate = function(self, card, context) - if context.repetition then - if context.cardarea == G.play then - local rank = SMODS.Ranks[context.other_card.base.value].key - if rank == "2" then - return { - message = localize('k_again_ex'), - repetitions = card.ability.extra.retriggers, - card = card - } - end - end - end - end -} -local weegaming_sprite = { - object_type = "Atlas", - key = "weegaming", - path = "j_placeholder.png", - px = 71, - py = 95 -} -local redbloon = { - object_type = "Joker", - name = "cry-redbloon", - key = "redbloon", - config = {extra = {money = 20, rounds_remaining = 2, text = "s"}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Red Bloon', - text = { - "Earn {C:money}$#1#{} in {C:attention}#2#{} round#3#", - "{C:red}self destructs{}" - } - }, - rarity = 1, - cost = 2, - discovered = true, - blueprint_compat = false, - eternal_compat = false, - perishable_compat = false, - atlas = "redbloon", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.money, center.ability.extra.rounds_remaining, center.ability.extra.text}} - end, - calculate = function(self, card, context) - 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 = card.ability.extra.rounds_remaining - 1 - if card.ability.extra.rounds_remaining > 0 then - return { - message = {"-1 Round"}, - colour = G.C.FILTER - } - else - ease_dollars(card.ability.extra.money) - 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 = "$" .. card.ability.extra.money, colour = G.C.MONEY - } - end - end - if card.ability.extra.rounds_remaining == 1 then - card.ability.extra.text = "" - end - end -} -local redbloon_sprite = { - object_type = "Atlas", - key = "redbloon", - path = "j_cry_redbloon.png", - px = 71, - py = 95 -} -local apjoker = { - object_type = "Joker", - name = "cry-apjoker", - key = "apjoker", - pos = {x = 0, y = 0}, - config = {extra = {x_mult = 4}}, - loc_txt = { - name = 'AP Joker', - text = { "{X:mult,C:white} X#1# {} Mult against {C:attention}Boss Blinds{}"} - }, - rarity = 2, - cost = 6, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - atlas = "apjoker", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.x_mult}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and G.GAME.blind.boss and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - end -} -local apjoker_sprite = { - object_type = "Atlas", - key = "apjoker", - path = "j_cry_apjoker.png", - px = 71, - py = 95 -} -local maze = { - object_type = "Joker", - name = "cry-maze", - key = "maze", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Labyrinth', - text = { - "All hands are considered the", - "{C:attention}first hand{} of each round,", - "all discards are considered the", - "{C:attention}first discard{} of each round" - } - }, - rarity = 1, - cost = 3, - discovered = true, - atlas = "maze", - calculate = function(self, card, context) - if (context.before or context.after or context.pre_discard or context.discard or context.cardarea == G.hand) and not context.blueprint and not context.retrigger_joker then - G.GAME.current_round.hands_played = 0 - G.GAME.current_round.discards_used = 0 - end - end, - add_to_deck = function(self, card, from_debuff) - G.GAME.current_round.hands_played = 0 - G.GAME.current_round.discards_used = 0 - end -} - -local maze_sprite = { - object_type = "Atlas", - key = "maze", - path = "j_cry_labyrinth.png", - px = 71, - py = 95 -} - ---Notes from my testing --- I've found that DNA and Burnt Joker work SOMEWHAT but can be jank at times (ESPECIALLY so with retrigger jokers). i can only assume other modded jokers will behave in a similar way. Trading card and sixth sense work without any issues tho so yey -local unjust_dagger = { -object_type = "Joker", -name = "cry-Unjust Dagger", -key = "unjust_dagger", -pos = {x = 0, y = 0}, -config = {extra = {x_mult = 1}}, -loc_txt = { -name = 'Unjust Dagger', -text = { -"When {C:attention}Blind{} is selected,", -"destroy Joker to the left", -"and gain {C:attention}one-fifth{} of", -"its sell value as {X:mult,C:white} XMult {}", -"{C:inactive}(Currently {X:mult,C:white} X#1# {C:inactive} Mult)" -} -}, -rarity = 2, -cost = 7, -discovered = true, -perishable_compat = false, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.x_mult}} - end, -atlas = "unjust_dagger", -calculate = function(self, card, context) - if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - local my_pos = nil - for i = 1, #G.jokers.cards do - if G.jokers.cards[i] == card then my_pos = i; break end -end - if context.setting_blind and not (context.blueprint_card or self).getting_sliced and my_pos and G.jokers.cards[my_pos-1] and not G.jokers.cards[my_pos-1].ability.eternal and not G.jokers.cards[my_pos-1].getting_sliced then - local sliced_card = G.jokers.cards[my_pos-1] - sliced_card.getting_sliced = true - G.GAME.joker_buffer = G.GAME.joker_buffer - 1 - G.E_MANAGER:add_event(Event({func = function() - G.GAME.joker_buffer = 0 - card.ability.extra.x_mult = card.ability.extra.x_mult + sliced_card.sell_cost*0.2 - card:juice_up(0.8, 0.8) - sliced_card:start_dissolve({HEX("57ecab")}, nil, 1.6) - play_sound('slice1', 0.96+math.random()*0.08) - return true end })) - card_eval_status_text(self, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult+0.2*sliced_card.sell_cost}}, colour = G.C.RED, no_juice = true}) -return {calculated = true} - end - end -} -local unjust_dagger_sprite = { -object_type = "Atlas", - key = "unjust_dagger", - path = "j_cry_unjust_dagger.png", - px = 71, - py = 95 -} -local jollysus = { - object_type = "Joker", - name = "cry-jollysus", - key = "jollysus", - pos = {x = 0, y = 0}, - config = {extra = {spawn = true, active = "Active!", inactive = ""}, jolly = {t_mult = 8, type = 'Pair'}}, - loc_txt = { - name = 'Jolly Joker?', - text = { - "Create a {C:attention}Jolly Joker{}", - "when a joker is {C:attention}sold{}", - "{C:red}Works 1 time per round{}", - "{C:inactive}#1##2#{}" - } - }, - rarity = 2, - cost = 5, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } - return {vars = {center.ability.extra.active, center.ability.extra.inactive}} - end, - atlas = "jollysus", - calculate = function(self, card, context) - if context.end_of_round and not context.retrigger_joker and not context.blueprint then - if not card.ability.extra.spawn then - card.ability.extra.active = "Active!" - card.ability.extra.inactive = "" - card.ability.extra.spawn = true - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "Reset", - colour = G.C.FILTER, - }) - } - end - end - if ((context.selling_card and context.card.ability.name == "cry-jollysus") or context.selling_self) and card.ability.extra.spawn and not context.retrigger_joker then --add support for selling itself (Blueprint compatible) - if not context.blueprint and not context.retrigger_joker then --ok tested this and making it sell itself next to blueprints doesn't make the blueprints create jokers, but it creates copies correctly when selling itself or blueprint so good enough for me - card.ability.extra.active = "" --also this doesn't work with brainstorm either (what is this jank????) - card.ability.extra.inactive = "No triggers left!" - card.ability.extra.spawn = false - end - local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') - card:add_to_deck() - G.jokers:emplace(card) --man, now that I think about it this is probably the most complicated joker i've done so far - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "M!", - colour = G.C.FILTER, - }) - } - end - if context.selling_card and card.ability.extra.spawn and not context.retrigger_joker then - if context.card.ability.set == 'Joker' then - if not context.blueprint and not context.retrigger_joker then - card.ability.extra.active = "" - card.ability.extra.inactive = "No triggers left!" - card.ability.extra.spawn = false - end - local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') - card:add_to_deck() - G.jokers:emplace(card) - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "M!", - colour = G.C.FILTER, - }) - } - end - end - end -} -local jollysus_sprite = { - object_type = "Atlas", - key = "jollysus", - path = "j_cry_jollysus.png", - px = 71, - py = 95 -} -local bubblem = { - object_type = "Joker", - name = "cry-bubblem", - key = "bubblem", - pos = {x = 0, y = 0}, - config = {extra = {spawn = false}, jolly = {t_mult = 8, type = 'Pair'}}, - loc_txt = { - name = 'Bubble M', - text = { - "Create a {C:dark_edition}Foil {C:attention}Jolly Joker{}", - "if hand played contains", - "a {C:attention}Four of a kind{}", - "{C:red}self destructs{}", - } - }, - rarity = 1, - cost = 2, - discovered = true, - loc_vars = function(self, info_queue, center) - info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } - info_queue[#info_queue+1] = G.P_CENTERS.e_foil - end, - atlas = "bubblem", - calculate = function(self, card, context) - if context.scoring_name and (context.scoring_name == 'Five of a Kind' or context.scoring_name == 'Four of a Kind' or context.scoring_name == 'Flush Five') then - card.ability.extra.spawn = true - end - - if context.cardarea == G.jokers and card.ability.extra.spawn and context.before and not context.blueprint and not context.retrigger_joker 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(self) - card:remove() - card = nil - return true - end - })) - return true - end - })) - local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') - card:set_edition({ - foil = true - }) - card:add_to_deck() - G.jokers:emplace(card) - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "M!", - colour = G.C.FILTER, - }) - } - end - end -} - -local bubblem_sprite = { - object_type = "Atlas", - key = "bubblem", - path = "j_cry_bubblem.png", - px = 71, - py = 95 -} -local mstack = { - object_type = "Joker", - name = "cry-mstack", - key = "mstack", - config = {extra = {sell = 0, retriggers = 0, text = ""}, jolly = {t_mult = 8, type = 'Pair'}}, - pos = {x = 0, y = 0}, - atlas = 'mstack', - loc_txt = { - name = 'M Stack', - text = { - "Retrigger all cards played", - "once for every {C:attention}2 Jolly Jokers{}", - "{C:attention}sold{}, up to {C:attention}8 sold{}", - "{C:inactive}Currently{}{C:attention:} #1#{}{C:inactive} retriggers #2#{}", - } - }, - rarity = 2, - cost = 7, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } - return {vars = {center.ability.extra.retriggers, center.ability.extra.text}} - end, - calculate = function(self, card, context) --note: hardcoded like this intentionally - if context.repetition then - if context.cardarea == G.play then - return { - message = localize('k_again_ex'), - repetitions = card.ability.extra.retriggers, - card = card - } - end - end - - if context.selling_card and context.card.ability.name == "Jolly Joker" and card.ability.extra.retriggers < 4 and not context.blueprint and not context.retrigger_joker then - if card.ability.extra.sell == 1 then - if not context.blueprint or context.retrigger_joker then - card.ability.extra.retriggers = card.ability.extra.retriggers + 1 - end - card.ability.extra.sell = 0 - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "Upgrade!", - colour = G.C.FILTER, - }) - } - else - card.ability.extra.sell = card.ability.extra.sell + 1 - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "1/2", - colour = G.C.FILTER, - }) - } - end - end - - if card.ability.extra.retriggers == 4 then - card.ability.extra.text = "(MAX)" - end - end, -} - -local mstack_sprite = { - object_type = "Atlas", - key = "mstack", - path = "j_cry_mstack.png", - px = 71, - py = 95 -} -return {name = "Misc. Jokers", - init = function() - --Dropshot Patches - local gigo = Game.init_game_object; - function Game:init_game_object() - local g = gigo(self) - g.current_round.cry_dropshot_card = {suit = 'Spades'} - return g - end - local rcc = reset_castle_card; - function reset_castle_card() - rcc() - G.GAME.current_round.cry_dropshot_card.suit = 'Spades' - local valid_castle_cards = {} - for k, v in ipairs(G.playing_cards) do - if v.ability.effect ~= 'Stone Card' then - valid_castle_cards[#valid_castle_cards+1] = v - end - end - if valid_castle_cards[1] then - local castle_card = pseudorandom_element(valid_castle_cards, pseudoseed('cry_dro'..G.GAME.round_resets.ante)) - if not G.GAME.current_round.cry_dropshot_card then - G.GAME.current_round.cry_dropshot_card = {} - end - G.GAME.current_round.cry_dropshot_card.suit = castle_card.base.suit - end - end - - --Maximized Patches - local cgi_ref = Card.get_id - override_maximized = false - function Card:get_id() - local id = cgi_ref(self) - if (next(find_joker("cry-Maximized")) and not override_maximized) then - if (id >= 2 and id <= 10) then id = 10 end - if (id >= 11 and id <= 13 or next(find_joker("Pareidolia"))) then id = 13 end - end - return id - end - --Fix issues with View Deck and Maximized - local gui_vd = G.UIDEF.view_deck - function G.UIDEF.view_deck(unplayed_only) - override_maximized = true - local ret_value = gui_vd(unplayed_only) - override_maximized = false - return ret_value - end - - --Cube Patches - local sc = Card.set_cost - function Card:set_cost() - sc(self) - if self.ability.name == "cry-Cube" then - self.cost = -25 - end - if self.ability.name == "cry-Big Cube" then - self.cost = 25 - end - end - - --Jimball Patches - local upd = Game.update - cry_jimball_dt = 0 - function Game:update(dt) - upd(self,dt) - cry_jimball_dt = cry_jimball_dt + dt - if G.P_CENTERS and G.P_CENTERS.j_cry_jimball and cry_jimball_dt > 0.1 then - cry_jimball_dt = 0 - local obj = G.P_CENTERS.j_cry_jimball - if (obj.pos.x == 5 and obj.pos.y == 6) then - obj.pos.x = 0 - obj.pos.y = 0 - elseif (obj.pos.x < 8) then obj.pos.x = obj.pos.x + 1 - elseif (obj.pos.y < 6) then - obj.pos.x = 0 - obj.pos.y = obj.pos.y + 1 - end - end - end - - end, - items = {dropshot_sprite, maximized_sprite, potofjokes_sprite, queensgambit_sprite, whip_sprite, lucky_joker_sprite, cursor_sprite, pickle_sprite, cube_sprite, triplet_rhythm_sprite, booster_sprite, chili_pepper_sprite, compound_interest_sprite, big_cube_sprite, eternalflame_sprite, nice_sprite, sus_sprite, chad_sprite, waluigi_sprite, seal_the_deal_sprite, jimball_sprite, fspinner_sprite, krustytheclown_sprite, blurred_sprite, gardenfork_sprite, lightupthenight_sprite, nosound_sprite, antennastoheaven_sprite, hunger_sprite, weegaming_sprite, redbloon_sprite, apjoker_sprite, maze_sprite, unjust_dagger_sprite, jollysus_sprite, bubblem_sprite, mstack_sprite, dropshot, maximized, potofjokes, queensgambit, wee_fib, compound_interest, whip, pickle, triplet_rhythm, booster, chili_pepper, lucky_joker, cursor, cube, big_cube, nice, sus, chad, jimball, waluigi, eternalflame, seal_the_deal, fspinner, krustytheclown, blurred, gardenfork, lightupthenight, nosound, antennastoheaven, hunger, weegaming, redbloon, apjoker, maze, unjust_dagger, jollysus, bubblem, mstack,}} diff --git a/Items/Items/Planets.lua b/Items/Items/Planets.lua deleted file mode 100644 index 4ffaa0f9a..000000000 --- a/Items/Items/Planets.lua +++ /dev/null @@ -1,142 +0,0 @@ -local timantti = { - object_type = "Consumable", - set = "Planet", - name = "cry-Timantti", - key = "Timantti", - pos = {x=0,y=0}, - config = {hand_types = {'High Card', 'Pair', 'Two Pair'}}, - loc_txt = { - name = 'Timantti', - text = { - "Level up {C:attention}#1#{},", - "{C:attention}#2#{}, and {C:attention}#3#" - } - }, - cost = 4, - discovered = true, - atlas = "c_suits", - can_use = function(self, card) - return true - end, - loc_vars = function(self, info_queue, center) - return {vars = self.config.hand_types} - end, - use = function(self, card, area, copier) - suit_level_up(self, card, area, copier) - end, - bulk_use = function(self, card, area, copier, number) - suit_level_up(self, card, area, copier, number) - end -} -local klubi = { - object_type = "Consumable", - set = "Planet", - name = "cry-Klubi", - key = "Klubi", - pos = {x=1,y=0}, - config = {hand_types = {'Three of a Kind', 'Straight', 'Flush'}}, - loc_txt = { - name = 'Klubi', - text = { - "Level up {C:attention}#1#{},", - "{C:attention}#2#{}, and {C:attention}#3#" - } - }, - cost = 4, - discovered = true, - atlas = "c_suits", - can_use = function(self, card) - return true - end, - loc_vars = function(self, info_queue, center) - return {vars = self.config.hand_types} - end, - use = function(self, card, area, copier) - suit_level_up(self, card, area, copier) - end, - bulk_use = function(self, card, area, copier, number) - suit_level_up(self, card, area, copier, number) - end -} -local sydan = { - object_type = "Consumable", - set = "Planet", - name = "cry-Sydan", - key = "Sydan", - pos = {x=2,y=0}, - config = {hand_types = {'Four of a Kind', 'Straight Flush', 'Full House'}}, - loc_txt = { - name = 'Sydan', - text = { - "Level up {C:attention}#1#{},", - "{C:attention}#2#{}, and {C:attention}#3#" - } - }, - cost = 4, - discovered = true, - atlas = "c_suits", - can_use = function(self, card) - return true - end, - loc_vars = function(self, info_queue, center) - return {vars = self.config.hand_types} - end, - use = function(self, card, area, copier) - suit_level_up(self, card, area, copier) - end, - bulk_use = function(self, card, area, copier, number) - suit_level_up(self, card, area, copier, number) - end -} -local lapio = { - object_type = "Consumable", - set = "Planet", - name = "cry-Lapio", - key = "Lapio", - pos = {x=3,y=0}, - config = {hand_types = {'Five of a Kind', 'Flush House', 'Flush Five'}, softlock = true}, - loc_txt = { - name = 'Lapio', - text = { - "Level up {C:attention}#1#{},", - "{C:attention}#2#{}, and {C:attention}#3#" - } - }, - cost = 4, - discovered = true, - atlas = "c_suits", - can_use = function(self, card) - return true - end, - loc_vars = function(self, info_queue, center) - return {vars = self.config.hand_types} - end, - use = function(self, card, area, copier) - suit_level_up(self, card, area, copier) - end, - bulk_use = function(self, card, area, copier, number) - suit_level_up(self, card, area, copier, number) - end -} - -function suit_level_up(center, card, area, copier, number) - for _, v in pairs(card.config.center.config.hand_types) do - update_hand_text({sound = 'button', volume = 0.7, pitch = 0.8, delay = 0.3}, {handname=localize(v, 'poker_hands'),chips = G.GAME.hands[v].chips, mult = G.GAME.hands[v].mult, level=G.GAME.hands[v].level}) - level_up_hand(card, v, nil, number) - update_hand_text({sound = 'button', volume = 0.7, pitch = 1.1, delay = 0}, {mult = 0, chips = 0, handname = '', level = ''}) - end -end - -local suits_sprite = { - object_type = "Atlas", - key = "c_suits", - path = "c_cry_suits.png", - px = 71, - py = 95 -} - -return {name = "Planets", - init = function() - - end, - items = {suits_sprite, sydan, klubi, lapio, timantti}} \ No newline at end of file diff --git a/Items/Items/Spectrals.lua b/Items/Items/Spectrals.lua deleted file mode 100644 index 2ae68c6a1..000000000 --- a/Items/Items/Spectrals.lua +++ /dev/null @@ -1,272 +0,0 @@ -local white_hole = { - object_type = "Consumable", - set = "Spectral", - name = "cry-White Hole", - key = "white_hole", - pos = {x=0,y=0}, - loc_txt = { - name = 'White Hole', - text = { "{C:attention}Remove{} all hand levels,", - "upgrade {C:legendary,E:1}most played{} poker hand", - "by {C:attention}3{} for each removed level" - } - }, - cost = 4, - atlas = "white_hole", - discovered = true, - 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) - --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(card, 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(card, _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) - --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(card, 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(card, _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 white_hole_sprite = { - object_type = "Atlas", - key = "white_hole", - path = "c_cry_white_hole.png", - px = 71, - py = 95 -} - -local vacuum = { - object_type = "Consumable", - set = "Spectral", - name = "cry-Vacuum", - key = "vacuum", - pos = {x=0,y=0}, - config = {extra = 4}, - loc_txt = { - name = 'Vacuum', - text = { - "Removes {C:red}all {C:green}modifications{}", - "from {C:red}all{} cards in your hand,", - "Earn {C:money}$#1#{} per {C:green}modification{} removed", - "{C:inactive,s:0.7}(ex. Enhancements, Seals, Editions)" - } - }, - cost = 15, - atlas = "vacuum", - discovered = true, - 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 earnings = 0 - G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() - play_sound('tarot1') - card: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 vacuum_sprite = { - object_type = "Atlas", - key = "vacuum", - - path = "c_cry_vacuum.png", - px = 71, - py = 95 -} - -local hammerspace = { - object_type = "Consumable", - set = "Spectral", - name = "cry-Hammerspace", - key = "hammerspace", - pos = {x=0,y=0}, - config = {}, - loc_txt = { - name = 'Hammerspace', - text = { - "Apply random {C:attention}consumables{}", - "as if they were {C:dark_edition}Enhancements{}", - "to your {C:attention}entire hand{}", - "{C:red}-1{} hand size" - } - }, - cost = 4, - atlas = "hammerspace", - discovered = true, - can_use = function(self, card) - return #G.hand.cards > 0 - end, - use = function(self, card, area, copier) - G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.4, func = function() - play_sound('tarot1') - card: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(G.P_CENTERS[pseudorandom_element(G.P_CENTER_POOLS.Consumeables, pseudoseed('cry_hammerspace')).key], true, nil);play_sound('tarot2', percent);CARD:juice_up(0.3, 0.3);return true end })) - end - G.hand:change_size(-1) - end -} -local hammerspace_sprite = { - object_type = "Atlas", - key = "hammerspace", - path = "s_hammerspace.png", - px = 71, - py = 95 -} - -local lock = { - object_type = "Consumable", - set = "Spectral", - name = "cry-Lock", - key = "lock", - pos = {x=0,y=0}, - config = {}, - loc_txt = { - name = 'Lock', - text = { - "Remove {C:red}all{} stickers from {C:red}all {C:attention}Jokers{},", - "then apply {C:purple,E:1}Eternal{} to a random {C:attention}Joker{}" - } - }, - cost = 4, - atlas = "lock", - discovered = true, - can_use = function(self, card) - return #G.jokers.cards > 0 - end, - use = function(self, card, area, copier) - 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') - card: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);CARD:set_eternal(nil);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') - card: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 lock_sprite = { - object_type = "Atlas", - key = "lock", - - path = "c_cry_lock.png", - px = 71, - py = 95 -} - -return {name = "Spectrals", - init = function() - - end, - items = {white_hole_sprite, vacuum_sprite, hammerspace_sprite, lock_sprite, white_hole, vacuum, hammerspace, lock}} diff --git a/Items/Items/Stakes.lua b/Items/Items/Stakes.lua deleted file mode 100644 index ba68d3f79..000000000 --- a/Items/Items/Stakes.lua +++ /dev/null @@ -1,672 +0,0 @@ -local pink = {object_type = "Stake", - name = "cry-Pink Stake", - key = "pink", - pos = {x = 0, y = 0}, - atlas = "stake", - applied_stakes = {"gold"}, - loc_txt = { - name = "Pink Stake", - text = { - "Required score scales", - "faster for each {C:attention}Ante" - } - }, - modifiers = function() - G.GAME.modifiers.scaling = math.max(G.GAME.modifiers.scaling or 0, 4) - end, - color = HEX("ff5ee6") -} -local brown = {object_type = "Stake", - name = "cry-Brown Stake", - key = "brown", - pos = {x = 1, y = 0}, - atlas = "stake", - applied_stakes = {"cry_pink"}, - modifiers = function() - G.GAME.modifiers.cry_eternal_perishable_compat = true - end, - loc_txt = { - name = "Brown Stake", - text = { - "All {C:attention}stickers{} are compatible", - "with each other" - } - }, - color = HEX("883200") -} -local yellow = {object_type = "Stake", - name = "cry-Yellow Stake", - key = "yellow", - pos = {x = 2, y = 0}, - atlas = "stake", - applied_stakes = {"cry_brown"}, - modifiers = function() - G.GAME.modifiers.cry_any_stickers = true - end, - loc_txt = { - name = "Yellow Stake", - text = { - "{C:attention}Stickers{} can appear on", - "all purchasable items" - } - }, - color = HEX("f7ff1f") -} -local jade = {object_type = "Stake", - name = "cry-Jade Stake", - key = "jade", - pos = {x = 3, y = 0}, - atlas = "stake", - applied_stakes = {"cry_yellow"}, - modifiers = function() - G.GAME.modifiers.flipped_cards = 20 - end, - loc_txt = { - name = "Jade Stake", - text = { - "Cards can be drawn {C:attention}face down{}", - } - }, - shiny = true, - color = HEX("78953c") -} -local cyan = {object_type = "Stake", - name = "cry-Cyan Stake", - key = "cyan", - pos = {x = 4, y = 0}, - atlas = "stake", - applied_stakes = {"cry_jade"}, - modifiers = function() - G.GAME.modifiers.cry_rarer_jokers = true - end, - loc_txt = { - name = "Cyan Stake", - text = { - "{C:green}Uncommon{} and {C:red}Rare{} Jokers are", - "less likely to appear", - } - }, - color = HEX("39ffcc") -} -local gray = {object_type = "Stake", - name = "cry-Gray Stake", - key = "gray", - pos = {x = 0, y = 1}, - atlas = "stake", - applied_stakes = {"cry_cyan"}, - modifiers = function() - G.GAME.modifiers.cry_reroll_scaling = 2 - end, - loc_txt = { - name = "Gray Stake", - text = { - "Rerolls increase by {C:attention}$2{} each" - } - }, - color = HEX("999999") -} -local crimson = {object_type = "Stake", - name = "cry-Crimson Stake", - key = "crimson", - pos = {x = 1, y = 1}, - atlas = "stake", - applied_stakes = {"cry_gray"}, - modifiers = function() - G.GAME.modifiers.cry_voucher_restock_antes = 2 - end, - loc_txt = { - name = "Crimson Stake", - text = { - "Vouchers restock on {C:attention}even{} Antes", - } - }, - color = HEX("800000") -} -local diamond = {object_type = "Stake", - name = "cry-Diamond Stake", - key = "diamond", - pos = {x = 2, y = 1}, - atlas = "stake", - applied_stakes = {"cry_crimson"}, - modifiers = function() - G.GAME.win_ante = 10 - end, - loc_txt = { - name = "Diamond Stake", - text = { - "Must beat Ante {C:attention}10{} to win", - } - }, - shiny = true, - color = HEX("88e5d9") -} -local amber = {object_type = "Stake", - name = "cry-Amber Stake", - key = "amber", - pos = {x = 3, y = 1}, - atlas = "stake", - applied_stakes = {"cry_diamond"}, - modifiers = function() - G.GAME.modifiers.cry_booster_packs = 1 - end, - loc_txt = { - name = "Amber Stake", - text = { - "{C:attention}-1{} Booster Pack slot", - } - }, - shiny = true, - color = HEX("feb900") -} -local bronze = {object_type = "Stake", - name = "cry-Bronze Stake", - key = "bronze", - pos = {x = 4, y = 1}, - atlas = "stake", - applied_stakes = {"cry_amber"}, - modifiers = function() - G.GAME.modifiers.cry_voucher_price_hike = 1.5 - end, - loc_txt = { - name = "Bronze Stake", - text = { - "Vouchers are {C:attention}50%{} more expensive", - } - }, - shiny = true, - color = HEX("d27c37") -} -local quartz = {object_type = "Stake", - name = "cry-Quartz Stake", - key = "quartz", - pos = {x = 0, y = 2}, - atlas = "stake", - applied_stakes = {"cry_bronze"}, - modifiers = function() - G.GAME.modifiers.cry_enable_pinned_in_shop = true - end, - loc_txt = { - name = "Quartz Stake", - text = { - "Jokers can be {C:attention}Pinned{}", - "{s:0.8,C:inactive}(Stays pinned to the leftmost position){}", - } - }, - shiny = true, - color = HEX("e8e8e8") -} -local ruby = {object_type = "Stake", - name = "cry-Ruby Stake", - key = "ruby", - pos = {x = 1, y = 2}, - atlas = "stake", - applied_stakes = {"cry_quartz"}, - modifiers = function() - G.GAME.modifiers.cry_big_boss_rate = 0.3 - end, - loc_txt = { - name = "Ruby Stake", - text = { - "{C:attention}Big{} Blinds can become", - "{C:attention}Boss{} Blinds", - } - }, - shiny = true, - color = HEX("fc5f55") -} -local glass = {object_type = "Stake", - name = "cry-Glass Stake", - key = "glass", - pos = {x = 2, y = 2}, - atlas = "stake", - applied_stakes = {"cry_ruby"}, - modifiers = function() - G.GAME.modifiers.cry_shatter_rate = 30 - end, - loc_txt = { - name = "Glass Stake", - text = { - "Cards can {C:attention}shatter{} when scored", - } - }, - shiny = true, - color = HEX("ffffff") -} -local sapphire = {object_type = "Stake", - name = "cry-Sapphire Stake", - key = "sapphire", - pos = {x = 3, y = 2}, - atlas = "stake", - applied_stakes = {"cry_glass"}, - modifiers = function() - G.GAME.modifiers.cry_ante_tax = 0.25 - G.GAME.modifiers.cry_ante_tax_max = 10 - end, - loc_txt = { - name = "Sapphire Stake", - text = { - "Lose {C:attention}25%{} of current money", - "at end of Ante", - "{s:0.8,C:inactive}(Up to $10){}", - } - }, - shiny = true, - color = HEX("3551fc") -} -local emerald = {object_type = "Stake", - name = "cry-Emerald Stake", - key = "emerald", - pos = {x = 4, y = 2}, - atlas = "stake", - applied_stakes = {"cry_sapphire"}, - modifiers = function() - G.GAME.modifiers.cry_enable_flipped_in_shop = true - end, - loc_txt = { - name = "Emerald Stake", - text = { - "Cards, packs, and vouchers", - "can be {C:attention}face down{}", - "{s:0.8,C:inactive}(Unable to be viewed until purchased){}", - } - }, - shiny = true, - color = HEX("06fc2c") -} -local platinum = {object_type = "Stake", - name = "cry-Platinum Stake", - key = "platinum", - pos = {x = 0, y = 3}, - atlas = "stake", - applied_stakes = {"cry_emerald"}, - modifiers = function() - G.GAME.modifiers.cry_no_small_blind = true - G.GAME.round_resets.blind_states['Small'] = 'Hide' - end, - loc_txt = { - name = "Platinum Stake", - text = { - "Small Blinds are {C:attention}removed{}", - } - }, - shiny = true, - color = HEX("b0f6ff") -} -local twilight = {object_type = "Stake", - name = "cry-Twilight Stake", - key = "twilight", - pos = {x = 1, y = 3}, - atlas = "stake", - applied_stakes = {"cry_platinum"}, - loc_txt = { - name = "Twilight Stake", - text = { - "Cards can be {C:attention}Banana{}", - "{s:0.8,C:inactive}(1 in 10 chance of being destroyed each round){}", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local verdant = {object_type = "Stake", - name = "cry-Verdant Stake", - key = "verdant", - pos = {x = 2, y = 3}, - atlas = "stake", - applied_stakes = {"cry_twilight"}, - loc_txt = { - name = "Verdant Stake", - text = { - "Required score scales", - "faster for each {C:attention}Ante", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local ember = {object_type = "Stake", - name = "cry-Ember Stake", - key = "ember", - pos = {x = 3, y = 3}, - atlas = "stake", - applied_stakes = {"cry_verdant"}, - loc_txt = { - name = "Ember Stake", - text = { - "All items have no sell value", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local dawn = {object_type = "Stake", - name = "cry-Dawn Stake", - key = "dawn", - pos = {x = 4, y = 3}, - atlas = "stake", - applied_stakes = {"cry_ember"}, - loc_txt = { - name = "Dawn Stake", - text = { - "Tarots and Spectrals target {C:attention}1", - "fewer card", - "{s:0.8,C:inactive}(Minimum of 1){}", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local horizon = {object_type = "Stake", - name = "cry-Horizon Stake", - key = "horizon", - pos = {x = 0, y = 4}, - atlas = "stake", - applied_stakes = {"cry_dawn"}, - loc_txt = { - name = "Horizon Stake", - text = { - "When blind selected, add a", - "{C:attention}random card{} to deck", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local blossom = {object_type = "Stake", - name = "cry-Blossom Stake", - key = "blossom", - pos = {x = 1, y = 4}, - atlas = "stake", - applied_stakes = {"cry_horizon"}, - loc_txt = { - name = "Blossom Stake", - text = { - "{C:attention}Final{} Boss Blinds can appear", - "after Ante 1", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local azure = {object_type = "Stake", - name = "cry-Azure Stake", - key = "azure", - pos = {x = 2, y = 4}, - atlas = "stake", - applied_stakes = {"cry_blossom"}, - loc_txt = { - name = "Azure Stake", - text = { - "Values on Jokers are reduced", - "by {C:attention}20%{}", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local ascendant = {object_type = "Stake", - name = "cry-Ascendant Stake", - key = "ascendant", - pos = {x = 3, y = 4}, - atlas = "stake", - applied_stakes = {"cry_azure"}, - loc_txt = { - name = "Ascendant Stake", - text = { - "{C:attention}-1{} Joker slot", - "{s:0.8,C:inactive}(Not yet implemented){}", - } - }, - shiny = true, - color = HEX("ffffff") --temporary before gradients -} -local stake_atlas = {object_type = "Atlas", - key = "stake", - - path = "stake_cry.png", - px = 29, - py = 29 -} -return {name = "More Stakes", - init = function(self) - -- Ante scaling changes - local gba = get_blind_amount - function get_blind_amount(ante) - local k = to_big(0.7) - if G.GAME.modifiers.scaling == 4 then - local amounts = { - to_big(300), to_big(1200), to_big(4000), to_big(11000), to_big(30000), to_big(100000), to_big(180000), to_big(300000) - } - if ante < 1 then return to_big(100) end - if ante <= 8 then return amounts[ante] end - local a, b, c, d = amounts[8],1.6,ante-8, 1 + 0.2*(ante-8) - local amount = a*(b+(k*c)^d)^c - amount.m = math.floor(10*amount.m)/10 - amount:normalize() - return amount - else return gba(ante) - end - end - -- Disallow use of Debuffed Perishable consumables - local cuc = Card.can_use_consumeable - function Card:can_use_consumeable(any_state, skip_check) - if self.ability.perishable and self.ability.perish_tally <= 0 then - return false - end - return cuc(self, any_state, skip_check) - end - -- Overriding Steamodded's registering of Incantation/Familiar/Grim - local function random_destroy(used_tarot) - local destroyed_cards = {} - local temp_hand = {} - local hasHand = false - for k, v in ipairs(G.hand.cards) do - if not v.ability.eternal then - temp_hand[#temp_hand+1] = v - hasHand = true - end - end - if hasHand then destroyed_cards[#destroyed_cards + 1] = pseudorandom_element(temp_hand, pseudoseed('random_destroy')) end - G.E_MANAGER:add_event(Event({ - trigger = 'after', - delay = 0.4, - func = function() - play_sound('tarot1') - if used_tarot and used_tarot.juice_up then used_tarot:juice_up(0.3, 0.5) end - return true - end - })) - G.E_MANAGER:add_event(Event({ - trigger = 'after', - delay = 0.1, - func = function() - for i = #destroyed_cards, 1, -1 do - local card = destroyed_cards[i] - if card.ability.name == 'Glass Card' then - card:shatter() - else - card:start_dissolve(nil, i ~= #destroyed_cards) - end - end - return true - end - })) - return destroyed_cards - end - SMODS.Consumable:take_ownership('grim', { - use = function(self, card, area, copier) - local used_tarot = copier or card - local destroyed_cards = random_destroy(used_tarot) - G.E_MANAGER:add_event(Event({ - trigger = 'after', - delay = 0.7, - func = function() - local cards = {} - for i = 1, card.ability.extra do - cards[i] = true - local suit_list = {} - for i = #SMODS.Suit.obj_buffer, 1, -1 do - suit_list[#suit_list + 1] = SMODS.Suit.obj_buffer[i] - end - local _suit, _rank = - SMODS.Suits[pseudorandom_element(suit_list, pseudoseed('grim_create'))].card_key, 'A' - local cen_pool = {} - for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do - if v.key ~= 'm_stone' then - cen_pool[#cen_pool + 1] = v - end - end - create_playing_card({ - front = G.P_CARDS[_suit .. '_' .. _rank], - center = pseudorandom_element(cen_pool, pseudoseed('spe_card')) - }, G.hand, nil, i ~= 1, { G.C.SECONDARY_SET.Spectral }) - end - playing_card_joker_effects(cards) - return true - end - })) - delay(0.3) - for i = 1, #G.jokers.cards do - G.jokers.cards[i]:calculate_joker({ remove_playing_cards = true, removed = destroyed_cards }) - end - end, - }) - SMODS.Consumable:take_ownership('familiar', { - use = function(self, card, area, copier) - local used_tarot = copier or card - local destroyed_cards = random_destroy(used_tarot) - G.E_MANAGER:add_event(Event({ - trigger = 'after', - delay = 0.7, - func = function() - local cards = {} - for i = 1, card.ability.extra do - cards[i] = true - local suit_list = {} - for i = #SMODS.Suit.obj_buffer, 1, -1 do - suit_list[#suit_list + 1] = SMODS.Suit.obj_buffer[i] - end - local faces = {} - for _, v in ipairs(SMODS.Rank.obj_buffer) do - local r = SMODS.Ranks[v] - if r.face then table.insert(faces, r.card_key) end - end - local _suit, _rank = - SMODS.Suits[pseudorandom_element(suit_list, pseudoseed('familiar_create'))].card_key, - pseudorandom_element(faces, pseudoseed('familiar_create')) - local cen_pool = {} - for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do - if v.key ~= 'm_stone' then - cen_pool[#cen_pool + 1] = v - end - end - create_playing_card({ - front = G.P_CARDS[_suit .. '_' .. _rank], - center = pseudorandom_element(cen_pool, pseudoseed('spe_card')) - }, G.hand, nil, i ~= 1, { G.C.SECONDARY_SET.Spectral }) - end - playing_card_joker_effects(cards) - return true - end - })) - delay(0.3) - for i = 1, #G.jokers.cards do - G.jokers.cards[i]:calculate_joker({ remove_playing_cards = true, removed = destroyed_cards }) - end - end, - }) - SMODS.Consumable:take_ownership('incantation', { - use = function(self, card, area, copier) - local used_tarot = copier or card - local destroyed_cards = random_destroy(used_tarot) - G.E_MANAGER:add_event(Event({ - trigger = 'after', - delay = 0.7, - func = function() - local cards = {} - for i = 1, card.ability.extra do - cards[i] = true - local suit_list = {} - for i = #SMODS.Suit.obj_buffer, 1, -1 do - suit_list[#suit_list + 1] = SMODS.Suit.obj_buffer[i] - end - local numbers = {} - for _RELEASE_MODE, v in ipairs(SMODS.Rank.obj_buffer) do - local r = SMODS.Ranks[v] - if v ~= 'Ace' and not r.face then table.insert(numbers, r.card_key) end - end - local _suit, _rank = - SMODS.Suits[pseudorandom_element(suit_list, pseudoseed('incantation_create'))].card_key, - pseudorandom_element(numbers, pseudoseed('incantation_create')) - local cen_pool = {} - for k, v in pairs(G.P_CENTER_POOLS["Enhanced"]) do - if v.key ~= 'm_stone' then - cen_pool[#cen_pool + 1] = v - end - end - create_playing_card({ - front = G.P_CARDS[_suit .. '_' .. _rank], - center = pseudorandom_element(cen_pool, pseudoseed('spe_card')) - }, G.hand, nil, i ~= 1, { G.C.SECONDARY_SET.Spectral }) - end - playing_card_joker_effects(cards) - return true - end - })) - delay(0.3) - for i = 1, #G.jokers.cards do - G.jokers.cards[i]:calculate_joker({ remove_playing_cards = true, removed = destroyed_cards }) - end - end, - }) - - -- This is short enough that I'm fine overriding it - function calculate_reroll_cost(skip_increment) - if G.GAME.current_round.free_rerolls < 0 then G.GAME.current_round.free_rerolls = 0 end - if G.GAME.current_round.free_rerolls > 0 then G.GAME.current_round.reroll_cost = 0; return end - G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase or 0 - if not skip_increment then G.GAME.current_round.reroll_cost_increase = G.GAME.current_round.reroll_cost_increase + (G.GAME.modifiers.cry_reroll_scaling or 1) end - G.GAME.current_round.reroll_cost = (G.GAME.round_resets.temp_reroll_cost or G.GAME.round_resets.reroll_cost) + G.GAME.current_round.reroll_cost_increase - end - - local sc = Card.set_cost - function Card:set_cost() - sc(self) - if self.ability.set == 'Voucher' and G.GAME.modifiers.cry_voucher_price_hike then - self.cost = math.floor(self.cost * G.GAME.modifiers.cry_voucher_price_hike) - --Update related costs - self.sell_cost = math.max(1, math.floor(self.cost/2)) + (self.ability.extra_value or 0) - if self.area and self.ability.couponed and (self.area == G.shop_jokers or self.area == G.shop_booster) then self.cost = 0 end - self.sell_cost_label = self.facing == 'back' and '?' or self.sell_cost - end - end - - for _, v in pairs(self.items) do - if v.object_type == "Stake" then - v.sticker_pos = v.pos - v.sticker_atlas = "sticker" - local words = {} - words[1], words[2] = v.loc_txt.name:match("(%w+)(.+)") - local stakeName = words[1] - v.loc_txt = {description = v.loc_txt} - v.loc_txt.sticker = { - name = stakeName.." Sticker", - text = { - "Used this Joker", - "to win on {C:attention}"..stakeName, - "{C:attention}Stake{} difficulty" - } - } - end - end - end, - items = {stake_atlas, pink, brown, yellow, jade, cyan, gray, crimson, diamond, - amber, bronze, quartz, ruby, glass, sapphire, emerald, platinum, - twilight, verdant, ember, dawn, horizon, blossom, azure, ascendant}} \ No newline at end of file diff --git a/Items/Items/yEpicJokers.lua b/Items/Items/yEpicJokers.lua deleted file mode 100644 index e2ec1d77d..000000000 --- a/Items/Items/yEpicJokers.lua +++ /dev/null @@ -1,1026 +0,0 @@ -cry_enable_epics = false -local googol_play = { - object_type = "Joker", - name = "cry-Googol Play Card", - key = "googol_play", - config = {extra = {Xmult = 1e100, odds = 10}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Googol Play Card', - text = { - "{C:green}#1# in #2#{} chance for", - "{X:red,C:white} X1e100 {} Mult" - } - }, - rarity = "cry_epic", - cost = 10, - discovered = true, - blueprint_compat = true, - atlas = "googol_play", - soul_pos = {x = 2, y = 0, extra = {x = 1, y = 0}}, - loc_vars = function(self, info_queue, center) - return {vars = {''..(G.GAME and G.GAME.probabilities.normal or 1), center.ability.extra.odds}} - end, - calculate = function(self, card, context) - if context.cardarea == G.jokers and not context.before and not context.after then - if pseudorandom('cry_googol_play') < G.GAME.probabilities.normal/card.ability.extra.odds then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.Xmult}}, - Xmult_mod = card.ability.extra.Xmult - } - else return {calculated = true} end - end - end, -} -local googol_play_sprite = { - object_type = "Atlas", - key = "googol_play", - - path = "j_cry_googol_play.png", - px = 71, - py = 95 -} -local sync_catalyst = { - object_type = "Joker", - name = "cry-Sync Catalyst", - key = "sync_catalyst", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Sync Catalyst', - text = { - "Balance {C:blue}Chips{} and", - "{C:red}Mult{} when this Joker", - "is triggered" - } - }, - rarity = "cry_epic", - cost = 11, - discovered = true, - blueprint_compat = true, - atlas = "sync_catalyst", - calculate = function(self, card, context) - if context.cardarea == G.jokers and not context.before and not context.after then - local tot = hand_chips + mult - hand_chips = mod_chips(math.floor(tot/2)) - mult = mod_mult(math.floor(tot/2)) - update_hand_text({delay = 0}, {mult = mult, chips = hand_chips}) - return { - message = localize('k_balanced'), - colour = {0.8, 0.45, 0.85, 1} - } - end - end, -} -local sync_catalyst_sprite = { - object_type = "Atlas", - key = "sync_catalyst", - - path = "j_cry_sync_catalyst.png", - px = 71, - py = 95 -} -local negative = { - object_type = "Joker", - name = "cry-Negative Joker", - key = "negative", - pos = {x = 0, y = 0}, - config = {extra = 3}, - loc_txt = { - name = 'Negative Joker', - text = { - "{C:dark_edition}+#1#{C:attention} Joker{} slots" - } - }, - rarity = "cry_epic", - cost = 12, - discovered = true, - atlas = "negative", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra}} - end, - add_to_deck = function(self, card, from_debuff) - G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra - end, - remove_from_deck = function(self, card, from_debuff) - G.jokers.config.card_limit = G.jokers.config.card_limit - card.ability.extra - end -} -local negative_sprite = { - object_type = "Atlas", - key = "negative", - - path = "j_cry_negative.png", - px = 71, - py = 95 -} -local canvas = { - object_type = "Joker", - name = "cry-Canvas", - key = "canvas", - pos = {x = 0, y = 0}, - config = {num_retriggers = 0}, - loc_txt = { - name = 'Canvas', - text = { - "{C:attention}Retrigger{} all {C:attention}Jokers{} to the left", - "once for {C:attention}every{} non-{C:blue}Common{C:attention} Joker{}", - "to the right of this Joker" - } - }, - rarity = "cry_epic", - cost = 15, - discovered = true, - blueprint_compat = true, - atlas = "canvas", - calculate = function(self, card, context) - if context.retrigger_joker_check and not context.retrigger_joker then - self.config.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 then - self.config.num_retriggers = self.config.num_retriggers + 1 - end - end - if 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 = self.config.num_retriggers, - card = card - } - end - end - end, -} -local canvas_sprite = { - object_type = "Atlas", - key = "canvas", - - path = "j_cry_canvas.png", - px = 71, - py = 95 -} -local error_joker = { - object_type = "Joker", - name = "cry-Error", - key = "error", - pos = {x = 0, y = 0}, - config = {extra = {sell_rounds = 0, active = false}}, - loc_txt = { - name = '{C:red}ERR{}{C:dark_edition}O{}{C:red}R{}', - text = { - "" - } - }, - rarity = "cry_epic", - cost = 1, - discovered = true, - blueprint_compat = false, - eternal_compat = false, - atlas = "error", - calculate = function(self, card, context) - if context.end_of_round and not context.blueprint and not context.repetition 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(self, eval, true) - end - return { - message = "???", - colour = G.C.BLACK - } - 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 (card and card.ability and card.ability.loyalty_remaining == 0) and not G.RESET_JIGGLES end - juice_card_until(self, 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 - end - end -} -local error_sprite = { - object_type = "Atlas", - key = "error", - - path = "j_cry_error.png", - px = 71, - py = 95 -} -local m = { - object_type = "Joker", - name = "cry-m", - key = "m", - pos = {x = 0, y = 0}, - config = {extra = {extra = 13, x_mult = 1}, jolly = {t_mult = 8, type = 'Pair'}}, - loc_txt = { - name = 'm', - text = { - "This Joker gains {X:mult,C:white} X#1# {} Mult", - "when {C:attention}Jolly Joker{} is sold", - "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" - } - }, - rarity = "cry_epic", - cost = 13, - discovered = true, - perishable_compat = false, - blueprint_compat = true,loc_vars = function(self, info_queue, center) - info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } - return {vars = {center.ability.extra.extra, center.ability.extra.x_mult}} - end, - atlas = "m", - calculate = function(self, card, context) - if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then - return { - message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, - Xmult_mod = card.ability.extra.x_mult - } - end - if context.selling_card and context.card.ability.name == "Jolly Joker" and not context.blueprint then - card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) - return {calculated = true} - end - end -} -local m_sprite = { - object_type = "Atlas", - key = "m", - - path = "j_cry_m.png", - px = 71, - py = 95 -} -local M = { - object_type = "Joker", - name = "cry-M", - key = "M", - pos = {x = 0, y = 0}, - config = {jolly = {t_mult = 8, type = 'Pair'}}, - loc_txt = { - name = 'M', - text = { - "When {C:attention}Blind{} is selected,", - "create a {C:dark_edition}Negative{}", - "{C:attention}Jolly Joker{}" - } - }, - rarity = "cry_epic", - cost = 13, - discovered = true, - blueprint_compat = true,loc_vars = function(self, info_queue, center) - info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } - info_queue[#info_queue+1] = G.P_CENTERS.e_negative - end, - atlas = "M", - calculate = function(self, card, context) - if context.setting_blind and not (context.blueprint_card or self).getting_sliced 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 {completed=true} - end - end -} -local M_sprite = { - object_type = "Atlas", - key = "M", - path = "j_cry_big_m.png", - px = 71, - py = 95 -} -local boredom = { - object_type = "Joker", - name = "cry-Boredom", - key = "boredom", - pos = {x = 0, y = 0}, - config = {extra = {odds = 2}}, - loc_txt = { - name = 'Boredom', - text = { - "{C:green}#1# in #2#{} chance to", - "{C:attention}retrigger{} each {C:attention}Joker{}", - "or {C:attention}played card{}", - "{C:inactive,s:0.8}(Excludes itself){}" - } - }, - rarity = "cry_epic", - cost = 12, - discovered = true, - blueprint_compat = true, - loc_vars = function(self, info_queue, center) - return {vars = {''..(G.GAME and G.GAME.probabilities.normal or 1), center.ability.extra.odds}} - end, - atlas = "boredom", - calculate = function(self, card, context) - if context.retrigger_joker_check and not context.retrigger_joker and context.other_card ~= self then - if pseudorandom("cry_boredom_joker") < G.GAME.probabilities.normal/card.ability.extra.odds then - return { - message = localize('k_again_ex'), - repetitions = 1, - card = card - } - else return {calculated = true} end - end - if context.repetition and context.cardarea == G.play then - if pseudorandom("cry_boredom_card") < G.GAME.probabilities.normal/card.ability.extra.odds then - return { - message = localize('k_again_ex'), - repetitions = 1, - card = card - } - else - return {calculated = true} - end - end - end -} -local boredom_sprite = { - object_type = "Atlas", - key = "boredom", - - path = "j_cry_boredom.png", - px = 71, - py = 95 -} -local number_blocks = { - object_type = "Joker", - name = "cry-Number Blocks", - key = "number_blocks", - config = {extra = {money_mod = 1, money = 0}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Number Blocks', - text = { - "Earn {C:money}$#1#{} at end of round,", - "permanently increase payout by", - "{C:money}$#2#{} for each {C:attention}#3#{} held in hand,", - "rank changes every round" - } - }, - rarity = "cry_epic", - cost = 12, - discovered = true, - atlas = "number_blocks", - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.money, center.ability.extra.money_mod, localize(G.GAME.current_round.cry_nb_card and 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 - card.ability.extra.money = card.ability.extra.money + card.ability.extra.money_mod - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')}) - return {calculated = true} - end - end, - calc_dollar_bonus = function(self, card) - if card.ability.extra.money > 0 then - return card.ability.extra.money - end - end -} -local number_blocks_sprite = { - object_type = "Atlas", - key = "number_blocks", - path = "j_cry_number_blocks.png", - px = 71, - py = 95 -} - -local double_scale = { - object_type = "Joker", - name = "cry-Double Scale", - key = "Double Scale", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Double Scale', - text = { - "Scaling {C:attention}Jokers{}", - "scale {C:attention}quadratically", - "{C:inactive,s:0.8}(ex. +1, +3, +6, +10)", - "{C:inactive,s:0.8}(grows by +1, +2, +3)" - } - }, - rarity = "cry_epic", - cost = 13, - discovered = true, - atlas = "double_scale", - --todo: support jokers that scale multiple variables - calculate = function(self, card, context) - --initialize tracking object - if not G.GAME.cry_double_scale then - G.GAME.cry_double_scale = {double_scale = true} --doesn't really matter what's in here as long as there's something - end - for i = 1, #G.jokers.cards do - --sort_id is a unique ID for each Joker - local jkr = G.jokers.cards[i] - if jkr.ability and type(jkr.ability) == 'table' then - if not G.GAME.cry_double_scale[jkr.sort_id] then - G.GAME.cry_double_scale[jkr.sort_id] = {ability = {double_scale = true}} - for k, v in pairs(jkr.ability) do - if type(jkr.ability[k]) ~= 'table' then - G.GAME.cry_double_scale[jkr.sort_id].ability[k] = v - else - G.GAME.cry_double_scale[jkr.sort_id].ability[k] = {} - for _k, _v in pairs(jkr.ability[k]) do - G.GAME.cry_double_scale[jkr.sort_id].ability[k][_k] = _v - end - end - end - elseif not G.GAME.cry_double_scale[jkr.sort_id].scaler then - dbl_info = G.GAME.cry_double_scale[jkr.sort_id] - if jkr.ability.name == "cry-Exponentia" then - dbl_info.base = {"extra", "pow_mult"} - dbl_info.scaler = {"extra", "pow_mult_mod"} - dbl_info.scaler_base = jkr.ability.extra.pow_mult_mod - dbl_info.offset = 1 - return - end - if jkr.ability.name == "cry-Redeo" then - dbl_info.base = {"extra", "money_req"} - dbl_info.scaler = {"extra", "money_mod"} - dbl_info.scaler_base = jkr.ability.extra.money_mod - dbl_info.offset = 1 - return - end - if jkr.ability.name == "cry-Chili Pepper" then - dbl_info.base = {"extra", "Xmult"} - dbl_info.scaler = {"extra", "Xmult_mod"} - dbl_info.scaler_base = jkr.ability.extra.Xmult_mod - dbl_info.offset = 1 - return - end - if jkr.ability.name == "Yorick" then - dbl_info.base = {"x_mult"} - dbl_info.scaler = {"extra", "xmult"} --not kidding - dbl_info.scaler_base = 1 - dbl_info.offset = 1 - return - end - if jkr.ability.name == "Hologram" then - dbl_info.base = {"x_mult"} - dbl_info.scaler = {"extra"} - dbl_info.scaler_base = jkr.ability.extra - dbl_info.offset = 1 - return - end - if jkr.ability.name == "Gift Card" then - dbl_info.base = {"extra_value"} - dbl_info.scaler = {"extra"} - dbl_info.scaler_base = jkr.ability.extra - dbl_info.offset = 1 - return - end - if jkr.ability.name == "Throwback" then - dbl_info.base = {"x_mult"} - dbl_info.scaler = {"extra"} - dbl_info.scaler_base = jkr.ability.x_mult or 1 - dbl_info.offset = 1 - return - end - if jkr.ability.name == "Egg" then - dbl_info.base = {"extra_value"} - dbl_info.scaler = {"extra"} - dbl_info.scaler_base = jkr.ability.extra - dbl_info.offset = 1 - return - end - for k, v in pairs(jkr.ability) do - --extra_value is ignored because it can be scaled by Gift Card - if k ~= "extra_value" and dbl_info.ability[k] ~= v and is_number(v) and is_number(dbl_info.ability[k]) then - dbl_info.base = {k} - local predicted_mod = math.abs(v-dbl_info.ability[k]) - local best_key = {""} - local best_coeff = 10^100 - for l, u in pairs(jkr.ability) do - if l ~= k and is_number(u) then - if predicted_mod/u >= 0.999 and predicted_mod/u < best_coeff then - best_coeff = predicted_mod/u - best_key = {l} - end - end - if type(jkr.ability[l]) == 'table' then - for _l, _u in pairs(jkr.ability[l]) do - if is_number(_u) and predicted_mod/_u >= 0.999 and predicted_mod/_u < best_coeff then - best_coeff = predicted_mod/_u - best_key = {l,_l} - end - end - end - end - dbl_info.scaler = best_key - end - if type(jkr.ability[k]) == 'table' then - for _k, _v in pairs(jkr.ability[k]) do - if dbl_info.ability[k][_k] ~= _v and is_number(_v) and is_number(dbl_info.ability[k][_k]) then - dbl_info.base = {k,_k} - local predicted_mod = math.abs(_v-dbl_info.ability[k][_k]) - local best_key = {""} - local best_coeff = 10^100 - for l, u in pairs(jkr.ability) do - if is_number(u) and predicted_mod/u >= 0.999 then - if predicted_mod/u < best_coeff then - best_coeff = predicted_mod/u - best_key = {l} - end - end - if type(jkr.ability[l]) == 'table' then - for _l, _u in pairs(jkr.ability[l]) do - if (l ~= k or _l ~= _k) and is_number(_u) and predicted_mod/_u >= 0.999 then - if predicted_mod/_u < best_coeff then - best_coeff = predicted_mod/_u - best_key = {l,_l} - end - end - end - end - end - dbl_info.scaler = best_key - end - end - end - end - if dbl_info.scaler then - dbl_info.scaler_base = #dbl_info.scaler == 2 and dbl_info.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] or dbl_info.ability[dbl_info.scaler[1]] - dbl_info.offset = 1 - end - end - if G.GAME.cry_double_scale[jkr.sort_id] and G.GAME.cry_double_scale[jkr.sort_id].scaler then - --update scaling metadata - dbl_info = G.GAME.cry_double_scale[jkr.sort_id] - local current_val, last_val, scale = 0, 0, 0 - if #dbl_info.base == 2 then - if not jkr.ability[dbl_info.base[1]] or not jkr.ability[dbl_info.base[1]][dbl_info.base[2]] then return end - current_val = jkr.ability[dbl_info.base[1]][dbl_info.base[2]] - last_val = dbl_info.ability[dbl_info.base[1]] and dbl_info.ability[dbl_info.base[1]][dbl_info.base[2]] or 1 - else - if not jkr.ability[dbl_info.base[1]] then return end - current_val = jkr.ability[dbl_info.base[1]] - last_val = dbl_info.ability[dbl_info.base[1]] or 1 - end - if #dbl_info.scaler == 2 then - if not jkr.ability[dbl_info.scaler[1]] or not jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] then return end - scale = jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] - else - if not jkr.ability[dbl_info.scaler[1]] then return end - scale = jkr.ability[dbl_info.scaler[1]] - end - scale_amt = math.abs((current_val-last_val)/scale) - if scale_amt > 0 then - dbl_info.offset = dbl_info.offset + scale_amt - local new_scale = dbl_info.scaler_base * dbl_info.offset - if #dbl_info.base == 2 then - if not jkr.ability[dbl_info.base[1]] or not jkr.ability[dbl_info.base[1]][dbl_info.base[2]] then return end - dbl_info.ability[dbl_info.base[1]][dbl_info.base[2]] = jkr.ability[dbl_info.base[1]][dbl_info.base[2]] - else - if not jkr.ability[dbl_info.base[1]] then return end - dbl_info.ability[dbl_info.base[1]] = jkr.ability[dbl_info.base[1]] - end - if #dbl_info.scaler == 2 then - if not jkr.ability[dbl_info.scaler[1]] or not jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] then return end - jkr.ability[dbl_info.scaler[1]][dbl_info.scaler[2]] = new_scale - else - if not jkr.ability[dbl_info.scaler[1]] then return end - jkr.ability[dbl_info.scaler[1]] = new_scale - end - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize('k_upgrade_ex')}) - end - end - end - end - return - end -} - -local double_scale_sprite = { - object_type = "Atlas", - key = "double_scale", - path = "j_cry_double_scale.png", - px = 71, - py = 95 -} -local oldcandy = { - object_type = "Joker", - name = "cry_oldcandy", - key = "oldcandy", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Nostalgic Candy', - text = { - "Permanently gain", - "{C:attention}+3{} hand size", - "when sold" - } - }, - rarity = "cry_epic", - cost = 10, - discovered = true, - eternal_compat = false, - atlas = "oldcandy", - calculate = function(self, card, context) --hardcoded, unfortunately - if context.selling_self and not context.blueprint then - G.hand:change_size(3) - end -end -} - -local oldcandy_sprite = { - object_type = "Atlas", - key = "oldcandy", - path = "j_cry_oldcandy.png", - px = 71, - py = 95 -} -local caramel = { - object_type = "Joker", - name = "cry-caramel", - key = "caramel", - config = {extra = {x_mult = 1.75, rounds_remaining = 11}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Caramel', - text = { - "All cards scored give {X:mult,C:white}X#1#{} Mult", - "for the next {C:attention}#2#{} rounds", - } - }, - rarity = "cry_epic", - cost = 11, - discovered = true, - blueprint_compat = true, - eternal_compat = false, - atlas = 'caramel', - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.x_mult, center.ability.extra.rounds_remaining}} - end, - calculate = function(self, card, context) - if context.individual then - if context.cardarea == G.play then - return { - x_mult = 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 = card.ability.extra.rounds_remaining - 1 - if card.ability.extra.rounds_remaining > 0 then - return { - message = {"-1 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 - end -} -local caramel_sprite = { - object_type = "Atlas", - key = "caramel", - - path = "j_cry_caramel.png", - px = 71, - py = 95 -} - -local curse = { - object_type = "Joker", - name = "cry_curse", - key = "curse", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Sob', - text = { - "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}run...{}", - "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}hide...{}", - "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}escape...{}", - "{C:inactive}(Must have room){}" - } - }, - rarity = "cry_epic", - cost = 4, - discovered = true, - perishable_compat = true, - atlas = "curse", - calculate = function(self, card, context) -- hardcoded, unfortunately - if context.selling_self and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.discard and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.pre_discard and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.reroll_shop and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.destroying_card and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.buying_card and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.skip_blind and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.cardarea == G.jokers and context.before and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.using_consumable and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.selling_card and context.card.ability.name ~= "Obelisk" and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.setting_blind and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - if context.skipping_booster and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", - colour = G.C.FILTER, - }) - } - end - end, - add_to_deck = function(self, card, from_debuff) - local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_obelisk') - card:set_edition({ - negative = true - }) - card:set_eternal(true) - card:add_to_deck() - G.jokers:emplace(card) - return { - card_eval_status_text(card, 'extra', nil, nil, nil, { - message = "Curse!", - colour = G.C.DARK_EDITION, - }) - } - end -} - -local curse_sprite = { - object_type = "Atlas", - key = "curse", - path = "j_cry_curse.png", - px = 71, - py = 95 -} - - -G.P_JOKER_RARITY_POOLS["cry_epic"] = {googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel, curse} - - -return {name = "Epic Jokers", - init = function() - - --Error Patches - 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","???"} - 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 = 'Specls', colour = G.C.SECONDARY_SET.Spectral}, - {string = "#@"..(G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.id or 11)..(G.deck and G.deck.cards[1] and G.deck.cards[#G.deck.cards].base.suit:sub(1,1) or 'D'), colour = G.C.RED}, - } - - cry_enable_epics = true - --Number Blocks Patches - local gigo = Game.init_game_object; - function Game:init_game_object() - local g = gigo(self) - g.current_round.cry_nb_card = {rank = 'Ace'} - return g - end - local rcc = reset_castle_card; - function reset_castle_card() - rcc() - G.GAME.current_round.cry_nb_card = {rank = 'Ace'} - local valid_castle_cards = {} - for k, v in ipairs(G.playing_cards) do - if v.ability.effect ~= 'Stone Card' then - valid_castle_cards[#valid_castle_cards+1] = v - end - end - if valid_castle_cards[1] then - local castle_card = pseudorandom_element(valid_castle_cards, pseudoseed('cry_nb'..G.GAME.round_resets.ante)) - if not G.GAME.current_round.cry_nb_card then - G.GAME.current_round.cry_nb_card = {} - end - G.GAME.current_round.cry_nb_card.rank = castle_card.base.value - G.GAME.current_round.cry_nb_card.id = castle_card.base.id - end - end - - --For Double Scale, modify Green Joker to use one variable - SMODS.Joker:take_ownership('green_joker', { - config = {extra = 1, mult = 0}, - name = "cry-Green Joker", --will prevent old calculation code from working - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra,center.ability.extra,center.ability.mult}} - end, - calculate = function(self, card, context) - if context.discard and not context.blueprint and context.other_card == context.full_hand[#context.full_hand] then - local prev_mult = card.ability.mult - card.ability.mult = math.max(0, card.ability.mult - card.ability.extra) - if card.ability.mult ~= prev_mult then - return { - message = localize{type='variable',key='a_mult_minus',vars={card.ability.extra}}, - colour = G.C.RED, - card = card - } - end - end - if context.cardarea == G.jokers and context.before and not context.blueprint then - card.ability.mult = card.ability.mult + card.ability.extra - return { - card = card, - message = localize{type='variable',key='a_mult',vars={card.ability.extra}} - } - end - if context.cardarea == G.jokers and not context.before and not context.after then - return { - message = localize{type='variable',key='a_mult',vars={card.ability.mult}}, - mult_mod = card.ability.mult - } - end - end, - loc_txt = {} - }) - end, - items = {googol_play_sprite, sync_catalyst_sprite, negative_sprite, canvas_sprite, error_sprite, M_sprite, m_sprite, boredom_sprite, double_scale_sprite, number_blocks_sprite, oldcandy_sprite, caramel_sprite, curse_sprite, googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel, curse}} diff --git a/Items/Items/zAntimatter.lua b/Items/Items/zAntimatter.lua deleted file mode 100644 index 1b72ce8e4..000000000 --- a/Items/Items/zAntimatter.lua +++ /dev/null @@ -1,67 +0,0 @@ - -local blank = { - object_type = "Back", - name = "cry-Blank", - key = "blank", - pos = {x = 0, y = 0}, - loc_txt = { - name = "Blank Deck", - text = { - "{C:inactive,E:1}Does nothing?" - } - }, - atlas = "blank" -} -local blank_sprite = { - object_type = "Atlas", - key = "blank", - path = "b_cry_blank.png", - px = 71, - py = 95 -} -local antimatter = { - object_type = "Back", - name = "cry-Antimatter", - key = "antimatter", - config = {cry_antimatter = true, - discards = 1, --Red Deck: 1 - hands = 1, --Blue Deck: 1 - dollars = 10, --Yellow Deck - extra_hand_bonus = 2, extra_discard_bonus = 1, --Green Deck - joker_slot = 1, --Black Deck: 1 - vouchers = {'v_crystal_ball', 'v_telescope', 'v_tarot_merchant', 'v_planet_merchant', 'v_overstock_norm', 'v_overstock_plus'}, --Vouchers from all decks - consumables = {'c_fool', 'c_fool', 'c_hex'}, --Consumables from all decks - spectral_rate = 2, --Ghost Deck - remove_faces = true, --Abandoned Deck - hand_size = 2, --Painted Deck - randomize_rank_suit = true, --Erratic Deck - cry_equilibrium = true, --Deck of Equilibrium - cry_misprint_min = 1, cry_misprint_max = 10, --Misprint Deck - cry_highlight_limit = 1e20, --Infinite Deck - -- Enhanced Decks - cry_force_enhancement = 'random', - cry_force_edition = 'random', - cry_force_seal = 'random', - cry_boss_blocked = {"bl_goad", "bl_window", "bl_club", "bl_head"} - }, - pos = {x = 0, y = 0}, - loc_txt = { - name = "Antimatter Deck", - text = { - "Applies the {C:legendary,E:1}upsides{}", - "of {C:attention}every{} deck" - } - }, - atlas = "antimatter" -} -local antimatter_sprite = { - object_type = "Atlas", - key = "antimatter", - path = "b_cry_antimatter.png", - px = 71, - py = 95 -} -return {name = "Antimatter Deck", - init = function() - end, - items = {blank_sprite, antimatter_sprite, blank, antimatter}} \ No newline at end of file diff --git a/Items/Items/zExotic.lua b/Items/Items/zExotic.lua deleted file mode 100644 index 08af3c9fc..000000000 --- a/Items/Items/zExotic.lua +++ /dev/null @@ -1,515 +0,0 @@ -local gateway = { - object_type = "Consumable", - set = "Spectral", - name = "cry-Gateway", - key = "gateway", - pos = {x=0,y=0}, - loc_txt = { - name = 'Gateway', - text = { "Create a random", - "{C:cry_exotic,E:1}Exotic{C:attention} Joker{}, destroy", - 'all other Jokers' } - }, - cost = 4, - atlas = "gateway", - hidden = true, --default soul_set and soul_rate of 0.3% in spectral packs is used - can_use = function(self, card) - return true - end, - use = function(self, card, area, copier) - 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 _first_dissolve = nil - G.E_MANAGER:add_event(Event({trigger = 'before', delay = 0.75, func = function() - for k, v in pairs(deletable_jokers) do - v:start_dissolve(nil, _first_dissolve) - _first_dissolve = true - 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_exotic", nil, nil, nil, 'cry_gateway') - card:add_to_deck() - G.jokers:emplace(card) - card:juice_up(0.3, 0.5) - return true end })) - delay(0.6) - end -} -local gateway_sprite = { - object_type = "Atlas", - key = "gateway", - - path = "c_cry_gateway.png", - px = 71, - py = 95 -} -local iterum = { - object_type = "Joker", - name = "cry-Iterum", - key = "iterum", - config = {extra = {x_mult = 2, repetitions = 1}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Iterum', - text = { - "Retrigger all cards played {C:attention}#2#{} time(s),", - "each played card gives", - "{X:mult,C:white} X#1# {} Mult when scored"} - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - blueprint_compat = true, - atlas = 'iterum', - soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.x_mult,center.ability.extra.repetitions}} - end, - calculate = function(self, card, context) - if context.repetition then - if context.cardarea == G.play then - return { - message = localize('k_again_ex'), - repetitions = card.ability.extra.repetitions, - card = card - } - end - elseif context.individual then - if context.cardarea == G.play then - return { - x_mult = card.ability.extra.x_mult, - colour = G.C.RED, - card = card - } - end - end - end -} -local iterum_sprite = { - object_type = "Atlas", - key = "iterum", - - path = "j_cry_iterum.png", - px = 71, - py = 95 -} -local universum = { - object_type = "Joker", - name = "cry-Universum", - key = "universum", - config = {extra = 2}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Universum', - text = { - "{C:attention}Poker hands{} gain", - "{X:red,C:white} X#1# {} Mult and {X:blue,C:white} X#1# {} Chips", - "when leveled up", - } - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - blueprint_compat = true, - atlas = "universum", - soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra}} - end, - calculate = function(self, card, context) - if context.cry_universum then - return {mod = card.ability.extra} - end - end -} -local universum_sprite = { - object_type = "Atlas", - key = "universum", - - path = "j_cry_universum.png", - px = 71, - py = 95 -} -local exponentia = { - object_type = "Joker", - name = "cry-Exponentia", - key = "exponentia", - config = {extra = {pow_mult = 1.1, pow_mult_mod = 0.01}}, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Exponentia', - text = { - "This Joker gains {X:dark_edition,C:white} ^#1# {} Mult", - "when {X:red,C:white} XMult {} is triggered", - "{C:inactive}(Currently {X:dark_edition,C:white} ^#2# {C:inactive} Mult)" - } - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - blueprint_compat = true, - perishable_compat = false, - atlas = "exponentia", - soul_pos = {x = 2, y = 0, extra = {x = 1, y = 0}}, - calculate = function(self, card, context) - if context.cardarea == G.jokers and (card.ability.extra.pow_mult > 1) and not context.before and not context.after then - return { - message = "^"..card.ability.extra.pow_mult.." Mult", - pow_mult_mod = card.ability.extra.pow_mult, - colour = G.C.MULT - } - end - end, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.pow_mult_mod, center.ability.extra.pow_mult}} - end -} -local exponentia_sprite = { - object_type = "Atlas", - key = "exponentia", - path = "j_cry_exponentia.png", - px = 71, - py = 95 -} -local speculo = { - object_type = "Joker", - name = "cry-Speculo", - key = "speculo", - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Speculo', - text = { - "Creates a {C:dark_edition}Negative{} copy", - "of a random {C:attention}Joker{}", - "at the end of the {C:attention}shop", - } - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - blueprint_compat = true, - atlas = "speculo", - soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, - calculate = function(self, card, context) - if context.ending_shop then - local eligibleJokers = {} - for i = 1, #G.jokers.cards do - if G.jokers.cards[i].ability.name ~= card.ability.name then eligibleJokers[#eligibleJokers+1] = G.jokers.cards[i] end - end - if #eligibleJokers > 0 then - G.E_MANAGER:add_event(Event({ - func = function() - local card = copy_card(pseudorandom_element(eligibleJokers, pseudoseed('cry_speculo')), nil) - card:set_edition({negative = true}, true) - card:add_to_deck() - G.jokers:emplace(card) - return true - end})) - card_eval_status_text(context.blueprint_card or self, 'extra', nil, nil, nil, {message = localize('k_duplicated_ex')}) - return {calculated = true} - end - return - end - end -} -local speculo_sprite = { - object_type = "Atlas", - key = "speculo", - path = "j_cry_speculo.png", - px = 71, - py = 95 -} -local redeo = { - object_type = "Joker", - name = "cry-Redeo", - key = "redeo", - config = {extra = {ante_reduction = 1, money_req = 10, money_remaining = 0, money_mod = 10}}, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.ante_reduction, center.ability.extra.money_req, center.ability.extra.money_remaining, center.ability.extra.money_mod}} - end, - pos = {x = 0, y = 0}, - loc_txt = { - name = 'Redeo', - text = { - "{C:attention}-#1#{} Ante when", - "{C:money}$#2#{} {C:inactive}($#3#){} spent", - "{C:inactive,s:0.8}Requirements increase by", - "{C:money,s:0.8}$#4#{C:inactive,s:0.8} after each use" - } - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - atlas = "redeo", - soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, - calculate = function(self, card, context) - if context.cry_ease_dollars and context.cry_ease_dollars < 0 and not context.blueprint then - card.ability.extra.money_remaining = card.ability.extra.money_remaining - context.cry_ease_dollars - local ante_mod = 0 - while card.ability.extra.money_remaining >= card.ability.extra.money_req do - card.ability.extra.money_remaining = card.ability.extra.money_remaining - card.ability.extra.money_req - card.ability.extra.money_req = card.ability.extra.money_req + card.ability.extra.money_mod - ante_mod = ante_mod - card.ability.extra.ante_reduction - end - if ante_mod < 0 then - ease_ante(ante_mod) - end - return {calculated = true} - end - end -} -local redeo_sprite = { - object_type = "Atlas", - key = "redeo", - path = "j_cry_redeo.png", - px = 71, - py = 95 -} - -local tenebris = { - object_type = "Joker", - name = "cry-Tenebris", - key = "tenebris", - pos = {x = 0, y = 0}, - soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, - config = {extra = {slots = 25, money = 25}}, - loc_txt = { - name = 'Tenebris', - text = { - "{C:dark_edition}+#1#{C:attention} Joker{} slots", - "Earn {C:money}$#2#{} at end of round" - } - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - atlas = "tenebris", - calc_dollar_bonus = function(self, card) - return card.ability.extra.money - end, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.slots, center.ability.extra.money}} - end, - add_to_deck = function(self, card, from_debuff) - G.jokers.config.card_limit = G.jokers.config.card_limit + card.ability.extra.slots - end, - remove_from_deck = function(self, card, from_debuff) - G.jokers.config.card_limit = G.jokers.config.card_limit - card.ability.extra.slots - end -} - -local tenebris_sprite = { - object_type = "Atlas", - key = "tenebris", - path = "j_cry_tenebris.png", - px = 71, - py = 95 -} - -local effarcire = { - object_type = "Joker", - name = "cry-Effarcire", - key = "effarcire", - config = {}, - pos = {x = 0, y = 0}, - soul_pos = {x = 1, y = 0, extra = {x = 2, y = 0}}, - loc_txt = { - name = 'Effarcire', - text = { - "Always draw {C:green}full deck{} to hand", - "when {C:attention}Blind{} is selected" - } - }, - rarity = 3, - cost = 50, - discovered = true, - atlas = 'effarcire', - rarity = "cry_exotic", - calculate = function(self, card, context) - if not context.blueprint then - if context.first_hand_drawn then - G.FUNCS.draw_from_deck_to_hand(#G.deck.cards) - elseif G.hand.config.card_limit < 1 then - G.hand.config.card_limit = 1 - end - end - end -} - -local effarcire_sprite = { - object_type = "Atlas", - key = "effarcire", - path = "j_cry_effarcire.png", - px = 71, - py = 95 -} -local crustulum = { - object_type = "Joker", - name = "cry-crustulum", - key = "crustulum", - config = {extra = {chips = 0, chip_mod = 4,}}, - pos = {x = 0, y = 0}, - soul_pos = {x = 2, y = 0, extra = {x = 1, y = 0}}, - loc_txt = { - name = 'Crustulum', - text = { - "This Joker gains {C:chips}+#2#{} Chips", - "per {C:attention}reroll{} in the shop,", - "{C:green}all rerolls are free{}", - "{C:inactive}(Currently {C:chips}+#1#{C:inactive} chips)" - } - }, - rarity = "cry_exotic", - cost = 50, - discovered = true, - atlas = "crustulum", - blueprint_compat = true, - perishable_compat = false, - loc_vars = function(self, info_queue, center) - return {vars = {center.ability.extra.chips, center.ability.extra.chip_mod}} - end, - calculate = function(self, card, context) --Warning, implementation is extremely scuffed ;-; - if context.reroll_shop and not context.blueprint then - card.ability.extra.chips = (card.ability.extra.chips) + card.ability.extra.chip_mod - card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}}, colour = G.C.CHIPS}) - G.GAME.current_round.free_rerolls = 1 - calculate_reroll_cost(true) - return {calculated = true} - end - if context.end_of_round then - G.GAME.current_round.free_rerolls = 1 - calculate_reroll_cost(true) - end - if context.cardarea == G.jokers and (card.ability.extra.chips) > 0 and not context.before and not context.after then - return { - message = localize{type='variable', key='a_chips', vars={card.ability.extra.chips}}, - chip_mod = card.ability.extra.chips - } - end - end, - add_to_deck = function(self, card, from_debuff) - G.GAME.current_round.free_rerolls = 1 - calculate_reroll_cost(true) - end -} -local crustulum_sprite = { - object_type = "Atlas", - key = "crustulum", - path = "j_cry_crustulum.png", - px = 71, - py = 95 -} - - -G.P_JOKER_RARITY_POOLS["cry_exotic"] = {iterum, universum, exponentia, speculo, redeo, tenebris, effarcire, crustulum} - -return {name = "Exotic Jokers", - init = function() - --Universum Patches - local uht = update_hand_text - function update_hand_text(config, vals) - if next(find_joker("cry-Universum")) then - G.E_MANAGER:add_event(Event({--This is the Hand name text for the poker hand - trigger = 'before', - blockable = not config.immediate, - delay = config.delay or 0.8, - func = function() - local col = G.C.GREEN - if vals.chips and G.GAME.current_round.current_hand.chips ~= vals.chips then - local delta = vals.chips - if is_number(vals.chips) and is_number(G.GAME.current_round.current_hand.chips) then delta = 'X'..number_format(vals.chips / G.GAME.current_round.current_hand.chips) end - G.GAME.current_round.current_hand.chips = vals.chips - G.hand_text_area.chips:update(0) - if vals.StatusText then - attention_text({ - text = delta, - scale = 0.8, - hold = 1, - cover = G.hand_text_area.chips.parent, - cover_colour = mix_colours(G.C.CHIPS, col, 0.1), - emboss = 0.05, - align = 'cm', - cover_align = 'cr' - }) - end - end - if vals.mult and G.GAME.current_round.current_hand.mult ~= vals.mult then - local delta = vals.mult - if is_number(vals.mult) and is_number(G.GAME.current_round.current_hand.mult) then delta = 'X'..number_format(vals.mult / G.GAME.current_round.current_hand.mult) end - G.GAME.current_round.current_hand.mult = vals.mult - G.hand_text_area.mult:update(0) - if vals.StatusText then - attention_text({ - text = delta, - scale = 0.8, - hold = 1, - cover = G.hand_text_area.mult.parent, - cover_colour = mix_colours(G.C.MULT, col, 0.1), - emboss = 0.05, - align = 'cm', - cover_align = 'cl' - }) - end - if not G.TAROT_INTERRUPT then G.hand_text_area.mult:juice_up() end - end - if vals.handname and G.GAME.current_round.current_hand.handname ~= vals.handname then - G.GAME.current_round.current_hand.handname = vals.handname - if not config.nopulse then - G.hand_text_area.handname.config.object:pulse(0.2) - end - end - if vals.chip_total then G.GAME.current_round.current_hand.chip_total = vals.chip_total;G.hand_text_area.chip_total.config.object:pulse(0.5) end - if vals.level and G.GAME.current_round.current_hand.hand_level ~= ' '..localize('k_lvl')..tostring(vals.level) then - if vals.level == '' then - G.GAME.current_round.current_hand.hand_level = vals.level - else - G.GAME.current_round.current_hand.hand_level = ' '..localize('k_lvl')..tostring(vals.level) - if is_number(vals.level) then - G.hand_text_area.hand_level.config.colour = G.C.HAND_LEVELS[math.min(vals.level, 7)] - else - G.hand_text_area.hand_level.config.colour = G.C.HAND_LEVELS[1] - end - G.hand_text_area.hand_level:juice_up() - end - end - if config.sound and not config.modded then play_sound(config.sound, config.pitch or 1, config.volume or 1) end - if config.modded then - G.HUD_blind:get_UIE_by_ID('HUD_blind_debuff_1'):juice_up(0.3, 0) - G.HUD_blind:get_UIE_by_ID('HUD_blind_debuff_2'):juice_up(0.3, 0) - G.GAME.blind:juice_up() - G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.06*G.SETTINGS.GAMESPEED, blockable = false, blocking = false, func = function() - play_sound('tarot2', 0.76, 0.4);return true end})) - play_sound('tarot2', 1, 0.4) - end - return true - end})) - else - uht(config, vals) - end - end - - --Redeo Patches - local ed = ease_dollars - function ease_dollars(mod, x) - ed(mod,x) - for i = 1, #G.jokers.cards do - local effects = G.jokers.cards[i]:calculate_joker({cry_ease_dollars = mod}) - if effects and effects.joker_repetitions then - rep_list = effects.joker_repetitions - for z=1, #rep_list do - if type(rep_list[z]) == 'table' and rep_list[z].repetitions then - for r=1, rep_list[z].repetitions do - card_eval_status_text(rep_list[z].card, 'jokers', nil, nil, nil, rep_list[z]) - if percent then percent = percent+percent_delta end - G.jokers.cards[i]:calculate_joker({cry_ease_dollars = mod, retrigger_joker = true}) - end - end - end - end - end - end - end, - items = {gateway_sprite, iterum_sprite, universum_sprite, exponentia_sprite, speculo_sprite, redeo_sprite, tenebris_sprite, effarcire_sprite, crustulum_sprite, gateway, iterum, universum, exponentia, speculo, redeo, tenebris, effarcire, crustulum,}} diff --git a/Items/Items/zzChallenges.lua b/Items/Items/zzChallenges.lua deleted file mode 100644 index bf725bc33..000000000 --- a/Items/Items/zzChallenges.lua +++ /dev/null @@ -1,71 +0,0 @@ -local sticker_sheet = { - object_type = "Challenge", - key = "sticker_sheet", - rules = { - custom = { - {id = 'all_eternal'}, - {id = 'cry_all_perishable'}, - {id = 'cry_all_rental'}, - {id = 'cry_all_pinned'}, - {id = 'cry_eternal_perishable_compat'}, - {id = 'cry_any_stickers'}, - {id = 'cry_sticker_sheet'}, - }, - modifiers = {} - }, - restrictions = { - banned_cards = {}, - banned_other = {} - }, - loc_txt = "Sticker Sheet" -} -local ballin = { - object_type = "Challenge", - key = "ballin", - rules = { - custom = {}, - modifiers = { - {id = 'joker_slots', value = 3} - } - }, - jokers = { - {id = 'j_cry_jimball',eternal=true} - }, - deck = {enhancement = 'm_stone'}, - loc_txt = "Ballin'" -} -local rush_hour = { - object_type = "Challenge", - key = "rush_hour", - loc_txt = "Rush Hour", - rules = { - custom = { - {id = 'cry_rush_hour'} --this just explains the rule - }, - modifiers = {} - }, - restrictions = { - banned_cards = { - {id = 'j_luchador'}, - {id = 'j_chicot'} - }, - banned_other = {} - } -} - -local challenges = {sticker_sheet} -if Cryptid_config["Misc. Jokers"] then challenges[#challenges+1] = ballin end -if Cryptid_config["Blinds"] then challenges[#challenges+1] = rush_hour end - -for k, v in pairs(G.P_CENTERS) do - if v.set == "Joker" then - if not v.perishable_compat or not v.eternal_compat then - sticker_sheet.restrictions.banned_cards[#sticker_sheet.restrictions.banned_cards+1] = {id = k} - end - end -end - -return {name = "Challenges", - init = function() - end, - items = challenges} \ No newline at end of file From 179de357970ee8dbf12deece47e9de4b90f8b3ff Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:34:31 -0700 Subject: [PATCH 3/7] Add files via upload --- Items/Blinds.lua | 190 ++++++++-------- Items/MiscJokers.lua | 509 ++++++++++++++++++++++++++++++++++++++++-- Items/yEpicJokers.lua | 231 ++++++++++++++++++- Items/zExotic.lua | 14 +- 4 files changed, 813 insertions(+), 131 deletions(-) diff --git a/Items/Blinds.lua b/Items/Blinds.lua index f067d4e3d..84cc09a35 100644 --- a/Items/Blinds.lua +++ b/Items/Blinds.lua @@ -3,7 +3,7 @@ function Blind:cry_ante_base_mod(dt) if not self.disabled then local obj = self.config.blind if obj.cry_ante_base_mod and type(obj.cry_ante_base_mod) == 'function' then - return obj:cry_ante_base_mod(dt) + return obj:cry_ante_base_mod(self, dt) end end return 0 @@ -12,7 +12,7 @@ function Blind:cry_round_base_mod(dt) if not self.disabled then local obj = self.config.blind if obj.cry_round_base_mod and type(obj.cry_round_base_mod) == 'function' then - return obj:cry_round_base_mod(dt) + return obj:cry_round_base_mod(self, dt) end end return 1 @@ -21,7 +21,7 @@ function Blind:cry_cap_score(score) if not self.disabled then local obj = self.config.blind if obj.cry_cap_score and type(obj.cry_cap_score) == 'function' then - return obj:cry_cap_score(score) + return obj:cry_cap_score(self, score) end end return score @@ -30,7 +30,7 @@ function Blind:cry_after_play() if not self.disabled then local obj = self.config.blind if obj.cry_after_play and type(obj.cry_after_play) == 'function' then - return obj:cry_after_play() + return obj:cry_after_play(self) end end end @@ -38,7 +38,7 @@ function Blind:cry_before_play() if not self.disabled then local obj = self.config.blind if obj.cry_before_play and type(obj.cry_before_play) == 'function' then - return obj:cry_before_play() + return obj:cry_before_play(self) end end end @@ -62,8 +62,8 @@ local tax = { atlas = "blinds", discovered = true, boss_colour = HEX('40ff40'), - cry_cap_score = function(self, score) - return math.floor(math.min(0.4*G.GAME.blind.chips,score)+0.5) + cry_cap_score = function(self, blind, score) + return math.floor(math.min(0.4*blind.chips,score)+0.5) end } @@ -87,14 +87,14 @@ local clock = { atlas = "blinds", discovered = true, boss_colour = HEX('853455'), - defeat = function(self, silent) + defeat = function(self, blind, silent) G.P_BLINDS.bl_cry_clock.mult = 0 end, - disable = function(self, silent) + disable = function(self, blind, silent) G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling*2 G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) end, - cry_ante_base_mod = function(self, dt) + cry_ante_base_mod = function(self, blind, dt) return 0.1*dt/3 end } @@ -117,7 +117,7 @@ local trick = { atlas = "blinds", discovered = true, boss_colour = HEX('babd24'), - cry_after_play = function(self) + cry_after_play = function(self, blind) --flip and shuffle all cards held in hand for k, v in ipairs(G.hand.cards) do if v.facing == "front" then @@ -179,11 +179,11 @@ local lavender_loop = { atlas = "blinds", discovered = true, boss_colour = HEX('ae00ff'), - disable = function(self, silent) + disable = function(self, blind, silent) G.GAME.blind.chips = get_blind_amount(G.GAME.round_resets.ante)*G.GAME.starting_params.ante_scaling*2 G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) end, - cry_round_base_mod = function(self, dt) + cry_round_base_mod = function(self, blind, dt) return 1.25^(dt/1.5) end } @@ -208,7 +208,7 @@ local vermillion_virus = { atlas = "blinds", discovered = true, boss_colour = HEX('f65d34'), - cry_before_play = function(self) + cry_before_play = function(self, blind) if G.jokers.cards[1] then local idx = pseudorandom(pseudoseed('cry_vermillion_virus'),1,#G.jokers.cards) if G.jokers.cards[idx] then @@ -246,21 +246,21 @@ local sapphire_stamp = { atlas = "blinds", discovered = true, boss_colour = HEX('4057d6'), - cry_before_play = function(self) + cry_before_play = function(self, blind) local idx = pseudorandom(pseudoseed("cry_sapphire_stamp"), 1, #G.hand.highlighted) G.hand:remove_from_highlighted(G.hand.highlighted[idx]) end, - set_blind = function(self, reset, silent) + set_blind = function(self, blind, reset, silent) if not reset then G.hand.config.highlighted_limit = G.hand.config.highlighted_limit + 1 end end, - defeat = function(self, silent) + defeat = function(self, blind, silent) if not self.disabled then G.hand.config.highlighted_limit = G.hand.config.highlighted_limit - 1 end end, - disable = function(self, silent) + disable = function(self, blind, silent) G.hand.config.highlighted_limit = G.hand.config.highlighted_limit - 1 end, } @@ -286,12 +286,12 @@ local obsidian_orb = { atlas = "blinds", discovered = true, boss_colour = HEX('290759'), - set_blind = function(self, reset, silent) + set_blind = function(self, blind, reset, silent) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.set_blind then s:set_blind(reset,silent) end + if s.set_blind then s:set_blind(blind,reset,silent) end if s.name == 'The Eye' and not reset then - G.GAME.blind.hands = { + blind.hands = { ["Flush Five"] = false, ["Flush House"] = false, ["Five of a Kind"] = false, @@ -307,18 +307,18 @@ local obsidian_orb = { } end if s.name == 'The Mouth' and not reset then - G.GAME.blind.only_hand = false + blind.only_hand = false end if s.name == 'The Fish' and not reset then - G.GAME.blind.prepped = nil + blind.prepped = nil end if s.name == 'The Water' and not reset then - G.GAME.blind.discards_sub = G.GAME.current_round.discards_left - ease_discard(-G.GAME.blind.discards_sub) + blind.discards_sub = G.GAME.current_round.discards_left + ease_discard(-blind.discards_sub) end if s.name == 'The Needle' and not reset then - G.GAME.blind.hands_sub = G.GAME.round_resets.hands - 1 - ease_hands_played(-G.GAME.blind.hands_sub) + blind.hands_sub = G.GAME.round_resets.hands - 1 + ease_hands_played(-blind.hands_sub) end if s.name == 'The Manacle' and not reset then G.hand:change_size(-1) @@ -349,20 +349,20 @@ local obsidian_orb = { end end end, - defeat = function(self, silent) + defeat = function(self, blind, silent) for k, _ in pairs(G.GAME.defeated_blinds) do - if G.P_BLINDS[k].defeat then G.P_BLINDS[k]:defeat(silent) end + if G.P_BLINDS[k].defeat then G.P_BLINDS[k]:defeat(blind, silent) end if G.P_BLINDS[k].name == "The Manacle" and not self.disabled then G.hand:change_size(1) end end end, - disable = function(self, silent) + disable = function(self, blind, silent) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.disable then s:disable(silent) end + if s.disable then s:disable(blind, silent) end if s.name == 'The Water' then - ease_discard(G.GAME.blind.discards_sub) + ease_discard(blind.discards_sub) end if s.name == 'The Wheel' or s.name == 'The House' or s.name == 'The Mark' or s.name == 'The Fish' then for i = 1, #G.hand.cards do @@ -375,11 +375,11 @@ local obsidian_orb = { end end if s.name == 'The Needle' then - ease_hands_played(G.GAME.blind.hands_sub) + ease_hands_played(blind.hands_sub) end if s.name == 'The Wall' then - G.GAME.blind.chips = G.GAME.blind.chips/2 - G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + blind.chips = blind.chips/2 + blind.chip_text = number_format(blind.chips) end if s.name == 'Cerulean Bell' then for k, v in ipairs(G.playing_cards) do @@ -392,15 +392,15 @@ local obsidian_orb = { G.FUNCS.draw_from_deck_to_hand(1) end if s.name == 'Violet Vessel' then - G.GAME.blind.chips = G.GAME.blind.chips/3 - G.GAME.blind.chip_text = number_format(G.GAME.blind.chips) + blind.chips = blind.chips/3 + blind.chip_text = number_format(blind.chips) end end end, - press_play = function(self) + press_play = function(self, blind) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.press_play then s:press_play() end + if s.press_play then s:press_play(blind) end if s.name == "The Hook" then G.E_MANAGER:add_event(Event({ func = function() local any_selected = nil @@ -419,17 +419,17 @@ local obsidian_orb = { end if any_selected then G.FUNCS.discard_cards_from_highlighted(nil, true) end return true end })) - G.GAME.blind.triggered = true + blind.triggered = true delay(0.7) end if s.name == 'Crimson Heart' then if G.jokers.cards[1] then - G.GAME.blind.triggered = true - G.GAME.blind.prepped = true + blind.triggered = true + blind.prepped = true end end if s.name == 'The Fish' then - G.GAME.blind.prepped = true + blind.prepped = true end if s.name == "The Tooth" then G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2, func = function() @@ -439,11 +439,11 @@ local obsidian_orb = { delay(0.23) end return true end })) - G.GAME.blind.triggered = true + blind.triggered = true end end end, - modify_hand = function(self, cards, poker_hands, text, mult, hand_chips) + modify_hand = function(self, blind, cards, poker_hands, text, mult, hand_chips) local new_mult = mult local new_chips = chips local trigger = false @@ -451,11 +451,11 @@ local obsidian_orb = { s = G.P_BLINDS[k] if s.modify_hand then local this_trigger = false - new_mult, new_chips, this_trigger = s:modify_hand(cards, poker_hands, text, new_mult, new_chips) + new_mult, new_chips, this_trigger = s:modify_hand(blind, cards, poker_hands, text, new_mult, new_chips) trigger = trigger or this_trigger end if s.name == "The Flint" then - G.GAME.blind.triggered = true + blind.triggered = true new_mult = math.max(math.floor(new_mult*0.5 + 0.5), 1) new_chips = math.max(math.floor(new_chips*0.5 + 0.5), 0) trigger = true @@ -463,75 +463,75 @@ local obsidian_orb = { end return new_mult or mult, new_chips or hand_chips, trigger end, - debuff_hand = function(self, cards, hand, handname, check) - G.GAME.blind.debuff_boss = nil + debuff_hand = function(self, blind, cards, hand, handname, check) + blind.debuff_boss = nil for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.debuff_hand and s:debuff_hand(cards, hand, handname, check) then - G.GAME.blind.debuff_boss = s + if s.debuff_hand and s:debuff_hand(blind, cards, hand, handname, check) then + blind.debuff_boss = s return true end if s.debuff then - G.GAME.blind.triggered = false + blind.triggered = false if s.debuff.hand and next(hand[s.debuff.hand]) then - G.GAME.blind.triggered = true - G.GAME.blind.debuff_boss = s + blind.triggered = true + blind.debuff_boss = s return true end if s.debuff.h_size_ge and #cards < s.debuff.h_size_ge then - G.GAME.blind.triggered = true - G.GAME.blind.debuff_boss = s + blind.triggered = true + blind.debuff_boss = s return true end if s.debuff.h_size_le and #cards > s.debuff.h_size_le then - G.GAME.blind.triggered = true - G.GAME.blind.debuff_boss = s + blind.triggered = true + blind.debuff_boss = s return true end if s.name == "The Eye" then - if G.GAME.blind.hands[handname] then - G.GAME.blind.triggered = true - G.GAME.blind.debuff_boss = s + if blind.hands[handname] then + blind.triggered = true + blind.debuff_boss = s return true end - if not check then G.GAME.blind.hands[handname] = true end + if not check then blind.hands[handname] = true end end if s.name == "The Mouth" then if s.only_hand and s.only_hand ~= handname then - G.GAME.blind.triggered = true - G.GAME.blind.debuff_boss = s + blind.triggered = true + blind.debuff_boss = s return true end if not check then s.only_hand = handname end end end if s.name == 'The Arm' then - G.GAME.blind.triggered = false + blind.triggered = false if G.GAME.hands[handname].level > 1 then - G.GAME.blind.triggered = true + blind.triggered = true if not check then level_up_hand(self.children.animatedSprite, handname, nil, -1) - G.GAME.blind:wiggle() + blind:wiggle() end end end if s.name == 'The Ox' then - G.GAME.blind.triggered = false + blind.triggered = false if handname == G.GAME.current_round.most_played_poker_hand then - G.GAME.blind.triggered = true + blind.triggered = true if not check then ease_dollars(-G.GAME.dollars, true) - G.GAME.blind:wiggle() + blind:wiggle() end end end end return false end, - drawn_to_hand = function(self) + drawn_to_hand = function(self, blind) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.drawn_to_hand then s:drawn_to_hand() end + if s.drawn_to_hand then s:drawn_to_hand(blind) end if s.name == 'Cerulean Bell' then local any_forced = nil for k, v in ipairs(G.hand.cards) do @@ -546,7 +546,7 @@ local obsidian_orb = { G.hand:add_to_highlighted(forced_card) end end - if s.name == 'Crimson Heart' and G.GAME.blind.prepped and G.jokers.cards[1] then + if s.name == 'Crimson Heart' and blind.prepped and G.jokers.cards[1] then local jokers = {} for i = 1, #G.jokers.cards do if not G.jokers.cards[i].debuff or #G.jokers.cards < 2 then jokers[#jokers+1] =G.jokers.cards[i] end @@ -561,10 +561,10 @@ local obsidian_orb = { end end end, - stay_flipped = function(self, area, card) + stay_flipped = function(self, blind, area, card) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.stay_flipped and s:stay_flipped(area, card) then return true end + if s.stay_flipped and s:stay_flipped(blind, area, card) then return true end if area == G.hand then if s.name == 'The Wheel' and pseudorandom(pseudoseed('wheel')) < G.GAME.probabilities.normal/7 then return true @@ -575,17 +575,17 @@ local obsidian_orb = { if s.name == 'The Mark' and card:is_face(true) then return true end - if s.name == 'The Fish' and G.GAME.blind.prepped then + if s.name == 'The Fish' and blind.prepped then return true end end end end, - debuff_card = function(self, card, from_blind) + debuff_card = function(self, blind, card, from_blind) if card and type(card) == 'table' and card.area then for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.debuff_card then s:debuff_card(card, from_blind) end + if s.debuff_card then s:debuff_card(blind, card, from_blind) end if s.debuff and not G.GAME.blind.disabled and card.area ~= G.jokers then --this part is buggy for some reason if s.debuff.suit and Card.is_suit(card, s.debuff.suit, true) then @@ -616,60 +616,60 @@ local obsidian_orb = { end end end, - cry_ante_base_mod = function(self, dt) + cry_ante_base_mod = function(self, blind, dt) local mod = 0 for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] if s.cry_ante_base_mod then - mod = mod + s:cry_ante_base_mod(dt) + mod = mod + s:cry_ante_base_mod(blind, dt) end end return mod end, - cry_round_base_mod = function(self, dt) + cry_round_base_mod = function(self, blind, dt) local mod = 1 for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] if s.cry_round_base_mod then - mod = mod * s:cry_round_base_mod(dt) + mod = mod * s:cry_round_base_mod(blind, dt) end end return mod end, - cry_cap_score = function(self, score) + cry_cap_score = function(self, blind, score) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] if s.cry_cap_score then - score = s:cry_cap_score(score) + score = s:cry_cap_score(blind, score) end end return score end, - cry_before_play = function(self) + cry_before_play = function(self, blind) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.cry_before_play then s:cry_before_play() end + if s.cry_before_play then s:cry_before_play(blind) end end end, - cry_after_play = function(self) + cry_after_play = function(self, blind) for k, _ in pairs(G.GAME.defeated_blinds) do s = G.P_BLINDS[k] - if s.cry_after_play then s:cry_after_play() end + if s.cry_after_play then s:cry_after_play(blind) end end end, - get_loc_debuff_text = function(self) - if not G.GAME.blind.debuff_boss then return "Applies abilities of all defeated bosses" end + get_loc_debuff_text = function(self, blind) + if not blind.debuff_boss then return "Applies abilities of all defeated bosses" end local loc_vars = nil - if G.GAME.blind.debuff_boss.name == 'The Ox' then + if blind.debuff_boss.name == 'The Ox' then loc_vars = {localize(G.GAME.current_round.most_played_poker_hand, 'poker_hands')} end - local loc_target = localize{type = 'raw_descriptions', key = G.GAME.blind.debuff_boss.key, set = 'Blind', vars = loc_vars} + local loc_target = localize{type = 'raw_descriptions', key = blind.debuff_boss.key, set = 'Blind', vars = loc_vars} local loc_debuff_text = '' for k, v in ipairs(loc_target) do loc_debuff_text = loc_debuff_text..v..(k <= #loc_target and ' ' or '') end - local disp_text = (G.GAME.blind.debuff_boss.name == 'The Wheel' and G.GAME.probabilities.normal or '')..loc_debuff_text - if (G.GAME.blind.debuff_boss.name == 'The Mouth') and G.GAME.blind.only_hand then disp_text = disp_text..' ['..localize(G.GAME.blind.only_hand, 'poker_hands')..']' end + local disp_text = (blind.debuff_boss.name == 'The Wheel' and G.GAME.probabilities.normal or '')..loc_debuff_text + if (blind.debuff_boss.name == 'The Mouth') and blind.only_hand then disp_text = disp_text..' ['..localize(blind.only_hand, 'poker_hands')..']' end return disp_text end } @@ -702,7 +702,7 @@ return {name = "Blinds", G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult_ante = G.GAME.round_resets.ante end if G.GAME.round_resets.blind_states.Boss ~= "Current" then - G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult + (G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].cry_ante_base_mod and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss]:cry_ante_base_mod(dt) or 0) + G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult = G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].mult + (G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss].cry_ante_base_mod and G.P_BLINDS[G.GAME.round_resets.blind_choices.Boss]:cry_ante_base_mod(nil, dt) or 0) --Update UI if G.blind_select_opts then local blind_UI = G.blind_select_opts.boss.definition.nodes[1].nodes[1].nodes[1].nodes[1] diff --git a/Items/MiscJokers.lua b/Items/MiscJokers.lua index b0bd6dd11..8fe43cc12 100644 --- a/Items/MiscJokers.lua +++ b/Items/MiscJokers.lua @@ -8,7 +8,7 @@ local dropshot = { name = 'Dropshot', text = { "This Joker gains {X:mult,C:white} X#1# {} Mult", - "per played, nonscoring {V:1}#2#{} card,", + "per played, {C:attention}nonscoring{} {V:1}#2#{} card,", "suit changes every round", "{C:inactive}(Currently {X:mult,C:white} X#3# {C:inactive} Mult)" } @@ -337,7 +337,7 @@ local cursor = { name = 'Cursor', text = { "This Joker gains {C:chips}+#2#{} Chips", - "per card {C:attention}purchased{}", + "for each card {C:attention}purchased{}", "{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips)" } }, @@ -380,9 +380,9 @@ local pickle = { loc_txt = { name = 'Pickle', text = { - "When Blind skipped, create", + "When {C:attention}Blind{} is skipped, create", "{C:attention}#1#{} Tags, reduced by", - "{C:red}#2#{} when Blind selected" + "{C:red}#2#{} when {C:attention}Blind{} is selected" } }, rarity = 2, @@ -580,15 +580,15 @@ local chili_pepper = { loc_txt = { name = 'Chili Pepper', text = { - "{X:mult,C:white} X#1# {} Mult, increases by", - "{X:mult,C:white} X#2# {} Mult at end of round,", - "destroyed after {C:attention}#3#{} rounds" + "This joker gains {X:mult,C:white} X#2# {} Mult at end of round,", + "{C:red}self destructs{} after {C:attention}#3#{} rounds", + "{C:inactive}currently{} {X:mult,C:white} X#1# {} {C:inactive}Mult{}" } }, rarity = 2, cost = 6, discovered = true, - blueprint_compat = true, + blueprint_compat = false, eternal_compat = false, perishable_compat = false, atlas = "chili_pepper", @@ -727,7 +727,7 @@ local eternalflame = { name = 'Eternal Flame', text = { "This Joker gains {X:mult,C:white} X#1# {} Mult", - "per {C:attention}card{} sold", + "for each card {C:attention}sold{}", "{C:inactive}(Currently {X:mult,C:white} X#2# {C:inactive} Mult)" } }, @@ -812,8 +812,8 @@ local seal_the_deal = { loc_txt = { name = 'Seal the Deal', text = { - "All scored cards on {C:attention}last hand", - "{C:attention}of round{} gain a {C:attention}random seal" + "Add a {C:attention}random seal{} to all", + "cards scored on {C:attention}last hand{} played" } }, rarity = 2, @@ -869,7 +869,7 @@ local chad = { name = 'Chad', text = { "Retrigger {C:attention}leftmost{} Joker", - "{C:attention}#1#{} additional times" + "{C:attention}#1#{} additional time(s)" } }, rarity = 3, @@ -1036,7 +1036,7 @@ local fspinner = { text = { "This Joker gains {C:chips}+#2#{} Chips", "if hand played is {C:attention}not{}", - "most played poker hand", + "most played {C:attention}poker hand{}", "{C:inactive}(Currently {C:chips}+#1#{C:inactive} Chips)" } }, @@ -1181,8 +1181,8 @@ local blurred = { loc_txt = { name = 'Blurred Joker', text = { - "{C:blue}+#1#{} hand when", - "blind is selected" + "{C:blue}+#1#{} hand(s) when", + "{C:attention}Blind{} is selected" } }, rarity = 1, @@ -1196,7 +1196,7 @@ local blurred = { calculate = function(self, card, context) if context.setting_blind and not (context.blueprint_card or card).getting_sliced then return { - extra = {focus = card, message = localize('k_hand')}, --make this actually work in the future + message = localize('k_hand'), --make this actually work in the future ease_hands_played(card.ability.extra.hands), delay(0.6), } @@ -1237,7 +1237,7 @@ local gardenfork = { for j = 1, #context.full_hand do if SMODS.Ranks[context.full_hand[j].base.value].key == "7" then ease_dollars(card.ability.extra.money) - return {message = "+$" .. card.ability.extra.money, colour = G.C.MONEY} + return {message = "$" .. card.ability.extra.money, colour = G.C.MONEY} end end end @@ -1262,7 +1262,7 @@ local lightupthenight = { loc_txt = { name = 'Light Up the Night', text = { - "Each played {C:attention}7{} and {C:attention}2{}", + "Each played {C:attention}7{} or {C:attention}2{}", "gives {X:mult,C:white}X#1#{} Mult when scored", } }, @@ -1303,8 +1303,8 @@ local nosound = { loc_txt = { name = 'No Sound, No Memory', text = { - "Retrigger all played {C:attention}7s{}", - "{C:attention:}#1#{} additional times", + "Retrigger each played {C:attention}7{}", + "{C:attention:}#1#{} additional time(s)", } }, rarity = 3, @@ -1422,6 +1422,473 @@ local hunger_sprite = { px = 71, py = 95 } +local weegaming = { + object_type = "Joker", + name = "cry-weegaming", + key = "weegaming", + config = {extra = {retriggers = 2}}, + pos = {x = 0, y = 0}, + atlas = 'weegaming', + loc_txt = { + name = '2D', + text = { + "Retrigger each played {C:attention}2{}", --wee gaming + "{C:attention:}#1#{} additional time(s) when scored", --wee gaming? + } + }, + rarity = 1, + cost = 5, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + return {vars = { center.ability.extra.retriggers}} + end, + calculate = function(self, card, context) + if context.repetition then + if context.cardarea == G.play then + local rank = SMODS.Ranks[context.other_card.base.value].key + if rank == "2" then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.retriggers, + card = card + } + end + end + end + end +} +local weegaming_sprite = { + object_type = "Atlas", + key = "weegaming", + path = "j_placeholder.png", + px = 71, + py = 95 +} +local redbloon = { + object_type = "Joker", + name = "cry-redbloon", + key = "redbloon", + config = {extra = {money = 20, rounds_remaining = 2, text = "s"}}, + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Red Bloon', + text = { + "Earn {C:money}$#1#{} in {C:attention}#2#{} round#3#", + "{C:red}self destructs{}" + } + }, + rarity = 1, + cost = 2, + discovered = true, + blueprint_compat = false, + eternal_compat = false, + perishable_compat = false, + atlas = "redbloon", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.money, center.ability.extra.rounds_remaining, center.ability.extra.text}} + end, + calculate = function(self, card, context) + 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 = card.ability.extra.rounds_remaining - 1 + if card.ability.extra.rounds_remaining > 0 then + return { + message = {"-1 Round"}, + colour = G.C.FILTER + } + else + ease_dollars(card.ability.extra.money) + 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 = "$" .. card.ability.extra.money, colour = G.C.MONEY + } + end + end + if card.ability.extra.rounds_remaining == 1 then + card.ability.extra.text = "" + end + end +} +local redbloon_sprite = { + object_type = "Atlas", + key = "redbloon", + path = "j_cry_redbloon.png", + px = 71, + py = 95 +} +local apjoker = { + object_type = "Joker", + name = "cry-apjoker", + key = "apjoker", + pos = {x = 0, y = 0}, + config = {extra = {x_mult = 4}}, + loc_txt = { + name = 'AP Joker', + text = { "{X:mult,C:white} X#1# {} Mult against {C:attention}Boss Blinds{}"} + }, + rarity = 2, + cost = 6, + discovered = true, + blueprint_compat = true, + perishable_compat = false, + atlas = "apjoker", + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.x_mult}} + end, + calculate = function(self, card, context) + if context.cardarea == G.jokers and G.GAME.blind.boss and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + end +} +local apjoker_sprite = { + object_type = "Atlas", + key = "apjoker", + path = "j_cry_apjoker.png", + px = 71, + py = 95 +} +local maze = { + object_type = "Joker", + name = "cry-maze", + key = "maze", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Labyrinth', + text = { + "All hands are considered the", + "{C:attention}first hand{} of each round,", + "all discards are considered the", + "{C:attention}first discard{} of each round" + } + }, + rarity = 1, + cost = 3, + discovered = true, + atlas = "maze", + calculate = function(self, card, context) + if (context.before or context.after or context.pre_discard or context.discard or context.cardarea == G.hand) and not context.blueprint and not context.retrigger_joker then + G.GAME.current_round.hands_played = 0 + G.GAME.current_round.discards_used = 0 + end + end, + add_to_deck = function(self, card, from_debuff) + G.GAME.current_round.hands_played = 0 + G.GAME.current_round.discards_used = 0 + end +} + +local maze_sprite = { + object_type = "Atlas", + key = "maze", + path = "j_cry_labyrinth.png", + px = 71, + py = 95 +} + +--Notes from my testing +-- I've found that DNA and Burnt Joker work SOMEWHAT but can be jank at times (ESPECIALLY so with retrigger jokers). i can only assume other modded jokers will behave in a similar way. Trading card and sixth sense work without any issues tho so yey +local unjust_dagger = { +object_type = "Joker", +name = "cry-Unjust Dagger", +key = "unjust_dagger", +pos = {x = 0, y = 0}, +config = {extra = {x_mult = 1}}, +loc_txt = { +name = 'Unjust Dagger', +text = { +"When {C:attention}Blind{} is selected,", +"destroy Joker to the left", +"and gain {C:attention}one-fifth{} of", +"its sell value as {X:mult,C:white} XMult {}", +"{C:inactive}(Currently {X:mult,C:white} X#1# {C:inactive} Mult)" +} +}, +rarity = 2, +cost = 7, +discovered = true, +perishable_compat = false, + loc_vars = function(self, info_queue, center) + return {vars = {center.ability.extra.x_mult}} + end, +atlas = "unjust_dagger", +calculate = function(self, card, context) + if context.cardarea == G.jokers and (card.ability.extra.x_mult > 1) and not context.before and not context.after then + return { + message = localize{type='variable',key='a_xmult',vars={card.ability.extra.x_mult}}, + Xmult_mod = card.ability.extra.x_mult + } + end + local my_pos = nil + for i = 1, #G.jokers.cards do + if G.jokers.cards[i] == card then my_pos = i; break end +end + if context.setting_blind and not (context.blueprint_card or self).getting_sliced and my_pos and G.jokers.cards[my_pos-1] and not G.jokers.cards[my_pos-1].ability.eternal and not G.jokers.cards[my_pos-1].getting_sliced then + local sliced_card = G.jokers.cards[my_pos-1] + sliced_card.getting_sliced = true + G.GAME.joker_buffer = G.GAME.joker_buffer - 1 + G.E_MANAGER:add_event(Event({func = function() + G.GAME.joker_buffer = 0 + card.ability.extra.x_mult = card.ability.extra.x_mult + sliced_card.sell_cost*0.2 + card:juice_up(0.8, 0.8) + sliced_card:start_dissolve({HEX("57ecab")}, nil, 1.6) + play_sound('slice1', 0.96+math.random()*0.08) + return true end })) + card_eval_status_text(self, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult+0.2*sliced_card.sell_cost}}, colour = G.C.RED, no_juice = true}) +return {calculated = true} + end + end +} +local unjust_dagger_sprite = { +object_type = "Atlas", + key = "unjust_dagger", + path = "j_cry_unjust_dagger.png", + px = 71, + py = 95 +} +local jollysus = { + object_type = "Joker", + name = "cry-jollysus", + key = "jollysus", + pos = {x = 0, y = 0}, + config = {extra = {spawn = true, active = "Active!", inactive = ""}, jolly = {t_mult = 8, type = 'Pair'}}, + loc_txt = { + name = 'Jolly Joker?', + text = { + "Create a {C:attention}Jolly Joker{}", + "when a joker is {C:attention}sold{}", + "{C:red}Works 1 time per round{}", + "{C:inactive}#1##2#{}" + } + }, + rarity = 2, + cost = 5, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + return {vars = {center.ability.extra.active, center.ability.extra.inactive}} + end, + atlas = "jollysus", + calculate = function(self, card, context) + if context.end_of_round and not context.retrigger_joker and not context.blueprint then + if not card.ability.extra.spawn then + card.ability.extra.active = "Active!" + card.ability.extra.inactive = "" + card.ability.extra.spawn = true + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "Reset", + colour = G.C.FILTER, + }) + } + end + end + if ((context.selling_card and context.card.ability.name == "cry-jollysus") or context.selling_self) and card.ability.extra.spawn and not context.retrigger_joker then --add support for selling itself (Blueprint compatible) + if not context.blueprint and not context.retrigger_joker then --ok tested this and making it sell itself next to blueprints doesn't make the blueprints create jokers, but it creates copies correctly when selling itself or blueprint so good enough for me + card.ability.extra.active = "" --also this doesn't work with brainstorm either (what is this jank????) + card.ability.extra.inactive = "No triggers left!" + card.ability.extra.spawn = false + end + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') + card:add_to_deck() + G.jokers:emplace(card) --man, now that I think about it this is probably the most complicated joker i've done so far + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "M!", + colour = G.C.FILTER, + }) + } + end + if context.selling_card and card.ability.extra.spawn and not context.retrigger_joker then + if context.card.ability.set == 'Joker' then + if not context.blueprint and not context.retrigger_joker then + card.ability.extra.active = "" + card.ability.extra.inactive = "No triggers left!" + card.ability.extra.spawn = false + end + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') + card:add_to_deck() + G.jokers:emplace(card) + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "M!", + colour = G.C.FILTER, + }) + } + end + end + end +} +local jollysus_sprite = { + object_type = "Atlas", + key = "jollysus", + path = "j_cry_jollysus.png", + px = 71, + py = 95 +} +local bubblem = { + object_type = "Joker", + name = "cry-bubblem", + key = "bubblem", + pos = {x = 0, y = 0}, + config = {extra = {spawn = false}, jolly = {t_mult = 8, type = 'Pair'}}, + loc_txt = { + name = 'Bubble M', + text = { + "Create a {C:dark_edition}Foil {C:attention}Jolly Joker{}", + "if hand played contains", + "a {C:attention}Four of a kind{}", + "{C:red}self destructs{}", + } + }, + rarity = 1, + cost = 2, + discovered = true, + loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + info_queue[#info_queue+1] = G.P_CENTERS.e_foil + end, + atlas = "bubblem", + calculate = function(self, card, context) + if context.scoring_name and (context.scoring_name == 'Five of a Kind' or context.scoring_name == 'Four of a Kind' or context.scoring_name == 'Flush Five') then + card.ability.extra.spawn = true + end + + if context.cardarea == G.jokers and card.ability.extra.spawn and context.before and not context.blueprint and not context.retrigger_joker 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(self) + card:remove() + card = nil + return true + end + })) + return true + end + })) + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_jolly') + card:set_edition({ + foil = true + }) + card:add_to_deck() + G.jokers:emplace(card) + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "M!", + colour = G.C.FILTER, + }) + } + end + end +} + +local bubblem_sprite = { + object_type = "Atlas", + key = "bubblem", + path = "j_cry_bubblem.png", + px = 71, + py = 95 +} +local mstack = { + object_type = "Joker", + name = "cry-mstack", + key = "mstack", + config = {extra = {sell = 0, retriggers = 0, text = ""}, jolly = {t_mult = 8, type = 'Pair'}}, + pos = {x = 0, y = 0}, + atlas = 'mstack', + loc_txt = { + name = 'M Stack', + text = { + "Retrigger all cards played", + "once for every {C:attention}2 Jolly Jokers{}", + "{C:attention}sold{}, up to {C:attention}8 sold{}", + "{C:inactive}Currently{}{C:attention:} #1#{}{C:inactive} retriggers #2#{}", + } + }, + rarity = 2, + cost = 7, + discovered = true, + blueprint_compat = true, + loc_vars = function(self, info_queue, center) + info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + return {vars = {center.ability.extra.retriggers, center.ability.extra.text}} + end, + calculate = function(self, card, context) --note: hardcoded like this intentionally + if context.repetition then + if context.cardarea == G.play then + return { + message = localize('k_again_ex'), + repetitions = card.ability.extra.retriggers, + card = card + } + end + end + + if context.selling_card and context.card.ability.name == "Jolly Joker" and card.ability.extra.retriggers < 4 and not context.blueprint and not context.retrigger_joker then + if card.ability.extra.sell == 1 then + if not context.blueprint or context.retrigger_joker then + card.ability.extra.retriggers = card.ability.extra.retriggers + 1 + end + card.ability.extra.sell = 0 + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "Upgrade!", + colour = G.C.FILTER, + }) + } + else + card.ability.extra.sell = card.ability.extra.sell + 1 + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "1/2", + colour = G.C.FILTER, + }) + } + end + end + + if card.ability.extra.retriggers == 4 then + card.ability.extra.text = "(MAX)" + end + end, +} + +local mstack_sprite = { + object_type = "Atlas", + key = "mstack", + path = "j_cry_mstack.png", + px = 71, + py = 95 +} return {name = "Misc. Jokers", init = function() --Dropshot Patches @@ -1503,4 +1970,4 @@ return {name = "Misc. Jokers", end end, - items = {dropshot_sprite, maximized_sprite, potofjokes_sprite, queensgambit_sprite, whip_sprite, lucky_joker_sprite, cursor_sprite, pickle_sprite, cube_sprite, triplet_rhythm_sprite, booster_sprite, chili_pepper_sprite, compound_interest_sprite, big_cube_sprite, eternalflame_sprite, nice_sprite, sus_sprite, chad_sprite, waluigi_sprite, seal_the_deal_sprite, jimball_sprite, fspinner_sprite, krustytheclown_sprite, blurred_sprite, gardenfork_sprite, lightupthenight_sprite, nosound_sprite, antennastoheaven_sprite, hunger_sprite, dropshot, maximized, potofjokes, queensgambit, wee_fib, compound_interest, whip, pickle, triplet_rhythm, booster, chili_pepper, lucky_joker, cursor, cube, big_cube, nice, sus, chad, jimball, waluigi, eternalflame, seal_the_deal, fspinner, krustytheclown, blurred, gardenfork, lightupthenight, nosound, antennastoheaven, hunger,}} + items = {dropshot_sprite, maximized_sprite, potofjokes_sprite, queensgambit_sprite, whip_sprite, lucky_joker_sprite, cursor_sprite, pickle_sprite, cube_sprite, triplet_rhythm_sprite, booster_sprite, chili_pepper_sprite, compound_interest_sprite, big_cube_sprite, eternalflame_sprite, nice_sprite, sus_sprite, chad_sprite, waluigi_sprite, seal_the_deal_sprite, jimball_sprite, fspinner_sprite, krustytheclown_sprite, blurred_sprite, gardenfork_sprite, lightupthenight_sprite, nosound_sprite, antennastoheaven_sprite, hunger_sprite, weegaming_sprite, redbloon_sprite, apjoker_sprite, maze_sprite, unjust_dagger_sprite, jollysus_sprite, bubblem_sprite, mstack_sprite, dropshot, maximized, potofjokes, queensgambit, wee_fib, compound_interest, whip, pickle, triplet_rhythm, booster, chili_pepper, lucky_joker, cursor, cube, big_cube, nice, sus, chad, jimball, waluigi, eternalflame, seal_the_deal, fspinner, krustytheclown, blurred, gardenfork, lightupthenight, nosound, antennastoheaven, hunger, weegaming, redbloon, apjoker, maze, unjust_dagger, jollysus, bubblem, mstack,}} diff --git a/Items/yEpicJokers.lua b/Items/yEpicJokers.lua index e9f666d7b..e2ec1d77d 100644 --- a/Items/yEpicJokers.lua +++ b/Items/yEpicJokers.lua @@ -165,7 +165,7 @@ local error_joker = { pos = {x = 0, y = 0}, config = {extra = {sell_rounds = 0, active = false}}, loc_txt = { - name = 'ERROR', + name = '{C:red}ERR{}{C:dark_edition}O{}{C:red}R{}', text = { "" } @@ -250,7 +250,7 @@ local m = { end if context.selling_card and context.card.ability.name == "Jolly Joker" and not context.blueprint then card.ability.extra.x_mult = card.ability.extra.x_mult + card.ability.extra.extra - card_eval_status_text(self, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) + card_eval_status_text(card, 'extra', nil, nil, nil, {message = localize{type = 'variable', key = 'a_xmult', vars = {card.ability.extra.x_mult}}}) return {calculated = true} end end @@ -272,7 +272,7 @@ local M = { loc_txt = { name = 'M', text = { - "When any Blind is selected,", + "When {C:attention}Blind{} is selected,", "create a {C:dark_edition}Negative{}", "{C:attention}Jolly Joker{}" } @@ -282,6 +282,7 @@ local M = { discovered = true, blueprint_compat = true,loc_vars = function(self, info_queue, center) info_queue[#info_queue+1] = { set = 'Joker', key = 'j_jolly', specific_vars = {self.config.jolly.t_mult, self.config.jolly.type} } + info_queue[#info_queue+1] = G.P_CENTERS.e_negative end, atlas = "M", calculate = function(self, card, context) @@ -314,7 +315,7 @@ local boredom = { text = { "{C:green}#1# in #2#{} chance to", "{C:attention}retrigger{} each {C:attention}Joker{}", - "{C:attention}or played card{}", + "or {C:attention}played card{}", "{C:inactive,s:0.8}(Excludes itself){}" } }, @@ -408,7 +409,7 @@ local double_scale = { loc_txt = { name = 'Double Scale', text = { - "Scaling jokers", + "Scaling {C:attention}Jokers{}", "scale {C:attention}quadratically", "{C:inactive,s:0.8}(ex. +1, +3, +6, +10)", "{C:inactive,s:0.8}(grows by +1, +2, +3)" @@ -716,7 +717,223 @@ local caramel_sprite = { px = 71, py = 95 } -G.P_JOKER_RARITY_POOLS["cry_epic"] = {googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel} + +local curse = { + object_type = "Joker", + name = "cry_curse", + key = "curse", + pos = {x = 0, y = 0}, + loc_txt = { + name = 'Sob', + text = { + "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}run...{}", + "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}hide...{}", + "{C:edition,E:1}you cannot{} {C:dark_edition,E:1}escape...{}", + "{C:inactive}(Must have room){}" + } + }, + rarity = "cry_epic", + cost = 4, + discovered = true, + perishable_compat = true, + atlas = "curse", + calculate = function(self, card, context) -- hardcoded, unfortunately + if context.selling_self and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.discard and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.pre_discard and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.reroll_shop and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.destroying_card and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.buying_card and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.skip_blind and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.cardarea == G.jokers and context.before and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.using_consumable and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.selling_card and context.card.ability.name ~= "Obelisk" and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.setting_blind and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + if context.skipping_booster and #G.jokers.cards + G.GAME.joker_buffer < G.jokers.config.card_limit 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 = "Curse!", + colour = G.C.FILTER, + }) + } + end + end, + add_to_deck = function(self, card, from_debuff) + local card = create_card('Joker', G.jokers, nil, nil, nil, nil, 'j_obelisk') + card:set_edition({ + negative = true + }) + card:set_eternal(true) + card:add_to_deck() + G.jokers:emplace(card) + return { + card_eval_status_text(card, 'extra', nil, nil, nil, { + message = "Curse!", + colour = G.C.DARK_EDITION, + }) + } + end +} + +local curse_sprite = { + object_type = "Atlas", + key = "curse", + path = "j_cry_curse.png", + px = 71, + py = 95 +} + + +G.P_JOKER_RARITY_POOLS["cry_epic"] = {googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel, curse} return {name = "Epic Jokers", @@ -806,4 +1023,4 @@ return {name = "Epic Jokers", loc_txt = {} }) end, - items = {googol_play_sprite, sync_catalyst_sprite, negative_sprite, canvas_sprite, error_sprite, M_sprite, m_sprite, boredom_sprite, double_scale_sprite, number_blocks_sprite, oldcandy_sprite, caramel_sprite, googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel}} + items = {googol_play_sprite, sync_catalyst_sprite, negative_sprite, canvas_sprite, error_sprite, M_sprite, m_sprite, boredom_sprite, double_scale_sprite, number_blocks_sprite, oldcandy_sprite, caramel_sprite, curse_sprite, googol_play, sync_catalyst, negative, canvas, error_joker, M, m, boredom, double_scale, number_blocks, oldcandy, caramel, curse}} diff --git a/Items/zExotic.lua b/Items/zExotic.lua index 2683fdcf1..08af3c9fc 100644 --- a/Items/zExotic.lua +++ b/Items/zExotic.lua @@ -184,7 +184,6 @@ local speculo = { text = { "Creates a {C:dark_edition}Negative{} copy", "of a random {C:attention}Joker{}", - "in your possession", "at the end of the {C:attention}shop", } }, @@ -280,8 +279,8 @@ local tenebris = { loc_txt = { name = 'Tenebris', text = { - "{C:dark_edition}+#1#{C:attention} Joker{} slots,", - "gives {C:money}$#2#{} at end of round" + "{C:dark_edition}+#1#{C:attention} Joker{} slots", + "Earn {C:money}$#2#{} at end of round" } }, rarity = "cry_exotic", @@ -320,9 +319,8 @@ local effarcire = { loc_txt = { name = 'Effarcire', text = { - "Always draw your", - "{C:green}entire deck{} to hand", - "at start of round" + "Always draw {C:green}full deck{} to hand", + "when {C:attention}Blind{} is selected" } }, rarity = 3, @@ -358,8 +356,8 @@ local crustulum = { loc_txt = { name = 'Crustulum', text = { - "This Joker gains", - "{C:chips}+#2#{} Chips per reroll,", + "This Joker gains {C:chips}+#2#{} Chips", + "per {C:attention}reroll{} in the shop,", "{C:green}all rerolls are free{}", "{C:inactive}(Currently {C:chips}+#1#{C:inactive} chips)" } From 62555615d9a8a07a3f059d61b42bd51813a9fe69 Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:42:07 -0700 Subject: [PATCH 4/7] Update yEpicJokers.lua forgot to remove this when copypasting lol --- Items/yEpicJokers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Items/yEpicJokers.lua b/Items/yEpicJokers.lua index e2ec1d77d..4b9ae0e5e 100644 --- a/Items/yEpicJokers.lua +++ b/Items/yEpicJokers.lua @@ -737,7 +737,7 @@ local curse = { discovered = true, perishable_compat = true, atlas = "curse", - calculate = function(self, card, context) -- hardcoded, unfortunately + calculate = function(self, card, context) if context.selling_self and #G.jokers.cards + G.GAME.joker_buffer <= G.jokers.config.card_limit 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 From 13d515d0b4f356d8e6b1b2ee97c97bae0d9b5e25 Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:46:26 -0700 Subject: [PATCH 5/7] Add files via upload --- assets/1x/j_cry_apjoker.png | Bin 0 -> 2380 bytes assets/1x/j_cry_big_m.png | Bin 988 -> 696 bytes assets/1x/j_cry_bubblem.png | Bin 0 -> 1272 bytes assets/1x/j_cry_curse.png | Bin 0 -> 1492 bytes assets/1x/j_cry_double_scale.png | Bin 2810 -> 2327 bytes assets/1x/j_cry_jollysus.png | Bin 0 -> 1654 bytes assets/1x/j_cry_labyrinth.png | Bin 0 -> 1873 bytes assets/1x/j_cry_m.png | Bin 949 -> 655 bytes assets/1x/j_cry_mstack.png | Bin 0 -> 1009 bytes assets/1x/j_cry_redbloon.png | Bin 0 -> 4366 bytes 10 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/1x/j_cry_apjoker.png create mode 100644 assets/1x/j_cry_bubblem.png create mode 100644 assets/1x/j_cry_curse.png create mode 100644 assets/1x/j_cry_jollysus.png create mode 100644 assets/1x/j_cry_labyrinth.png create mode 100644 assets/1x/j_cry_mstack.png create mode 100644 assets/1x/j_cry_redbloon.png diff --git a/assets/1x/j_cry_apjoker.png b/assets/1x/j_cry_apjoker.png new file mode 100644 index 0000000000000000000000000000000000000000..493ae68ce0aa8308b2098396ebca79ef8a10f975 GIT binary patch literal 2380 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 diff --git a/assets/1x/j_cry_jollysus.png b/assets/1x/j_cry_jollysus.png new file mode 100644 index 0000000000000000000000000000000000000000..c47da9373eb98a4a0a903bda58e427c18e3848c9 GIT binary patch literal 1654 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 literal 0 HcmV?d00001 diff --git a/assets/1x/j_cry_m.png b/assets/1x/j_cry_m.png index 984e01b9d0ec170497a4dc703b461dcdcd976f96..28beaffed6e3db3a637377f91228079853b81fd9 100644 GIT binary patch delta 618 zcmdnW-p@M0pq|Oo)5S5QBJS;6U%$f!0&bTtHzaU!Pe@=?e;}Y^A;ishkTZc%NGE}F z(Q?gMA$@9Lb8akF$$NA?R`mJt^ZEN!a-;IK;vAWz>rb9Oetum@-1h0qb>+@Vvp;?I zXi13K)!*N@z5D(3XW`kUtjkjj&T%kaY5M%_>-ODN)>%C}ch_swpPTo5`SE4v*U#TS zbxK5TUt6$}g!@rOCO`LFm&1j;M^)C&x%cdrj(3}}h+Q_*6rSUyakEtp{Q2%IFnxoJ zh3#S%nFlwzB#I5vlZta@$A62un7Z{%-mN}4i{zBP-oKl!ACft<6d*y)SZa{^3|}$}MxVHvai8K7Zz}$Z{^}^yXy7DOrbZG=#CHzY#jkcU=DMl$@7Y z*2`=oAGTOcy7W@>e9HmLDcuKd1Rj$qUHh0{uAt#^S<|L24vXt8o2NFlTF$7STy=eO zem}^8rj43;Pb{KKPq;ptV3~66#mr>qS@~-t?a!aQ?t6P)qwvIuf7b1J{)S8D!ID(| zna z-C9?%=>PMb5f;wZUOaV;eZHjOqImDYO_SV`?S4(GYS?+}^{4EE6PYJ@8qWB>aFvWi y;-MZzuTVy1ee<Bwn*X`M00f?{elF{r5}E*8>?(r* delta 915 zcmV;E18n?{1+@o|FnLjPZ~|C> z1PfS#n9~e$tJ6~{`RA46B#!INt|v}ne|hz)?4&z4C;lY~+~_S|e*Agx%In>$XEPqx z4-=HPFQ0m4bNc@K{yg?KFK*9VW^g=%nG_KK&ES0d_3z>J^M5B-#k{}!;7&cCKYhH8 z`RmWWrx0Ri=*VgCU%Zy^yd)^Avmn05eGnoqtdjO6wV?L@BuiiG|iFgn=0iM<7Z0az&ieNa}b7G$>FHpC; zRl^y*05q=za#o(XZ{=xmy;?b5Rs*X&hlU)Pl~1WfR>`BT?U?(yvg5l@}lf zX3eCq2#(c*kU^sGV(qMoE}aX8(?Zs3!)aZN!f;BIk?n}TSS|u`JfvT#HZYu2r!7)O zvzBGh=rL;`!Ejm>f#^WCfTR6Vo>Q+nK#$tS3^@D`RnHON#Ij@+oTb?+1$7JM=txLi z_|VP-$A4NOPwjhBPOA25q8zJgVx8GjIVsO+0;gsruqWkcuUr&XIX9;v*AxnBpPrPH zo9|Vn@}+!wgHsxhsR%3`thBu+ILI``J)GPs?}1a`k)*M=Ock|iUza7qsmxb__6aTvGCL25z50Vb!(Y^AG4g!l+; zWZ2E%gu#WEV(`5Wk6#K2O!&qSA^V`1@Hf3yh3}dXaFXwu8NoMNkKsQ7i?6F=Px&t4TybRCr$P-A#%WF%SpvH{c1pgyJl9;eaB}0Yv5ug5rTh!83?>fDus`7rIpR z5}rU9sg@ekF-cX@sZ=MaUODsn<#m4jPo+P6(?XG3 z5AWWZ)#mW&>(8a{_wU?XTvj+U!(bu+Xod6f%a6-@w{J|F7{BB1KYu^K5L=RCIBOom zNsJQ`=kb$g%iG_+etE!u`|ZJNBQ9(ls`DcPv2n2TZju1Z|CvJU>2<@YRdYf~kw}hT z+q8!4?vevAZyvl_?a#9hPnQXy^|C9R5DbE70PO}R1)~K-;#$q=LhR!IWstVoh-TgSuD}+~V&~-5NmRI8;hfvmqBq>KI5A zXA4ZM@cL~^!NBK>;pD)iW+m9jSb`*BL~-yWm8vh;K?*YjBz?XmmYkBACKpKh=v^F# zN)Wf`hKAP=I5mKz>q`i_NpiLhF%1~;f*jf#IR|qRR~d7LV$r23j;sDIMlNVIK zs=WT_;(7Jt8BSu?7>?nTja<>>;IT}q?m(@mv2<6E-O~jMNTPFF(Z!R~Gf*=e?hxBk zf|}y=2Gks>yAoKIQA>_ia`61AY`^8btILAycd=F{LN^O* zwT;^>HmsKahx7Z_f4l$e+V#yh-z3|1H@G=l}!yN zw=)z>ZhM?^uZqL%5C?|a76(PGAcra!JWJS-GY={nuxTzzjdaDd1umIx3^)(|*&&Xr0KRk(-7$p!LLF+2_zC^THAz@dO* zbz~Zx7*OuP;V=a`RB-)kG^y(|QzeHpjl1g@PD0FZ3@3L${arsNIsVrnsh?FYS=5|O z45!ktqLSjjZpm@J{AM@_jOI94G~JO=`=%TBpmBG@s%#FDc~|J}Xy}vtohNqpL8hDK zt;T@dzwu0 fGnI$!5Y7Domb1sJ^`msr00000NkvXXu0mjfCU@Nb literal 0 HcmV?d00001 diff --git a/assets/1x/j_cry_redbloon.png b/assets/1x/j_cry_redbloon.png new file mode 100644 index 0000000000000000000000000000000000000000..b8e20302d71bf1afb14177524aff705036bec341 GIT binary patch literal 4366 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�q)O&o1yL{6gR6f4LCHA z)gcEtj%&ol+O}N`D&s3t{e$RH<*cT9(M=X`#;w$74rh#&L56i9L6i*|b)Yoc>EQRq z=PGqJL36;Sb*jo#yD1-C5h9g0TEIzLrO_PjH@KQ3`4MdNKDFm!AMbe zuoF0;iZQ3)dJA)=u0_mogG_H7$cM~K!oOnHBL5tAFr)P)zJAqSc z7;~Ppfir!59Da^Ib*q>+-TP}k&S${#XF{y#l0h zlamFV!J0E|amaa`fAMyV`J5RqX*9=XBupX!)(UCV?)i){Kc1Xxv@$YFOrH5u*Q%i4 zJ?OL@C;u%0bKBw&nTJ?JHRrb45Sho@GlFybOMaT;KY}vjlqi`H@Idih!6E@|5 z#eLx{vzL2Ku-BHyOt;63SSz#?&JF&W!{)rqAXzianx)q$LjD;i zF!J;P%(Tl$(zLq0E<~OjB7!rcE=1h70uY=xFLq(l`k2rt*Dn!^}mTHb;4A8!wE=+h&B!1|%y`O)+Yl-LQz#tjH`Q;|c9MNy_9tid;!8hJ#KL+8{ zsE%=uwih@ObAUaw8bZzk|D7|~2+n<*&9N2UnU~1-*ZlR0c3_S{a{!=w8bSmH$q3G` zH)B6XdI6zJAt+<@NrZ8$CTw+-Ja3#L{`2K+43Gp4eH82^-`fx(f8z``f^+|tIQ*O- zv6UoUer`&qlk0W}JmwRzU2+sn6^-Cw^I{DEb3rPC9| zhf^%fnY~qIj&1~ne2(!=*ixaBTw~zogpt)lQhJi<}#(od=6SIL2 zKJR(P0P<`bIHrIu$XpLHlD?Y7fx-La*~(e#-=FN)f4JZ8e{Nw8ZKN##Y7MybT4mRB zz<0d|(MHP52T@U|V6EuQ=^w@T?(aT$Z|-M~2S2|1iy;gcdcdDm@!l>dfz;Y*@NK-_ z__t=hjSth-ef~dyO<+)rLDJ^{000hUSV?A0O#mtY000O800000007cclK=n!07*qo IM6N<$g6#W6hyVZp literal 0 HcmV?d00001 From 4b75e3d2719408dfb328e5f33a07f38b76a17f21 Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:49:30 -0700 Subject: [PATCH 6/7] Add files via upload --- assets/2x/j_cry_apjoker.png | Bin 0 -> 4025 bytes assets/2x/j_cry_big_m.png | Bin 1251 -> 1808 bytes assets/2x/j_cry_bubblem.png | Bin 0 -> 2422 bytes assets/2x/j_cry_curse.png | Bin 0 -> 2784 bytes assets/2x/j_cry_double_scale.png | Bin 3034 -> 4142 bytes assets/2x/j_cry_jollysus.png | Bin 0 -> 3001 bytes assets/2x/j_cry_labyrinth.png | Bin 0 -> 3807 bytes assets/2x/j_cry_m.png | Bin 1197 -> 1663 bytes assets/2x/j_cry_mstack.png | Bin 0 -> 2259 bytes 9 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/2x/j_cry_apjoker.png create mode 100644 assets/2x/j_cry_bubblem.png create mode 100644 assets/2x/j_cry_curse.png create mode 100644 assets/2x/j_cry_jollysus.png create mode 100644 assets/2x/j_cry_labyrinth.png create mode 100644 assets/2x/j_cry_mstack.png diff --git a/assets/2x/j_cry_apjoker.png b/assets/2x/j_cry_apjoker.png new file mode 100644 index 0000000000000000000000000000000000000000..b06527c105409f55d2f91db16cdc8d05ab17e7dd GIT binary patch literal 4025 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 fFdHn8Wr6W!s`SIa+(2fzb4730M zAh;Z-dagQmbzW)US9R#lLH?>?B0P^B0YvSjaR9)#xKJIvWBjIa+_;^m*Wao><3wH8 z3>fPpTH?Ff;%D08yM+LL$IqCp8|$u8CQNNxtTU@bz9Ny=ivCPAJ3NOnst|8KKGj1^ zM4|d5U#a0s6iL%;?@7;_{y3hXQxnUYcOnC$39j0aHAGnXW2|a<++(N3#0YXnBJs2N zG%=bdy4`kASDhJ$L8lrCI=se^*kbnD!}b4HYNM(G%Lnf6mU;Fc<^C5htM{vvGJf^Q z;{^$WgapHJheIG;|G};40BoIa_`5Z#mKoD%1dOH%)IZq~+ASq3QM-m@4vCWGSk?S} zd0<}THiZodfDLS$1RClLImSd*m~6X*F_n%+oqAn&);+a|@uB%>WCVI0ltt zz;5nAfja1Rvn>qA6mJXnT*rKU>cWNX1lYPqm> z+G%@^-BVsr*~*m*XWl1e)2vxXlY8P@0l2zHU1s56zZ~;~lP4W5$(+l!n`(5xy4&rBUqE};eZ`;&`*y8MY|(tRYm9Q=lJ|A) z+#Uy(H~v%n0HsqO-3;9VRWkM*-8WX>un} z;FeLD2GB$Up+XETdv^p81D}`lc;jF){R0^bRwkAU@L=eZwooN0y#ce<90|s@R1x<6+Z~Bu;1pbZcp!uWp^gm98Q;?KZ$cb& zrJGNx+)mGwDj=^s%!Aiw_ZO<5p?mxllP^008Fcb5bA5Rt!fNom!P~q%NkQK+5I$2+ zJH!F4xFnG5S$xqckN}w2I*>Ub1`6ViI4eVMmX5KPKK`SspT6jD<6POAfIvzKK1jf>*292V z&)*flAj14zChjU`x<>_23adUe^mYE!4TDewl|*6ujb|w2{0^%VMkF8iOl8)9D+%G0 uT=<+C%>1ryaW{AG};s6(C8dY?}|K@+&Yf$I_ literal 1251 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 literal 0 HcmV?d00001 diff --git a/assets/2x/j_cry_curse.png b/assets/2x/j_cry_curse.png new file mode 100644 index 0000000000000000000000000000000000000000..279a1391a173c9869c7bf18999469bb93f4f9b40 GIT binary patch literal 2784 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 literal 0 HcmV?d00001 diff --git a/assets/2x/j_cry_double_scale.png b/assets/2x/j_cry_double_scale.png index 36884d3d6bf8528bbea3647608152987ffd797bc..e72bb3aa2f3ee7ed94cc88f5056e3c46d5424bbb 100644 GIT binary patch literal 4142 zcmV+}5Yg|6P)Px^=t)FDRCr$PUA?X(M;YDSkeI*;Lb3?01&N60-UI|MK!PkGfrT@_03k0x1_C4` zi^MMgg5+*Qgaj*x$dX0kfY{+0dAe(GpP4h~RCQH#bL85x}`WOjvK64IE^chldC2LDA`05_t9M z)#8N^NEeI~z®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 literal 3034 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 literal 0 HcmV?d00001 diff --git a/assets/2x/j_cry_labyrinth.png b/assets/2x/j_cry_labyrinth.png new file mode 100644 index 0000000000000000000000000000000000000000..e87392f95699401db2f8629f44c7f23fcf1b5f09 GIT binary patch literal 3807 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 V3uK$B8JYk9002ovPDHLkV1k4Lp#=Z{ literal 0 HcmV?d00001 diff --git a/assets/2x/j_cry_m.png b/assets/2x/j_cry_m.png index a418e475aadd27b145f6870c2f52fc1557503217..d271105f6016306157d37fb4114dae9cc3a6afb0 100644 GIT binary patch literal 1663 zcmd6oe>7AH6vyA28IPHmuo|>LIME5#Mg%tpwDu>w-`bCIGpKvL7zZzfVT%w(@Plz0BDmhhyA4_Y`mDw9olNa zIdj`I-ElX^e5~eIxruXIG9S?N;=r2e9<#u z3wFPfEi?Zr0#kqbO?tjTSb|JH6@|8{I} z!rd^VA4_+u>u|2JxovKA;*oiP~sIGQM#N)RQx{h1Rt z=(?k{CuN!A>*3k)=X)n?1sSP3GoMW{$ymZb&2T^u8qp6o4*Zlr_J5}a6&Vi_`AaZ3 zLrF7%yT@6{Ohc-bAMf744|}_p^3F$%LH$USX(WeuNT|)|*6lubzHbg0&R70Y^%*>) zKFz{ks2FKk|Ja8LftC4Xp*$z-s@8`(1}eD6_Z~Qd+zxdpzHBIDt*&a=gX8Wykx*}o zj#gaM782oVm;SC~;6I>e*wwFd-%YOs;4MwvN}ODJa|;A&sKH4=XkP7IjU6_vbFL-9 zla{mA1WGCYX%Oh$61n{7-%~kboxv}oOoh_;f?xy6%<&XsoP1}^WEJ8dsQaFczUc}I zvlQyqyk{7F%Hjne)%B!n(fs_#WDjd8fii*wJ#9zwNw=tdLltLLaU@wl^CRjCOnPJO z64C|UGEDLEeHyv+{qm`uwQ;kxR+Sn zp;>oTX)!3nh*3tsIQt)>Ow9V2^%pqdipE&XMriDjvkHV4@myaU!;rn#DL^5sUMhh; z4f$-dq`Jp7apb~p=jN_!irDinK15%eXG!m;4!JkCjNb@T*e<8p3H-C|z4-Yq)?y5l z8|^_H0(9DqK+Krhv&0Zy;Td}XFKp!UbxHrLQFQc*cCmYW$hmOp6rM}EaktG3V`F!*y4}B-#>% zQ}sI+_;5{_#1wWwNh3mtwL5_|Kt)KzlhZ4#IM{`6*FM8i z$-i$H^DtCbZu!E0ul`TX_T$nIBjRkTKb^h#BX7OAlP>?Vtf(2!{pH_(&$H;c|NqbL zd-v=A{ybj2d69+7zWKi!FU`5FZ~xbT=kVcAJtFNV>gPxA|NHU!U4xprTUJhAANT&t zv>nUJ^Y8z8|61OzRxrgl^@sh~qbMv1MxE$H1wJ)!G~jIdbLZ04=bn zu5s#ee)7ol+#No{?D@rkGD;t}YPnjPA62}RYu~4Ib(w|Bqeo|CU3=H}*K7Ivb~!Kk zxmD|_B|D0#5DR91f9!Mq@{Q@md|l2dpX=siRxYz&4z&K#pG?s?&5s0b)|A#{y|moP z6$<2Jmc?HU@|?0v3@HD`^0@Nz;&YCL9VOM9c3rvxv~w44-}7f6#;mo4&*p7-w{O)f z5s>?VHks_U+P7ue#%n8G3p@1AFK$iyms&WQ9F@#kL`ags%P&O+xG26-rL{ha zU$xEJ0q7cSzxBV@T$`qT^>y02_lx(pfcAWsZP;G-r6Bv#+?mt=)jb0+aZoBvYJ}^kPKYzSo{k^5( zGD`CpBhFm_xwC8 z(7e%09ojHKS+ zkSexHpsGa{M{h8mSg7eIm|gzs?A~{;EOrOXQJU8E@b@YUmZO^Mu7B^) zcU(LFPa0y_+r5v!J>H<*Tx_&<-t6Rpj)=!|rWhZOX$2=ANKRP1DrwrhJ*Gt=M?*Ev zo!oM3J}^o}mP_1cI&H6Ow@{ivjv*gwkE<0w*|J*3{vX3So1N(RW#lI%K VwBkSf4Ok2@c)I$ztaD0e0sw|yNb>*y diff --git a/assets/2x/j_cry_mstack.png b/assets/2x/j_cry_mstack.png new file mode 100644 index 0000000000000000000000000000000000000000..61760740b068a410338081b219050a3ce73afbec GIT binary patch literal 2259 zcmYjTc{r2{7k_8QkTFKKLKAL_B~ujf&KQa8G?itnaladlrSeX)G$URSGR?9D*LoA(h}_nhl0_@v_McfU7CsJs33u zLz3qQT(`8WuF8g6Ce}H$ZppEsvBtO%=uawT-zX62#-iQSrlIzdxYFwEUh;rJK z*OtDl?2=+YI8|1!@y_Kf<#1th<~#zzGRhzz$bBtKpv1996WI z611T@Inc8IhJrxTOk}Ns5Qo0)I*y38W?S(Y>|4zw@R-0@-!J73R$r`oX6GrgGD2EX zMM#2j+cyty&yz+$SluS@`^^?S*e~v$V^3tW)=9j?9Mv&Hh?j^{QM8iy&;IRpC3zpK zmIo@)9Tpr6=r-Yj+oDUHQPu4+{a)@a+&pDvtp{;4-BKT+clX3R>L;D{gDO)aN{cL@ z@*~DAK0}>PVRi4LI#fgsD|IW7A3iQ&D-~BVur8U)(|q4SXuWAu2iPKoko>7ol(*j3 z&ZoI~`QP}-KXH&yUM?M%lSj#C2|UxJx8#wT8ghK$7Ir2eqp!|qdUb4fWJv6fVj z9ji-ZT+>6%^6t1`&iMGo2hCVT>PY&3pLfxp-i!@oz%kwKI`zHhODK z0`OYEa>t8q0PoJ~8b`Mb4o{p4fLP=s{)`2aR(c}9IJCFTj=uKW%vfv06t#DI?2QDm zs(~@Nouu!#{16X<*_v7NvoOC~eUz*jNroz=7_-NE{_wvyhnU!GmXMFZN~}F+dcVF+ z*?k^RfD&;;5xu2|p&8vD!woPJKP)zIoE}RQk13sN(m{ggYg;O0>s1$J7MuKxvSmT^WTN2lPmmV<-0+Dn zc71R>0Vt@Zbf+?#jg_Et4-R7pz?eKw6ANC?R_WA#U`5MBsVXEGBKLWRG9v~n@jR#4M z^3W!1M#JY9qkm<68Q}@nwei3KS6%n)P0*I0h&fm<@d5%|y`m6nhCtPB%CFWi0<407 zIa@?SbCt{MgJXEbW8&6`?t7{@Ij-9Qu9Kw80zoXErZ5~)(qpdN7wO$!kWg~g;YV?u z{6zhY(8^@}gpt-JZdq4-_xLr7mtF?QIk>e(4)NG-G)K!UA*#? z|10|sskJ0eD#g7$Ok%}v(uAbym&QS6r{BeJYof)9YKVv4CgN^0cEhrHQSVsNW z7y-+C_S}sB5!1f*lP_FY%{!vPEQsSB`#z|49+YUu0{o>W5*Q{cIIC-7Rxs@wCflC$ zrY$^Gt13j?f3&DzJ|U%*S^HT>=A``}qYFACErh#2KP9-|q)XMY@{-vN!J#>^kvwt zuSoXV@Q|U(%;H7AI$DLDe<8#4LYYI<#@f|3W>xu87zJsxaao?64dr+N3B`@S-^Uu^ zu0Ar|EmnT*;Bz)W(n$z+FRf}tNu8hHQxL$avAn@ph-G1Qx0YIW(W6*8VXnCY7b*DT;irjy-2i-CLiQZ86`5VZgM}!d( zqf3!Q%O4fOsv}n6sM>K;@};=r<(#_e$pkSoSU*45#xVuU4eb_X`<=Fl*z(>ks;{dz z?_1>JN)5+Lu7}{M1IKl|U#wj$X%4Vyrh>=dN{l?0Zln|&s90SU_*enV8{GOh>12@7 zHBGGw(fNsG3h%s7m@iM<%7R73UZ`+)r;5B`kfMLbu`Vu+C5B@f&>+qHS+wbYl~#K{ zpt-%c_yZZ^bz8+_r3=ihM1cqqaf8qVq+SCc7Mz+b>Aa-Zw6@Pq%KS*Wv#S;@XrA^C zVPqZ%j#h&_PGl=!XhDa3FVX*OxXs*AH*Py_II(WuQl4H)9M$CGb^2# z!!Z7k0aCwI>2xoiHgJ$U+IHqD>pQ(D?&i}ETh{NBXeMQ8d=H*h?c~oOVI3seQP$@^ dxTmZELr=0p)5>`s>t71s>PU0AZ~yDXzX3O!FLM9@ literal 0 HcmV?d00001 From bb02823d0ff33a5ce2ad9092616f9eb24ac8abf5 Mon Sep 17 00:00:00 2001 From: Jevonnissocoolman Date: Wed, 26 Jun 2024 15:52:02 -0700 Subject: [PATCH 7/7] Add files via upload --- assets/2x/j_cry_redbloon.png | Bin 0 -> 6177 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/2x/j_cry_redbloon.png diff --git a/assets/2x/j_cry_redbloon.png b/assets/2x/j_cry_redbloon.png new file mode 100644 index 0000000000000000000000000000000000000000..67b0992d9d93c8379cb4064d25b7c088688748b6 GIT binary patch literal 6177 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 literal 0 HcmV?d00001