Add new charm

This commit is contained in:
Emik 2026-02-02 15:43:46 +01:00
parent e5bd52a1a3
commit 61194ae6ed
Signed by: emik
GPG key ID: 6B0CD72A5E503BDF
8 changed files with 116 additions and 112 deletions

View file

@ -15,6 +15,10 @@ return {
},
},
Blind = {
bl_Roland_divide = {
name = "The Great Divide",
text = {"Half of the deck", "is {C:discard}discarded"},
},
bl_Roland_improbable = {
name = "The Improbable",
text = {"All probabilities", "cannot happen"},
@ -23,10 +27,6 @@ return {
name = "The Nimble",
text = {"The first 5 cards", "drawn are played"},
},
bl_Roland_divide = {
name = "The Great Divide",
text = {"Half of the deck", "is {C:discard}discarded"},
},
bl_Roland_tranquilizer = {
name = "The Tranquilizer",
text = {"#1#s are debuffed", "Changes based on", "most common rank"},
@ -40,31 +40,26 @@ return {
j_Roland_escapey = {
name = "Escapey",
text = {
"Destroy {C:attention}tags{} or {C:attention}non-selected",
"{C:attention}consumables{} on use. Level up",
"the {C:planet}most played hand{} by {C:planet}#1#{}",
"for each destroyed object",
"{C:inactive}(Currently #2#)",
" ",
"#3#{C:inactive,s:0.75,E:1}#4#{C:red,s:1.5,E:1}#5#",
"#6#{C:blue,E:1}#7#{}#8#{C:inactive,s:0.75,E:1}#9#{C:red,s:1.5,E:1}#10#",
"Use to {C:attention}destroy tags{} or {C:attention}unselected consumables",
"in exchange for {C:planet}leveling up #1# random hands",
"{C:inactive,s:0.75,E:1}#2#{C:red,s:1.5,E:1}#3#{s:0.9}#4#{C:blue,E:1,s:0.9}#5#{s:0.9}#6#",
},
merge = {"Since no objects apply, fuse", "with other ", " jokers"},
merge = {"Since none apply, fuse with other ", " jokers"},
quotes = {
marble = {{"there is no escape..."}},
marble = {"there is no escape..."},
normal = {
{"I can't wait to", "work with you!"},
{"Did you need something", "from me?"},
{"Oh! I'm just so", "happy to see you!"},
{"Can I talk about something irrelevant?", "I promise it won't be long."},
{"Can you introduce me to your friends?", "Assuming you have friends of course!"},
"I can't wait to work with you!",
"Did you need something from me?",
"Oh! I'm just so happy to see you!",
"Can I say something irrelevant? I promise it won't be long.",
"Tell me about your buddies! Assuming you have them, anyway.",
},
scared = {
{"What am I", "going to do?!"},
{"I'm not scared,", "you are!"},
{"Tell me when", "this is over..."},
{"I can't keep", "looking at this!"},
{"Let me go hide in", "this corner... Okay?"},
"What am I going to do?!",
"I'm not scared, you are!",
"Tell me when this is over...",
"I can't keep looking at this!",
"Let me go hide in this corner... Okay?",
},
},
},

View file

@ -1,5 +1,5 @@
{
"priority": -2,
"priority": 5e-324,
"id": "Roland",
"name": "Roland",
"prefix": "Roland",

View file

@ -35,9 +35,7 @@ SMODS.Challenge {
pronouns = "she_them",
}
q {
trigger = "immediate",
func = function()
q(function()
f {
{G.P_CENTERS, is_joker, jokerful.banned_cards},
{G.P_TAGS, is_banned_from_pastry, pastries.banned_tags},
@ -46,5 +44,4 @@ q {
}:foreach(function(v)
f(v[1]):filter(v[2]):foreach(adder(v[3]))
end)
end,
}
end)

19
src/charm.lua Normal file
View file

@ -0,0 +1,19 @@
local _, q = unpack(... or require "src.functional")
Bakery_API.Charm {
key = "tags",
atlas = "void",
pos = {x = 0, y = 0},
calculate = function(_, _, context)
local _ = context.skip_blind and q(function()
G.round_eval = G.round_eval and G.round_eval:remove()
G.blind_select = G.blind_select and G.blind_select:remove()
G.blind_prompt_box = G.blind_prompt_box and G.blind_prompt_box:remove()
G.GAME.current_round.jokers_purchased = 0
G.STATE = G.STATES.SHOP
G.GAME.shop_free = nil
G.GAME.shop_d6ed = nil
G.STATE_COMPLETE = false
end)
end,
}

View file

@ -1,15 +1,5 @@
local f, q, u = unpack(... or require "src.functional")
local function common_hand()
return (G.GAME or {}).current_round and f(G.GAME.hands):reduce(
{name = "High Card", order = -1 / 0, played = 0},
function(a, v, k)
return (a.played < v.played or (a.played == v.played) and (a.order > v.order)) and
{name = k, order = v.order, played = v.played} or a
end
).name or "High Card"
end
local function destructible(card)
return not card.highlighted and not (card.ability or {}).eternal
end
@ -26,6 +16,35 @@ local function is_mergeable_with(it)
end
end
local function level_up(hand, by, card)
local function update(handname, chips, mult, level, pitch)
update_hand_text(
{sound = "button", volume = 0.7, pitch = pitch or 0.8, delay = 0.3},
{handname = handname, chips = chips, level = level, mult = mult}
)
end
if by <= 0 then
return
end
hand = hand or "NO_HAND_SPECIFIED"
local hand_obj = G.GAME.hands[hand]
if hand == "all" or hand == "allhands" or hand == "all_hands" then
update(localize "k_all_hands", "...", "...", "")
f(G.GAME.hands):keys():foreach(function(k)
level_up_hand(card, k, nil, by)
end)
elseif hand_obj then
update(localize(hand, "poker_hands"), hand_obj.chips, hand_obj.mult, hand_obj.level)
level_up_hand(card, hand, nil, by)
end
update("", 0, 0, "", 1.1)
end
SMODS.Atlas {
px = 71,
py = 95,
@ -47,7 +66,7 @@ SMODS.Joker {
pos = {x = 0, y = 0},
sinis = {x = 2, y = 0},
soul_pos = {x = 1, y = 0},
config = {extra = {level_up_by = 1}},
config = {extra = {hands = 2}},
cost = 8,
rarity = 3,
eternal_compat = true,
@ -61,27 +80,23 @@ SMODS.Joker {
local quotes = loc_self.quotes
local merge = G.jokers
and f(G.jokers.cards):filter(is_mergeable_with(card)):any()
and f(G.jokers.cards):any(is_mergeable_with(card))
and loc_self.merge or {}
local normal = (merge[1] or sinister) and {} or
pseudorandom_element(quotes.normal, pseudoseed "EscapeyQuotes") or {}
local normal = (merge[1] or sinister) and "" or
pseudorandom_element(quotes.normal, pseudoseed "EscapeyQuotes") or ""
local scared = (merge[1] or not sinister) and {} or
pseudorandom_element(quotes.scared, pseudoseed "EscapeyQuotes") or {}
local scared = (merge[1] or not sinister) and "" or
pseudorandom_element(quotes.scared, pseudoseed "EscapeyQuotes") or ""
return {
vars = {
card.ability.extra.level_up_by,
localize(common_hand(), "poker_hands"),
card.ability.extra.hands,
normal,
scared,
merge[1] or "",
normal[1] or "",
scared[1] or "",
merge[1] and loc_self.name or "",
merge[2] or "",
merge[3] and loc_self.name or "",
merge[3] or "",
normal[2] or "",
scared[2] or "",
},
}
end,
@ -92,15 +107,13 @@ SMODS.Joker {
end):sub(2))
end
end,
---@param card Card
Bakery_can_use = function(_, card)
return not card.debuff and u() and (
#G.GAME.tags ~= 0 or
f(G.consumeables.cards):filter(destructible):any() or
f(G.jokers.cards):filter(is_mergeable_with(card)):any()
f(G.consumeables.cards):any(destructible) or
f(G.jokers.cards):any(is_mergeable_with(card))
)
end,
---@param card Card
Bakery_use_button_text = function(_, card)
if card.debuff then
return "DEBUFFED"
@ -109,7 +122,6 @@ SMODS.Joker {
return #G.GAME.tags == 0 and not f(G.consumeables.cards):filter(destructible):any() and
f(G.jokers.cards):filter(is_mergeable_with(card)):any() and "FUSE" or "ESCAPE"
end,
---@param card Card
Bakery_use_joker = function(_, card)
if card.debuff then
return
@ -125,34 +137,19 @@ SMODS.Joker {
f(G.jokers.cards):filter(is_mergeable_with(card)):foreach(function(v)
any_carbon = any_carbon or is_carbon(v)
level_sum = level_sum + v.ability.extra.level_up_by * (v.getEvalQty and v:getEvalQty() or 1)
level_sum = level_sum + v.ability.extra.hands * (v.getEvalQty and v:getEvalQty() or 1)
sell_sum = sell_sum + v.sell_cost * (v.getEvalQty and v:getEvalQty() or 1)
v:start_dissolve({HEX "57ecab"}, nil, 1.6)
end)
if not any_carbon then
card.ability.extra.level_up_by = card.ability.extra.level_up_by + level_sum
card.ability.extra.hands = card.ability.extra.hands + level_sum
end
card.sell_cost = card.sell_cost + sell_sum
return
end
local function update(name, chip, mul, lv, notif, snd, vol, pit, de)
update_hand_text({
sound = type(snd) == "string" and snd or type(snd) == "nil" and "button",
volume = vol or 0.7,
pitch = pit or 0.8,
delay = de or 0.3,
}, {
handname = name or "????",
chips = chip or "?",
level = lv or "?",
mult = mul or "?",
StatusText = notif,
})
end
local function fast_delete(v)
return function()
attention_text {
@ -171,19 +168,6 @@ SMODS.Joker {
end
end
local hand = common_hand()
if hand == "all" or hand == "allhands" or hand == "all_hands" then
update(localize "k_all_hands", "...", "...", "")
elseif G.GAME.hands[hand or "NO_HAND_SPECIFIED"] then
update(
localize(hand, "poker_hands"),
G.GAME.hands[hand].chips,
G.GAME.hands[hand].mult,
G.GAME.hands[hand].level
)
end
local destroyed = 0
if consumable_count == 0 then
@ -207,12 +191,17 @@ SMODS.Joker {
end)
end
level_up_hand(card, hand, nil, destroyed * card.ability.extra.level_up_by)
local hands = f(G.GAME.hands):filter(function(v, _)
return v.visible
end):keys():into()
update_hand_text(
{sound = "button", volume = 0.7, pitch = 1.1, delay = 0},
{mult = 0, chips = 0, handname = "", level = ""}
)
pseudoshuffle(hands, pseudoseed "RolandEscapey")
local levels = destroyed * card.ability.extra.hands
level_up("all", math.floor(levels / #hands), card)
f(hands):take(levels % #hands):foreach(function(v)
level_up(v, 1, card)
end)
end,
}
@ -317,12 +306,16 @@ SMODS.Joker {
atlas = "void",
pronouns = "they_them",
pos = {x = 0, y = 0},
config = {extra = {money = 2}},
cost = 3,
rarity = 1,
calculate = function(_, _, context)
return context.repetition and
context.cardarea == G.play and
context.scoring_name == "Four of a Kind" and {repetitions = 1} or nil
loc_vars = function(_, _, card)
return {vars = {card.ability.extra.money}}
end,
calculate = function(_, card, context)
return context.joker_main and
context.scoring_name == "Four of a Kind" and
{dollars = card.ability.extra.money} or nil
end,
}

View file

@ -1,6 +1,6 @@
local qol = assert(SMODS.load_file "src/functional.lua")() or require "src.functional"
qol[1] {"challenge", "spectral", "blind", "joker", "back", "seal"}:foreach(function(v)
qol[1] {"challenge", "spectral", "blind", "charm", "joker", "back", "seal"}:foreach(function(v)
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
end)

View file

@ -70,7 +70,7 @@ SMODS.Consumable {
end,
use = function(_, card, _)
local cards = f(G.hand.cards, ipairs):into()
pseudoshuffle(cards, pseudoseed "Roland_two")
pseudoshuffle(cards, pseudoseed "RolandDual")
f(cards):take(card.ability.extra.amount):foreach(function(v)
v:set_seal(SMODS.poll_seal {guaranteed = true})

View file

@ -174,7 +174,7 @@ Balatest.TestPlay {
assert = function()
Balatest.assert_eq(#G.jokers.cards, 1)
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.level_up_by, 2)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 2)
end,
}
@ -237,7 +237,7 @@ Balatest.TestPlay {
assert = function()
Balatest.assert_eq(#G.jokers.cards, 1)
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.level_up_by, 2)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 2)
end,
}
@ -279,7 +279,7 @@ Balatest.TestPlay {
Balatest.assert_eq(#G.jokers.cards, 1)
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.level_up_by, 1)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 1)
end,
}
@ -322,7 +322,7 @@ Balatest.TestPlay {
Balatest.assert_eq(#G.jokers.cards, 1)
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.level_up_by, 1)
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 1)
end,
}