diff --git a/.gitignore b/.gitignore index cb1b7c5..1b01869 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,6 @@ luac.out # Syncthing .stfolder + +# Autogenerated +assets/1x/jokers diff --git a/assets/1x/joker.png b/assets/1x/joker.png index 40fa29a..9d53e7f 100644 Binary files a/assets/1x/joker.png and b/assets/1x/joker.png differ diff --git a/assets/1x/spectral.png b/assets/1x/spectral.png index 890f4d2..5e356dd 100644 Binary files a/assets/1x/spectral.png and b/assets/1x/spectral.png differ diff --git a/assets/2x/back.png b/assets/2x/back.png index 044616b..cb77959 100644 Binary files a/assets/2x/back.png and b/assets/2x/back.png differ diff --git a/assets/2x/blind.png b/assets/2x/blind.png index 6477e01..80ea98e 100644 Binary files a/assets/2x/blind.png and b/assets/2x/blind.png differ diff --git a/assets/2x/charm.png b/assets/2x/charm.png index 2bacb90..4ec4b7b 100644 Binary files a/assets/2x/charm.png and b/assets/2x/charm.png differ diff --git a/assets/2x/icon.png b/assets/2x/icon.png index 938aec1..3308924 100644 Binary files a/assets/2x/icon.png and b/assets/2x/icon.png differ diff --git a/assets/2x/joker.png b/assets/2x/joker.png index c0cb074..0f69e37 100644 Binary files a/assets/2x/joker.png and b/assets/2x/joker.png differ diff --git a/assets/2x/seal.png b/assets/2x/seal.png index ecd13af..dc53e71 100644 Binary files a/assets/2x/seal.png and b/assets/2x/seal.png differ diff --git a/assets/2x/spectral.png b/assets/2x/spectral.png index 80898f8..84211ee 100644 Binary files a/assets/2x/spectral.png and b/assets/2x/spectral.png differ diff --git a/assets/2x/tag.png b/assets/2x/tag.png index 268cf97..469d1cd 100644 Binary files a/assets/2x/tag.png and b/assets/2x/tag.png differ diff --git a/assets/2x/tarot.png b/assets/2x/tarot.png index 13d9445..c20ee6d 100644 Binary files a/assets/2x/tarot.png and b/assets/2x/tarot.png differ diff --git a/assets/repack.sh b/assets/repack.sh new file mode 100755 index 0000000..9aefaec --- /dev/null +++ b/assets/repack.sh @@ -0,0 +1,10 @@ +#!/bin/sh +directory=$(dirname $(readlink -f "$0")) +mkdir -p "$directory/1x/jokers" + +for i in $(seq 0 25); do + files="$files $directory/1x/jokers/$i.png"; +done + +magick montage -background '#00000000' $files -geometry +0+0 "$directory/1x/joker.png" +"$directory/upscale.sh" diff --git a/assets/unpack.sh b/assets/unpack.sh new file mode 100755 index 0000000..2033412 --- /dev/null +++ b/assets/unpack.sh @@ -0,0 +1,4 @@ +#!/bin/sh +directory=$(dirname $(readlink -f "$0")) +mkdir -p "$directory/1x/jokers" +magick "$directory/1x/joker.png" -crop 71x95 +repage +adjoin "$directory/1x/jokers/%02d.png" diff --git a/localization/en-us.lua b/localization/en-us.lua index a55be8b..e4545bf 100644 --- a/localization/en-us.lua +++ b/localization/en-us.lua @@ -118,10 +118,24 @@ return { }, }, Joker = { + j_Roland_amberacorn = { + name = "Amber Acorn", + text = {"{X:mult,C:white}X#1#{} Mult", "Moves before", "hand is played"}, + }, j_Roland_arctic = { name = "Arctic Circle", text = {"Retrigger {C:dark_edition}Frozen {}cards", "Retrigger playing cards"}, }, + j_Roland_artemis = { + name = "Artemis X", + text = { + "Earn {C:money}$#1# {}at end of round", + "Payout increases by {C:money}$#2#", + "when these {C:planet}Planet {}cards", + "are used in order:", + "{V:1}Earth{C:inactive} - {V:2}Mars{C:inactive} - {V:3}Earth", + }, + }, j_Roland_basket = { name = "Basket", text = { @@ -130,14 +144,6 @@ return { "of every consumable", }, }, - j_Roland_blight = { - name = "Blight", - text = { - "Third played card", - "gives {X:red,C:white}X#1#{} Mult", - "if it is {C:dark_edition}Frozen", - }, - }, j_Roland_bulldozer = { name = "Bulldozer", text = { @@ -146,6 +152,14 @@ return { "{C:inactive}(Currently {X:red,C:white}X#1#{C:inactive})", }, }, + j_Roland_coldturkey = { + name = "Cold Turkey", + text = { + "Third scored card", + "gives {X:red,C:white}X#1#{} Mult", + "if it is {C:dark_edition}Frozen", + }, + }, j_Roland_domino = { name = "Domino", text = { @@ -249,10 +263,6 @@ return { "{C:inactive}(Currently {C:red}+#2#{C:inactive} Mult)", }, }, - j_Roland_stubborn = { - name = "Stubborn", - text = {"{X:mult,C:white}X#1#{} Mult", "Moves before", "hand is played"}, - }, j_Roland_suitable = { name = "Suitable", text = {"{V:1}#1# {}are {C:attention}Wild", "Suit changes", "every round"}, @@ -337,26 +347,18 @@ return { Spectral = { c_Roland_afterimage = { name = "Afterimage", - text = { - "Add {C:dark_edition}Negative {}to {C:attention}#1#", - "selected card in hand", - "{C:red}#2#{} hand size", - }, - }, - c_Roland_dual = { - name = "Dual", text = { "Add random seals", "to {C:attention}#1#{} random", "cards in {C:hands}hand", }, }, - c_Roland_mirror = { - name = "Mirror", + c_Roland_refract = { + name = "Refract", text = { "Add a {C:dark_edition}Glass Seal", "to {C:attention}#1#{} selected", - "card in {C:hands}hand", + "cards in {C:hands}hand", }, }, c_Roland_void = { diff --git a/manifest.json b/manifest.json index d6c2b39..dcf016e 100644 --- a/manifest.json +++ b/manifest.json @@ -6,7 +6,7 @@ "author": [ "Emik" ], - "version": "2.4.5", + "version": "2.5.0", "badge_colour": "8BE9FD", "main_file": "src/main.lua", "badge_text_colour": "44475A", diff --git a/src/joker.lua b/src/joker.lua index fbe2976..aa1511e 100644 --- a/src/joker.lua +++ b/src/joker.lua @@ -69,6 +69,25 @@ joker { end, } +joker { + key = "jokersr", + pronouns = "he_him", + config = {extra = {xmult = 1.25}}, + attributes = {"xmult"}, + cost = 2, + rarity = 2, + eternal_compat = true, + blueprint_compat = true, + perishable_compat = true, + loc_vars = function(_, _, card) + return {vars = {card.ability.extra.xmult}} + end, + calculate = function(_, card, context) + return (context.joker_main or context.forcetrigger) and + {card = card, xmult = card.ability.extra.xmult} or nil + end, +} + joker { key = "mrsbones", pronouns = "she_her", @@ -106,25 +125,112 @@ joker { } joker { - key = "phytoestrogens", - pronouns = "she_her", - config = {extra = {xmult = 0.25}}, - attributes = {"mult", "xmult"}, - cost = 8, - rarity = 3, - eternal_compat = true, + key = "sunny", + pronouns = "they_them", + artist = "char", + attributes = {"food", "on_sell"}, + cost = 2, + rarity = 1, + eternal_compat = false, blueprint_compat = true, perishable_compat = true, loc_vars = function(_, _, card) - return {vars = {card.ability.extra.xmult}} + local last = ((G.deck or {}).cards or {})[1] + + if not last or card.area ~= G.jokers then + return { + vars = { + "", + localize {type = "variable", key = "b_Roland_na"}, + "", + colours = {G.C.JOKER_GREY, G.C.JOKER_GREY}, + }, + } + end + + local suit = last.base.suit + local value = last.base.value + local name = last.ability.name or "" + local no_rank = SMODS.has_no_rank(last) + local no_suit = SMODS.has_no_suit(last) + + return { + vars = { + value and not no_rank and localize(value or 14, "ranks") or name, + not no_rank and not no_suit and localize {type = "variable", key = "b_Roland_of"} or "", + no_suit and "" or localize(suit, "suits_plural"), + colours = {G.C.IMPORTANT, G.C.SUITS[suit] or G.C.JOKER_GREY}, + }, + } end, - calculate = function(_, card, context) - if not context.joker_main and not context.forcetrigger then + calculate = function(_, _, context) + if not context.selling_self and not context.forcetrigger then return end - SMODS.calculate_effect({mult = hand_chips}, card) - SMODS.calculate_effect({xmult = card.ability.extra.xmult}, card) + draw_card(G.deck, G.hand, 100, "up", false, G.deck.cards[1]) + local current_round = G.GAME.current_round + local facing_blind = G.GAME.facing_blind + SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}} + + SMODS.calculate_context { + first_hand_drawn = not current_round.any_hand_drawn and facing_blind or nil, + hand_drawn = facing_blind and {G.deck.cards[1]} --[[@as true]], + other_drawn = not facing_blind and {G.deck.cards[1]}, + } + + if type(facing_blind) == "table" then + facing_blind.any_hand_drawn = facing_blind.any_hand_drawn or facing_blind + end + end, +} + +joker { + key = "hardboiled", + pronouns = "they_them", + attributes = {"food", "editions", "modify_card", "on_sell"}, + cost = 5, + rarity = 2, + eternal_compat = false, + blueprint_compat = true, + perishable_compat = true, + loc_vars = function(_, info_queue) + table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) + end, + calculate = function(_, _, context) + return (context.selling_self or context.forcetrigger) and f(G.hand.cards):each(function(v) + q { + delay = 0.1, + func = function() + v:set_edition {Roland_frozen = true} + end, + } + end) or nil + end, +} + +joker { + key = "basket", + pronouns = "they_them", + attributes = {"food", "generation", "on_sell"}, + cost = 8, + rarity = 3, + eternal_compat = false, + blueprint_compat = true, + perishable_compat = true, + loc_vars = function(_, info_queue) + table.insert(info_queue, negative) + end, + calculate = function(_, _, context) + return (context.selling_self or context.forcetrigger) and f(G.consumeables.cards):each(function(v) + q { + delay = 1, + func = function() + play_sound "timpani" + SMODS.add_card {edition = "e_negative", key = v.config.center.key} + end, + } + end) or nil end, } @@ -244,112 +350,90 @@ joker { } joker { - key = "sunny", - pronouns = "they_them", - artist = "char", - attributes = {"food", "on_sell"}, - cost = 2, + key = "coldturkey", + pronouns = "he_him", + config = {extra = {xmult = 2}}, + attributes = {"xmult"}, + cost = 4, rarity = 1, - eternal_compat = false, + eternal_compat = true, blueprint_compat = true, perishable_compat = true, - loc_vars = function(_, _, card) - local last = ((G.deck or {}).cards or {})[1] - - if not last or card.area ~= G.jokers then - return { - vars = { - "", - localize {type = "variable", key = "b_Roland_na"}, - "", - colours = {G.C.JOKER_GREY, G.C.JOKER_GREY}, - }, - } - end - - local suit = last.base.suit - local value = last.base.value - local name = last.ability.name or "" - local no_rank = SMODS.has_no_rank(last) - local no_suit = SMODS.has_no_suit(last) - - return { - vars = { - value and not no_rank and localize(value or 14, "ranks") or name, - not no_rank and not no_suit and localize {type = "variable", key = "b_Roland_of"} or "", - no_suit and "" or localize(suit, "suits_plural"), - colours = {G.C.IMPORTANT, G.C.SUITS[suit] or G.C.JOKER_GREY}, - }, - } + loc_vars = function(_, info_queue, card) + table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) + return {vars = {card.ability.extra.xmult}} end, - calculate = function(_, _, context) - if not context.selling_self and not context.forcetrigger then - return - end + calculate = function(_, card, context) + local target = (context.scoring_hand or {})[3] - draw_card(G.deck, G.hand, 100, "up", false, G.deck.cards[1]) - local current_round = G.GAME.current_round - local facing_blind = G.GAME.facing_blind - SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}} - - SMODS.calculate_context { - first_hand_drawn = not current_round.any_hand_drawn and facing_blind or nil, - hand_drawn = facing_blind and {G.deck.cards[1]} --[[@as true]], - other_drawn = not facing_blind and {G.deck.cards[1]}, - } - - if type(facing_blind) == "table" then - facing_blind.any_hand_drawn = facing_blind.any_hand_drawn or facing_blind - end + return (context.individual and + context.cardarea == G.play and + context.other_card == target and + is_frozen(context.other_card) or + context.forcetrigger) and + {xmult = card.ability.extra.xmult} or nil end, } joker { - key = "hardboiled", + key = "snowsquall", pronouns = "they_them", - attributes = {"food", "editions", "modify_card", "on_sell"}, - cost = 5, + config = {extra = {mult_gain = 1, mult = 0}}, + attributes = {"mult", "scaling", "hand_type"}, + cost = 6, rarity = 2, - eternal_compat = false, + eternal_compat = true, + blueprint_compat = true, + perishable_compat = false, + loc_vars = function(_, info_queue, card) + table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) + local extra = card.ability.extra + return {vars = {extra.mult_gain, extra.mult}} + end, + calculate = function(_, card, context) + local extra = card.ability.extra + + if context.joker_main or context.forcetrigger then + return {mult = extra.mult} + end + + if context.blueprint or + not context.individual or + context.cardarea ~= G.play or + not is_frozen(context.other_card) then + return + end + + extra.mult = extra.mult + extra.mult_gain + return {message = localize "k_upgrade_ex", colour = G.C.RED, message_card = card} + end, +} + +joker { + key = "arctic", + pronouns = "it_its", + cost = 10, + rarity = 3, + config = {extra = {[false] = 1, [true] = 2}}, + attributes = {"retrigger", "editions"}, + eternal_compat = true, blueprint_compat = true, perishable_compat = true, loc_vars = function(_, info_queue) table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) end, - calculate = function(_, _, context) - return (context.selling_self or context.forcetrigger) and f(G.hand.cards):each(function(v) - q { - delay = 0.1, - func = function() - v:set_edition {Roland_frozen = true} - end, - } - end) or nil - end, -} - -joker { - key = "basket", - pronouns = "they_them", - attributes = {"food", "generation", "on_sell"}, - cost = 8, - rarity = 3, - eternal_compat = false, - blueprint_compat = true, - perishable_compat = true, - loc_vars = function(_, info_queue) - table.insert(info_queue, negative) - end, - calculate = function(_, _, context) - return (context.selling_self or context.forcetrigger) and f(G.consumeables.cards):each(function(v) - q { - delay = 1, - func = function() - play_sound "timpani" - SMODS.add_card {edition = "e_negative", key = v.config.center.key} - end, - } - end) or nil + calculate = function(_, card, context) + return context.repetition and {repetitions = card.ability.extra[is_frozen(context.other_card)]} or + SMODS.merge_effects( + f(G.jokers.cards):where(is_frozen):map(function(v) + return SMODS.blueprint_effect(card, v, context) or true + end):where(function(v) + return type(v) == "table" + end):map(function(v) + v.colour = G.C.DARK_EDITION + return v + end):values():table() + ) end, } @@ -406,58 +490,6 @@ joker { end, } -joker { - key = "suitable", - pronouns = "she_they", - attributes = {"suit", "passive", "hearts", "diamonds", "spades", "clubs"}, - cost = 4, - rarity = 2, - eternal_compat = true, - blueprint_compat = false, - perishable_compat = true, - loc_vars = function(_, info_queue) - table.insert(info_queue, G.P_CENTERS.m_wild) - local suit = (G.GAME.current_round.Roland_suitable or {}).suit or "Spades" - return {vars = {localize(suit, "suits_plural"), colours = {G.C.SUITS[suit]}}} - end, - add_to_deck = function() - G.GAME.modifiers.Roland_suitable = (G.GAME.modifiers.Roland_suitable or 0) + 1 - end, - remove_from_deck = function() - G.GAME.modifiers.Roland_suitable = (G.GAME.modifiers.Roland_suitable or 0) - 1 - end, -} - -function SMODS.current_mod.reset_game_globals() - local immutable = f(SMODS.find_card "j_Roland_suitable"):any(is_frozen) - local suitable = {suit = "Spades"} - - G.GAME.current_round.Roland_suitable = immutable and - G.GAME.current_round.Roland_suitable or suitable - - if immutable then - return - end - - local suits = f(G.playing_cards):where(SMODS.has_no_suit, false):table() - local card = pseudorandom_element(suits, "Roland_suitable" .. G.GAME.round_resets.ante) - suitable.suit = card and card.base.suit or suitable.suit -end - -local orig_get_enhancements = SMODS.get_enhancements - -function SMODS.get_enhancements(card, ...) - if (G.GAME.modifiers.Roland_suitable or 0) <= 0 or - card.base.suit ~= G.GAME.current_round.Roland_suitable.suit or - (card.area ~= G.hand and card.area ~= G.play) then - return orig_get_enhancements(card, ...) - end - - local ret = orig_get_enhancements(card, ...) or {} - ret.m_wild = true - return ret -end - joker { key = "misfortune", pronouns = "she_they", @@ -506,25 +538,6 @@ joker { end, } -joker { - key = "jokersr", - pronouns = "he_him", - config = {extra = {xmult = 1.25}}, - attributes = {"xmult"}, - cost = 2, - rarity = 2, - eternal_compat = true, - blueprint_compat = true, - perishable_compat = true, - loc_vars = function(_, _, card) - return {vars = {card.ability.extra.xmult}} - end, - calculate = function(_, card, context) - return (context.joker_main or context.forcetrigger) and - {card = card, xmult = card.ability.extra.xmult} or nil - end, -} - joker { key = "bulldozer", pronouns = "it_its", @@ -563,6 +576,104 @@ joker { end, } +joker { + key = "phytoestrogens", + pronouns = "she_her", + config = {extra = {xmult = 0.25}}, + attributes = {"mult", "xmult"}, + cost = 8, + rarity = 3, + eternal_compat = true, + blueprint_compat = true, + perishable_compat = true, + loc_vars = function(_, _, card) + return {vars = {card.ability.extra.xmult}} + end, + calculate = function(_, card, context) + if not context.joker_main and not context.forcetrigger then + return + end + + SMODS.calculate_effect({mult = hand_chips}, card) + SMODS.calculate_effect({xmult = card.ability.extra.xmult}, card) + end, +} + +joker { + key = "nilly", + pronouns = "any_all", + config = {extra = {flipped = false}}, + attributes = {"xmult"}, + cost = 0, + rarity = 2, + eternal_compat = true, + blueprint_compat = true, + perishable_compat = true, + loc_vars = function(_, _, card) + return { + vars = {localize { + type = "variable", + key = card.ability.extra.flipped and "b_Roland_enabled" or "b_Roland_disabled", + }}, + } + end, + inject = function(...) + SMODS.Joker.inject(...) + Bakery_API.double_sided_jokers.j_Roland_nilly = true + end, + calculate = function(_, card, context) + if (not context.joker_main or not card.ability.extra.flipped) and not context.forcetrigger then + return + end + + mult = mod_mult(0) + update_hand_text({delay = 0}, {chips = hand_chips, mult = mult}) + return {sound = "Roland_nilly", message = "0X " .. localize "k_mult", colour = G.C.MULT, card = card} + end, + Bakery_can_use = function(_, card) + return not card.debuff + end, + Bakery_use_button_text = function(_, card) + return localize { + type = "variable", + key = card.debuff and "b_Roland_debuffed" or "b_Roland_toggle", + } + end, + Bakery_use_joker = function(_, card) + local _ = card.debuff or Bakery_API.flip_double_sided(card) + end, +} + +joker { + key = "amberacorn", + pronouns = "he_they", + config = {extra = {xmult = 3}}, + attributes = {"xmult"}, + cost = 9, + rarity = 3, + eternal_compat = true, + blueprint_compat = true, + perishable_compat = false, + loc_vars = function(_, _, card) + return {vars = {card.ability.extra.xmult}} + end, + calculate = function(_, card, context) + if context.joker_main or context.forcetrigger then + return {card = card, xmult = card.ability.extra.xmult} + end + + if not context.press_play then + return + end + + local keys = f(card.area.cards):where(f().nq(card)):keys():table() + local k = pseudorandom_element(keys, pseudoseed "Roland_stubborn") or card.rank + + card.area.cards[k], card.area.cards[card.rank] = + card.area.cards[card.rank], card.area.cards[k] + end, +} + joker { key = "martingale", pronouns = "he_him", @@ -612,6 +723,112 @@ joker { end, } +joker { + key = "suitable", + pronouns = "she_they", + attributes = {"suit", "passive", "hearts", "diamonds", "spades", "clubs"}, + cost = 4, + rarity = 2, + eternal_compat = true, + blueprint_compat = false, + perishable_compat = true, + loc_vars = function(_, info_queue) + table.insert(info_queue, G.P_CENTERS.m_wild) + local suit = (G.GAME.current_round.Roland_suitable or {}).suit or "Spades" + return {vars = {localize(suit, "suits_plural"), colours = {G.C.SUITS[suit]}}} + end, + add_to_deck = function() + G.GAME.modifiers.Roland_suitable = (G.GAME.modifiers.Roland_suitable or 0) + 1 + end, + remove_from_deck = function() + G.GAME.modifiers.Roland_suitable = (G.GAME.modifiers.Roland_suitable or 0) - 1 + end, +} + +function SMODS.current_mod.reset_game_globals() + local immutable = f(SMODS.find_card "j_Roland_suitable"):any(is_frozen) + local suitable = {suit = "Spades"} + + G.GAME.current_round.Roland_suitable = immutable and + G.GAME.current_round.Roland_suitable or suitable + + if immutable then + return + end + + local suits = f(G.playing_cards):where(SMODS.has_no_suit, false):table() + local card = pseudorandom_element(suits, "Roland_suitable" .. G.GAME.round_resets.ante) + suitable.suit = card and card.base.suit or suitable.suit +end + +local orig_get_enhancements = SMODS.get_enhancements + +function SMODS.get_enhancements(card, ...) + if (G.GAME.modifiers.Roland_suitable or 0) <= 0 or + card.base.suit ~= G.GAME.current_round.Roland_suitable.suit or + (card.area ~= G.hand and card.area ~= G.play) then + return orig_get_enhancements(card, ...) + end + + local ret = orig_get_enhancements(card, ...) or {} + ret.m_wild = true + return ret +end + +joker { + key = "artemis", + pronouns = "she_they", + cost = 6, + rarity = 2, + config = {extra = { + dollars = 1, + increase = 2, + progress = 0, + flipped = false, + sequence = {"c_earth", "c_mars", "c_earth"}, + }}, + calc_dollar_bonus = function(_, card) + return card.ability.extra.dollars + end, + inject = function(...) + SMODS.Joker.inject(...) + Bakery_API.double_sided_jokers.j_Roland_artemis = true + end, + loc_vars = function(_, info_queue, card) + local extra = card.ability.extra + + local function color(i) + return i == extra.progress + 1 and (i == 2 and G.C.ORANGE or G.C.BLUE) or G.C.JOKER_GREY + end + + f(extra.sequence):each(function(v) + table.insert(info_queue, G.P_CENTERS[v]) + end) + + return {vars = {extra.dollars, extra.increase, colours = f(#extra.sequence):map(color):table()}} + end, + calculate = function(_, card, context) + local extra = card.ability.extra + + if context.blueprint or + not context.using_consumeable or + context.consumeable.config.center.key ~= extra.sequence[extra.progress + 1] then + return + end + + extra.progress = extra.progress + 1 + _ = (extra.progress == 1) ~= extra.flipped and Bakery_API.flip_double_sided(card) + + if extra.sequence[extra.progress + 1] then + return {message = localize "k_progress", colour = extra.progress == 2 and G.C.ORANGE or G.C.BLUE} + end + + extra.progress = 0 + extra.dollars = extra.dollars + extra.increase + return {message = localize "k_upgrade_ex", colour = G.C.MONEY} + end, +} + joker { key = "oops", pronouns = "she_they", @@ -649,165 +866,3 @@ joker { end end, } - -joker { - key = "nilly", - pronouns = "any_all", - config = {extra = {flipped = false}}, - attributes = {"xmult"}, - cost = 0, - rarity = 2, - eternal_compat = true, - blueprint_compat = true, - perishable_compat = true, - loc_vars = function(_, _, card) - return { - vars = {localize { - type = "variable", - key = card.ability.extra.flipped and "b_Roland_enabled" or "b_Roland_disabled", - }}, - } - end, - inject = function(...) - SMODS.Joker.inject(...) - Bakery_API.double_sided_jokers.j_Roland_nilly = true - end, - calculate = function(_, card, context) - if (not context.joker_main or not card.ability.extra.flipped) and not context.forcetrigger then - return - end - - mult = mod_mult(0) - update_hand_text({delay = 0}, {chips = hand_chips, mult = mult}) - return {sound = "Roland_nilly", message = "0X " .. localize "k_mult", colour = G.C.MULT, card = card} - end, - Bakery_can_use = function(_, card) - return not card.debuff - end, - Bakery_use_button_text = function(_, card) - return localize { - type = "variable", - key = card.debuff and "b_Roland_debuffed" or "b_Roland_toggle", - } - end, - Bakery_use_joker = function(_, card) - local _ = card.debuff or Bakery_API.flip_double_sided(card) - end, -} - -joker { - key = "arctic", - pronouns = "it_its", - cost = 10, - rarity = 3, - config = {extra = {[false] = 1, [true] = 2}}, - attributes = {"retrigger", "editions"}, - eternal_compat = true, - blueprint_compat = true, - perishable_compat = true, - loc_vars = function(_, info_queue) - table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) - end, - calculate = function(_, card, context) - return context.repetition and {repetitions = card.ability.extra[is_frozen(context.other_card)]} or - SMODS.merge_effects( - f(G.jokers.cards):where(is_frozen):map(function(v) - return SMODS.blueprint_effect(card, v, context) or true - end):where(function(v) - return type(v) == "table" - end):map(function(v) - v.colour = G.C.DARK_EDITION - return v - end):values():table() - ) - end, -} - -joker { - key = "snowsquall", - pronouns = "they_them", - config = {extra = {mult_gain = 1, mult = 0}}, - attributes = {"mult", "scaling", "hand_type"}, - cost = 6, - rarity = 2, - eternal_compat = true, - blueprint_compat = true, - perishable_compat = false, - loc_vars = function(_, info_queue, card) - table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) - local extra = card.ability.extra - return {vars = {extra.mult_gain, extra.mult}} - end, - calculate = function(_, card, context) - local extra = card.ability.extra - - if context.joker_main or context.forcetrigger then - return {mult = extra.mult} - end - - if context.blueprint or - not context.individual or - context.cardarea ~= G.play or - not is_frozen(context.other_card) then - return - end - - extra.mult = extra.mult + extra.mult_gain - return {message = localize "k_upgrade_ex", colour = G.C.RED, message_card = card} - end, -} - -joker { - key = "stubborn", - pronouns = "he_they", - config = {extra = {xmult = 3}}, - attributes = {"xmult"}, - cost = 9, - rarity = 3, - eternal_compat = true, - blueprint_compat = true, - perishable_compat = false, - loc_vars = function(_, _, card) - return {vars = {card.ability.extra.xmult}} - end, - calculate = function(_, card, context) - if context.joker_main or context.forcetrigger then - return {card = card, xmult = card.ability.extra.xmult} - end - - if not context.press_play then - return - end - - local keys = f(card.area.cards):where(f().nq(card)):keys():table() - local k = pseudorandom_element(keys, pseudoseed "Roland_stubborn") or card.rank - - card.area.cards[k], card.area.cards[card.rank] = - card.area.cards[card.rank], card.area.cards[k] - end, -} - -joker { - key = "blight", - pronouns = "he_him", - config = {extra = {xmult = 2}}, - attributes = {"xmult"}, - cost = 4, - rarity = 1, - eternal_compat = true, - blueprint_compat = true, - perishable_compat = false, - loc_vars = function(_, info_queue, card) - table.insert(info_queue, G.P_CENTERS.e_Roland_frozen) - return {vars = {card.ability.extra.xmult}} - end, - calculate = function(_, card, context) - local target = (context.scoring_hand or {})[3] - - return context.individual and - context.cardarea == G.play and - context.other_card == target and - is_frozen(context.other_card) and - {xmult = card.ability.extra.xmult} or nil - end, -} diff --git a/src/spectral.lua b/src/spectral.lua index 595a008..2f45e95 100644 --- a/src/spectral.lua +++ b/src/spectral.lua @@ -38,38 +38,6 @@ spectral { key = "afterimage", pronouns = "he_they", artist = "aster", - attributes = {"editions", "modify_card", "hand_size", "spectral"}, - config = {extra = {amount = 1, hand = -2}}, - loc_vars = function(_, info_queue, card) - table.insert(info_queue, {key = "e_negative_playing_card", set = "Edition", config = {extra = 1}}) - return {vars = {card.ability.extra.amount, card.ability.extra.hand}} - end, - can_use = function(_, card) - return u() and card.ability.extra.amount == #Bakery_API.get_highlighted() - end, - use = function(_, card) - f(Bakery_API.get_highlighted()):each(function(v) - q { - delay = 0.1, - func = function() - v:set_edition {negative = true} - end, - } - end) - - q { - delay = 0.1, - func = function() - G.hand:change_size(card.ability.extra.hand) - Bakery_API.unhighlight_all() - end, - } - end, -} - -spectral { - key = "dual", - pronouns = "they_them", config = {extra = {amount = 2}}, attributes = {"seal", "modify_card", "spectral"}, loc_vars = function(_, _, card) @@ -99,9 +67,9 @@ spectral { } spectral { - key = "mirror", + key = "refract", pronouns = "he_him", - config = {extra = {amount = 1}}, + config = {extra = {amount = 2}}, attributes = {"seal", "modify_card", "spectral"}, loc_vars = function(_, info_queue, card) table.insert(info_queue, G.P_SEALS.Roland_glass)