Compare commits

..

7 commits
3.0.5 ... main

Author SHA1 Message Date
713276e568
Improve performance of Arctic Circle 2026-10-14 18:23:58 +02:00
4a922f8d0d
Use nodes directly instead of finding them 2026-10-14 18:22:43 +02:00
3119a8561d
Add unused patch 2026-10-14 18:16:47 +02:00
7b491d3bb3 Bump version
Signed-off-by: emik <emik.cuber@gmail.com>
2026-10-13 12:32:32 +00:00
a762cff1fe Fix crash related to Suitable
Signed-off-by: emik <emik.cuber@gmail.com>
2026-10-13 12:31:56 +00:00
8a18b78d2c
Add unused utility function
(purposely not bumping version)
2026-10-13 03:27:33 +02:00
d1ca223855
Patch reroll exploit, rebalance challenges 2026-10-11 22:39:41 +02:00
6 changed files with 80 additions and 30 deletions

View file

@ -212,3 +212,13 @@ match_indent = true
# position = "at"
# payload = 'local cmdName = inputText'
# match_indent = true
# [[patches]]
# [patches.pattern]
# target = '=[SMODS DebugPlus "debugplus/util.lua"]'
# pattern = "function global.stringifyTable(tab, depth, num, dec, indent)"
# position = "after"
# payload = """if type(tab) == "table" and type(tab.table) == "function" then
# tab = tab:table()
# end"""
# match_indent = true

View file

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

View file

@ -232,24 +232,21 @@ blind {
boss = {min = 3},
boss_colour = HEX "102a41ff",
pronouns = "it_its",
defeat = function(self)
self.cards():where "Roland_blizzard":each(set_freeze())
defeat = function()
f(G.I.CARD):where "Roland_blizzard":each(set_freeze())
G.GAME.blind.disabled = true
end,
disable = function(self)
self:defeat()
end,
calculate = function(self, b, context)
calculate = function(_, b, context)
return not b.disabled and
context.hand_drawn and
self.cards()
f(G.I.CARD)
:where("Roland_blizzard", false)
:where("facing", "front")
:each(set_freeze(true)) or nil
end,
cards = function()
return f(G):where(getmetatable, CardArea):flatmap("cards", ipairs)
end,
}
blind {

View file

@ -34,7 +34,7 @@ local function is_center_banned_from_pastry(v)
p_arcana_mega_2 = true,
}
local pastries_targets = {Enhanced = true, Joker = true, Tarot = true, Spectral = true}
local pastries_targets = {Enhanced = true, Joker = true, Tarot = true, Spectral = true, Voucher = true}
return arcana_boosters[v.key] or pastries_targets[v.set] and is_banned_from_pastry(v)
end
@ -48,7 +48,7 @@ end
---@return fun(v: SMODS.Blind, k: string): boolean?
local function is_showdown_except(key)
return function(v, k)
return v.boss and v.boss.showdown and key ~= k
return key ~= k and v.boss and (v.boss.hardcore or v.boss.no_orb or v.boss.showdown)
end
end

View file

