diff --git a/manifest.json b/manifest.json index c5a95f9..003fcf7 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "id": "Roland", "name": "Roland", "prefix": "Roland", - "version": "2.8.30", + "version": "2.8.31", "badge_colour": "8BE9FD", "display_name": "Roland", "main_file": "src/main.lua", diff --git a/src/back.lua b/src/back.lua index 7418cef..65c1794 100644 --- a/src/back.lua +++ b/src/back.lua @@ -141,7 +141,7 @@ back { modifiers.Roland_swapper_deck = true modifiers.Roland_alt_swapper_deck = modifiers.Roland_alt_swapper_deck or self:is_alt() end, - calculate = f().noop, + calculate = f.noop, } local swapper = {Spectral = "Tarot", Tarot = "Spectral"} diff --git a/src/challenge.lua b/src/challenge.lua index 4945d1c..51221a5 100644 --- a/src/challenge.lua +++ b/src/challenge.lua @@ -67,7 +67,7 @@ SMODS.Challenge { local spin_to_win = SMODS.Challenge { key = "Spin_To_Win", - jokers = f(4):map(f().const {id = "j_joker", eternal = true}):table(), + jokers = f(4):map(f.const {id = "j_joker", eternal = true}):table(), restrictions = {banned_cards = {{id = "c_Roland_coolheaded"}}}, pronouns = "they_them", apply = function(self) @@ -91,7 +91,7 @@ SMODS.Challenge { pronouns = "she_them", } -local starting_jokers = f(5):map(f().const {id = "j_joker"}):table() +local starting_jokers = f(5):map(f.const {id = "j_joker"}):table() SMODS.Challenge { key = "Eternally_Amber", diff --git a/src/edition.lua b/src/edition.lua index 386f29e..2e70e8d 100644 --- a/src/edition.lua +++ b/src/edition.lua @@ -161,7 +161,7 @@ function Card:calculate_joker(context, ...) local key = "Roland_frozen_" .. v ability[key] = ability[key] or ret[1][v] return ability[key] - end):where(f().id):table() + end):where(f.id):table() end local orig_calculate_dollar_bonus = Card.calculate_dollar_bonus diff --git a/src/joker.lua b/src/joker.lua index a0b243e..b7b60ee 100644 --- a/src/joker.lua +++ b/src/joker.lua @@ -701,7 +701,7 @@ joker { card.Roland_amber_waiting = true local cards = card.area.cards - local keys = f(cards):where(f().nq(card)):keys():table() + local keys = f(cards):where(f.nq(card)):keys():table() if not next(keys) then return @@ -849,7 +849,7 @@ joker { return f(context.scoring_hand):any(function(x) return x:is_suit(v.suit) and x.base.value == v.value end) or {} - end):any(f().eq(context.other_card)) and {xmult = card.ability.extra.xmult} or nil + end):any(f.eq(context.other_card)) and {xmult = card.ability.extra.xmult} or nil end, Bakery_can_use = function(self, card) local key = self:Roland_idle_status(card) diff --git a/src/lib/funky.lua b/src/lib/funky.lua index 9ca7259..5c1a841 100644 --- a/src/lib/funky.lua +++ b/src/lib/funky.lua @@ -3,10 +3,91 @@ ---@license MPL-2.0 ---@version 1.0.0 --- +---@alias FFrom (fun(iter: table, fpairs?: fun(t: table): (fun(table: table, index?: K): K?, V?)): F | { [K]: V })|(fun(iter: number, fpairs?: number, step?: number): F | { [number]: number })|(fun(iter: string): (fun(table: { [string]: V }): V))|(fun(iter: string): (fun(table: { [string]: V }): V))|(fun(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 = {} if not f then + ---@generic I, O + ---@param first fun(v: I): O + ---@return fun(v: I): O + function f.chain(first) + error {first} + end + + ---@generic I, T, O + ---@param first fun(v: I): T + ---@param second fun(v: T): O + ---@return fun(v: I): O + function f.chain(first, second) + error {first, second} + end + + ---@generic I, T1, T2, O + ---@param first fun(v: I): T1 + ---@param second fun(v: T1): T2 + ---@param third fun(v: T2): O + ---@return fun(v: I): O + function f.chain(first, second, third) + error {first, second, third} + end + + ---@generic I, T1, T2, T3, O + ---@param first fun(v: I): T1 + ---@param second fun(v: T1): T2 + ---@param third fun(v: T2): T3 + ---@param fourth fun(v: T3): O + ---@return fun(v: I): O + function f.chain(first, second, third, fourth) + error {first, second, third, fourth} + end + + ---@generic I, T1, T2, T3, T4, O + ---@param first fun(v: I): T1 + ---@param second fun(v: T1): T2 + ---@param third fun(v: T2): T3 + ---@param fourth fun(v: T3): T4 + ---@param fifth fun(v: T4): O + ---@return fun(v: I): O + function f.chain(first, second, third, fourth, fifth) + error {first, second, third, fourth, fifth} + end + + ---@generic I, O + ---@param all {[1]: (fun(v: I): O)} + ---@return fun(v: I): O + function f.chain(all) + error(all) + end + + ---@generic I, T, O + ---@param all {[1]: (fun(v: I): T), [2]: (fun(v: T): O)} + ---@return fun(v: I): O + function f.chain(all) + error(all) + end + + ---@generic I, T1, T2, O + ---@param all {[1]: (fun(v: I): T1), [2]: (fun(v: T1): T2), [3]: (fun(v: T2): O)} + ---@return fun(v: I): O + function f.chain(all) + error(all) + end + + ---@generic I, T1, T2, T3, O + ---@param all {[1]: (fun(v: I): T1), [2]: (fun(v: T1): T2), [3]: (fun(v: T2): T3), [4]: (fun(v: T3): O)} + ---@return fun(v: I): O + function f.chain(all) + error(all) + end + + ---@generic I, T1, T2, T3, T4, O + ---@param all {[1]: (fun(v: I): T1), [2]: (fun(v: T1): T2), [3]: (fun(v: T2): T3), [4]: (fun(v: T3): T4), [4]: (fun(v: T4): O)} + ---@return fun(v: I): O + function f.chain(all) + error(all) + end + ---@generic K, V ---@param self F | { [K]: V } ---@return K?, V? @@ -137,32 +218,67 @@ function f.indices(v) end end +f[true and "chain"] = function(...) + for _, v in ipairs(...) do + if type(v) == "table" then + for _, vv in ipairs(v) do + ret = ret and function(...) + return vv(ret(...)) + end or vv + end + else + ret = ret and function(...) + return v(ret(...)) + end or v + end + end + + return ret or f.noop +end + ---@generic K, V ---@param fnext? fun(): K?, V? ---@return F|{ [K]: V } ---@nodiscard function f.new(fnext) - local ret = {next = fnext or f.noop} - - for k, v in pairs(f) do - ret[k] = v - end - - return ret + -- Iterating over `f` is far easier, but we do this for performance sake. + return { + all = f.all, + any = f.any, + chain = f.chain, + concat = f.concat, + const = f.const, + count = f.count, + eq = f.eq, + fals = f.fals, + flatmap = f.flatmap, + fold = f.fold, + from = f.from, + id = f.id, + index = f.index, + indices = f.indices, + map = f.map, + new = f.new, + next = fnext or f.noop, + noop = f.noop, + nq = f.nq, + tru = f.tru, + where = f.where, + each = f.each, + keys = f.keys, + pun = f.pun, + skip = f.skip, + slice = f.slice, + string = f.string, + swap = f.swap, + table = f.table, + take = f.take, + values = f.values, + } end --- Creates an enumeration. ----@generic K, V ----@param iter table ----@param fpairs? fun(t: table): (fun(table: table, index?: K): K?, V?) ----@param step? nil ----@return F | { [K]: V } ----@overload fun(iter: number, fpairs?: number, step?: number): F | { [number]: number } ----@overload fun(iter: string): (fun(table: { [string]: V }): V) ----@overload fun(iter: fun(): K, V): F | { [K]: V } ----@overload fun(iter: false): fun(): false ----@overload fun(iter: true): fun(): true ----@overload fun(iter: nil): F +---@type FFrom function f.from(iter, fpairs, step) if iter == nil then return none @@ -207,7 +323,7 @@ function f.from(iter, fpairs, step) end end) else - local next, context, k, v = autopairs(iter, fpairs) + local next, context, k, v = autopairs(iter, type(fpairs) == "function" and fpairs or nil) return f.new(function() k, v = next(context, k) @@ -650,5 +766,5 @@ function f:each(func) end none = f.new() - -return f.from +local ret = (setmetatable or f.const(f.from))(f, {__call = f.from}) ---@type F|FFrom +return ret diff --git a/src/tag.lua b/src/tag.lua index 0a31d24..ba45624 100644 --- a/src/tag.lua +++ b/src/tag.lua @@ -69,7 +69,7 @@ SMODS.Tag { if not tag.triggered and context.type == "Bakery_play_hand_late" and tag.ability.amount == 0 then tag.triggered = true - tag:yep("X", G.C.RED, f().tru) + tag:yep("X", G.C.RED, f.tru) end if tag.triggered or diff --git a/src/tweaks.lua b/src/tweaks.lua index 3846b4e..1f59d35 100644 --- a/src/tweaks.lua +++ b/src/tweaks.lua @@ -100,7 +100,7 @@ local orig_get_blind_amount = get_blind_amount ---@param ante number ---@return table|number local function blind(ante) - return ante == 39 and 1e294 or (_G["to_number"] or f().id)(orig_get_blind_amount(ante)) + return ante == 39 and 1e294 or (_G["to_number"] or f.id)(orig_get_blind_amount(ante)) end local function no_harsh_ante_scaling() @@ -120,8 +120,8 @@ function get_blind_amount(ante, ...) local big, rem = _G["Big"], tonumber(blind((ante % loop) + 1)) - return ante / 15 >= loop and big:new(f(blind(ante - (loop * 15))):map(f().const(10)):table()) or - (ante / 9 >= loop and big:new(f(ante / loop - 8):map(f().const(10)):concat {rem}:table()) or + return ante / 15 >= loop and big:new(f(blind(ante - (loop * 15))):map(f.const(10)):table()) or + (ante / 9 >= loop and big:new(f(ante / loop - 8):map(f.const(10)):concat {rem}:table()) or (ante / 2 >= loop and big:new {rem, ante / loop} or (big.constants and big.constants.TEN or big:new {10}):pow(rem))) end