Compare commits

...

24 commits
1.4.0 ... main

Author SHA1 Message Date
6ff684ed79
Add new Karma Deck; moving old to Ascension Sleeve; moving old to challenge 2025-12-28 16:22:39 +01:00
8e44deab99
Remove xchips, buff Betmma and Saint, nerf Oxy 2025-10-10 01:14:35 +02:00
023fa306ff
Require 2 uses of Joker in a Tarot from start 2025-08-19 18:28:21 +02:00
63a48ff597
Remove if statement 2025-08-06 00:47:16 +02:00
af75973c0b
Fix moire never appearing in non-cryptid 2025-08-06 00:46:47 +02:00
d131dadae8
Increase odds for jumbo and moire to appear 2025-08-06 00:42:17 +02:00
dd96176c3d
Buff non-cryptid joker-in-a-tarot 2025-07-28 21:45:11 +02:00
f93d8f09e6
Display uses left in Cryptid 2025-07-20 10:06:30 +02:00
ed3303e575
Use escape hatch 2025-06-24 14:32:54 +02:00
93e0a4f6d6
Heavily nerf joker-in-a-tarot 2025-06-24 13:51:14 +02:00
b4834d2c9b
Fix capitalization 2025-05-15 02:21:21 +02:00
571eff1e53
Nerf survivor in non-cryptid to promote more interesting play 2025-05-12 16:59:49 +02:00
91a5163b20
Fix Saint mechanics and Wee phrasing in non-cryptid 2025-05-11 02:49:34 +02:00
9de61821c5
Update .editorconfig 2025-05-02 23:42:40 +02:00
c494379e07
Only apply this to attuned saint 2025-05-02 02:31:48 +02:00
3002fe967f
Fix saint debuff and rot lag 2025-05-02 02:25:38 +02:00
89b072cb45
Include other spectrals 2025-04-29 13:21:52 +02:00
00abcb0c14
Decrease price of Hunter in Cryptid 2025-04-26 21:43:44 +02:00
a2a238be3a
Hunter is now Epic 2025-04-25 03:47:38 +02:00
23a77ed39f
Rebalance on Ephemeris Sleeve 2025-04-25 01:57:52 +02:00
1c592f3878
Add dedicated sleeve sprites 2025-04-25 01:37:47 +02:00
0b6aa8afbb
Negate boolean 2025-04-24 21:32:42 +02:00
7549eb55d9
Add new voucher 2025-04-24 05:02:01 +02:00
151023da0e
Improve We 2025-04-18 23:03:27 +02:00
16 changed files with 306 additions and 182 deletions

View file

@ -20,11 +20,11 @@ continuation_indent = 4
# this mean utf8 length , if this is 'unset' then the line width is no longer checked # this mean utf8 length , if this is 'unset' then the line width is no longer checked
# this option decides when to chopdown the code # this option decides when to chopdown the code
max_line_length = lf max_line_length = 120
# optional crlf/lf/cr/auto, if it is 'auto', in windows it is crlf other platforms are lf # optional crlf/lf/cr/auto, if it is 'auto', in windows it is crlf other platforms are lf
# in neovim the value 'auto' is not a valid option, please use 'unset' # in neovim the value 'auto' is not a valid option, please use 'unset'
end_of_line = auto end_of_line = lf
# none/ comma / semicolon / only_kv_colon # none/ comma / semicolon / only_kv_colon
table_separator_style = none table_separator_style = none

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

