Use functional loops over imperative
This commit is contained in:
parent
341a12bf65
commit
e62eec9de5
9 changed files with 83 additions and 93 deletions
|
|
@ -1 +1 @@
|
||||||
../../BalatroBakery/src/
|
../../BalatroBakery/
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../Talisman/
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
local _, q = unpack(... or require "src.functional")
|
local f, q = unpack(... or require "src.functional")
|
||||||
|
|
||||||
SMODS.Atlas {
|
SMODS.Atlas {
|
||||||
px = 34,
|
px = 34,
|
||||||
|
|
@ -16,26 +16,26 @@ 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)
|
||||||
for _, v in ipairs(card_area.cards) do
|
f(card_area.cards):filter(function(v)
|
||||||
if not SMODS.has_no_rank(v) then
|
return not SMODS.has_no_rank(v)
|
||||||
local id = v:get_id()
|
end):foreach(function(v)
|
||||||
tally[id] = (tally[id] or 0) + 1
|
local id = v:get_id()
|
||||||
to_name[id] = v.base.value
|
to_name[id] = v.base.value
|
||||||
end
|
tally[id] = (tally[id] or 0) + 1
|
||||||
end
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
tally_up(G.deck)
|
tally_up(G.deck)
|
||||||
tally_up(G.hand)
|
tally_up(G.hand)
|
||||||
tally_up(G.discard)
|
tally_up(G.discard)
|
||||||
local max_key, max_value = -1 / 0, -1 / 0
|
|
||||||
|
|
||||||
for k, v in pairs(tally) do
|
local max_key = f(tally):reduce({-1 / 0, -1 / 0}, function(a, v, k)
|
||||||
if v > max_value or k > max_key and v == max_value then
|
if v > a[1] or k > a[2] and v == a[1] then
|
||||||
max_key = k
|
return {v, k}
|
||||||
max_value = v
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
return a
|
||||||
|
end)[2]
|
||||||
|
|
||||||
return max_key, to_name[max_key]
|
return max_key, to_name[max_key]
|
||||||
end
|
end
|
||||||
|
|
@ -115,6 +115,7 @@ SMODS.Blind {
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
mult = 2,
|
mult = 2,
|
||||||
dollars = 5,
|
dollars = 5,
|
||||||
|
config = {draw = 5},
|
||||||
defeat = function(self)
|
defeat = function(self)
|
||||||
self.disabled = false
|
self.disabled = false
|
||||||
end,
|
end,
|
||||||
|
|
@ -127,13 +128,9 @@ SMODS.Blind {
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, v in ipairs(G.hand.cards) do
|
f(G.hand.cards, ipairs):take(self.config.draw):foreach(function(v)
|
||||||
if i > 5 then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
G.hand:add_to_highlighted(v, true)
|
G.hand:add_to_highlighted(v, true)
|
||||||
end
|
end)
|
||||||
|
|
||||||
G.FUNCS.play_cards_from_highlighted(nil)
|
G.FUNCS.play_cards_from_highlighted(nil)
|
||||||
end
|
end
|
||||||
|
|
@ -159,13 +156,15 @@ SMODS.Blind {
|
||||||
dollars = 5,
|
dollars = 5,
|
||||||
disable = function()
|
disable = function()
|
||||||
local function disable()
|
local function disable()
|
||||||
for i = 1, #G.discard.cards do
|
local count = #G.discard.cards
|
||||||
draw_card(G.discard, G.hand, i / #G.discard.cards * 100, "up", false, G.discard.cards[i], nil, nil, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, #G.discard.cards do
|
f(G.discard.cards):take(count):foreach(function(v, i)
|
||||||
draw_card(G.hand, G.deck, i / #G.discard.cards * 100, "up", false, G.discard.cards[i])
|
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)
|
||||||
|
draw_card(G.hand, G.deck, i / count * 100, "up", false, v)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
q(disable)
|
q(disable)
|
||||||
|
|
@ -225,11 +224,11 @@ SMODS.Blind {
|
||||||
local needs_text_change = false
|
local needs_text_change = false
|
||||||
|
|
||||||
local function process(card_area)
|
local function process(card_area)
|
||||||
for _, v in pairs(card_area.cards) do
|
f(card_area.cards):foreach(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
|
||||||
end
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
process(G.deck)
|
process(G.deck)
|
||||||
|
|
@ -265,16 +264,16 @@ SMODS.Blind {
|
||||||
end
|
end
|
||||||
|
|
||||||
local cards_added = {}
|
local cards_added = {}
|
||||||
local length = #G.hand.highlighted
|
local count = #G.hand.highlighted
|
||||||
|
|
||||||
for i = 1, length do
|
f(G.hand.highlighted, ipairs):take(count):foreach(function(v, i)
|
||||||
local copy = copy_card(G.hand.highlighted[i])
|
local copy = copy_card(G.hand.highlighted[i])
|
||||||
copy:add_to_deck()
|
copy:add_to_deck()
|
||||||
table.insert(G.hand, copy)
|
table.insert(G.hand, copy)
|
||||||
table.insert(cards_added, copy)
|
table.insert(cards_added, copy)
|
||||||
table.insert(G.playing_cards, copy)
|
table.insert(G.playing_cards, copy)
|
||||||
draw_card(G.hand, G.discard, i / length * 100, "down", false, copy, nil, nil, true)
|
draw_card(G.hand, G.discard, i / count * 100, "down", false, copy, nil, nil, true)
|
||||||
end
|
end)
|
||||||
|
|
||||||
playing_card_joker_effects(cards_added)
|
playing_card_joker_effects(cards_added)
|
||||||
end,
|
end,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ local function protect_ev(fun)
|
||||||
return fun
|
return fun
|
||||||
end
|
end
|
||||||
|
|
||||||
local luaf = assert(SMODS.load_file("src/LuaFunctional/functional.lua"))()
|
local luaf = assert(SMODS.load_file("src/LuaFunctional/functional.lua"))() or require "src.LuaFunctional.functional"
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -54,17 +54,18 @@ if false then
|
||||||
function unpack(list, i, j)
|
function unpack(list, i, j)
|
||||||
error({list, i, j})
|
error({list, i, j})
|
||||||
end
|
end
|
||||||
|
|
||||||
luaf = require "src.LuaFunctional.functional"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@class Query<K, V>: metatable
|
||||||
|
local _ = luaf._proto
|
||||||
|
|
||||||
--- Creates a non-numerically-indexed query from the given table.
|
--- Creates a non-numerically-indexed query from the given table.
|
||||||
---@param obj table
|
---@param obj table
|
||||||
---@param f_pairs? fun(t: table): unknown
|
---@param f_pairs? fun(t: table): unknown
|
||||||
---@param numeric boolean?
|
---@param numeric boolean?
|
||||||
---@return Query
|
---@return Query
|
||||||
local function f(obj, f_pairs, numeric)
|
local function f(obj, f_pairs, numeric)
|
||||||
return f_pairs and luaf.from(obj, f_pairs, numeric ~= false) or luaf.pairs(obj)
|
return f_pairs and luaf.from(obj, f_pairs, numeric ~= false) or (obj[1] and luaf.ipairs(obj) or luaf.pairs(obj))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Queues an event to be run.
|
--- Queues an event to be run.
|
||||||
|
|
@ -75,7 +76,15 @@ local function q(fun, front)
|
||||||
G.E_MANAGER:add_event(protect_ev(fun), nil, front)
|
G.E_MANAGER:add_event(protect_ev(fun), nil, front)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@class Query<K, V>: metatable
|
--- Determines if a center is allowed to be usable.
|
||||||
local _ = luaf._proto
|
---@return boolean
|
||||||
|
local function u()
|
||||||
|
return not ((G.play and #G.play.cards > 0 or
|
||||||
|
G.CONTROLLER.locked or
|
||||||
|
(G.GAME.STOP_USE and G.GAME.STOP_USE > 0)) and
|
||||||
|
G.STATE ~= G.STATES.HAND_PLAYED and
|
||||||
|
G.STATE ~= G.STATES.DRAW_TO_HAND and
|
||||||
|
G.STATE ~= G.STATES.PLAY_TAROT)
|
||||||
|
end
|
||||||
|
|
||||||
return {f, q}
|
return {f, q, u}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,4 @@
|
||||||
local f, q = unpack(... or require "src.functional")
|
local f, q, u = unpack(... or require "src.functional")
|
||||||
|
|
||||||
local function can_use()
|
|
||||||
return not ((G.play and #G.play.cards > 0 or
|
|
||||||
G.CONTROLLER.locked or
|
|
||||||
(G.GAME.STOP_USE and G.GAME.STOP_USE > 0)) and
|
|
||||||
G.STATE ~= G.STATES.HAND_PLAYED and
|
|
||||||
G.STATE ~= G.STATES.DRAW_TO_HAND and
|
|
||||||
G.STATE ~= G.STATES.PLAY_TAROT)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function common_hand()
|
local function common_hand()
|
||||||
return (G.GAME or {}).current_round and f(G.GAME.hands):reduce(
|
return (G.GAME or {}).current_round and f(G.GAME.hands):reduce(
|
||||||
|
|
@ -103,7 +94,7 @@ SMODS.Joker {
|
||||||
end,
|
end,
|
||||||
---@param card Card
|
---@param card Card
|
||||||
Bakery_can_use = function(_, card)
|
Bakery_can_use = function(_, card)
|
||||||
return not card.debuff and can_use() and (
|
return not card.debuff and u() and (
|
||||||
#G.GAME.tags ~= 0 or
|
#G.GAME.tags ~= 0 or
|
||||||
f(G.consumeables.cards):filter(destructible):any() or
|
f(G.consumeables.cards):filter(destructible):any() or
|
||||||
f(G.jokers.cards):filter(is_mergeable_with(card)):any()
|
f(G.jokers.cards):filter(is_mergeable_with(card)):any()
|
||||||
|
|
|
||||||
|
|
@ -18,3 +18,7 @@ SMODS.Atlas {
|
||||||
key = "modicon",
|
key = "modicon",
|
||||||
path = "icon.png",
|
path = "icon.png",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMODS.current_mod.optional_features = function()
|
||||||
|
return {cardareas = {deck = true}}
|
||||||
|
end
|
||||||
|
|
|
||||||
25
src/seal.lua
25
src/seal.lua
|
|
@ -1,3 +1,5 @@
|
||||||
|
local f, _ = unpack(... or require "src.functional")
|
||||||
|
|
||||||
-- SMODS.Atlas {
|
-- SMODS.Atlas {
|
||||||
-- px = 71,
|
-- px = 71,
|
||||||
-- py = 95,
|
-- py = 95,
|
||||||
|
|
@ -10,23 +12,26 @@ SMODS.Seal {
|
||||||
badge_colour = HEX("12f254"),
|
badge_colour = HEX("12f254"),
|
||||||
atlas = "void",
|
atlas = "void",
|
||||||
pos = {x = 0, y = 0},
|
pos = {x = 0, y = 0},
|
||||||
|
config = {ready = true},
|
||||||
calculate = function(_, card, context)
|
calculate = function(_, card, context)
|
||||||
if not context.blind_defeated or card.area ~= G.deck then
|
if context.setting_blind or context.starting_shop then
|
||||||
|
card.Roland_frost = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if not context.end_of_round or card.area ~= G.deck or card.Roland_frost then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
card.Roland_frost = true
|
||||||
local tag = Tag(get_next_tag_key("Roland_frost"))
|
local tag = Tag(get_next_tag_key("Roland_frost"))
|
||||||
|
|
||||||
if tag.name == "Orbital Tag" then
|
if tag.name == "Orbital Tag" then
|
||||||
local hands = {}
|
tag.ability.orbital_hand = pseudorandom_element(
|
||||||
|
f(G.GAME.hands):filter(function(v)
|
||||||
for k, v in pairs(G.GAME.hands) do
|
return v.visible
|
||||||
if v.visible then
|
end):into(),
|
||||||
table.insert(hands, k)
|
pseudoseed("Roland_frost")
|
||||||
end
|
)
|
||||||
end
|
|
||||||
|
|
||||||
tag.ability.orbital_hand = pseudorandom_element(hands, pseudoseed("Roland_frost"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
add_tag(tag)
|
add_tag(tag)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,4 @@
|
||||||
local f, q = unpack(... or require "src.functional")
|
local f, q, u = unpack(... or require "src.functional")
|
||||||
|
|
||||||
local function can_use()
|
|
||||||
return not ((G.play and #G.play.cards > 0 or
|
|
||||||
G.CONTROLLER.locked or
|
|
||||||
(G.GAME.STOP_USE and G.GAME.STOP_USE > 0)) and
|
|
||||||
G.STATE ~= G.STATES.HAND_PLAYED and
|
|
||||||
G.STATE ~= G.STATES.DRAW_TO_HAND and
|
|
||||||
G.STATE ~= G.STATES.PLAY_TAROT)
|
|
||||||
end
|
|
||||||
|
|
||||||
SMODS.Sound({key = "void", path = "void.ogg"})
|
SMODS.Sound({key = "void", path = "void.ogg"})
|
||||||
|
|
||||||
|
|
@ -37,10 +28,10 @@ SMODS.Consumable {
|
||||||
return {vars = {card.ability.extra.amount, card.ability.extra.hand}}
|
return {vars = {card.ability.extra.amount, card.ability.extra.hand}}
|
||||||
end,
|
end,
|
||||||
can_use = function(_, card)
|
can_use = function(_, card)
|
||||||
return can_use() 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, _, _)
|
||||||
for _, v in ipairs(Bakery_API.get_highlighted()) do
|
f(Bakery_API.get_highlighted()):foreach(function(v)
|
||||||
q {
|
q {
|
||||||
delay = 0.1,
|
delay = 0.1,
|
||||||
func = function()
|
func = function()
|
||||||
|
|
@ -48,7 +39,7 @@ SMODS.Consumable {
|
||||||
v:juice_up(0.5, 0.5)
|
v:juice_up(0.5, 0.5)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
end)
|
||||||
|
|
||||||
q {
|
q {
|
||||||
delay = 0.1,
|
delay = 0.1,
|
||||||
|
|
@ -75,7 +66,7 @@ SMODS.Consumable {
|
||||||
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 can_use()
|
return #G.playing_cards > 1 and u()
|
||||||
end,
|
end,
|
||||||
use = function(_, card, _, _)
|
use = function(_, card, _, _)
|
||||||
local function destructible(v)
|
local function destructible(v)
|
||||||
|
|
@ -102,17 +93,7 @@ SMODS.Consumable {
|
||||||
f(G.jokers.cards):foreach(calculate_joker)
|
f(G.jokers.cards):foreach(calculate_joker)
|
||||||
|
|
||||||
for _ = 1, card.ability.extra.amount do
|
for _ = 1, card.ability.extra.amount do
|
||||||
local cryptid = create_card(
|
local cryptid = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_cryptid", "void")
|
||||||
nil,
|
|
||||||
G.consumeables,
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
"c_cryptid",
|
|
||||||
"void"
|
|
||||||
)
|
|
||||||
|
|
||||||
cryptid:set_edition({negative = true}, true)
|
cryptid:set_edition({negative = true}, true)
|
||||||
cryptid:add_to_deck()
|
cryptid:add_to_deck()
|
||||||
G.consumeables:emplace(cryptid)
|
G.consumeables:emplace(cryptid)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
local f = unpack(... or require "src.functional")
|
||||||
|
|
||||||
if not Balatest then
|
if not Balatest then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -139,13 +141,13 @@ Balatest.TestPlay {
|
||||||
Balatest.wait_for_input()
|
Balatest.wait_for_input()
|
||||||
end,
|
end,
|
||||||
assert = function()
|
assert = function()
|
||||||
for k, v in pairs(G.hand.cards) do
|
f(G.hand.cards):foreach(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"
|
||||||
|
|
||||||
Balatest.assert(v.debuff == (v.base.value == "Ace"), message)
|
Balatest.assert(v.debuff == (v.base.value == "Ace"), message)
|
||||||
end
|
end)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,13 +166,13 @@ Balatest.TestPlay {
|
||||||
Balatest.play_hand {"2S"}
|
Balatest.play_hand {"2S"}
|
||||||
end,
|
end,
|
||||||
assert = function()
|
assert = function()
|
||||||
for k, v in pairs(G.hand.cards) do
|
f(G.hand.cards):foreach(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"
|
||||||
|
|
||||||
Balatest.assert(v.debuff == (v.base.value == "2"), message)
|
Balatest.assert(v.debuff == (v.base.value == "2"), message)
|
||||||
end
|
end)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,9 +185,9 @@ Balatest.TestPlay {
|
||||||
Balatest.wait_for_input()
|
Balatest.wait_for_input()
|
||||||
end,
|
end,
|
||||||
assert = function()
|
assert = function()
|
||||||
for k, v in pairs(G.hand.cards) do
|
f(G.hand.cards):foreach(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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue