Remove use of submodules in favor of own solution

This commit is contained in:
Emik 2026-02-20 03:02:41 +01:00
parent 23e96b70cc
commit 8e6e307e6b
Signed by: emik
GPG key ID: 6B0CD72A5E503BDF
22 changed files with 567 additions and 92 deletions

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "src/LuaFunctional"]
path = src/LuaFunctional
url = https://github.com/BakersDozenBagels/LuaFunctional.git

66
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,66 @@
{
"Lua.diagnostics.severity": {
"ambiguity-1": "Error",
"assign-type-mismatch": "Error",
"await-in-sync": "Error",
"cast-local-type": "Error",
"cast-type-mismatch": "Error",
"circle-doc-class": "Error",
"close-non-object": "Error",
"code-after-break": "Error",
"codestyle-check": "Error",
"count-down-loop": "Error",
"deprecated": "Error",
"different-requires": "Error",
"discard-returns": "Error",
"doc-field-no-class": "Error",
"duplicate-doc-alias": "Error",
"duplicate-doc-field": "Error",
"duplicate-doc-param": "Error",
"duplicate-index": "Error",
"duplicate-set-field": "Error",
"empty-block": "Error",
"global-element": "Error",
"global-in-nil-env": "Error",
"incomplete-signature-doc": "Error",
"inject-field": "Error",
"invisible": "Error",
"lowercase-global": "Error",
"missing-fields": "Error",
"missing-global-doc": "Error",
"missing-local-export-doc": "Error",
"missing-parameter": "Error",
"missing-return": "Error",
"missing-return-value": "Error",
"name-style-check": "Error",
"need-check-nil": "Error",
"newfield-call": "Error",
"newline-call": "Error",
"no-unknown": "Error",
"not-yieldable": "Error",
"param-type-mismatch": "Error",
"redefined-local": "Error",
"redundant-parameter": "Error",
"redundant-return": "Error",
"redundant-return-value": "Error",
"redundant-value": "Error",
"return-type-mismatch": "Error",
"spell-check": "Error",
"trailing-space": "Error",
"unbalanced-assignments": "Error",
"undefined-doc-class": "Error",
"undefined-doc-name": "Error",
"undefined-doc-param": "Error",
"undefined-env-child": "Error",
"undefined-field": "Error",
"undefined-global": "Error",
"unknown-cast-variable": "Error",
"unknown-diag-code": "Error",
"unknown-operator": "Error",
"unreachable-code": "Error",
"unused-function": "Error",
"unused-label": "Error",
"unused-local": "Error",
"unused-vararg": "Error",
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

@ -1 +0,0 @@
Subproject commit 5cd6766468f04e36a5b25f0d55b82f5eeb164b56

View file

@ -1,4 +1,4 @@
local f, q = unpack(... or require "src.functional") local f, q = unpack(... or require "lib.shared")
local function save(ret) local function save(ret)
q(save_run) q(save_run)
@ -47,7 +47,7 @@ local back = (function()
key = key, key = key,
pos = tbl.pos, pos = tbl.pos,
atlas = "back", atlas = "back",
config = tbl.config and f(tbl.config):into() or nil, config = tbl.config and f(tbl.config):table() or nil,
loc_vars = function(self, ...) loc_vars = function(self, ...)
local ret = tbl.loc_vars and tbl.loc_vars(self, ...) or {} local ret = tbl.loc_vars and tbl.loc_vars(self, ...) or {}
ret.key = self:is_alt() and self.key .. "_alt" or self.key ret.key = self:is_alt() and self.key .. "_alt" or self.key
@ -102,7 +102,7 @@ back {
q { q {
delay = 0.4, delay = 0.4,
func = function() func = function()
SMODS.calculate_effect({message = localize("ph_boss_disabled")}, card) SMODS.calculate_effect({message = localize "ph_boss_disabled"}, card)
G.GAME.blind:wiggle() G.GAME.blind:wiggle()
play_sound "timpani" play_sound "timpani"
delay(0.4) delay(0.4)
@ -140,7 +140,7 @@ back {
ease_dollars(-G.GAME.dollars) ease_dollars(-G.GAME.dollars)
attention_text { attention_text {
text = localize("k_nope_ex"), text = localize "k_nope_ex",
backdrop_colour = G.C.MONEY, backdrop_colour = G.C.MONEY,
offset = {x = 0, y = 0}, offset = {x = 0, y = 0},
silent = true, silent = true,
@ -176,9 +176,9 @@ function create_card(_type, ...)
return orig_create_card(swapper[_type] or _type, ...) return orig_create_card(swapper[_type] or _type, ...)
end end
local type = f(SMODS.ConsumableTypes):keys():filter(function(v) local type = f(SMODS.ConsumableTypes):keys():where(function(v)
return v ~= _type return v ~= _type
end):into() end):table()
local has_type = SMODS.ConsumableTypes[_type] local has_type = SMODS.ConsumableTypes[_type]
return orig_create_card(has_type and pseudorandom_element(type, pseudoseed "Roland_alt_swapper_deck") or _type, ...) return orig_create_card(has_type and pseudorandom_element(type, pseudoseed "Roland_alt_swapper_deck") or _type, ...)

View file

@ -1,4 +1,4 @@
local f, q = unpack(... or require "src.functional") local f, q = unpack(... or require "lib.shared")
local blind = (function() local blind = (function()
local y = 0 local y = 0
@ -35,9 +35,9 @@ local function common_rank()
--- Tallies up a card area's cards. --- Tallies up a card area's cards.
---@param card_area CardArea ---@param card_area CardArea
local function tally_up(card_area) local function tally_up(card_area)
f(card_area.cards):filter(function(v) f(card_area.cards):where(function(v)
return not SMODS.has_no_rank(v) return not SMODS.has_no_rank(v)
end):foreach(function(v) end):each(function(v)
local id = v:get_id() local id = v:get_id()
to_name[id] = v.base.value to_name[id] = v.base.value
tally[id] = (tally[id] or 0) + 1 tally[id] = (tally[id] or 0) + 1
@ -48,7 +48,7 @@ local function common_rank()
tally_up(G.hand) tally_up(G.hand)
tally_up(G.discard) tally_up(G.discard)
local max_key = f(tally):reduce({-1 / 0, -1 / 0}, function(a, v, k) local max_key = f(tally):fold({-1 / 0, -1 / 0}, function(a, v, k)
if v > a[1] or k > a[2] and v == a[1] then if v > a[1] or k > a[2] and v == a[1] then
return {v, k} return {v, k}
end end
@ -124,7 +124,7 @@ blind {
return false return false
end end
f(G.hand.cards, ipairs):take(self.config.draw):foreach(function(v) f(G.hand.cards, ipairs):take(self.config.draw):each(function(v)
G.hand:add_to_highlighted(v, true) G.hand:add_to_highlighted(v, true)
end) end)
@ -149,7 +149,7 @@ blind {
pronouns = "any_all", pronouns = "any_all",
disable = function() disable = function()
q(function() q(function()
f(G.hand.cards):foreach(function(v, i) f(G.hand.cards):each(function(v, i)
draw_card(G.hand, G.deck, i / #G.hand.cards * 100, "up", false, v) draw_card(G.hand, G.deck, i / #G.hand.cards * 100, "up", false, v)
end) end)
end) end)
@ -191,11 +191,11 @@ blind {
return return
end end
f(G.discard.cards):take(count):foreach(function(v, i) f(G.discard.cards):take(count):each(function(v, i)
draw_card(G.discard, G.hand, i / count * 100, "up", false, v, nil, nil, true) draw_card(G.discard, G.hand, i / count * 100, "up", false, v, nil, nil, true)
end) end)
f(G.discard.cards):take(count):foreach(function(v, i) f(G.discard.cards):take(count):each(function(v, i)
draw_card(G.hand, G.deck, i / count * 100, "up", false, v) draw_card(G.hand, G.deck, i / count * 100, "up", false, v)
end) end)
end) end)
@ -231,7 +231,7 @@ blind {
local cards_added = {} local cards_added = {}
local count = #G.hand.highlighted local count = #G.hand.highlighted
f(G.hand.highlighted, ipairs):take(count):foreach(function(v, i) f(G.hand.highlighted, ipairs):take(count):each(function(v, i)
local copy = copy_card(v) local copy = copy_card(v)
copy:add_to_deck() copy:add_to_deck()
table.insert(G.hand, copy) table.insert(G.hand, copy)
@ -277,8 +277,10 @@ blind {
local needs_text_change local needs_text_change
---comment
---@param card_area CardArea|{cards: Card[]}
local function process(card_area) local function process(card_area)
f(card_area.cards):foreach(function(v) f(card_area.cards):each(function(v)
local debuff = v.debuff local debuff = v.debuff
v:set_debuff(self:recalc_debuff(v, false)) v:set_debuff(self:recalc_debuff(v, false))
needs_text_change = needs_text_change or debuff ~= v.debuff needs_text_change = needs_text_change or debuff ~= v.debuff
@ -327,7 +329,7 @@ end
function SMODS.current_mod:calculate(context) function SMODS.current_mod:calculate(context)
---@diagnostic disable-next-line: undefined-global ---@diagnostic disable-next-line: undefined-global
local _ = type(G.calc) == "function" and G.calc(f(context):keys():conjoin(", ")) local _ = type(G.calc) == "function" and G.calc(f(context):keys():string())
local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities
-- Normally unreachable since we set it to nil ourselves, -- Normally unreachable since we set it to nil ourselves,
@ -462,7 +464,7 @@ local venerable_visage = blind {
delay(1) delay(1)
f(G.playing_cards):foreach(function(v) f(G.playing_cards):each(function(v)
q { q {
trigger = "before", trigger = "before",
delay = speed, delay = speed,
@ -475,7 +477,7 @@ local venerable_visage = blind {
delay(1) delay(1)
f(G.P_CARDS):foreach(function(v) f(G.P_CARDS):each(function(v)
q { q {
delay = speed, delay = speed,
func = function() func = function()

View file

@ -1,4 +1,4 @@
local f, q = unpack(... or require "src.functional") local f, q = unpack(... or require "lib.shared")
local jokerful = {banned_cards = {}} local jokerful = {banned_cards = {}}
local pastries = {banned_cards = {}, banned_tags = {}, banned_other = {}} local pastries = {banned_cards = {}, banned_tags = {}, banned_other = {}}
-- local surgery = {banned_other = {}} -- local surgery = {banned_other = {}}
@ -58,7 +58,7 @@ q(function()
{G.P_BLINDS, is_banned_from_pastry, pastries.banned_other}, {G.P_BLINDS, is_banned_from_pastry, pastries.banned_other},
{G.P_CENTERS, is_center_banned_from_pastry, pastries.banned_cards}, {G.P_CENTERS, is_center_banned_from_pastry, pastries.banned_cards},
-- {G.P_BLINDS, is_blind_banned_from_surgery, surgery.banned_other}, -- {G.P_BLINDS, is_blind_banned_from_surgery, surgery.banned_other},
}:foreach(function(v) }:each(function(v)
f(v[1]):filter(v[2]):foreach(adder(v[3])) f(v[1]):where(v[2]):each(adder(v[3]))
end) end)
end) end)

View file

@ -1,4 +1,4 @@
local f, q = unpack(... or require "src.functional") local _, q = unpack(... or require "lib.shared")
local mod = SMODS.current_mod local mod = SMODS.current_mod
SMODS.Atlas { SMODS.Atlas {

View file

@ -1,4 +1,4 @@
local f, q, u = unpack(... or require "src.functional") local f, q, u = unpack(... or require "lib.shared")
local joker = (function() local joker = (function()
local z = 0 local z = 0
@ -63,7 +63,7 @@ local function level_up(hand, by, card)
if hand == "all" or hand == "allhands" or hand == "all_hands" then if hand == "all" or hand == "allhands" or hand == "all_hands" then
update(localize "k_all_hands", "...", "...", "") update(localize "k_all_hands", "...", "...", "")
f(G.GAME.hands):keys():foreach(function(k) f(G.GAME.hands):keys():each(function(k)
level_up_hand(card, k, nil, by) level_up_hand(card, k, nil, by)
end) end)
elseif hand_obj then elseif hand_obj then
@ -132,15 +132,15 @@ joker {
return "DEBUFFED" return "DEBUFFED"
end end
return #G.GAME.tags == 0 and not f(G.consumeables.cards):filter(destructible):any() and return #G.GAME.tags == 0 and not f(G.consumeables.cards):any(destructible) and
f(G.jokers.cards):filter(is_mergeable_with(card)):any() and "FUSE" or "ESCAPE" f(G.jokers.cards):any(is_mergeable_with(card)) and "FUSE" or "ESCAPE"
end, end,
Bakery_use_joker = function(_, card) Bakery_use_joker = function(_, card)
if card.debuff then if card.debuff then
return return
end end
local consumables = f(G.consumeables.cards):filter(destructible):into() local consumables = f(G.consumeables.cards):where(destructible):table()
local consumable_count = #consumables local consumable_count = #consumables
local tag_count = #G.GAME.tags local tag_count = #G.GAME.tags
@ -148,7 +148,7 @@ joker {
local level_sum, sell_sum = 0, 0 local level_sum, sell_sum = 0, 0
local any_carbon = is_carbon(card) local any_carbon = is_carbon(card)
f(G.jokers.cards):filter(is_mergeable_with(card)):foreach(function(v) f(G.jokers.cards):where(is_mergeable_with(card)):each(function(v)
any_carbon = any_carbon or is_carbon(v) any_carbon = any_carbon or is_carbon(v)
level_sum = level_sum + v.ability.extra.hands * (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) sell_sum = sell_sum + v.sell_cost * (v.getEvalQty and v:getEvalQty() or 1)
@ -187,7 +187,7 @@ joker {
local trigger = #G.GAME.tags >= 30 and "immediate" or "before" local trigger = #G.GAME.tags >= 30 and "immediate" or "before"
local delay = #G.GAME.tags >= 30 and 0 or 1 / #G.GAME.tags local delay = #G.GAME.tags >= 30 and 0 or 1 / #G.GAME.tags
f(G.GAME.tags):foreach(function(v) f(G.GAME.tags):each(function(v)
q { q {
trigger = trigger, trigger = trigger,
blocking = #G.GAME.tags < 30, blocking = #G.GAME.tags < 30,
@ -198,19 +198,19 @@ joker {
destroyed = destroyed + 1 destroyed = destroyed + 1
end) end)
else else
f(consumables):foreach(function(v) f(consumables):each(function(v)
v:start_dissolve({HEX "57ecabff"}, nil, 1.6) v:start_dissolve({HEX "57ecabff"}, nil, 1.6)
destroyed = destroyed + 1 destroyed = destroyed + 1
end) end)
end end
local hands = f(G.GAME.hands):filter(f "visible"):keys():into() local hands = f(G.GAME.hands):where(f "visible"):keys():table()
pseudoshuffle(hands, pseudoseed "RolandEscapey") pseudoshuffle(hands, pseudoseed "RolandEscapey")
local levels = destroyed * card.ability.extra.hands local levels = destroyed * card.ability.extra.hands
level_up("all", math.floor(levels / #hands), card) level_up("all", math.floor(levels / #hands), card)
f(hands):take(levels % #hands):foreach(function(v) f(hands):take(levels % #hands):each(function(v)
level_up(v, 1, card) level_up(v, 1, card)
end) end)
end, end,
@ -372,7 +372,7 @@ joker {
card.getting_sliced = true card.getting_sliced = true
q(function() q(function()
local scored_cards = f(G.play.cards):filter(f "highlighted"):into() local scored_cards = f(G.play.cards):where(f "highlighted"):each()
local copied = {} local copied = {}
for _ = 1, extra.times do for _ = 1, extra.times do

443
src/lib/funky.lua Normal file
View file

@ -0,0 +1,443 @@
---@author Emik
---@copyright (c) 2026 Emik
---@license MPL-2.0
---@version 1.0.0
---
---@class F
local f = {}
if not f then
---@generic K, V
---@param self F | { [K]: V }
---@return K?, V?
function f:next()
error()
end
end
--- Always returns nil.
---@return nil
function f.noop()
end
--- Always returns false.
---@return false
function f.fals()
return false
end
--- Always returns true.
---@return true
function f.tru()
return true
end
---@generic T
---@param v T
---@return fun(): T
---@nodiscard
function f.const(v)
if v == true then
return f.tru
elseif v == false then
return f.fals
elseif v == nil then
return f.noop
end
return function()
return v
end
end
---@generic K, V
---@param v K
---@return fun(x: { [K]: V }): V
---@nodiscard
function f.index(v)
return function(x)
return x[v]
end
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
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 K
---@return V
local function autopairs(tbl, fpairs)
return (fpairs or tbl[#tbl] and ipairs or pairs)(tbl)
end
---@generic K, V, U
---@param self F|{ [K]: V }
---@param func F|fun(v: V, k: K): U
---@return F|{ [K]: U }
---@nodiscard
function f:map(func)
return f.new(function()
local k, v = self:next()
if k ~= nil then
return k, func(v, k)
end
end)
end
---@generic K, V, U
---@param self F|{ [K]: V }
---@param func F|fun(v: V, k: K): { [any]: U }
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
---@return F|{ [K]: U }
---@nodiscard
function f:flatmap(func, fpairs)
-- local i = 0
local vt, vk, vv, vp
return f.new(function()
if vk then
vk, vv = vp(vt, vk)
if vk ~= nil then
-- i = i + 1
-- return i, vv
return vk, vv
end
end
while true do
local k, v = self:next()
if k == nil then
return
end
v = func(v, k)
if type(v) ~= "table" then
-- i = i + 1
-- return i, v
return k, v
end
vp, vt, vk = autopairs(v, fpairs)
vk, vv = vp(vt, vk)
if vk ~= nil then
-- i = i + 1
-- return i, vv
return vk, vv
end
end
end)
end
---@generic K, V
---@param self F|{ [K]: V }
---@param func F|fun(v: V, k: K): boolean
---@return F|{ [K]: V }
---@nodiscard
function f:where(func)
local i = 0
return f.new(function()
local k, v
while true do
k, v = self:next()
if k == nil then
return
end
if func(v, k) then
i = i + 1
return i, v
end
end
end)
end
---@generic K, V
---@param self F|{ [K]: V }
---@return F|{ [integer]: K }
---@nodiscard
function f:keys()
local i = 0
return f.new(function()
local k = self:next()
if k ~= nil then
i = i + 1
return i, k
end
end)
end
---@generic K, V
---@param self F|{ [K]: V }
---@return F|{ [integer]: V }
---@nodiscard
function f:values()
local i = 0
return f.new(function()
local k, v = self:next()
if k ~= nil then
i = i + 1
return i, v
end
end)
end
---@generic K, V
---@param self F|{ [K]: V }
---@param skip? integer
---@param take? integer
---@return F|{ [K]: V }
---@nodiscard
function f:slice(skip, take)
if (not skip or skip <= 0) and not take then
return self
end
local i = 0
return f.new(function()
if take and take <= 0 then
return
end
while skip and skip > 0 do
skip = skip - 1
self:next()
end
local k, v = self:next()
if k ~= nil and (not take or i < take) then
i = i + 1
return i, v
end
end)
end
---@generic K, V
---@param self F|{ [K]: V }
---@param n? integer
---@return F|{ [K]: V }
---@nodiscard
function f:skip(n)
return self:slice(n)
end
---@generic K, V
---@param self F|{ [K]: V }
---@param n? integer
---@return F|{ [K]: V }
---@nodiscard
function f:take(n)
return self:slice(0, n)
end
---@generic K, V, A
---@param self F|{ [K]: V }
---@param seed A
---@param func fun(a: A, v: V, k: K): A
---@return A
---@overload fun(self: F|{ [K]: V }, seed: fun(a: A, v: V, k: K): A): A
---@nodiscard
function f:fold(seed, func)
local k, v
if not func then
func = seed
k, seed = self:next()
if k == nil then
return seed
end
end
while true do
k, v = self:next()
if k == nil then
return seed
end
seed = func(seed, v, k)
end
end
---@generic K, V
---@param self F|{ [K]: V }
---@param func F|fun(v: V, k: K): boolean
---@return boolean|V
---@nodiscard
function f:any(func)
for k, v in self.next do
if not func or func(v, k) then
return v or true
end
end
return false
end
---@generic K, V
---@param self F|{ [K]: V }
---@param func F|fun(v: V, k: K): boolean
---@return boolean|V
---@nodiscard
function f:all(func)
for k, v in self.next do
if not func or not func(v, k) then
return v and false
end
end
return true
end
---@generic K, V
---@param self F|{ [K]: V }
---@param func F|fun(v: V, k: K): boolean
---@return integer
---@nodiscard
function f:count(func)
local ret = 0
for k, v in self.next do
if not func or func(v, k) then
ret = ret + 1
end
end
return ret
end
---@generic K, V
---@param self F|{ [K]: V }
---@return string
---@nodiscard
function f:string()
local k, v = self:next()
if k == nil then
return "{}"
end
local ret = "{" .. (type(k) == "number" and "" or tostring(k) .. ": ") .. tostring(v)
while true do
k, v = self:next()
if k == nil then
return ret .. "}"
end
ret = ret .. ", " .. (type(k) == "number" and tostring(v) or tostring(k) .. ": " .. tostring(v))
end
end
---@generic K, V
---@param self F|{ [K]: V }
---@return { [K]: V }
---@nodiscard
function f:table()
local ret = {}
for k, v in self.next do
ret[k] = v
end
return ret
end
---@generic K, V
---@param self F|{ [K]: V }
---@param func? F|fun(v: V, k: K)
function f:each(func)
for k, v in self.next do
if func then
func(v, k)
end
end
end
local none = f.new()
--- Creates an enumeration.
---@generic K, V
---@param tbl table<K, V>
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K?, V?)
---@param step? nil
---@return F | { [K]: V }
---@overload fun(tbl: number, fpairs?: number, step?: number): F | { [number]: number }
---@overload fun(tbl: string|K): fun(table: { [string|K]: V }): V
---@overload fun(tbl: false): fun(): false
---@overload fun(tbl: true): fun(): true
---@overload fun(tbl: nil): F
return function(tbl, fpairs, step)
if tbl == true then
return f.tru
elseif tbl == false then
return f.fals
elseif tbl == nil then
return none
end
local tbl_type = type(tbl)
if tbl_type == "string" then
return f.index(tbl)
elseif tbl_type == "number" then
local ik = 0
local start = fpairs and tbl or 1
local stop = not fpairs and tbl or
(type(fpairs) == "number") and fpairs or error("Invalid argument type for 'fpairs': " .. type(fpairs))
if step ~= 0 and ((step < 0) == (start < stop)) then
return none
end
return f.new(function()
local iv = tbl + ik * (step or 1)
ik = ik + 1
if start > stop and iv >= stop or
start < stop and iv <= stop or
start == stop and iv == stop then
return ik, iv
end
end)
elseif tbl_type ~= "table" then
error("Invalid argument type for 'tbl': " .. type(tbl))
end
local next, context, k, v = autopairs(tbl, fpairs)
return f.new(function()
k, v = next(context, k)
return k, v
end)
end

View file

@ -23,10 +23,7 @@ local function protect_ev(fun)
return fun return fun
end end
local origf = F -- This exists to remove the @deprecated warning.
local luaf = assert(SMODS.load_file "src/LuaFunctional/functional.lua")() or require "src.LuaFunctional.functional"
F = origf -- We do not condone globals as side effects!
if false then if false then
---Returns the elements from the given `list`. This function is equivalent to ---Returns the elements from the given `list`. This function is equivalent to
---```lua ---```lua
@ -58,36 +55,7 @@ if false then
end end
end end
---@class Query<K, V>: metatable local f = assert(SMODS.load_file "src/lib/funky.lua")() or require "lib.funky"
local _ = luaf._proto
--- Creates a non-numerically-indexed query from the given table.
---@param obj table?
---@param f_pairs? fun(t: table): unknown
---@param numeric boolean?
---@return Query
---@overload fun(obj: string): (fun(any): any)
-- ---@overload fun(obj: true): (fun(): true)
-- ---@overload fun(obj: false): (fun(): false)
local function f(obj, f_pairs, numeric)
if obj == true then
return luaf.tru
elseif obj == false then
return luaf.fals
elseif obj == nil then
return luaf.pairs {}
elseif type(obj) == "string" then
return luaf.index(obj)
elseif type(obj) ~= "table" then
error("Invalid argument type for f's obj: " .. type(obj))
elseif f_pairs then
return luaf.from(obj, f_pairs, numeric ~= false)
elseif obj[#obj] then
return luaf.ipairs(obj)
else
return luaf.pairs(obj)
end
end
--- Queues an event to be run. --- Queues an event to be run.
--- Note that events added this way implicitly `return true` unless you explicitly `return false`, unlike the vanilla ones. --- Note that events added this way implicitly `return true` unless you explicitly `return false`, unlike the vanilla ones.

View file

@ -1,11 +1,11 @@
local qol = assert(SMODS.load_file "src/functional.lua")() or require "src.functional" local qol = assert(SMODS.load_file "lib/shared.lua")() or require "lib.shared"
qol[1] {"challenge", "spectral", "tweaks", "blind", "charm", "joker", "back", "seal"}:foreach(function(v) qol[1] {"challenge", "spectral", "tweaks", "blind", "charm", "joker", "back", "seal"}:each(function(v)
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol) assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
end) end)
if Balatest then if Balatest then
qol[1] {"joker", "blind", "spectral"}:foreach(function(v) qol[1] {"joker", "blind", "spectral"}:each(function(v)
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol) assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
end) end)
end end

View file

@ -1,4 +1,4 @@
local f, q = unpack(... or require "src.functional") local f, q = unpack(... or require "lib.shared")
SMODS.Atlas { SMODS.Atlas {
px = 71, px = 71,
@ -23,7 +23,7 @@ SMODS.Seal {
local tag = Tag(get_next_tag_key "Roland_glass") local tag = Tag(get_next_tag_key "Roland_glass")
if tag.name == "Orbital Tag" then if tag.name == "Orbital Tag" then
local hands = f(G.GAME.hands):filter(f "visible"):keys():into() local hands = f(G.GAME.hands):where(f "visible"):keys():table()
tag.ability.orbital_hand = pseudorandom_element(hands, pseudoseed "Roland_glass") tag.ability.orbital_hand = pseudorandom_element(hands, pseudoseed "Roland_glass")
end end

View file

@ -1,4 +1,4 @@
local f, q, u = unpack(... or require "src.functional") local f, q, u = unpack(... or require "lib.shared")
local spectral = (function() local spectral = (function()
local x = 0 local x = 0
@ -47,7 +47,7 @@ spectral {
return u() and card.ability.extra.amount == #Bakery_API.get_highlighted() return u() and card.ability.extra.amount == #Bakery_API.get_highlighted()
end, end,
use = function(_, card) use = function(_, card)
f(Bakery_API.get_highlighted()):foreach(function(v) f(Bakery_API.get_highlighted()):each(function(v)
q { q {
delay = 0.1, delay = 0.1,
func = function() func = function()
@ -78,10 +78,10 @@ spectral {
return u() and #G.hand.cards > 0 return u() and #G.hand.cards > 0
end, end,
use = function(_, card, _) use = function(_, card, _)
local cards = f(G.hand.cards, ipairs):into() local cards = f(G.hand.cards, ipairs):table()
pseudoshuffle(cards, pseudoseed "RolandDual") pseudoshuffle(cards, pseudoseed "RolandDual")
f(cards):take(card.ability.extra.amount):foreach(function(v) f(cards):take(card.ability.extra.amount):each(function(v)
local seal local seal
for _ = 1, 31 do for _ = 1, 31 do
@ -109,7 +109,7 @@ spectral {
return u() and #Bakery_API.get_highlighted() == card.ability.extra.amount return u() and #Bakery_API.get_highlighted() == card.ability.extra.amount
end, end,
use = function(_, _, _) use = function(_, _, _)
f(Bakery_API.get_highlighted()):foreach(function(v) f(Bakery_API.get_highlighted()):each(function(v)
v:set_seal "Roland_glass" v:set_seal "Roland_glass"
end) end)
end, end,
@ -128,7 +128,7 @@ local void = spectral {
return {vars = {card.ability.extra.amount}} return {vars = {card.ability.extra.amount}}
end, end,
can_use = function() can_use = function()
return #G.playing_cards > 1 and u() return #G.playing_cards > 1 and not not u()
end, end,
use = function(_, card) use = function(_, card)
local function destructible(v) local function destructible(v)
@ -145,14 +145,14 @@ local void = spectral {
end end
local function void() local function void()
local cards = f(G.playing_cards):filter(destructible):into() local cards = f(G.playing_cards):where(destructible):table()
local function calculate_joker(v) local function calculate_joker(v)
v:calculate_joker {remove_playing_cards = true, removed = cards} v:calculate_joker {remove_playing_cards = true, removed = cards}
end end
f(cards):foreach(destroy) f(cards):each(destroy)
f(G.jokers.cards):foreach(calculate_joker) f(G.jokers.cards):each(calculate_joker)
for _ = 1, card.ability.extra.amount do for _ = 1, card.ability.extra.amount do
local cryptid = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_cryptid", "void") local cryptid = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_cryptid", "void")

View file

@ -1,4 +1,4 @@
local f = unpack(... or require "src.functional") local f = unpack(... or require "lib.shared")
if not Balatest then if not Balatest then
return return
@ -26,7 +26,7 @@ Balatest.TestPlay {
deck = {cards = {{s = "S", r = "2", e = "m_lucky"}, {s = "S", r = "3"}}}, deck = {cards = {{s = "S", r = "2", e = "m_lucky"}, {s = "S", r = "3"}}},
execute = function() execute = function()
Balatest.play_hand {"2S"} Balatest.play_hand {"2S"}
Balatest.next_round("bl_small") Balatest.next_round "bl_small"
Balatest.play_hand {"2S"} Balatest.play_hand {"2S"}
end, end,
assert = function() assert = function()
@ -141,7 +141,7 @@ Balatest.TestPlay {
Balatest.wait_for_input() Balatest.wait_for_input()
end, end,
assert = function() assert = function()
f(G.hand.cards):foreach(function(v, k) f(G.hand.cards):each(function(v, k)
local message = v.debuff and local message = v.debuff and
"Card " .. k .. " should not be debuffed" or "Card " .. k .. " should not be debuffed" or
"Card " .. k .. " should be debuffed" "Card " .. k .. " should be debuffed"
@ -166,7 +166,7 @@ Balatest.TestPlay {
Balatest.play_hand {"2S"} Balatest.play_hand {"2S"}
end, end,
assert = function() assert = function()
f(G.hand.cards):foreach(function(v, k) f(G.hand.cards):each(function(v, k)
local message = v.debuff and local message = v.debuff and
"Card " .. k .. " should not be debuffed" or "Card " .. k .. " should not be debuffed" or
"Card " .. k .. " should be debuffed" "Card " .. k .. " should be debuffed"
@ -185,7 +185,7 @@ Balatest.TestPlay {
Balatest.wait_for_input() Balatest.wait_for_input()
end, end,
assert = function() assert = function()
f(G.hand.cards):foreach(function(v, k) f(G.hand.cards):each(function(v, k)
Balatest.assert(not v.debuff, "Card " .. k .. " should not be debuffed") Balatest.assert(not v.debuff, "Card " .. k .. " should not be debuffed")
end) end)
end, end,

View file

@ -1,4 +1,4 @@
local _, q = unpack(... or require "src.functional") local _, q = unpack(... or require "lib.shared")
SMODS.Joker:take_ownership("joker", {cost = 1}, true) SMODS.Joker:take_ownership("joker", {cost = 1}, true)
local orig_can_highlight = CardArea.can_highlight local orig_can_highlight = CardArea.can_highlight