@ -48,6 +48,7 @@ payload = '''if Jane and (type(G.ARGS.score_intensity.required_score) == "table"
local base = Cryptid and 10 or G.ARGS.score_intensity.required_score local base = Cryptid and 10 or G.ARGS.score_intensity.required_score
local expo = Cryptid and G.ARGS.score_intensity.required_score or 10 local expo = Cryptid and G.ARGS.score_intensity.required_score or 10
Jane.sinister = (G.ARGS.score_intensity.earned_score / (big(base) ^ big(expo))):to_number() > 1 Jane.sinister = (G.ARGS.score_intensity.earned_score / (big(base) ^ big(expo))):to_number() > 1
G.escapey_sinister = Jane.sinister
end''' end'''
match_indent = true match_indent = true
@ -57,10 +58,15 @@ target = "functions/state_events.lua"
pattern = "for _, v in ipairs(SMODS.get_card_areas('playing_cards')) do" pattern = "for _, v in ipairs(SMODS.get_card_areas('playing_cards')) do"
position = "after" position = "after"
payload = '''if v == G.hand and not (G.GAME.blind and G.GAME.blind.name == "The Card" and not G.GAME.blind.disabled) and next(SMODS.find_card("j_jane_survivor")) then payload = '''if v == G.hand and not (G.GAME.blind and G.GAME.blind.name == "The Card" and not G.GAME.blind.disabled) and next(SMODS.find_card("j_jane_survivor")) then
for _, v in ipairs(G.hand.cards) do if Cryptid then
local area = {cards = {v}} for _, v in ipairs(G.hand.cards) do
SMODS.calculate_main_scoring({cardarea = area, full_hand = area.cards, scoring_hand = area.cards, scoring_name = text, poker_hands = poker_hands}, area.cards) local area = {cards = {v}}
SMODS.calculate_main_scoring({cardarea = area, full_hand = area.cards, scoring_hand = area.cards, scoring_name = text, poker_hands = poker_hands}, nil) SMODS.calculate_main_scoring({cardarea = area, full_hand = area.cards, scoring_hand = area.cards, scoring_name = text, poker_hands = poker_hands}, area.cards)
SMODS.calculate_main_scoring({cardarea = area, full_hand = area.cards, scoring_hand = area.cards, scoring_name = text, poker_hands = poker_hands}, nil)
end
else
SMODS.calculate_main_scoring({cardarea = G.hand, full_hand = G.hand.cards, scoring_hand = G.hand.cards, scoring_name = text, poker_hands = poker_hands}, G.hand.cards)
SMODS.calculate_main_scoring({cardarea = G.hand, full_hand = G.hand.cards, scoring_hand = G.hand.cards, scoring_name = text, poker_hands = poker_hands}, nil)
end end
else''' else'''
match_indent = true match_indent = true
@ -125,8 +131,24 @@ match_indent = true
[[patches]] [[patches]]
[patches.pattern] [patches.pattern]
target = '=[SMODS Cryptid "items/exotic.lua"]' target = '=[SMODS Cryptid "items/spectral.lua"]'
pattern = 'local _first_dissolve = nil' pattern = "local _first_dissolve = nil"
position = "after" position = "after"
payload = 'deletable_jokers = next(SMODS.find_card("j_jane_saint")) and {} or deletable_jokers' payload = 'deletable_jokers = next(SMODS.find_card("j_jane_saint")) and {} or deletable_jokers'
match_indent = true match_indent = true
[[patches]]
[patches.pattern]
target = '=[SMODS Cryptid "items/exotic.lua"]'
pattern = "local _first_dissolve = nil"
position = "after"
payload = 'deletable_jokers = next(SMODS.find_card("j_jane_saint")) and {} or deletable_jokers'
match_indent = true
[[patches]]
[patches.pattern]
target = '=[SMODS _ "src/utils.lua"]'
pattern = "function SMODS.has_enhancement(card, key)"
position = "after"
payload = "if not card.config then return false end"
match_indent = true

View file

@ -17,5 +17,5 @@
"conflicts": [ "conflicts": [
"Jen" "Jen"
], ],
"version": "1.4.0" "version": "1.5.19"
} }

1
refs/CardSleeves Symbolic link
View file

@ -0,0 +1 @@
../../CardSleeves/

View file

@ -5,6 +5,13 @@ SMODS.Atlas {
path = Jane.config.texture_pack .. "/b_jane_decks.png", path = Jane.config.texture_pack .. "/b_jane_decks.png",
} }
SMODS.Atlas {
px = 73,
py = 95,
key = "janesleeves",
path = Jane.config.texture_pack .. "/sleeve_jane_sleeves.png",
}
local function back(x) local function back(x)
local key = x.key local key = x.key
local apply = x.apply local apply = x.apply
@ -40,7 +47,7 @@ local function back(x)
CardSleeves.Sleeve { CardSleeves.Sleeve {
key = key, key = key,
pos = x.pos, pos = x.pos,
atlas = "janedecks", atlas = "janesleeves",
loc_txt = {name = name, text = text}, loc_txt = {name = name, text = text},
apply = function(self, ...) apply = function(self, ...)
-- Game becomes genuinely unplayable if this is allowed. -- Game becomes genuinely unplayable if this is allowed.
@ -88,8 +95,6 @@ local function back(x)
} }
end end
local eternal_text = Cryptid and "Absolute" or "Eternal"
back { back {
key = "nitro", key = "nitro",
atlas = "janedecks", atlas = "janedecks",
@ -144,7 +149,7 @@ back {
end, end,
} }
local rain_world_jokers = { Jane.rain_world_jokers = {
"j_jane_monk", "j_jane_monk",
"j_jane_survivor", "j_jane_survivor",
"j_jane_hunter", "j_jane_hunter",
@ -156,12 +161,6 @@ local rain_world_jokers = {
"j_jane_rot", "j_jane_rot",
} }
local is_rain_world_joker = {}
for _, v in pairs(rain_world_jokers) do
is_rain_world_joker[v] = true
end
local function add_rain_world_joker() local function add_rain_world_joker()
if not G.jokers then if not G.jokers then
return return
@ -169,13 +168,14 @@ local function add_rain_world_joker()
local unobtained = {} local unobtained = {}
for _, v in pairs(rain_world_jokers) do for _, v in pairs(Jane.rain_world_jokers) do
if not next(SMODS.find_card(v, true)) then if not next(SMODS.find_card(v, true)) then
unobtained[#unobtained + 1] = v unobtained[#unobtained + 1] = v
end end
end end
local chosen = pseudorandom_element(next(unobtained) and unobtained or rain_world_jokers, pseudoseed("karma_deck")) local chosen = pseudorandom_element(next(unobtained) and unobtained or Jane.rain_world_jokers,
pseudoseed("karma_deck"))
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, chosen, "karma_deck_next") local card = create_card("Joker", G.jokers, nil, nil, nil, nil, chosen, "karma_deck_next")
card:add_to_deck() card:add_to_deck()
card:start_materialize() card:start_materialize()
@ -189,65 +189,24 @@ back {
loc_txt = { loc_txt = {
name = "Karma Deck", name = "Karma Deck",
text = { text = {
"Start with a {C:legendary}Rain World Joker", "Start with a",
"Create another when", "{C:legendary}Rain World Joker",
"{C:attention}Boss Blind {}is defeated",
}, },
}, },
alt_loc_txt = { alt_loc_txt = {
name = "Ascension Sleeve", name = "Ascension Sleeve",
text = { text = {
"Start with all {C:legendary}Rain World Jokers {}instead", "Create a {C:legendary}Rain World Joker",
"Destroy a random {C:legendary}Rain World Joker {}when", "when {C:attention}Boss Blind {}is defeated",
"{C:attention}Boss Blind {}is defeated, or {C:red}lose",
}, },
}, },
alt_apply = function(_) alt_apply = function(_)
for _, v in ipairs(rain_world_jokers) do Jane.q(add_rain_world_joker)
Jane.q(function()
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, v, "karma_deck_next")
card:add_to_deck()
card:start_materialize()
G.jokers:emplace(card)
play_sound("timpani")
end, 0.2)
end
end, end,
apply = function(_) apply = function(_)
Jane.q(add_rain_world_joker) Jane.q(add_rain_world_joker)
end, end,
alt_calculate = function(_, _, context) alt_calculate = function(_, _, context)
local function l()
if G.STAGE == G.STAGES.RUN then
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
end
end
if not Jane.is_end_of_ante(context) then
return
end
local destructible_jokers = {}
for _, v in pairs(G.jokers.cards) do
if is_rain_world_joker[v.config.center.key] and not ((v.ability or {}).eternal or (v.ability or {}).cry_absolute) then
destructible_jokers[#destructible_jokers + 1] = v
end
end
if not next(destructible_jokers) then
return l()
end
local chosen = pseudorandom_element(destructible_jokers, pseudoseed("karma_deck"))
if chosen then
chosen.getting_sliced = true
chosen:start_dissolve()
end
end,
calculate = function(_, _, context)
if Jane.is_end_of_ante(context) then if Jane.is_end_of_ante(context) then
add_rain_world_joker() add_rain_world_joker()
end end
@ -344,6 +303,7 @@ back {
local orig_get_current_pool = get_current_pool local orig_get_current_pool = get_current_pool
---@diagnostic disable-next-line: lowercase-global
function get_current_pool(_type, ...) function get_current_pool(_type, ...)
local pool, pool_key = orig_get_current_pool(_type, ...) local pool, pool_key = orig_get_current_pool(_type, ...)
@ -518,6 +478,8 @@ back {
if new_discards ~= 0 then if new_discards ~= 0 then
ease_discard(new_discards, true) ease_discard(new_discards, true)
end end
rebalance_orrery()
end, end,
} }
@ -592,24 +554,30 @@ local function two(x)
for k, v in pairs(x) do for k, v in pairs(x) do
if type(v) == "number" then if type(v) == "number" then
x[k] = 2 x[k] = x[k] == 0 and 0 or 2
elseif type(v) == "table" then elseif type(v) == "table" then
two(v) two(v)
end end
end end
end end
local eternal_text = Cryptid and "Absolute" or "Eternal"
back { back {
key = "weeck", key = "weeck",
atlas = "janedecks", atlas = "janedecks",
pos = {x = 4, y = 1}, pos = {x = 4, y = 1},
loc_txt = { loc_txt = {
name = "Weeck", name = "Weeck",
text = { text = Cryptid and {
"Start with an {C:purple,E:1}" .. eternal_text, "Start with an {C:purple,E:1}" .. eternal_text,
"{C:attention}Wee Joker {}and a deck", "{C:attention}Wee Joker {}and a deck",
"containing {C:attention}2 {C:purple,E:1}" .. eternal_text, "containing {C:attention}2 {C:purple,E:1}" .. eternal_text,
"{C:attention}2's {}of {C:attention}each suit", "{C:attention}2's {}of {C:attention}each suit",
} or {
"Start with an {C:purple,E:1}" .. eternal_text,
"{C:attention}Wee Joker {}and a deck",
"of {C:attention}2 2's {}of {C:attention}each suit",
}, },
}, },
alt_loc_txt = { alt_loc_txt = {
@ -625,7 +593,6 @@ back {
p.hands = 2 p.hands = 2
p.dollars = 2 p.dollars = 2
p.discards = 2 p.discards = 2
p.hand_size = 2
G.GAME.skips = 2 G.GAME.skips = 2
p.joker_slots = 2 p.joker_slots = 2
p.reroll_cost = 2 p.reroll_cost = 2
@ -633,8 +600,6 @@ back {
p.boosters_in_shop = 2 p.boosters_in_shop = 2
p.consumable_slots = 2 p.consumable_slots = 2
p.vouchers_in_shop = 2 p.vouchers_in_shop = 2
G.GAME.round_resets.temp_handsize = 2
G.GAME.weeckweeck = true
for _, v in pairs(G.GAME.hands) do for _, v in pairs(G.GAME.hands) do
v.mult = 2 v.mult = 2
@ -648,16 +613,10 @@ back {
apply_weeck() apply_weeck()
end, end,
alt_calculate = function(_) alt_calculate = function(_)
for _, v in pairs(G.hand.cards) do if not G.GAME.we then
two(v.ability) G.GAME.we = true
end G.hand.config.highlighted_limit = 2
G.hand:change_size(2 - G.hand.config.card_limit)
for _, v in pairs(G.jokers.cards) do
two(v.ability)
end
for _, v in pairs(G.consumeables.cards) do
two(v.ability)
end end
end, end,
} }
@ -911,7 +870,8 @@ function CardArea:emplace(card, location, stay_flipped)
G.deck and G.deck and
G.consumeables and G.consumeables and
(self == G.jokers or self == G.hand or self == G.deck or self == G.consumeables) and (self == G.jokers or self == G.hand or self == G.deck or self == G.consumeables) and
G.GAME.mysterious and card.ability and not G.GAME.mysterious and
card.ability and not
card.ability.mysterious_created and not card.ability.mysterious_created and not
card.created_from_split then card.created_from_split then
card.ability.mysterious_created = true card.ability.mysterious_created = true
@ -990,5 +950,9 @@ function CardArea:emplace(card, location, stay_flipped)
end) end)
else else
orig_emplace(self, card, location, stay_flipped) orig_emplace(self, card, location, stay_flipped)
if G.GAME.we then
two(card.ability)
end
end end
end end

78
src/challenge.lua Normal file
View file

@ -0,0 +1,78 @@
local is_rain_world_joker = {}
for _, v in pairs(Jane.rain_world_jokers) do
is_rain_world_joker[v] = true
end
SMODS.Challenge {
key = "downpour",
loc_txt = {
name = "Downpour",
},
rules = {custom = {
{id = "jane_downpour1"},
{id = "jane_downpour2"},
{id = "jane_downpour3"},
{id = "jane_downpour4"},
}},
apply = function(_)
G.GAME.win_ante = 16
for _, v in ipairs(Jane.rain_world_jokers) do
Jane.q(function()
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, v, "karma_deck_next")
card:add_to_deck()
card:start_materialize()
G.jokers:emplace(card)
play_sound("timpani")
end, 0.2)
end
end,
calculate = function(_, context)
local function l()
if G.STAGE == G.STAGES.RUN then
G.STATE = G.STATES.GAME_OVER
G.STATE_COMPLETE = false
end
end
if not Jane.is_end_of_ante(context) then
return
end
local destructible_jokers = {}
for _, v in pairs(G.jokers.cards) do
if is_rain_world_joker[v.config.center.key] and not ((v.ability or {}).eternal or (v.ability or {}).cry_absolute) then
destructible_jokers[#destructible_jokers + 1] = v
end
end
if not next(destructible_jokers) then
return l()
end
local chosen = pseudorandom_element(destructible_jokers, pseudoseed("karma_deck"))
if chosen then
chosen.getting_sliced = true
chosen:start_dissolve()
end
end,
}
G.localization.misc.v_text["ch_c_jane_downpour1"] = {
"Start with all {C:legendary}Rain World Jokers",
}
G.localization.misc.v_text["ch_c_jane_downpour2"] = {
"Destroy a random {C:legendary}Rain World Joker {}when",
}
G.localization.misc.v_text["ch_c_jane_downpour3"] = {
"{C:attention}Boss Blind {}is defeated, or {C:red}lose",
}
G.localization.misc.v_text["ch_c_jane_downpour4"] = {
"Win on {C:attention}Ante 16",
}

View file

@ -10,7 +10,7 @@ local function allow_moire()
end end
for _, v in pairs(SMODS.find_card("j_jane_saint")) do for _, v in pairs(SMODS.find_card("j_jane_saint")) do
if v.is_attuned then if v.ability.extra.is_attuned then
return true return true
end end
end end
@ -28,23 +28,21 @@ SMODS.Edition({
name = "Polygloss", name = "Polygloss",
label = "Polygloss", label = "Polygloss",
text = Cryptid and { text = Cryptid and {
"{C:chips}+#1#{}, {X:chips,C:white}x#2#{} & {X:chips,C:dark_edition}^#3#{} Chips", "{C:chips}+#1#{} Chips",
"{C:mult}+#4#{}, {X:mult,C:white}x#5#{} & {X:mult,C:dark_edition}^#6#{} Mult", "{C:mult}+#2#{}, {X:mult,C:white}X#3#{}, & {X:mult,C:dark_edition}^#4#{} Mult",
"{C:money}$#7# {}when scored",
} or {
"{C:chips}+#1#{} & {X:chips,C:white}x#2#{}",
"{C:mult}+#3#{} & {X:mult,C:white}x#4#{}",
"{C:money}$#5# {}when scored", "{C:money}$#5# {}when scored",
} or {
"{C:chips}+#1#{} Chips",
"{C:mult}+#2#{} & {X:mult,C:white}X#3#{} Mult",
"{C:money}$#4# {}when scored",
}, },
}, },
config = { config = {
mult = 1, mult = 2,
chips = 1, chips = 12,
x_mult = 1.1, x_mult = 1.2,
x_chips = 1.1,
p_dollars = 1, p_dollars = 1,
e_chips = Cryptid and 1.01 or nil, e_mult = Cryptid and 1.02 or nil,
e_mult = Cryptid and 1.01 or nil,
}, },
sound = {sound = "jane_e_polygloss", per = 1.2, vol = 0.4}, sound = {sound = "jane_e_polygloss", per = 1.2, vol = 0.4},
weight = 8, weight = 8,
@ -53,8 +51,7 @@ SMODS.Edition({
shader = "polygloss", shader = "polygloss",
apply_to_float = false, apply_to_float = false,
loc_vars = function(self, _, _) loc_vars = function(self, _, _)
local vars = {self.config.chips, self.config.x_chips} local vars = {self.config.chips}
vars[#vars + 1] = self.config.e_chips
vars[#vars + 1] = self.config.mult vars[#vars + 1] = self.config.mult
vars[#vars + 1] = self.config.x_mult vars[#vars + 1] = self.config.x_mult
vars[#vars + 1] = self.config.e_mult vars[#vars + 1] = self.config.e_mult
@ -71,8 +68,6 @@ SMODS.Edition({
return { return {
e_mult = card.edition.e_mult, e_mult = card.edition.e_mult,
x_mult = card.edition.x_mult, x_mult = card.edition.x_mult,
e_chips = card.edition.e_chips,
x_chips = card.edition.x_chips,
p_dollars = card.edition.p_dollars, p_dollars = card.edition.p_dollars,
} }
elseif context.main_scoring and context.cardarea == G.play then elseif context.main_scoring and context.cardarea == G.play then
@ -81,8 +76,6 @@ SMODS.Edition({
chips = card.edition.chips, chips = card.edition.chips,
e_mult = card.edition.e_mult, e_mult = card.edition.e_mult,
x_mult = card.edition.x_mult, x_mult = card.edition.x_mult,
e_chips = card.edition.e_chips,
x_chips = card.edition.x_chips,
p_dollars = card.edition.p_dollars, p_dollars = card.edition.p_dollars,
} }
end end
@ -151,7 +144,7 @@ SMODS.Edition({
end end
end, end,
sound = {sound = "jane_e_jumbo", per = 1, vol = 0.5}, sound = {sound = "jane_e_jumbo", per = 1, vol = 0.5},
weight = 3, weight = 4,
extra_cost = 5, extra_cost = 5,
in_shop = true, in_shop = true,
shader = false, shader = false,
@ -164,11 +157,14 @@ SMODS.Edition({
loc_txt = { loc_txt = {
name = "Moire", name = "Moire",
label = "Moire", label = "Moire",
text = {"{X:chips,C:dark_edition}^#1#{C:chips} Chips{}, {X:mult,C:dark_edition}^#2#{C:mult} Mult"}, text = {
"{X:chips,C:dark_edition}^#1#{C:chips} Chips",
"{X:mult,C:dark_edition}^#2#{C:mult} Mult",
},
}, },
config = {e_chips = Cryptid and 0.8 or 0.9, e_mult = Cryptid and 1.2 or 1.1}, config = {e_chips = Cryptid and 0.8 or 0.9, e_mult = Cryptid and 1.2 or 1.1},
sound = {sound = "jane_e_moire", per = 1, vol = 0.7}, sound = {sound = "jane_e_moire", per = 1, vol = 0.7},
weight = 1, weight = 2,
extra_cost = 6, extra_cost = 6,
in_shop = true, in_shop = true,
shader = "moire", shader = "moire",

View file

@ -362,7 +362,7 @@ function Jane.oxy(card, removed)
end end
end end
local steel = 1.5 local steel = 2
SMODS.Joker { SMODS.Joker {
key = "oxy", key = "oxy",
@ -370,15 +370,15 @@ SMODS.Joker {
loc_txt = { loc_txt = {
name = "Oxy{C:dark_edition}#1#", name = "Oxy{C:dark_edition}#1#",
text = { text = {
"{C:attention}Scored steel {}cards give", "{C:attention}Scored steel {}cards",
"{X:mult,C:white}x#2#{} {C:mult}Mult {}and {X:chips,C:white}x#2#{} {C:chips}Chips", "give {X:mult,C:white}X#2#{} {C:mult}Mult",
"{C:dark_edition,E:1}#3#{}#4#{C:red}#5#{C:attention}#6#", "{C:dark_edition,E:1}#3#{}#4#{C:red}#5#{C:attention}#6#",
"{C:dark_edition,E:1}#7#{}#8#", "{C:dark_edition,E:1}#7#{}#8#",
"#9#{C:dark_edition,E:1}#10#", "#9#{C:dark_edition,E:1}#10#",
"{C:inactive,s:0.75,E:1}#11#{C:red,s:1.5,E:1}#12#", "{C:inactive,s:0.75,E:1}#11#{C:red,s:1.5,E:1}#12#",
}, },
}, },
config = {extra = {corrupted_steel = 2.5, is_corrupted = false, milestone = 3, progress = 0}}, config = {extra = {corrupted_steel = 6, is_corrupted = false, milestone = 3, progress = 0}},
pos = {x = 0, y = 0}, pos = {x = 0, y = 0},
sinis = {x = 2, y = 0}, sinis = {x = 2, y = 0},
soul_pos = {x = 1, y = 0}, soul_pos = {x = 1, y = 0},
@ -472,7 +472,7 @@ SMODS.Joker {
context.cardarea == G.play and context.cardarea == G.play and
context.other_card.ability.name == "Steel Card" then context.other_card.ability.name == "Steel Card" then
local amount = extra.is_corrupted and extra.corrupted_steel or steel local amount = extra.is_corrupted and extra.corrupted_steel or steel
return {x_chips = amount, x_mult = amount, colour = G.C.PURPLE, card = card}, true return {x_mult = amount, colour = G.C.PURPLE, card = card}, true
end end
end, end,
} }
@ -482,6 +482,7 @@ if Cryptid then
end end
local operator = Cryptid and "^" or "X" local operator = Cryptid and "^" or "X"
local operator_prefix = Cryptid and "{X:dark_edition,C:mult}" or "{X:mult,C:white}"
SMODS.Joker { SMODS.Joker {
key = "betmma", key = "betmma",
@ -489,12 +490,12 @@ SMODS.Joker {
loc_txt = { loc_txt = {
name = "Betmma", name = "Betmma",
text = { text = {
"{X:dark_edition,C:chips}+" .. operator .. "#1#{C:chips} Chips{} for every", operator_prefix .. "+" .. operator .. "#1#{C:mult} Mult{} for every",
"{C:attention}unique Voucher redeemed", "{C:attention}unique Voucher redeemed",
"{C:inactive}(Currently {X:dark_edition,C:chips}" .. operator .. "#2#{C:inactive})", "{C:inactive}(Currently " .. operator_prefix .. operator .. "#2#{C:inactive})",
}, },
}, },
config = {extra = {tet = Cryptid and 0.1 or 0.25}}, config = {extra = {tet = Cryptid and 0.25 or 0.5}},
pos = {x = 0, y = 0}, pos = {x = 0, y = 0},
soul_pos = {x = 1, y = 0}, soul_pos = {x = 1, y = 0},
blueprint_compat = true, blueprint_compat = true,
@ -517,7 +518,7 @@ SMODS.Joker {
card = card, card = card,
colour = G.C.jane_RGB, colour = G.C.jane_RGB,
message = operator .. number_format(num), message = operator .. number_format(num),
[Cryptid and "e_chips" or "x_chips"] = num, [Cryptid and "e_mult" or "x_mult"] = num,
}, true }, true
end end
end, end,
@ -557,7 +558,7 @@ SMODS.Joker {
if context.other_card and context.other_card:get_id() == 7 and scj(context) then if context.other_card and context.other_card:get_id() == 7 and scj(context) then
grand_dad(card) grand_dad(card)
local palette = granddad_palette[math.random(#granddad_palette)] local palette = granddad_palette[math.random(#granddad_palette)]
local rnd = pseudorandom(pseudoseed("granddad"), 1, Cryptid and 7 or 5) local rnd = pseudorandom(pseudoseed("granddad"), 1, Cryptid and 5 or 4)
if rnd == 1 then if rnd == 1 then
return { return {
@ -582,25 +583,11 @@ SMODS.Joker {
}, true }, true
elseif rnd == 4 then elseif rnd == 4 then
return { return {
message = Cryptid and "x7" or "x1.77", message = Cryptid and "X7 Mult" or "X1.77 Mult",
x_chips = Cryptid and 7 or 1.77,
colour = palette,
card = card,
}, true
elseif rnd == 5 then
return {
message = Cryptid and "x7 Mult" or "x1.77 Mult",
x_mult = Cryptid and 7 or 1.77, x_mult = Cryptid and 7 or 1.77,
colour = palette, colour = palette,
card = card, card = card,
}, true }, true
elseif rnd == 6 then
return {
message = "^1.77",
e_chips = 1.77,
colour = palette,
card = card,
}, true
else else
return { return {
message = "^1.77 Mult", message = "^1.77 Mult",
@ -620,10 +607,10 @@ SMODS.Joker {
loc_txt = { loc_txt = {
name = "Peppino Spaghetti", name = "Peppino Spaghetti",
text = { text = {
"{X:dark_edition,C:red}" .. operator .. "2^x{C:red} Mult{} for every", operator_prefix .. operator .. "2^x{C:red} Mult{} for every",
"{C:attention}food or Peppino Joker", "{C:attention}food or Peppino Joker",
"in your possession", "in your possession",
"{C:inactive}(Currently {X:dark_edition,C:red}" .. operator .. "#1#{C:red} Mult{C:inactive})", "{C:inactive}(Currently " .. operator_prefix .. operator .. "#1#{C:red} Mult{C:inactive})",
}, },
}, },
pos = {x = 0, y = 0}, pos = {x = 0, y = 0},

View file

@ -313,6 +313,7 @@ for _, v in ipairs({
"back", "back",
"blind", "blind",
"booster", "booster",
"challenge",
"edition", "edition",
"joker", "joker",
"slugcat", "slugcat",

View file

@ -125,9 +125,9 @@ SMODS.Joker {
name = "The Survivor", name = "The Survivor",
text = { text = {
"All cards held in hand", "All cards held in hand",
"{C:attention}contribute to scoring {}and", "{C:attention}contribute to scoring" .. (Cryptid and " {}and" or ""),
"are all considered as", Cryptid and "are all considered as" or nil,
"the {C:attention}first played card", Cryptid and "the {C:attention}first played card" or nil,
}, },
}, },
pos = {x = 0, y = 0}, pos = {x = 0, y = 0},
@ -156,8 +156,8 @@ SMODS.Joker {
eternal_compat = false, eternal_compat = false,
perishable_compat = false, perishable_compat = false,
soul_pos = {x = 1, y = 0}, soul_pos = {x = 1, y = 0},
cost = Cryptid and 20 or 8, cost = Cryptid and 15 or 8,
rarity = Cryptid and 4 or 3, rarity = Cryptid and epic or 3,
loc_vars = function(_, info_queue, card) loc_vars = function(_, info_queue, card)
local function rounds(amount) local function rounds(amount)
return " round" .. ((math.abs(amount) > 1 or math.abs(amount) == 0) and "s" or "") return " round" .. ((math.abs(amount) > 1 or math.abs(amount) == 0) and "s" or "")
@ -469,7 +469,7 @@ function Card:set_debuff(should_debuff)
end end
local function attunement() local function attunement()
return (G.GAME or {}).weeckweeck and 2 or (Cryptid and 1.001 or 1.2) return (G.GAME or {}).weeckweeck and 2 or (Cryptid and 1.002 or 1.2)
end end
SMODS.Joker { SMODS.Joker {
@ -478,9 +478,10 @@ SMODS.Joker {
loc_txt = { loc_txt = {
name = "The Saint{C:jane_RGB}#1#", name = "The Saint{C:jane_RGB}#1#",
text = Cryptid and { text = Cryptid and {
"{C:spectral}Ankh and Gateway {}will {C:attention}not destroy Jokers", "{C:spectral}Analog{}, {C:spectral}Ankh{}, {C:spectral}Gateway{}, and",
"{C:jane_RGB}#2#{}#3#{X:black,C:jane_RGB,s:1.5}#4#{C:spectral}#5#{C:chips}#6#{}#7#{C:mult}#8#", "{C:spectral,s:0.95}Summoning {s:0.95}will {C:attention,s:0.95}not destroy Jokers",
"{C:inactive,s:1.25}#9#{C:attention,s:1.25}#10#{C:inactive,s:1.25}#11#{C:inactive}#12#", "{C:jane_RGB}#2#{}#3#{X:black,C:jane_RGB,s:1.5}#4#{C:spectral}#5#{C:mult}#6#",
"{C:inactive,s:1.25}#7#{C:attention,s:1.25}#8#{C:inactive,s:1.25}#9#{C:inactive}#10#",
} or { } or {
"{C:spectral}Ankh {}will {C:attention}not destroy Jokers", "{C:spectral}Ankh {}will {C:attention}not destroy Jokers",
"{C:jane_RGB}#2#{}#3#{C:dark_edition}#4#{C:spectral}#5#", "{C:jane_RGB}#2#{}#3#{C:dark_edition}#4#{C:spectral}#5#",
@ -494,8 +495,17 @@ SMODS.Joker {
rarity = 4, rarity = 4,
blueprint_compat = true, blueprint_compat = true,
loc_vars = function(_, info_queue, card) loc_vars = function(_, info_queue, card)
if Cryptid then
info_queue[#info_queue + 1] = G.P_CENTERS.c_cry_analog
end
info_queue[#info_queue + 1] = G.P_CENTERS.c_ankh info_queue[#info_queue + 1] = G.P_CENTERS.c_ankh
info_queue[#info_queue + 1] = Cryptid and G.P_CENTERS.c_cry_gateway or G.P_CENTERS.c_soul info_queue[#info_queue + 1] = Cryptid and G.P_CENTERS.c_cry_gateway or G.P_CENTERS.c_soul
if Cryptid then
info_queue[#info_queue + 1] = G.P_CENTERS.c_cry_summoning
end
local extra = card.ability.extra local extra = card.ability.extra
local karma = extra.karma local karma = extra.karma
local max_karma = extra.max_karma local max_karma = extra.max_karma
@ -508,9 +518,7 @@ SMODS.Joker {
attuned and "" or "after using ", attuned and "" or "after using ",
attuned and "^^" .. attunement() or max_karma, attuned and "^^" .. attunement() or max_karma,
attuned and "" or " Gateways", attuned and "" or " Gateways",
attuned and " Chips " or "", attuned and " Mult" or "",
attuned and "& " or "",
attuned and "Mult" or "",
attuned and "" or "[", attuned and "" or "[",
attuned and "" or karma, attuned and "" or karma,
attuned and "" or " / " .. max_karma .. "]", attuned and "" or " / " .. max_karma .. "]",
@ -518,7 +526,7 @@ SMODS.Joker {
} or { } or {
attuned and " (Attuned)" or "", attuned and " (Attuned)" or "",
attuned and "" or "Attune ", attuned and "" or "Attune ",
attuned and "Fires on cards with " or "after using ", attuned and "Boosts cards with " or "after using ",
attuned and "editions" or max_karma, attuned and "editions" or max_karma,
attuned and "" or " Ankh or Soul Cards", attuned and "" or " Ankh or Soul Cards",
attuned and "" or "[", attuned and "" or "[",
@ -529,6 +537,8 @@ SMODS.Joker {
} }
end, end,
update = function(_, card, _) update = function(_, card, _)
card.debuff_immune = card.ability.extra.is_attuned
if card.added_to_deck and card.children.center and card.children.floating_sprite then if card.added_to_deck and card.children.center and card.children.floating_sprite then
local extra = card.ability.extra local extra = card.ability.extra
card.children.floating_sprite:set_sprite_pos({x = extra.is_attuned and 2 or 1, y = 0}) card.children.floating_sprite:set_sprite_pos({x = extra.is_attuned and 2 or 1, y = 0})
@ -540,7 +550,7 @@ SMODS.Joker {
extra.is_attuned = extra.is_attuned and extra.karma >= max_karma extra.is_attuned = extra.is_attuned and extra.karma >= max_karma
local function ascend() local function ascend()
if not extra.is_attuning then if extra.is_attuning then
return return
end end
@ -581,21 +591,24 @@ SMODS.Joker {
card.ability.perish_tally = 1e9 card.ability.perish_tally = 1e9
end end
if ({[false] = context.repetition, [true] = not context.joker_main})[not not Cryptid] then if Cryptid and not context.joker_main then
return
end
if not Cryptid and not context.other_joker and (not context.individual or context.cardarea ~= G.play) then
return return
end end
local attune = attunement() local attune = attunement()
local trigger = ({ local trigger = ({
e_holo = {mult_mod = 50}, e_holo = {mult = 50},
e_foil = {chip_mod = 250}, e_foil = {chips = 250},
e_polychrome = {xmult_mod = 2.5}, e_polychrome = {x_mult = 2.5},
e_jane_polygloss = { e_jane_polygloss = {
mult = 10, mult = 10,
chips = 10,
x_mult = 2, x_mult = 2,
x_chips = 2, chips = 100,
p_dollars = 10, p_dollars = 10,
}, },
e_jane_moire = { e_jane_moire = {
@ -605,7 +618,7 @@ SMODS.Joker {
[Cryptid and "EEmult_mod" or "Emult_mod"] = attune, [Cryptid and "EEmult_mod" or "Emult_mod"] = attune,
message = (Cryptid and "^^" or "^") .. attune .. " Chips & Mult", message = (Cryptid and "^^" or "^") .. attune .. " Chips & Mult",
}, },
})[Cryptid and "e_jane_moire" or ((context.other_card or {}).edition or {}).key] })[Cryptid and "e_jane_moire" or ((context.other_card or context.other_joker or {}).edition or {}).key]
if trigger then if trigger then
trigger.card = card trigger.card = card
@ -693,6 +706,10 @@ SMODS.Joker {
end end
local function spawn() local function spawn()
if card.cloned then
return
end
local rot = copy_card(card) local rot = copy_card(card)
rot.cloned = true rot.cloned = true
rot:add_to_deck() rot:add_to_deck()
@ -703,9 +720,7 @@ SMODS.Joker {
if has_room() and not card.cloned and Jane.is_end_of_ante(context, card) then if has_room() and not card.cloned and Jane.is_end_of_ante(context, card) then
Jane.q(spawn, 0.5) Jane.q(spawn, 0.5)
else else
Jane.q(function() card.cloned = false
card.cloned = false
end, 5)
end end
end, end,
} }

View file

@ -1,29 +1,40 @@
local function j()
return G.GAME.used_vouchers.v_jane_jolly_voucher and "j_jolly" or "j_joker"
end
local required = 2
local function get_uses()
G.GAME.joker_in_a_tarot = G.GAME.joker_in_a_tarot or 0
return G.GAME.joker_in_a_tarot
end
local blurbs = { local blurbs = {
"M!",
"Hey! Pick me!", "Hey! Pick me!",
"You wouldn't say no to a free negative me, would you?", "Hee-hee, hoo-hoo!",
"Sometimes, an extra four mult goes a long way!", "Looks like the joke is on you!",
"Ouch, I think the joke is on me!",
"I won't take up space, I promise!", "I won't take up space, I promise!",
"Don't ask how I ended up in a tarot!", "Don't ask how I ended up in a tarot!",
"Hee-hee, hoo-hoo!",
"Who knew even fortunes could be a circus act?",
"Looks like the joke is on the crystal globe!",
"It's a little cramped in this tarot...!",
"Ouch, I think the joke is on me!",
"Looks like the joke is on you!",
"I'm not just a clown; I'm the whole circus!",
"Seems a little suspicious for a jolly old fella like me to be in this card...",
"I can't help if I'm still in this silly old card, break me out!",
"Let me tell you, you'd love the show going on in this tarot!",
"I'd give you more tickets to JimCon, but I'm fresh out.",
"I've heard of a round buffoon that lives in a pretty funky town...",
"I can't give four mult if I'm still in this card!",
"I'm rooting for you! Even if it means I'll never get out of this card...",
"Who knew I'd have access to a great show? That show being you!",
"The stakes are only gonna rise here!", "The stakes are only gonna rise here!",
"Juggling is one of my favourite passtimes!",
"I wonder what's the deal with pairs?", "I wonder what's the deal with pairs?",
"It's a little cramped in this tarot...!",
"Juggling is one of my favourite passtimes!",
"I'm not just a clown; I'm the whole circus!",
"Looks like the joke is on the crystal globe!",
"Who knew even fortunes could be a circus act?",
"Sometimes, an extra four mult goes a long way!",
"I can't give four mult if I'm still in this card!",
"You wouldn't say no to a free negative me, would you?",
"I'd give you more tickets to JimCon, but I'm fresh out.",
"Let me tell you, you'd love the show going on in this tarot!",
"Who knew I'd have access to a great show? That show being you!",
"I can't help if I'm still in this silly old card, break me out!",
"I've heard of a round buffoon that lives in a pretty funky town...",
"You don't need to understand math to enjoy watching the digits climb!", "You don't need to understand math to enjoy watching the digits climb!",
"M!", "I'm rooting for you! Even if it means I'll never get out of this card...",
"Seems a little suspicious for a jolly old fella like me to be in this card...",
} }
SMODS.Consumable { SMODS.Consumable {
@ -31,22 +42,41 @@ SMODS.Consumable {
atlas = "janeacc", atlas = "janeacc",
set = "Tarot", set = "Tarot",
loc_txt = { loc_txt = {
name = "Joker-in-a-Tarot", name = "#1#-in-a-Tarot",
text = { text = {
"Create a {C:dark_edition}Negative {C:attention}default Joker", "Create a {C:dark_edition}Negative {C:attention}#2#",
"{C:inactive,E:1}#1#{}", "after {C:attention}#3# {}uses {C:inactive}(#4# left)",
"{C:inactive,E:1}#5#{}",
}, },
}, },
loc_vars = function(_, info_queue, card) loc_vars = function(_, info_queue, card)
info_queue[#info_queue + 1] = G.P_CENTERS.j_joker info_queue[#info_queue + 1] = G.P_CENTERS[j()]
card.blurb = card.blurb or pseudorandom_element(blurbs, pseudoseed("jokerinatarotblurbs")) local is_jolly = G.GAME.used_vouchers.v_jane_jolly_voucher
return {vars = {card.blurb}}
card.blurb = not card.fake_card and
(card.blurb or pseudorandom_element(blurbs, pseudoseed("jokerinatarotblurbs"))) or ""
if is_jolly then
card.blurb = card.blurb:gsub("four", "eight")
end
local desc = is_jolly and "Jolly Joker" or "default Joker"
local name = is_jolly and "Jolly" or "Joker"
return {vars = {name, desc, required, required - get_uses(), card.blurb}}
end, end,
pos = {x = 0, y = 1}, pos = {x = 0, y = 1},
cost = 4, cost = 4,
can_use = Jane.can_use, can_use = Jane.can_use,
use = function(_, _, _, _) use = function(_, _, _, _)
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_joker", "jokerfromatarot") local uses = get_uses() + 1
if uses < required then
G.GAME.joker_in_a_tarot = uses
return
end
G.GAME.joker_in_a_tarot = 0
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, j(), "jokerfromatarot")
card:set_edition({negative = true}, true) card:set_edition({negative = true}, true)
card.cost = 1 card.cost = 1
card.base_cost = 1 card.base_cost = 1
@ -62,3 +92,10 @@ SMODS.Consumable {
end end
end, end,
} }
if Cryptid then
Cryptid.aliases["joker in a tarot"] = "c_jane_jokerinatarot"
Cryptid.aliases["joker-in-a-tarot"] = "c_jane_jokerinatarot"
Cryptid.aliases["jolly in a tarot"] = "c_jane_jokerinatarot"
Cryptid.aliases["jolly-in-a-tarot"] = "c_jane_jokerinatarot"
end

View file

@ -1,3 +1,10 @@
SMODS.Atlas {
key = "janejollyvoucher",
px = 71,
py = 95,
path = Jane.config.texture_pack .. "/v_jane_jolly_voucher.png",
}
SMODS.Atlas { SMODS.Atlas {
key = "janetokenvoucher", key = "janetokenvoucher",
px = 71, px = 71,
@ -5,6 +12,22 @@ SMODS.Atlas {
path = Jane.config.texture_pack .. "/v_jane_token_voucher.png", path = Jane.config.texture_pack .. "/v_jane_token_voucher.png",
} }
SMODS.Voucher {
key = "jolly_voucher",
atlas = "janejollyvoucher",
loc_txt = {
name = "Jolly Voucher",
text = {"{C:attention,T:c_jane_jokerinatarot}Joker-in-a-Tarot {}creates", "{C:attention,T:j_jolly}Jolly Joker {}instead"},
},
pos = {x = 0, y = 0},
cost = 8,
loc_vars = function(_, info_queue, _)
info_queue[#info_queue + 1] = G.P_CENTERS.c_jane_jokerinatarot
info_queue[#info_queue + 1] = G.P_CENTERS.j_jolly
return {vars = {}}
end,
}
SMODS.Voucher { SMODS.Voucher {
key = "token_voucher", key = "token_voucher",
atlas = "janetokenvoucher", atlas = "janetokenvoucher",