@ -589,9 +589,7 @@ joker {
end
return SMODS.merge_effects(
f(G)
:where(getmetatable, CardArea)
:flatmap("cards", ipairs)
f(G.I.CARD)
:where(is_frozen)
:map(copy(card, context))
:where(type, "table")
@ -741,8 +739,13 @@ joker {
crimson = function()
local _ = G.jokers and f(G.jokers.cards, f.revpairs):where(is_frozen, false):each(function(v)
local right = G.jokers.cards[v.rank + 1]
local orig_calculate_reroll_cost = v.config.center.key == "j_chaos" and calculate_reroll_cost or nil
local debuffed_by_crimson = right and not right.debuff and right.config.center.key == "j_Roland_crimson"
if orig_calculate_reroll_cost then
calculate_reroll_cost = f.noop
end
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
local debuff = not not v.debuff
v:set_debuff(true)
@ -752,6 +755,10 @@ joker {
v.ability.Roland_crimson = nil
v:set_debuff(debuff)
end
if orig_calculate_reroll_cost then
calculate_reroll_cost = orig_calculate_reroll_cost
end
end)
end,
}
@ -1197,7 +1204,8 @@ end
local orig_get_enhancements = SMODS.get_enhancements
function SMODS.get_enhancements(card, ...)
if (G.GAME.modifiers.Roland_suitable or 0) <= 0 or
if not card.base or
(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, ...)

View file

@ -3,7 +3,7 @@
---@license MPL-2.0
---@version 1.0.0
---
---@alias FFrom (fun<K, V>(iter: table<K, V>, fpairs?: fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K?, V?)): F | { [K]: V })|(fun(iter: number, fpairs?: number, step?: number): F | { [number]: number })|(fun<V>(iter: string): (fun(table: { [string]: V }): V))|(fun<V>(iter: string): (fun(table: { [string]: V }): V))|(fun<K, V>(iter: fun(): K, V): F | { [K]: V })|(fun(iter: false): fun(): false)|(fun(iter: true): fun(): true)|(fun(iter: nil): F)
---@alias FFrom (fun<K, V>(iter: { [K]: V }, fpairs?: fun(t: { [K]: V }): (fun(table: { [K]: V }, index?: K): K?, V?)): F | { [K]: V })|(fun(iter: number, fpairs?: number, step?: number): F | { [number]: number })|(fun<V>(iter: string): (fun(table: { [string]: V }): V))|(fun<V>(iter: string): (fun(table: { [string]: V }): V))|(fun<K, V>(iter: fun(): K, V): F | { [K]: V })|(fun(iter: false): fun(): false)|(fun(iter: true): fun(): true)|(fun(iter: nil): F)
---@class F
local f = {}
@ -254,10 +254,10 @@ local function autofunc(func)
end
---@generic K, V
---@param tbl table<K, V>
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
---@return fun(tbl: table<K, V>, key: K): K, V
---@return table<K, V>
---@param tbl { [K]: V }
---@param fpairs? fun(t: { [K]: V }): (fun(table: { [K]: V }, index?: K): K, V)
---@return fun(tbl: { [K]: V }, key: K): K, V
---@return { [K]: V }
---@return V
---@nodiscard
local function autopairs(tbl, fpairs)
@ -393,19 +393,44 @@ function f.insert(v, k)
end
end
local chairs = function(s, i)
local k = i and i + 1 or 1
local v = s:sub(k, k)
if v == nil then
return
end
local t = type(v)
if t ~= "string" and t ~= "table" or #v ~= 0 then
return k, v
end
end
---@generic T: string|{sub: fun(self: self, i: integer, j: integer)}
---@param str T
---@return fun(t: T, i?: integer): integer, T
---@return T
function f.chairs(str)
return chairs, str
end
local revpairs = function(t, i)
local k = i and i - 1 or #t
local v = t[k]
if v ~= nil then
return k, v
end
end
---@generic T
---@param tbl T[]
---@return fun(t: T[], i?: integer): integer, T
---@return T[]
function f.revpairs(tbl)
return function(t, i)
local k = i and i - 1 or #t
local v = t[k]
if v ~= nil then
return k, v
end
end, tbl
return revpairs, tbl
end
---@param any any
@ -471,6 +496,7 @@ function f.new(fnext)
arg = f.arg,
call = f.call,
chain = f.chain,
chairs = f.chairs,
compose = f.compose,
concat = f.concat,
const = f.const,
@ -524,7 +550,16 @@ function f.from(iter, fpairs, step)
local t = type(iter)
if t == "string" then
return f.indices(iter)
if not fpairs then
return f.indices(iter)
end
local next, tbl, k, v = fpairs(iter --[[@as { sub: fun(self: self, i: integer, j?: integer) }]])
return f.new(function()
k, v = next(tbl, k)
return k, v
end)
elseif t == "number" then
local ik, is, start = 0, step or 1, fpairs and iter or 1
@ -647,9 +682,9 @@ end
---@generic K, V, U
---@param self F|{ [K]: V }
---@param func fun(v: V, k: K): { [any]: U }
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
---@param fpairs? fun(t: { [K]: V }): (fun(table: { [K]: V }, index?: K): K, V)
---@return F|{ [K]: U }
---@overload fun(self: F|{ [K]: V }, func: string, fpairs?: fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)): F|{ [K]: U }
---@overload fun(self: F|{ [K]: V }, func: string, fpairs?: fun(t: { [K]: V }): (fun(table: { [K]: V }, index?: K): K, V)): F|{ [K]: U }
---@nodiscard
function f:flatmap(func, fpairs)
self = f.isf(self) and self or f.from(self)