Improve Frozen compatibility, Nerf Arctic Circle

This commit is contained in:
Emik 2026-06-03 22:01:52 +02:00
parent 2ab4f8a4be
commit f6fc9cc357
Signed by: emik
GPG key ID: 6B0CD72A5E503BDF
6 changed files with 78 additions and 66 deletions

View file

@ -125,7 +125,7 @@ return {
}, },
j_Roland_arctic = { j_Roland_arctic = {
name = "Arctic Circle", name = "Arctic Circle",
text = {"Retrigger {C:dark_edition}Frozen {}cards", "Retrigger playing cards"}, text = {"Retrigger {C:attention}all", "{C:dark_edition}Frozen {}cards"},
}, },
j_Roland_artemis = { j_Roland_artemis = {
name = "Artemis X", name = "Artemis X",
@ -261,7 +261,7 @@ return {
}, },
j_Roland_phytoestrogens = { j_Roland_phytoestrogens = {
name = "Phytoestrogens", name = "Phytoestrogens",
text = {"{C:mult}+Chips{} Mult", "{X:mult,C:white}X#1#{} Mult"}, text = {"{C:mult}+Chips{} Mult, {X:mult,C:white}X#1#{} Mult"},
}, },
j_Roland_sapling = { j_Roland_sapling = {
name = "Sapling", name = "Sapling",

View file

@ -12,12 +12,12 @@ priority = -2
target = "game.lua" target = "game.lua"
pattern = "self.GAME.round_resets.blind_choices.Boss = get_new_boss()" pattern = "self.GAME.round_resets.blind_choices.Boss = get_new_boss()"
position = "before" position = "before"
payload = ''' payload = """
if G.GAME.modifiers.Roland_blossom_deck then if G.GAME.modifiers.Roland_blossom_deck then
self.GAME.round_resets.blind_choices.Small = get_new_boss() self.GAME.round_resets.blind_choices.Small = get_new_boss()
self.GAME.round_resets.blind_choices.Big = get_new_boss() self.GAME.round_resets.blind_choices.Big = get_new_boss()
end end
''' """
match_indent = true match_indent = true
[[patches]] [[patches]]
@ -25,12 +25,12 @@ match_indent = true
target = "functions/common_events.lua" target = "functions/common_events.lua"
pattern = "G.GAME.round_resets.blind_choices.Boss = get_new_boss()" pattern = "G.GAME.round_resets.blind_choices.Boss = get_new_boss()"
position = "before" position = "before"
payload = ''' payload = """
if G.GAME.modifiers.Roland_blossom_deck then if G.GAME.modifiers.Roland_blossom_deck then
G.GAME.round_resets.blind_choices.Small = get_new_boss() G.GAME.round_resets.blind_choices.Small = get_new_boss()
G.GAME.round_resets.blind_choices.Big = get_new_boss() G.GAME.round_resets.blind_choices.Big = get_new_boss()
end end
''' """
match_indent = true match_indent = true
[[patches]] [[patches]]
@ -85,3 +85,11 @@ payload = """if next(SMODS.find_card "j_Roland_misfortune") then
card:set_edition "e_negative" card:set_edition "e_negative"
end""" end"""
match_indent = true match_indent = true
[[patches]]
[patches.regex]
target = "card.lua"
pattern = "math\\.floor\\(\\(G\\.GAME\\.dollars \\+ \\(G\\.GAME\\.dollar_buffer or 0\\)\\)/self\\.ability\\.extra\\.dollars\\)"
position = "at"
payload = "G.P_CENTERS.j_erosion:mult(self)"
match_indent = true

View file

@ -3,7 +3,7 @@
"id": "Roland", "id": "Roland",
"name": "Roland", "name": "Roland",
"prefix": "Roland", "prefix": "Roland",
"version": "2.8.1", "version": "2.8.2",
"badge_colour": "8BE9FD", "badge_colour": "8BE9FD",
"display_name": "Roland", "display_name": "Roland",
"main_file": "src/main.lua", "main_file": "src/main.lua",

View file

@ -17,7 +17,6 @@ local frozen_sounds = f(4):map(frozen_sound):map("key"):table()
local needs_chip_mult_override = { local needs_chip_mult_override = {
Bull = true, Bull = true,
Erosion = true,
Misprint = true, Misprint = true,
TierList = true, TierList = true,
Bootstraps = true, Bootstraps = true,
@ -48,7 +47,7 @@ local function freeze(card)
---@return T ---@return T
local function copy(x) local function copy(x)
return type(x) == "table" and f(x):map(copy):where(function(v, k) return type(x) == "table" and f(x):map(copy):where(function(v, k)
return k ~= "Roland_frozen_proxy" and (k ~= "nine_tally" or v ~= 0) return k ~= "nine_tally" or v ~= 0
end):table() or x end):table() or x
end end
@ -58,7 +57,7 @@ local function freeze(card)
card.Roland_frozen_ability = card.Roland_frozen_ability or copy(card.ability) card.Roland_frozen_ability = card.Roland_frozen_ability or copy(card.ability)
card.ability = card.Roland_frozen_ability and copy(card.Roland_frozen_ability) or card.ability card.ability = card.Roland_frozen_ability and copy(card.Roland_frozen_ability) or card.ability
card.Roland_frozen_probability = card.Roland_frozen_probability or SMODS.get_probability_vars(card, 1, 1) card.Roland_frozen = card.Roland_frozen and {probability = SMODS.get_probability_vars(card, 1, 1)}
local ability, ret = card.ability, card.Roland_frozen_ability local ability, ret = card.ability, card.Roland_frozen_ability
if type(ability) ~= "table" then if type(ability) ~= "table" then
@ -93,15 +92,10 @@ SMODS.Edition {
in_shop = true, in_shop = true,
apply_to_float = false, apply_to_float = false,
calculate = function(_, card, context) calculate = function(_, card, context)
if not context.fix_probability and not context.mod_probability then local _ = not context.fix_probability and not context.mod_probability and freeze(card)
freeze(card)
end
end, end,
on_remove = function(card) on_remove = function(card)
card.Roland_frozen_proxy = nil card.Roland_frozen, card.Roland_frozen_ability, card.Roland_frozen_current_round = nil, nil, nil
card.Roland_frozen_estate = nil
card.Roland_frozen_ability = nil
card.Roland_frozen_probability = nil
end, end,
get_weight = function(self) get_weight = function(self)
return G.GAME.edition_rate * self.weight return G.GAME.edition_rate * self.weight
@ -153,7 +147,7 @@ function Card:calculate_joker(context, ...)
local ret = {orig_calculate_joker(self, context, ...)} local ret = {orig_calculate_joker(self, context, ...)}
if not is_frozen or not ret[1] then if not is_frozen or type(ret[1]) ~= "table" then
return unpack(ret) return unpack(ret)
end end
@ -163,24 +157,11 @@ function Card:calculate_joker(context, ...)
return unpack(ret) return unpack(ret)
end end
ability.Roland_frozen_mult_mod = ability.Roland_frozen_mult_mod or ret[1].mult_mod return f {mult = "mult_mod", chips = "chip_mod", xmult = "xmult", x_mult = "x_mult"}:map(function(v)
ability.Roland_frozen_chip_mod = ability.Roland_frozen_chip_mod or ret[1].chip_mod local key = "Roland_frozen_" .. v
ability.Roland_frozen_xmult = ability.Roland_frozen_xmult or ret[1].xmult ability[key] = ability[key] or ret[1][v]
return ability[key]
return { end):where(f().id):table()
chip_mod = ability.Roland_frozen_chip_mod,
mult_mod = ability.Roland_frozen_mult_mod,
xmult = ability.Roland_frozen_xmult,
message = localize {
type = "variable",
key = "a_mult",
vars = {
ability.Roland_frozen_mult_mod or
ability.Roland_frozen_chip_mod or
ability.Roland_frozen_xmult,
},
},
}
end end
local orig_calculate_dollar_bonus = Card.calculate_dollar_bonus local orig_calculate_dollar_bonus = Card.calculate_dollar_bonus
@ -205,9 +186,21 @@ end
local orig_get_probability_vars = SMODS.get_probability_vars local orig_get_probability_vars = SMODS.get_probability_vars
function G.P_CENTERS.j_erosion:mult(card)
local ability = card.Roland_frozen_ability
local ret = math.floor((G.GAME.dollars + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
if not ability then
return ret
end
ability.Roland_erosion_mult = ability.Roland_erosion_mult or ret
return ability.Roland_erosion_mult
end
function SMODS.get_probability_vars(trigger_obj, ...) function SMODS.get_probability_vars(trigger_obj, ...)
local numerator, denominator = orig_get_probability_vars(trigger_obj, ...) local numerator, denominator = orig_get_probability_vars(trigger_obj, ...)
return trigger_obj and trigger_obj.Roland_frozen_probability or numerator, denominator return trigger_obj and (trigger_obj.Roland_frozen or {}).probability or numerator, denominator
end end
q(function() q(function()
@ -217,19 +210,19 @@ q(function()
return return
end end
---@param card Card|{ Roland_frozen_estate: integer } ---@param card Card|{ Roland_frozen: {estate: integer} }
local function estate_pos(card) local function estate_pos(card)
if card.area ~= G.jokers and card.area.config.type ~= "title" then if card.area ~= G.jokers and card.area.config.type ~= "title" then
return 1 return 1
end end
card.Roland_frozen_estate = card.Roland_frozen_estate and card.Roland_frozen.estate = card.Roland_frozen.estate and
card.Roland_frozen_estate or card.Roland_frozen.estate or
(f(card.area.cards):swap():any(function(_, k) (f(card.area.cards):swap():any(function(_, k)
return k == card return k == card
end) or 1) end) or 1)
return card.Roland_frozen_estate return card.Roland_frozen.estate
end end
local orig_calculate = estate.calculate local orig_calculate = estate.calculate
@ -268,18 +261,18 @@ q(function()
return return
end end
---@param card Card|{ Roland_frozen_proxy: number } ---@param card Card|{ Roland_frozen: {proxy: string} }
local function get_proxied_joker(card) local function get_proxied_joker(card)
if not G.jokers or not G.jokers.cards then if not G.jokers or not G.jokers.cards then
return return
end end
card.Roland_frozen_proxy = card.Roland_frozen_proxy or card.Roland_frozen.proxy = card.Roland_frozen.proxy or
(Bakery_API.get_proxied_joker() or card).config.center.key (Bakery_API.get_proxied_joker() or card).config.center.key
---@param v Card ---@param v Card
local function eq(v) local function eq(v)
return v.config.center.key == card.Roland_frozen_proxy return v.config.center.key == card.Roland_frozen.proxy
end end
return f(G.jokers.cards):any(eq) ---@type Card? return f(G.jokers.cards):any(eq) ---@type Card?
@ -290,9 +283,9 @@ q(function()
function proxy:calculate(card, context, ...) function proxy:calculate(card, context, ...)
if not card or not card.edition or not card.edition.Roland_frozen then if not card or not card.edition or not card.edition.Roland_frozen then
return orig_calculate(self, card, context, ...) return orig_calculate(self, card, context, ...)
else
return SMODS.blueprint_effect(card, get_proxied_joker(card), context)
end end
return SMODS.blueprint_effect(card, get_proxied_joker(card), context)
end end
local orig_loc_vars = proxy.loc_vars local orig_loc_vars = proxy.loc_vars

View file

@ -438,7 +438,7 @@ joker {
pronouns = "they_them", pronouns = "they_them",
cost = 10, cost = 10,
rarity = 3, rarity = 3,
config = {extra = {frozen = 2, non_frozen = 1}}, config = {extra = {frozen = 1}},
attributes = {"retrigger", "editions"}, attributes = {"retrigger", "editions"},
eternal_compat = true, eternal_compat = true,
blueprint_compat = true, blueprint_compat = true,
@ -449,18 +449,21 @@ joker {
calculate = function(_, card, context) calculate = function(_, card, context)
local extra = card.ability.extra local extra = card.ability.extra
return (context.repetition and context.other_card) and if context.repetition and context.other_card then
{card = card, repetitions = is_frozen(context.other_card) and extra.frozen or extra.non_frozen} or local repetitions = is_frozen(context.other_card) and extra.frozen or extra.non_frozen
SMODS.merge_effects( return repetitions ~= 0 and {card = card, repetitions = repetitions} or nil
f(G.jokers.cards):where(is_frozen):map(function(v) end
return SMODS.blueprint_effect(card, v, context) or true
end):where(function(v) return SMODS.merge_effects(
return type(v) == "table" f(G.jokers.cards):where(is_frozen):map(function(v)
end):map(function(v) return SMODS.blueprint_effect(card, v, context) or true
v.colour = G.C.DARK_EDITION end):where(function(v)
return v return type(v) == "table"
end):values():table() end):map(function(v)
) v.colour = G.C.DARK_EDITION
return v
end):values():table()
)
end, end,
} }

View file

@ -18,6 +18,14 @@ end
---@type F ---@type F
local none local none
---@generic T: F|function|string|nil
---@param func T
---@return T
---@nodiscard
local function autofunc(func)
return type(func) == "string" and f.index(func) or func or f.id
end
---@generic K, V ---@generic K, V
---@param tbl table<K, V> ---@param tbl table<K, V>
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V) ---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
@ -236,7 +244,7 @@ end
---@nodiscard ---@nodiscard
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U } ---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U }
function f:map(func) function f:map(func)
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
return f.new(function() return f.new(function()
local k, v = self:next() local k, v = self:next()
@ -257,7 +265,7 @@ end
function f:flatmap(func, fpairs) function f:flatmap(func, fpairs)
-- local i = 0 -- local i = 0
local vt, vk, vv, vp local vt, vk, vv, vp
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
return f.new(function() return f.new(function()
if vk then if vk then
@ -307,7 +315,7 @@ end
function f:flatmap(func, fpairs) function f:flatmap(func, fpairs)
-- local i = 0 -- local i = 0
local vt, vk, vv, vp local vt, vk, vv, vp
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
return f.new(function() return f.new(function()
if vk then if vk then
@ -355,7 +363,7 @@ end
---@nodiscard ---@nodiscard
---@overload fun(self: F|{ [K]: V }, func: string, is?: any): F|{ [K]: V } ---@overload fun(self: F|{ [K]: V }, func: string, is?: any): F|{ [K]: V }
function f:where(func, is) function f:where(func, is)
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
return f.new(function() return f.new(function()
local k, v local k, v
@ -517,7 +525,7 @@ end
---@nodiscard ---@nodiscard
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V ---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
function f:any(func) function f:any(func)
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
for k, v in self.next do for k, v in self.next do
if not func or func(v, k) then if not func or func(v, k) then
@ -535,7 +543,7 @@ end
---@nodiscard ---@nodiscard
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V ---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
function f:all(func) function f:all(func)
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
for k, v in self.next do for k, v in self.next do
if not func or not func(v, k) then if not func or not func(v, k) then
@ -554,7 +562,7 @@ end
---@overload fun(self: F|{ [K]: V }, func: string): integer ---@overload fun(self: F|{ [K]: V }, func: string): integer
function f:count(func) function f:count(func)
local ret = 0 local ret = 0
func = type(func) == "string" and f.index(func) or func func = autofunc(func)
for k, v in self.next do for k, v in self.next do
if not func or func(v, k) then if not func or func(v, k) then