diff --git a/assets/1x/voucher.png b/assets/1x/voucher.png new file mode 100644 index 0000000..117efca Binary files /dev/null and b/assets/1x/voucher.png differ diff --git a/assets/1x/voucher.png.kra b/assets/1x/voucher.png.kra new file mode 100644 index 0000000..834096c Binary files /dev/null and b/assets/1x/voucher.png.kra differ diff --git a/assets/2x/back.png b/assets/2x/back.png index 5bb9e1b..8ba4eed 100644 Binary files a/assets/2x/back.png and b/assets/2x/back.png differ diff --git a/assets/2x/blind.png b/assets/2x/blind.png index a896500..6ac2097 100644 Binary files a/assets/2x/blind.png and b/assets/2x/blind.png differ diff --git a/assets/2x/charm.png b/assets/2x/charm.png index da3934a..ad12724 100644 Binary files a/assets/2x/charm.png and b/assets/2x/charm.png differ diff --git a/assets/2x/icon.png b/assets/2x/icon.png index ca1887d..aaa2c20 100644 Binary files a/assets/2x/icon.png and b/assets/2x/icon.png differ diff --git a/assets/2x/joker.png b/assets/2x/joker.png index 444300f..7184564 100644 Binary files a/assets/2x/joker.png and b/assets/2x/joker.png differ diff --git a/assets/2x/phorm.png b/assets/2x/phorm.png index 8bfbb56..b2cf244 100644 Binary files a/assets/2x/phorm.png and b/assets/2x/phorm.png differ diff --git a/assets/2x/seal.png b/assets/2x/seal.png index 39f0af7..a429701 100644 Binary files a/assets/2x/seal.png and b/assets/2x/seal.png differ diff --git a/assets/2x/sleeve.png b/assets/2x/sleeve.png index e131437..f3d3c32 100644 Binary files a/assets/2x/sleeve.png and b/assets/2x/sleeve.png differ diff --git a/assets/2x/spectral.png b/assets/2x/spectral.png index b2cae0f..7709e09 100644 Binary files a/assets/2x/spectral.png and b/assets/2x/spectral.png differ diff --git a/assets/2x/tag.png b/assets/2x/tag.png index 92d5ac8..c78af0e 100644 Binary files a/assets/2x/tag.png and b/assets/2x/tag.png differ diff --git a/assets/2x/tarot.png b/assets/2x/tarot.png index f501939..b1c372c 100644 Binary files a/assets/2x/tarot.png and b/assets/2x/tarot.png differ diff --git a/assets/2x/unicon.png b/assets/2x/unicon.png index 4e89cc7..a61d8e2 100644 Binary files a/assets/2x/unicon.png and b/assets/2x/unicon.png differ diff --git a/assets/2x/voucher.png b/assets/2x/voucher.png new file mode 100644 index 0000000..c6761ab Binary files /dev/null and b/assets/2x/voucher.png differ diff --git a/localization/en-us.lua b/localization/en-us.lua index 824acfc..9d97f08 100644 --- a/localization/en-us.lua +++ b/localization/en-us.lua @@ -495,6 +495,22 @@ return { }, }, }, + Voucher = { + v_Roland_ceres = { + name = "Ceres", + text = { + "Level up {C:attention}Flush House", + "when it is played", + }, + }, + v_Roland_neptune = { + name = "Neptune", + text = { + "Level up {C:attention}Straight Flush", + "when it is played", + }, + }, + }, }, misc = { challenge_names = { diff --git a/manifest.json b/manifest.json index 64d6fe2..251d6f8 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "id": "Roland", "name": "Roland", "prefix": "Roland", - "version": "2.9.14", + "version": "2.9.15", "badge_colour": "8BE9FD", "display_name": "Roland", "main_file": "src/main.lua", diff --git a/src/blind.lua b/src/blind.lua index 810f8ca..093a36a 100644 --- a/src/blind.lua +++ b/src/blind.lua @@ -23,10 +23,7 @@ SMODS.Atlas { atlas_table = "ANIMATION_ATLAS", } -SMODS.Sound { - key = "kick", - path = "kick.ogg", -} +SMODS.Sound {key = "kick", path = "kick.ogg"} local function common_rank() local tally, to_name = {}, {} @@ -353,6 +350,18 @@ function SMODS.current_mod:calculate(context) local _ = not str and type(G.calc[1]) == "function" and G.calc[1](f(context):keys():string()) end + local _ = context.before and + f {"v_Roland_ceres", "v_Roland_neptune"} + :where(f.index_into(G.GAME.used_vouchers)) + :map(f.index_into(G.P_CENTERS)) + :where("config.hand_type", context.scoring_name) + :any() and + SMODS.calculate_effect { + level_up = true, + message = localize "k_level_up_ex", + card = G.play.cards[math.ceil(#G.play.cards / 2)] or G.deck.cards[#G.deck.cards] or {}, + } + local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities local _ = context.end_of_round and diff --git a/src/lib/funky.lua b/src/lib/funky.lua index 0333c62..4455634 100644 --- a/src/lib/funky.lua +++ b/src/lib/funky.lua @@ -9,81 +9,91 @@ local f = {} if not f then ---@generic I, O - ---@param first fun(v: I): O + ---@param first string|fun(v: I): O ---@return fun(v: I): O + ---@nodiscard function f.chain(first) error {first} end ---@generic I, T, O - ---@param first fun(v: I): T - ---@param second fun(v: T): O + ---@param first string|fun(v: I): T + ---@param second string|fun(v: T): O ---@return fun(v: I): O + ---@nodiscard 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 + ---@param first string|fun(v: I): T1 + ---@param second string|fun(v: T1): T2 + ---@param third string|fun(v: T2): O ---@return fun(v: I): O + ---@nodiscard 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 + ---@param first string|fun(v: I): T1 + ---@param second string|fun(v: T1): T2 + ---@param third string|fun(v: T2): T3 + ---@param fourth string|fun(v: T3): O ---@return fun(v: I): O + ---@nodiscard 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 + ---@param first string|fun(v: I): T1 + ---@param second string|fun(v: T1): T2 + ---@param third string|fun(v: T2): T3 + ---@param fourth string|fun(v: T3): T4 + ---@param fifth string|fun(v: T4): O ---@return fun(v: I): O + ---@nodiscard 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)} + ---@param all { [1]: (string|fun(v: I): O) } ---@return fun(v: I): O + ---@nodiscard function f.chain(all) error(all) end ---@generic I, T, O - ---@param all {[1]: (fun(v: I): T), [2]: (fun(v: T): O)} + ---@param all { [1]: (string|fun(v: I): T), [2]: (string|fun(v: T): O) } ---@return fun(v: I): O + ---@nodiscard 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)} + ---@param all { [1]: (string|fun(v: I): T1), [2]: (string|fun(v: T1): T2), [3]: (string|fun(v: T2): O) } ---@return fun(v: I): O + ---@nodiscard 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)} + ---@param all { [1]: (string|fun(v: I): T1), [2]: (string|fun(v: T1): T2), [3]: (string|fun(v: T2): T3), [4]: (string|fun(v: T3): O) } ---@return fun(v: I): O + ---@nodiscard 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)} + ---@param all { [1]: (string|fun(v: I): T1), [2]: (string|fun(v: T1): T2), [3]: (string|fun(v: T2): T3), [4]: (string|fun(v: T3): T4), [4]: (string|fun(v: T4): O) } ---@return fun(v: I): O + ---@nodiscard function f.chain(all) error(all) end @@ -104,7 +114,7 @@ local none ---@return T ---@nodiscard local function autofunc(func) - return type(func) == "string" and f.index(func) or func or f.id + return type(func) == "string" and f.indices(func) or func or f.id end ---@generic K, V @@ -157,6 +167,7 @@ end ---@generic T ---@param value T ---@return fun(T): boolean +---@nodiscard function f.eq(value) return function(v) return value == v @@ -166,6 +177,7 @@ end ---@generic T ---@param value T ---@return fun(T): boolean +---@nodiscard function f.nq(value) return function(v) return value ~= v @@ -232,11 +244,15 @@ f[true and "chain"] = function(...) for _, v in ipairs(...) do if type(v) == "table" then for _, vv in ipairs(v) do + vv = autofunc(vv) + ret = ret and function(...) return vv(ret(...)) end or vv end else + v = autofunc(v) + ret = ret and function(...) return v(ret(...)) end or v @@ -275,6 +291,7 @@ function f.new(fnext) next = fnext or f.noop, noop = f.noop, nq = f.nq, + peek = f.peek, pun = f.pun, skip = f.skip, slice = f.slice, @@ -382,12 +399,30 @@ function f:concat(...) end) end +---@generic K, V +---@param self F|{ [K]: V } +---@param func fun(v: V, k: K): any +---@return F|{ [K]: V } +---@nodiscard +function f:peek(func) + func = autofunc(func) + + return f.new(function() + local k, v = self:next() + + if k ~= nil then + func(v, k) + return k, v + end + end) +end + ---@generic K, V, U ---@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): U +---@param func fun(v: V, k: K): U ---@return F|{ [K]: U } ----@nodiscard ---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U } +---@nodiscard function f:map(func) func = autofunc(func) @@ -402,61 +437,11 @@ end ---@generic K, V, U ---@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): { [any]: U } +---@param func fun(v: V, k: K): { [any]: U } ---@param fpairs? fun(t: table): (fun(table: table, index?: K): K, V) ---@return F|{ [K]: U } ----@nodiscard ---@overload fun(self: F|{ [K]: V }, func: string, fpairs?: fun(t: table): (fun(table: table, index?: K): K, V)): F|{ [K]: U } -function f:flatmap(func, fpairs) - -- local i = 0 - local vt, vk, vv, vp - func = autofunc(func) - - 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, U ----@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): { [any]: U } ----@param fpairs? fun(t: table): (fun(table: table, index?: K): K, V) ----@return F|{ [K]: U } ---@nodiscard ----@overload fun(self: F|{ [K]: V }, func: string, fpairs?: fun(t: table): (fun(table: table, index?: K): K, V)): F|{ [K]: U } function f:flatmap(func, fpairs) -- local i = 0 local vt, vk, vv, vp @@ -502,7 +487,7 @@ end ---@generic K, V ---@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): boolean +---@param func fun(v: V, k: K): boolean ---@param is? any ---@return F|{ [K]: V } ---@nodiscard @@ -665,10 +650,10 @@ end ---@generic K, V ---@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): any +---@param func fun(v: V, k: K): any ---@return boolean|V ----@nodiscard ---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V +---@nodiscard function f:any(func) func = autofunc(func) @@ -683,10 +668,10 @@ end ---@generic K, V ---@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): any +---@param func fun(v: V, k: K): any ---@return boolean|V ----@nodiscard ---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V +---@nodiscard function f:all(func) func = autofunc(func) @@ -701,10 +686,10 @@ end ---@generic K, V ---@param self F|{ [K]: V } ----@param func F|fun(v: V, k: K): any +---@param func fun(v: V, k: K): any ---@return integer ----@nodiscard ---@overload fun(self: F|{ [K]: V }, func: string): integer +---@nodiscard function f:count(func) local ret = 0 func = autofunc(func) diff --git a/src/main.lua b/src/main.lua index 6f2da77..33ccfea 100644 --- a/src/main.lua +++ b/src/main.lua @@ -58,10 +58,22 @@ q { end, } -f {"challenge", "spectral", "edition", "tweaks", "blind", "charm", "joker", "tarot", "back", "seal", "tag"} - :each(function(v) - assert(SMODS.load_file("src/" .. v .. ".lua"))(qol) - end) +f { + "challenge", + "spectral", + "edition", + "tweaks", + "blind", + "charm", + "joker", + "tarot", + "back", + "seal", + "tag", + "voucher", +}:each(function(v) + assert(SMODS.load_file("src/" .. v .. ".lua"))(qol) +end) if Balatest then f {"joker", "blind", "spectral"}:each(function(v) diff --git a/src/voucher.lua b/src/voucher.lua new file mode 100644 index 0000000..6f21589 --- /dev/null +++ b/src/voucher.lua @@ -0,0 +1,38 @@ +local voucher = (function() + local x = 0 + + ---@param tbl SMODS.Voucher|{attributes: Attributes[]} + ---@return SMODS.Voucher + return function(tbl) + tbl.pos = {x = x, y = 0} + tbl.atlas = "voucher" + tbl.cost = 10 + x = x + 1 + return SMODS.Voucher(tbl) + end +end)() + +SMODS.Atlas { + px = 71, + py = 95, + key = "voucher", + path = "voucher.png", +} + +voucher { + key = "ceres", + pronouns = "it_its", + config = {hand_type = "Flush House"}, + attributes = {"planet", "passive", "hand_type", "space"}, + in_pool = function(self) + return G.GAME.hands[self.config.hand_type].visible + end, +} + +voucher { + key = "neptune", + pronouns = "it_its", + requires = {"v_Roland_ceres"}, + config = {hand_type = "Straight Flush"}, + attributes = {"planet", "passive", "hand_type", "space"}, +}