Compare commits
40 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b8094efab | |||
| 374aa5ec24 | |||
| 7d2bd84c9f | |||
| 31627f836d | |||
| 58b1ee9a63 | |||
| 407c18dc6e | |||
| ff55a27567 | |||
| 178e415614 | |||
| f126173091 | |||
| 27ce5bbb2e | |||
| 4fda3af9c0 | |||
| ad24529beb | |||
| fd9ad55325 | |||
| 44367939a6 | |||
| f170f855a1 | |||
| 4619a24736 | |||
| 9f19d85769 | |||
| 8edd1c1c73 | |||
| 2628ae39e6 | |||
| 5e5abf42aa | |||
| b6b49350cb | |||
| e8d0b74a1d | |||
| b4b05d37dc | |||
| 5204ba71a0 | |||
| ce35879117 | |||
| a639a92c3c | |||
| 2a880adb68 | |||
| 1bc58245f2 | |||
| ae14790b7f | |||
| e4d4f2e4dd | |||
| 7cc27f1ee9 | |||
| 91b6f700cf | |||
| 9813b53ddd | |||
|
|
87b0e5534b | ||
| 75c102c298 | |||
| c199c236ab | |||
| adc431f5cd | |||
| 179cecd9fa | |||
| 798a92b148 | |||
| 805be430b0 |
|
|
@ -33,7 +33,7 @@ table_separator_style = none
|
||||||
trailing_table_separator = smart
|
trailing_table_separator = smart
|
||||||
|
|
||||||
# keep/remove/remove_table_only/remove_string_only
|
# keep/remove/remove_table_only/remove_string_only
|
||||||
call_arg_parentheses = keep
|
call_arg_parentheses = remove
|
||||||
|
|
||||||
detect_end_of_line = false
|
detect_end_of_line = false
|
||||||
|
|
||||||
|
|
|
||||||
52
README.md
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Roland
|
||||||
|
|
||||||
|
[](https://github.com/Emik03/Roland/blob/main/LICENSE)
|
||||||
|
|
||||||
|
This is a [Steamodded](https://github.com/Steamodded/smods) mod for the video game [Balatro (2024)](https://playbalatro.com).
|
||||||
|
|
||||||
|
This mod has been in the works since early 2025, and been worked on continously until its official public release as a celebration for my 23rd birthday.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- [About](#about)
|
||||||
|
- [Contents](#contents)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
The main theme of this mod centers around the addition of a new edition: Frozen.
|
||||||
|
|
||||||
|
Frozen can be applied to playing cards or jokers and will cause whatever state they have to be locked in place, removing any possibility of future scaling; positive or negative.
|
||||||
|
|
||||||
|
The primary goal is to create interesting interactions in-and-outside of the added editions. This does not necessarily mean that these mechanics have to be balanced, but does hopefully make new strategies viable and breathe new life into some of the base game's weaker jokers. It is designed to work very well with its parent mod [Bakery](https://github.com/BakersDozenBagels/BalatroBakery), but can work just as well on its own or with other content mods.
|
||||||
|
|
||||||
|
The mod offers a config for accessibility options, general convenience, modifications that I believe make the game healthier, and otherwise purely cosmetic.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
- 31 Jokers
|
||||||
|
- 1 Tarot Card
|
||||||
|
- 4 Spectral Cards
|
||||||
|
- 2 Vouchers
|
||||||
|
- 1 Seal
|
||||||
|
- 1 Edition
|
||||||
|
- 2 Tags
|
||||||
|
- 9 Blinds
|
||||||
|
- 4 Decks
|
||||||
|
- 4 [Deck Sleeves (CardSleeves)](https://github.com/larswijn/CardSleeves)
|
||||||
|
- 5 [Charms (Bakery)](https://github.com/BakersDozenBagels/BalatroBakery)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Set up [Steamodded](https://github.com/Steamodded/smods/wiki#i-want-to-play-with-mods).
|
||||||
|
2. Set up [Bakery](https://github.com/BakersDozenBagels). You are free to use the [Lite version](https://github.com/BakersDozenBagels/BalatroBakery/tree/lite) if you want to play Roland standalone.
|
||||||
|
3. Clone the repository into your mods folder, or download it as a zip and place it there.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This repository falls under the [MPL-2 license](https://www.mozilla.org/en-US/MPL/2.0/).
|
||||||
|
|
||||||
|
You may copy individual or multiple source files, granted that you keep the copyright license, and disclose the source back to this repository.
|
||||||
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 13 KiB |
BIN
assets/1x/backExtra.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 8.6 KiB |
BIN
assets/2x/backExtra.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 3 KiB After Width: | Height: | Size: 4.7 KiB |
|
|
@ -414,6 +414,16 @@ return {
|
||||||
text = {"{X:red,C:white}X#1#{} discards each round"},
|
text = {"{X:red,C:white}X#1#{} discards each round"},
|
||||||
unlock = {"Defeat {C:dark_edition}#1#"},
|
unlock = {"Defeat {C:dark_edition}#1#"},
|
||||||
},
|
},
|
||||||
|
j_Roland_yard = {
|
||||||
|
name = "Yard Sale",
|
||||||
|
text = {
|
||||||
|
"Gain {C:money}$#1#{} when a",
|
||||||
|
"card is {C:attention}added",
|
||||||
|
"or {C:attention}removed",
|
||||||
|
"from the deck",
|
||||||
|
},
|
||||||
|
unlock = {"Complete the", "{C:attention}#1#", "challenge"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Other = {
|
Other = {
|
||||||
roland_glass_seal = {
|
roland_glass_seal = {
|
||||||
|
|
@ -458,8 +468,8 @@ return {
|
||||||
sleeve_Roland_dropship_alt = {
|
sleeve_Roland_dropship_alt = {
|
||||||
name = "Business Sleeve",
|
name = "Business Sleeve",
|
||||||
text = {
|
text = {
|
||||||
"{C:attention}Jokers {}are {C:dark_edition}Negative",
|
"{C:attention}Jokers {}are instead",
|
||||||
"{C:attention}Perishable {}lasts forever",
|
"{C:dark_edition}Negative {}and {C:money}Rental",
|
||||||
"",
|
"",
|
||||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||||
},
|
},
|
||||||
|
|
@ -594,7 +604,7 @@ return {
|
||||||
c_Roland_Jokerful = "Jokerful",
|
c_Roland_Jokerful = "Jokerful",
|
||||||
c_Roland_Pastries = "Sweet Pastries",
|
c_Roland_Pastries = "Sweet Pastries",
|
||||||
c_Roland_Spin_To_Win = "Spin to Win",
|
c_Roland_Spin_To_Win = "Spin to Win",
|
||||||
c_Roland_Yard_Sale = "Yard Sale",
|
c_Roland_Spring_Cleaning = "Spring Cleaning",
|
||||||
},
|
},
|
||||||
v_dictionary = {
|
v_dictionary = {
|
||||||
b_Roland_add = "ADD",
|
b_Roland_add = "ADD",
|
||||||
|
|
@ -634,8 +644,6 @@ return {
|
||||||
ch_c_Roland_Eternally_Violet = {"{C:attention}Violet Vessel{}'s effect is active every blind"},
|
ch_c_Roland_Eternally_Violet = {"{C:attention}Violet Vessel{}'s effect is active every blind"},
|
||||||
ch_c_Roland_Glass1 = {"Played cards with no seal have a"},
|
ch_c_Roland_Glass1 = {"Played cards with no seal have a"},
|
||||||
ch_c_Roland_Glass2 = {"{C:green}1 in 2{} chance to gain {C:dark_edition}Glass Seal"},
|
ch_c_Roland_Glass2 = {"{C:green}1 in 2{} chance to gain {C:dark_edition}Glass Seal"},
|
||||||
ch_c_Roland_Yard_Sale1 = {"Gain {C:money}$5 {}when playing cards are {C:attention}added {}or {C:attention}removed"},
|
|
||||||
ch_c_Roland_Yard_Sale2 = {"Earn {C:red}no money {}from any other source"},
|
|
||||||
ch_c_Roland_Go = {"Set money to {C:money}$0 {}when entering the shop"},
|
ch_c_Roland_Go = {"Set money to {C:money}$0 {}when entering the shop"},
|
||||||
ch_c_Roland_Jokerful = {"The only jokers are {C:mult}Joker{} and {C:chips}Ms. Joker"},
|
ch_c_Roland_Jokerful = {"The only jokers are {C:mult}Joker{} and {C:chips}Ms. Joker"},
|
||||||
ch_c_Roland_Pastries = {"All blinds, cards, and tags are of {C:gold}Bakery{} or {C:blue}Roland"},
|
ch_c_Roland_Pastries = {"All blinds, cards, and tags are of {C:gold}Bakery{} or {C:blue}Roland"},
|
||||||
|
|
@ -644,6 +652,7 @@ return {
|
||||||
ch_c_Roland_Showdown_Crimson = {"Showdown blinds are {C:attention}Crimson Heart {}(stacks with above)"},
|
ch_c_Roland_Showdown_Crimson = {"Showdown blinds are {C:attention}Crimson Heart {}(stacks with above)"},
|
||||||
ch_c_Roland_Showdown_Verdant = {"Showdown blinds are {C:attention}Verdant Leaf {}(stacks with above)"},
|
ch_c_Roland_Showdown_Verdant = {"Showdown blinds are {C:attention}Verdant Leaf {}(stacks with above)"},
|
||||||
ch_c_Roland_Showdown_Violet = {"Showdown blinds are {C:attention}Violet Vessel {}(stacks with above)"},
|
ch_c_Roland_Showdown_Violet = {"Showdown blinds are {C:attention}Violet Vessel {}(stacks with above)"},
|
||||||
|
ch_c_Roland_Spring_Cleaning = {"Earn {C:red}no money {}from sources other than {C:attention}Yard Sale"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
41
lovely.toml
|
|
@ -65,6 +65,18 @@ position = "at"
|
||||||
payload = "elseif G.GAME.blind_on_deck == 'Big' then"
|
payload = "elseif G.GAME.blind_on_deck == 'Big' then"
|
||||||
match_indent = true
|
match_indent = true
|
||||||
|
|
||||||
|
# Prevent Incantation from overriding Faster Planets
|
||||||
|
[[patches]]
|
||||||
|
[patches.pattern]
|
||||||
|
target = '=[SMODS incantation "Incantation.lua"]'
|
||||||
|
pattern = "function Card:use_consumeable(area, copier)"
|
||||||
|
position = "after"
|
||||||
|
payload = """if SMODS.Mods.Roland.config.faster_planets and
|
||||||
|
self.ability.consumeable.hand_type then
|
||||||
|
return useconsumeref(self, area, copier)
|
||||||
|
end"""
|
||||||
|
match_indent = true
|
||||||
|
|
||||||
# Misfortune Cookie
|
# Misfortune Cookie
|
||||||
[[patches]]
|
[[patches]]
|
||||||
[patches.pattern]
|
[patches.pattern]
|
||||||
|
|
@ -83,7 +95,7 @@ pattern = "local card = create_card('Tarot',G.consumeables, nil, nil, nil, nil,
|
||||||
position = "after"
|
position = "after"
|
||||||
times = 1
|
times = 1
|
||||||
payload = """if next(SMODS.find_card "j_Roland_misfortune") then
|
payload = """if next(SMODS.find_card "j_Roland_misfortune") then
|
||||||
card:set_edition "e_negative"
|
card:set_edition("e_negative", true, true)
|
||||||
end"""
|
end"""
|
||||||
match_indent = true
|
match_indent = true
|
||||||
|
|
||||||
|
|
@ -105,7 +117,7 @@ target = "card.lua"
|
||||||
pattern = "local card = create_card(card_type,G.consumeables, nil, nil, nil, nil, _planet, 'blusl')"
|
pattern = "local card = create_card(card_type,G.consumeables, nil, nil, nil, nil, _planet, 'blusl')"
|
||||||
position = "after"
|
position = "after"
|
||||||
payload = """if next(SMODS.find_card "j_Roland_misfortune") then
|
payload = """if next(SMODS.find_card "j_Roland_misfortune") then
|
||||||
card:set_edition "e_negative"
|
card:set_edition("e_negative", true, true)
|
||||||
end"""
|
end"""
|
||||||
match_indent = true
|
match_indent = true
|
||||||
|
|
||||||
|
|
@ -154,7 +166,6 @@ target = "card.lua"
|
||||||
pattern = "math\\.floor\\(\\(G\\.GAME\\.dollars \\+ \\(G\\.GAME\\.dollar_buffer or 0\\)\\)/self\\.ability\\.extra\\.dollars\\)"
|
pattern = "math\\.floor\\(\\(G\\.GAME\\.dollars \\+ \\(G\\.GAME\\.dollar_buffer or 0\\)\\)/self\\.ability\\.extra\\.dollars\\)"
|
||||||
position = "at"
|
position = "at"
|
||||||
payload = "SMODS.Mods.Roland.bootstraps_mult(self)"
|
payload = "SMODS.Mods.Roland.bootstraps_mult(self)"
|
||||||
match_indent = true
|
|
||||||
|
|
||||||
[[patches]]
|
[[patches]]
|
||||||
[patches.regex]
|
[patches.regex]
|
||||||
|
|
@ -177,3 +188,27 @@ pattern = "value = value + card.ability[property]"
|
||||||
position = "at"
|
position = "at"
|
||||||
payload = "value = value + (card.ability[property] or 0)"
|
payload = "value = value + (card.ability[property] or 0)"
|
||||||
match_indent = true
|
match_indent = true
|
||||||
|
|
||||||
|
# [[patches]]
|
||||||
|
# [patches.pattern]
|
||||||
|
# target = '=[SMODS DebugPlus "debugplus/console.lua"]'
|
||||||
|
# pattern = "if toCheck == '/' or toCheck == 'kp/' then"
|
||||||
|
# position = "at"
|
||||||
|
# payload = "if toCheck == '/' or toCheck == 'kp/' or toCheck == 'f' then"
|
||||||
|
# match_indent = true
|
||||||
|
|
||||||
|
# [[patches]]
|
||||||
|
# [patches.pattern]
|
||||||
|
# target = '=[SMODS DebugPlus "debugplus/console.lua"]'
|
||||||
|
# pattern = 'local cmdName = string.lower(string.gsub(inputText, "^(%S+).*", "%1"))'
|
||||||
|
# position = "at"
|
||||||
|
# payload = 'local cmdName = "eval"'
|
||||||
|
# match_indent = true
|
||||||
|
|
||||||
|
# [[patches]]
|
||||||
|
# [patches.pattern]
|
||||||
|
# target = '=[SMODS DebugPlus "debugplus/console.lua"]'
|
||||||
|
# pattern = 'local rawArgs = string.gsub(inputText, "^%S+%s*(.*)", "%1")'
|
||||||
|
# position = "at"
|
||||||
|
# payload = 'local cmdName = inputText'
|
||||||
|
# match_indent = true
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"id": "Roland",
|
"id": "Roland",
|
||||||
"name": "Roland",
|
"name": "Roland",
|
||||||
"prefix": "Roland",
|
"prefix": "Roland",
|
||||||
"version": "2.9.54",
|
"version": "3.0.2",
|
||||||
"badge_colour": "8BE9FD",
|
"badge_colour": "8BE9FD",
|
||||||
"display_name": "Roland",
|
"display_name": "Roland",
|
||||||
"main_file": "src/main.lua",
|
"main_file": "src/main.lua",
|
||||||
|
|
|
||||||
1
refs/src
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
../../smods/src
|
||||||
67
src/back.lua
|
|
@ -8,7 +8,7 @@ end
|
||||||
local back = (function()
|
local back = (function()
|
||||||
local x = 0
|
local x = 0
|
||||||
|
|
||||||
---@param tbl SMODS.Back|{attributes?: Attributes[], is_alt: (fun(self: self): boolean), alt_apply?: fun(self: SMODS.Back|table, back: Back|table), alt_calculate?: fun(self: SMODS.Back|table, back: Back|table, context: CalcContext|table): table?, boolean?}
|
---@param tbl SMODS.Back|{attributes?: Attributes[], pronouns: string, is_alt: (fun(self: self): boolean), alt_apply?: fun(self: SMODS.Back|table, back: Back|table), alt_calculate?: fun(self: SMODS.Back|table, back: Back|table, context: CalcContext|table): table?, boolean?}
|
||||||
return function(tbl)
|
return function(tbl)
|
||||||
local key = tbl.key
|
local key = tbl.key
|
||||||
local apply = tbl.apply
|
local apply = tbl.apply
|
||||||
|
|
@ -32,6 +32,7 @@ local back = (function()
|
||||||
key = key,
|
key = key,
|
||||||
pos = tbl.pos,
|
pos = tbl.pos,
|
||||||
atlas = "sleeve",
|
atlas = "sleeve",
|
||||||
|
pronouns = tbl.pronouns,
|
||||||
config = tbl.config and f(tbl.config):table() 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 {}
|
||||||
|
|
@ -39,7 +40,7 @@ local back = (function()
|
||||||
return ret
|
return ret
|
||||||
end,
|
end,
|
||||||
apply = function(self, ...)
|
apply = function(self, ...)
|
||||||
return (tbl.alt_apply and self:is_alt() and tbl.alt_apply or apply)(self, ...)
|
return save((tbl.alt_apply and self:is_alt() and tbl.alt_apply or apply)(self, ...))
|
||||||
end,
|
end,
|
||||||
calculate = function(self, ...)
|
calculate = function(self, ...)
|
||||||
return (tbl.alt_calculate and self:is_alt() and tbl.alt_calculate or calculate)(self, ...)
|
return (tbl.alt_calculate and self:is_alt() and tbl.alt_calculate or calculate)(self, ...)
|
||||||
|
|
@ -53,13 +54,20 @@ local back = (function()
|
||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
SMODS.Atlas {
|
local back_atlas = SMODS.Atlas {
|
||||||
key = "back",
|
key = "back",
|
||||||
path = "back.png",
|
path = "back.png",
|
||||||
px = 71,
|
px = 71,
|
||||||
py = 95,
|
py = 95,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local extra_atlas = SMODS.Atlas {
|
||||||
|
key = "back_extra",
|
||||||
|
path = "backExtra.png",
|
||||||
|
px = 71,
|
||||||
|
py = 95,
|
||||||
|
}
|
||||||
|
|
||||||
local _ = CardSleeves and SMODS.Atlas {
|
local _ = CardSleeves and SMODS.Atlas {
|
||||||
key = "sleeve",
|
key = "sleeve",
|
||||||
path = "sleeve.png",
|
path = "sleeve.png",
|
||||||
|
|
@ -72,10 +80,10 @@ back {
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
config = {extra = {alt_times = 9, times = 3}},
|
config = {extra = {alt_times = 9, times = 3}},
|
||||||
attributes = {"passive", "boss_blind"},
|
attributes = {"passive", "boss_blind"},
|
||||||
loc_vars = function(self, _, _)
|
loc_vars = function(self)
|
||||||
return {vars = {self.config.extra.alt_times}}
|
return {vars = {self.config.extra.alt_times}}
|
||||||
end,
|
end,
|
||||||
apply = function(_, _)
|
apply = function()
|
||||||
G.GAME.modifiers.Roland_blossom_deck = true
|
G.GAME.modifiers.Roland_blossom_deck = true
|
||||||
end,
|
end,
|
||||||
calculate = function(self, b, context)
|
calculate = function(self, b, context)
|
||||||
|
|
@ -125,7 +133,7 @@ back {
|
||||||
calculate = f.noop,
|
calculate = f.noop,
|
||||||
}
|
}
|
||||||
|
|
||||||
back {
|
local b_dropship = back {
|
||||||
key = "dropship",
|
key = "dropship",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
attributes = {"passive", "generation"},
|
attributes = {"passive", "generation"},
|
||||||
|
|
@ -138,12 +146,51 @@ back {
|
||||||
not not f(G.jokers.cards):map "ability":all "perishable"
|
not not f(G.jokers.cards):map "ability":all "perishable"
|
||||||
end,
|
end,
|
||||||
apply = function(self)
|
apply = function(self)
|
||||||
G.GAME.modifiers.Roland_dropship = true
|
G.GAME.modifiers.Roland_dropship = not self:is_alt()
|
||||||
G.GAME.modifiers.Roland_dropship_alt = self:is_alt()
|
G.GAME.modifiers.Roland_dropship_alt = self:is_alt()
|
||||||
end,
|
end,
|
||||||
calculate = f.noop,
|
calculate = f.noop,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local dropship_tape
|
||||||
|
|
||||||
|
q {
|
||||||
|
blocking = false,
|
||||||
|
no_delete = true,
|
||||||
|
func = function()
|
||||||
|
dropship_tape = SMODS.create_sprite(0, 0, G.CARD_W, G.CARD_H, extra_atlas, {x = 0, y = 0})
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
SMODS.DrawStep {
|
||||||
|
key = "dropship_tape",
|
||||||
|
order = 5,
|
||||||
|
conditions = {vortex = false, facing = "back"},
|
||||||
|
func = function(self)
|
||||||
|
if self.children.back.atlas ~= back_atlas or self.children.back.sprite_pos.x ~= b_dropship.pos.x then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
dropship_tape.role.draw_major = self
|
||||||
|
local deck = self.area.config.type == "deck"
|
||||||
|
local sticker_offset = self.sticker_offset or {}
|
||||||
|
|
||||||
|
-- Don't draw dissolve since it's baked into the sprite already. Also, I had to boost its alpha for the
|
||||||
|
-- shine to look correct, so drawing this would look *awful*.
|
||||||
|
-- dropship_tape:draw_shader("dissolve", nil, nil, deck, self.children.center, self.sticker_rotation, sticker_offset.x, sticker_offset.y)
|
||||||
|
dropship_tape:draw_shader(
|
||||||
|
"voucher",
|
||||||
|
nil,
|
||||||
|
self.ARGS.send_to_shader,
|
||||||
|
deck,
|
||||||
|
self.children.center,
|
||||||
|
self.sticker_rotation,
|
||||||
|
sticker_offset.x,
|
||||||
|
sticker_offset.y
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
local swapper = {Spectral = "Tarot", Tarot = "Spectral"}
|
local swapper = {Spectral = "Tarot", Tarot = "Spectral"}
|
||||||
local orig_create_card = create_card
|
local orig_create_card = create_card
|
||||||
|
|
||||||
|
|
@ -152,14 +199,14 @@ local function create_dropshipped_card(_type, ...)
|
||||||
local ok = _type == "Joker" and ret.ability
|
local ok = _type == "Joker" and ret.ability
|
||||||
|
|
||||||
if ok and G.GAME.modifiers.Roland_dropship_alt then
|
if ok and G.GAME.modifiers.Roland_dropship_alt then
|
||||||
ret:set_edition({negative = true}, true)
|
ret.ability.rental = true
|
||||||
ret.ability.perish_tally = 1 / 0
|
local _ = ret:set_edition({negative = true}, true, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ok and G.GAME.modifiers.Roland_dropship then
|
if ok and G.GAME.modifiers.Roland_dropship then
|
||||||
|
ret.ability.perish_tally = 5
|
||||||
ret.ability.perishable = true
|
ret.ability.perishable = true
|
||||||
ret.cost, ret.sell_cost = 0, 0
|
ret.cost, ret.sell_cost = 0, 0
|
||||||
ret.ability.perish_tally = G.GAME.modifiers.Roland_dropship_alt and 1 / 0 or 5
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ blind {
|
||||||
boss = {min = 6},
|
boss = {min = 6},
|
||||||
boss_colour = HEX "bdaeccff",
|
boss_colour = HEX "bdaeccff",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
collection_loc_vars = function(_)
|
collection_loc_vars = function()
|
||||||
return {
|
return {
|
||||||
vars = {localize {
|
vars = {localize {
|
||||||
type = "variable",
|
type = "variable",
|
||||||
|
|
@ -265,7 +265,7 @@ blind {
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
loc_vars = function(_)
|
loc_vars = function()
|
||||||
local _, name = common_rank()
|
local _, name = common_rank()
|
||||||
return {vars = {localize(name or "Ace", "ranks")}}
|
return {vars = {localize(name or "Ace", "ranks")}}
|
||||||
end,
|
end,
|
||||||
|
|
@ -319,7 +319,7 @@ blind {
|
||||||
dollars = 5,
|
dollars = 5,
|
||||||
defeat = disable_improbable,
|
defeat = disable_improbable,
|
||||||
disable = disable_improbable,
|
disable = disable_improbable,
|
||||||
set_blind = function(_)
|
set_blind = function()
|
||||||
G.GAME.modifiers.Roland_improbable = true
|
G.GAME.modifiers.Roland_improbable = true
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
@ -380,7 +380,7 @@ function SMODS.current_mod:calculate(context)
|
||||||
:map(f.index_into(G.P_CENTERS))
|
:map(f.index_into(G.P_CENTERS))
|
||||||
:where("config.extra.hand_type", context.scoring_name)
|
:where("config.extra.hand_type", context.scoring_name)
|
||||||
:pun "SMODS.Voucher"
|
:pun "SMODS.Voucher"
|
||||||
:each(function(v, _)
|
:each(function(v)
|
||||||
SMODS.smart_level_up_hand(nil, v.config.extra.hand_type, false, v.config.extra.amount)
|
SMODS.smart_level_up_hand(nil, v.config.extra.hand_type, false, v.config.extra.amount)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ end
|
||||||
---@param v SMODS.GameObject
|
---@param v SMODS.GameObject
|
||||||
---@return boolean|string
|
---@return boolean|string
|
||||||
local function is_economy(v)
|
local function is_economy(v)
|
||||||
return f(Bakery_API.econ_only_items):where(f.id, v.key):any()
|
return f(Bakery_API.econ_only_items):where(f.eq(v.key)):any()
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param key string
|
---@param key string
|
||||||
|
|
@ -82,26 +82,22 @@ SMODS.Challenge {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local yard_sale
|
|
||||||
|
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Yard_Sale",
|
key = "Spring_Cleaning",
|
||||||
config = {extra = {dollars = 5}, no_interest = true},
|
config = {no_interest = true},
|
||||||
|
consumeables = {{id = "c_hanged_man"}},
|
||||||
|
jokers = {{id = "j_Roland_yard"}, {id = "j_Roland_yard"}},
|
||||||
vouchers = {{id = "v_magic_trick"}, {id = "v_overstock_norm"}},
|
vouchers = {{id = "v_magic_trick"}, {id = "v_overstock_norm"}},
|
||||||
rules = {custom = multirule("Yard_Sale", 2), modifiers = {{id = "dollars", value = 14}}},
|
rules = {custom = {{id = "Roland_Spring_Cleaning"}}},
|
||||||
restrictions = yard,
|
restrictions = yard,
|
||||||
apply = function()
|
apply = function()
|
||||||
G.GAME.modifiers.no_blind_reward = {Small = true, Big = true, Boss = true}
|
G.GAME.modifiers.no_blind_reward = {Small = true, Big = true, Boss = true}
|
||||||
G.GAME.modifiers.no_extra_hand_money = true
|
G.GAME.modifiers.no_extra_hand_money = true
|
||||||
|
|
||||||
f(Bakery_API.econ_only_items):keys():each(function(v)
|
f(Bakery_API.econ_only_items):keys():where(f.nq "j_Roland_yard"):each(function(v)
|
||||||
G.GAME.banned_keys[v] = true
|
G.GAME.banned_keys[v] = true
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
calculate = function(self, context)
|
|
||||||
yard_sale = (context.playing_card_added or context.remove_playing_cards) and not context.blueprint
|
|
||||||
return yard_sale and {dollars = self.config.extra.dollars * #(context.cards or context.removed or {})} or nil
|
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
|
|
@ -342,12 +338,14 @@ q {
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
table.insert(Bakery_API.econ_only_items, "j_Roland_yard")
|
||||||
|
table.insert(Bakery_API.econ_only_items, "j_Roland_artemis")
|
||||||
local orig = Bakery_API.no_money_decks
|
local orig = Bakery_API.no_money_decks
|
||||||
|
|
||||||
Bakery_API.no_money_decks = setmetatable({}, {
|
Bakery_API.no_money_decks = setmetatable({}, {
|
||||||
orig = orig,
|
orig = orig,
|
||||||
__index = function(_, k)
|
__index = function(_, k)
|
||||||
return (G.GAME or {}).challenge == "c_Roland_Yard_Sale" and not yard_sale or orig[k]
|
return (G.GAME or {}).challenge == "c_Roland_Spring_Cleaning" or orig[k]
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
28
src/credits.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
-- Special shoutout to all contributors. <3
|
||||||
|
return {
|
||||||
|
aster = {
|
||||||
|
name = "asterSSH",
|
||||||
|
fg = HEX "f8f8f2ff",
|
||||||
|
bg = HEX "bd93f9ff",
|
||||||
|
},
|
||||||
|
bakersdozenbagels = {
|
||||||
|
name = "BakersDozenBagels",
|
||||||
|
fg = HEX "362708ff",
|
||||||
|
bg = HEX "edd198ff",
|
||||||
|
},
|
||||||
|
ghostlyfield = {
|
||||||
|
name = "ghostlyfield",
|
||||||
|
fg = HEX "ffffffff",
|
||||||
|
bg = HEX "b290e6ff",
|
||||||
|
},
|
||||||
|
hamester = {
|
||||||
|
name = "Hamester",
|
||||||
|
fg = HEX "ffffffff",
|
||||||
|
bg = HEX "ffa100ff",
|
||||||
|
},
|
||||||
|
redstoad = {
|
||||||
|
name = "RedsToad",
|
||||||
|
fg = HEX "ffffffff",
|
||||||
|
bg = HEX "da4044ff",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -329,8 +329,6 @@ function Card:calculate_dollar_bonus(...)
|
||||||
return orig_calculate_dollar_bonus(self, ...)
|
return orig_calculate_dollar_bonus(self, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
local orig_get_probability_vars = SMODS.get_probability_vars
|
|
||||||
|
|
||||||
function SMODS.current_mod.bootstraps_mult(card)
|
function SMODS.current_mod.bootstraps_mult(card)
|
||||||
local ability = card.Roland_frozen_ability
|
local ability = card.Roland_frozen_ability
|
||||||
local ret = math.floor((G.GAME.dollars + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
|
local ret = math.floor((G.GAME.dollars + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
|
||||||
|
|
@ -343,9 +341,17 @@ function SMODS.current_mod.bootstraps_mult(card)
|
||||||
return ability.Roland_bootstraps_mult
|
return ability.Roland_bootstraps_mult
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local orig_get_probability_vars = SMODS.get_probability_vars
|
||||||
|
|
||||||
function SMODS.get_probability_vars(trigger_obj, ...)
|
function SMODS.get_probability_vars(trigger_obj, ...)
|
||||||
local numerator, denominator = orig_get_probability_vars(trigger_obj, ...)
|
local numerator, denominator = orig_get_probability_vars(trigger_obj, ...)
|
||||||
return trigger_obj and (trigger_obj.Roland_frozen or {}).probability or numerator, denominator
|
local override = ((trigger_obj or {}).Roland_frozen or {}).probability
|
||||||
|
|
||||||
|
if override then
|
||||||
|
return type(denominator) == "table" and to_big(override) or override, denominator
|
||||||
|
else
|
||||||
|
return numerator, denominator
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
q {
|
q {
|
||||||
|
|
|
||||||
177
src/joker.lua
|
|
@ -54,24 +54,10 @@ local joker = (function()
|
||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
---@generic T
|
|
||||||
---@param tbl T[]
|
|
||||||
---@return fun(t: T[], i: integer): integer, T
|
|
||||||
---@return T[]
|
|
||||||
local function ipairs_reversed(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
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param card Card
|
---@param card Card
|
||||||
|
---@return boolean
|
||||||
local function is_frozen(card)
|
local function is_frozen(card)
|
||||||
return card.edition and card.edition.key == "e_Roland_frozen"
|
return card and card.edition and card.edition.Roland_frozen
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param card? Card|false|{suit: string, value: string}
|
---@param card? Card|false|{suit: string, value: string}
|
||||||
|
|
@ -210,8 +196,8 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "sunny",
|
key = "sunny",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
artist = "char",
|
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "ghostlyfield",
|
||||||
attributes = {"food", "on_sell"},
|
attributes = {"food", "on_sell"},
|
||||||
cost = 2,
|
cost = 2,
|
||||||
rarity = 1,
|
rarity = 1,
|
||||||
|
|
@ -232,8 +218,8 @@ joker {
|
||||||
SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}}
|
SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}}
|
||||||
|
|
||||||
SMODS.calculate_context {
|
SMODS.calculate_context {
|
||||||
hand_drawn = facing_blind and {G.deck.cards[1]} and true,
|
hand_drawn = facing_blind and {G.deck.cards[1]} or true,
|
||||||
other_drawn = not facing_blind and {G.deck.cards[1]} and true,
|
other_drawn = not facing_blind and {G.deck.cards[1]} or true,
|
||||||
first_hand_drawn = not current_round.any_hand_drawn and facing_blind or nil,
|
first_hand_drawn = not current_round.any_hand_drawn and facing_blind or nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,14 +243,15 @@ joker {
|
||||||
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||||
end,
|
end,
|
||||||
calculate = function(_, _, context)
|
calculate = function(_, _, context)
|
||||||
return (context.selling_self or context.forcetrigger) and f(G.hand.cards):each(function(v)
|
return (context.selling_self or context.forcetrigger) and
|
||||||
q {
|
f(G.hand.cards):where("edition", false):each(function(v)
|
||||||
delay = 0.1,
|
q {
|
||||||
func = function()
|
delay = 0.1,
|
||||||
v:set_edition {Roland_frozen = true}
|
func = function()
|
||||||
end,
|
v:set_edition {Roland_frozen = true}
|
||||||
}
|
end,
|
||||||
end) or nil
|
}
|
||||||
|
end) or nil
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,7 +274,9 @@ joker {
|
||||||
delay = 1,
|
delay = 1,
|
||||||
func = function()
|
func = function()
|
||||||
play_sound "timpani"
|
play_sound "timpani"
|
||||||
SMODS.add_card {edition = "e_negative", key = v.config.center.key}
|
|
||||||
|
SMODS.add_card {edition = "e_negative", key = v.config.center.key, silent = true}
|
||||||
|
.ability.qty = v.ability.qty
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end) or nil
|
end) or nil
|
||||||
|
|
@ -297,7 +286,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "monomino",
|
key = "monomino",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
artist = "char",
|
artist = "ghostlyfield",
|
||||||
config = {extra = {price = 4, hand_name = "Four of a Kind"}},
|
config = {extra = {price = 4, hand_name = "Four of a Kind"}},
|
||||||
attributes = {"sell_value", "scaling", "economy", "hand_type"},
|
attributes = {"sell_value", "scaling", "economy", "hand_type"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
|
|
@ -326,7 +315,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "domino",
|
key = "domino",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
artist = "char",
|
artist = "ghostlyfield",
|
||||||
config = {extra = {mult_gain = 4, hand_name = "Four of a Kind", mult = 0}},
|
config = {extra = {mult_gain = 4, hand_name = "Four of a Kind", mult = 0}},
|
||||||
attributes = {"mult", "scaling", "hand_type"},
|
attributes = {"mult", "scaling", "hand_type"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
|
|
@ -357,7 +346,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "trimino",
|
key = "trimino",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
artist = "char",
|
artist = "ghostlyfield",
|
||||||
config = {extra = {times = 4, hand_name = "Four of a Kind"}},
|
config = {extra = {times = 4, hand_name = "Four of a Kind"}},
|
||||||
attributes = {"generation", "hand_type"},
|
attributes = {"generation", "hand_type"},
|
||||||
cost = 8,
|
cost = 8,
|
||||||
|
|
@ -416,7 +405,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "misfortune",
|
key = "misfortune",
|
||||||
pronouns = "she_they",
|
pronouns = "she_they",
|
||||||
artist = "char",
|
artist = "ghostlyfield",
|
||||||
attributes = {"discard", "passive", "tarot", "planet", "generation", "seals"},
|
attributes = {"discard", "passive", "tarot", "planet", "generation", "seals"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
|
|
@ -436,6 +425,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "polaris",
|
key = "polaris",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
|
artist = "ghostlyfield",
|
||||||
attributes = {"editions", "space"},
|
attributes = {"editions", "space"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 1,
|
rarity = 1,
|
||||||
|
|
@ -461,7 +451,7 @@ joker {
|
||||||
card.Roland_polaris = true
|
card.Roland_polaris = true
|
||||||
local first = context.scoring_hand[1]
|
local first = context.scoring_hand[1]
|
||||||
|
|
||||||
if not first or first.edition and first.edition.Roland_frozen then
|
if not first or first.edition then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -508,6 +498,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "snowsquall",
|
key = "snowsquall",
|
||||||
pronouns = "he_they",
|
pronouns = "he_they",
|
||||||
|
artist = "ghostlyfield",
|
||||||
config = {extra = {mult_gain = 3, mult = 0}},
|
config = {extra = {mult_gain = 3, mult = 0}},
|
||||||
attributes = {"mult", "scaling", "hand_type"},
|
attributes = {"mult", "scaling", "hand_type"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
|
|
@ -539,13 +530,37 @@ joker {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---comment
|
||||||
|
---@param card Card
|
||||||
|
---@param context table|CalcContext
|
||||||
|
---@return function
|
||||||
|
local function copy(card, context)
|
||||||
|
---@param v Card
|
||||||
|
return function(v)
|
||||||
|
local override_compat = v.config.center.blueprint_compat == nil
|
||||||
|
|
||||||
|
if override_compat then
|
||||||
|
v.config.center.blueprint_compat = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local ret = SMODS.blueprint_effect(card, v, context)
|
||||||
|
|
||||||
|
if override_compat then
|
||||||
|
v.config.center.blueprint_compat = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "arctic",
|
key = "arctic",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
|
artist = "ghostlyfield",
|
||||||
cost = 10,
|
cost = 10,
|
||||||
rarity = 3,
|
rarity = 3,
|
||||||
config = {extra = {frozen = 1, non_frozen = 0, max_stack = 6, color = "DARK_EDITION"}},
|
config = {extra = {frozen = 1, non_frozen = 0, color = "DARK_EDITION"}},
|
||||||
attributes = {"retrigger", "editions"},
|
attributes = {"retrigger", "editions", "copying"},
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
blueprint_compat = true,
|
blueprint_compat = true,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
|
|
@ -555,9 +570,9 @@ joker {
|
||||||
calculate = function(_, card, context)
|
calculate = function(_, card, context)
|
||||||
local extra = card.ability.extra
|
local extra = card.ability.extra
|
||||||
|
|
||||||
if extra.max_stack and
|
if f(context.blueprint_copiers_stack)
|
||||||
context.blueprint_copiers_stack and
|
:where("config.center.key", card.config.center.key)
|
||||||
extra.max_stack < #context.blueprint_copiers_stack then
|
:any() then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -570,14 +585,15 @@ joker {
|
||||||
end
|
end
|
||||||
|
|
||||||
return SMODS.merge_effects(
|
return SMODS.merge_effects(
|
||||||
f(G.jokers.cards):where(is_frozen):where(function(v)
|
f(G)
|
||||||
return v.config.center.key ~= card.config.center.key
|
:where(getmetatable, CardArea)
|
||||||
end):map(function(v)
|
:flatmap("cards", ipairs)
|
||||||
return SMODS.blueprint_effect(card, v, context)
|
:where(is_frozen)
|
||||||
end):where(type, "table"):map(function(v)
|
:map(copy(card, context))
|
||||||
v.colour = G.C[extra.color]
|
:where(type, "table")
|
||||||
return v
|
:map(f.insert(G.C[extra.color], "colour"))
|
||||||
end):values():table()
|
:values()
|
||||||
|
:table()
|
||||||
)
|
)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
@ -585,8 +601,8 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "sapling",
|
key = "sapling",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
artist = "char",
|
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "ghostlyfield",
|
||||||
attributes = {"mult", "suit"},
|
attributes = {"mult", "suit"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
rarity = 1,
|
rarity = 1,
|
||||||
|
|
@ -719,13 +735,9 @@ joker {
|
||||||
{card = card, xmult = card.ability.extra.xmult} or nil
|
{card = card, xmult = card.ability.extra.xmult} or nil
|
||||||
end,
|
end,
|
||||||
crimson = function()
|
crimson = function()
|
||||||
local _ = G.jokers and f(G.jokers.cards, ipairs_reversed):where(is_frozen, false):each(function(v)
|
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 right = G.jokers.cards[v.rank + 1]
|
||||||
|
local debuffed_by_crimson = right and not right.debuff and right.config.center.key == "j_Roland_crimson"
|
||||||
local debuffed_by_crimson = right and
|
|
||||||
not right.debuff and
|
|
||||||
right.config.center.key == "j_Roland_crimson" and
|
|
||||||
not ({j_mp_turtle_bean = true, j_turtle_bean = true})[v.config.center.key]
|
|
||||||
|
|
||||||
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
|
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
|
||||||
local debuff = not not v.debuff
|
local debuff = not not v.debuff
|
||||||
|
|
@ -827,6 +839,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "venerable",
|
key = "venerable",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
|
artist = "ghostlyfield",
|
||||||
defeated_blind = "bl_Roland_venerable_visage",
|
defeated_blind = "bl_Roland_venerable_visage",
|
||||||
config = {extra = {xdiscard = 3}},
|
config = {extra = {xdiscard = 3}},
|
||||||
pixel_size = {w = 68, h = 68},
|
pixel_size = {w = 68, h = 68},
|
||||||
|
|
@ -853,11 +866,45 @@ joker {
|
||||||
ease_discard(round_resets.discards - discards)
|
ease_discard(round_resets.discards - discards)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
joker {
|
||||||
|
key = "yard",
|
||||||
|
pronouns = "he_him",
|
||||||
|
artist = "ghostlyfield",
|
||||||
|
config = {extra = {dollars = 3}},
|
||||||
|
attributes = {"economy"},
|
||||||
|
cost = 6,
|
||||||
|
rarity = 1,
|
||||||
|
unlocked = true,
|
||||||
|
discovered = true,
|
||||||
|
eternal_compat = true,
|
||||||
|
blueprint_compat = true,
|
||||||
|
perishable_compat = true,
|
||||||
|
check_for_unlock = function()
|
||||||
|
return not not f.indices "challenge_progress.completed.c_Roland_Spring_Cleaning" (G.PROFILES[G.SETTINGS.profile])
|
||||||
|
end,
|
||||||
|
locked_loc_vars = function()
|
||||||
|
return {vars = {localize("c_Roland_Spring_Cleaning", "challenge_names")}}
|
||||||
|
end,
|
||||||
|
loc_vars = function(_, _, card)
|
||||||
|
return {vars = {card.ability.extra.dollars}}
|
||||||
|
end,
|
||||||
|
calculate = function(_, card, c)
|
||||||
|
local ret = (c.forcetrigger or c.playing_card_added or c.remove_playing_cards) and
|
||||||
|
{dollars = card.ability.extra.dollars * #(c.cards or c.removed or {c.forcetrigger})} or nil
|
||||||
|
|
||||||
|
if ret and (G.GAME or {}).challenge == "c_Roland_Spring_Cleaning" then
|
||||||
|
G.GAME.dollars = G.GAME.dollars + ret.dollars
|
||||||
|
else
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "bulldozer",
|
key = "bulldozer",
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "ghostlyfield",
|
||||||
attributes = {"xmult"},
|
attributes = {"xmult"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
|
|
@ -920,8 +967,8 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "nilly",
|
key = "nilly",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
artist = "ghostlyfield",
|
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "ghostlyfield",
|
||||||
config = {extra = {flipped = false}},
|
config = {extra = {flipped = false}},
|
||||||
attributes = {"xmult", "bakery_double_sided"},
|
attributes = {"xmult", "bakery_double_sided"},
|
||||||
cost = 0,
|
cost = 0,
|
||||||
|
|
@ -957,6 +1004,7 @@ joker {
|
||||||
key = "martingale",
|
key = "martingale",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "ghostlyfield",
|
||||||
config = {extra = {odds = 2}},
|
config = {extra = {odds = 2}},
|
||||||
attributes = {"xmult", "chance"},
|
attributes = {"xmult", "chance"},
|
||||||
cost = 8,
|
cost = 8,
|
||||||
|
|
@ -1020,6 +1068,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "idle",
|
key = "idle",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
|
artist = "ghostlyfield",
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
Roland_idle_capacity = 6,
|
Roland_idle_capacity = 6,
|
||||||
cost = G.P_CENTERS.j_idol.cost,
|
cost = G.P_CENTERS.j_idol.cost,
|
||||||
|
|
@ -1096,6 +1145,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "suitable",
|
key = "suitable",
|
||||||
pronouns = "she_they",
|
pronouns = "she_they",
|
||||||
|
artist = "ghostlyfield",
|
||||||
attributes = {"suit", "passive", "hearts", "diamonds", "spades", "clubs"},
|
attributes = {"suit", "passive", "hearts", "diamonds", "spades", "clubs"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
|
|
@ -1148,8 +1198,8 @@ end
|
||||||
joker {
|
joker {
|
||||||
key = "artemis",
|
key = "artemis",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
artist = "hamester",
|
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "hamester",
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
config = {extra = {
|
config = {extra = {
|
||||||
|
|
@ -1215,6 +1265,7 @@ joker {
|
||||||
key = "excalibur",
|
key = "excalibur",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
idea = "redstoad",
|
idea = "redstoad",
|
||||||
|
artist = "ghostlyfield",
|
||||||
cost = 8,
|
cost = 8,
|
||||||
rarity = 3,
|
rarity = 3,
|
||||||
config = {extra = {
|
config = {extra = {
|
||||||
|
|
@ -1225,7 +1276,7 @@ joker {
|
||||||
}},
|
}},
|
||||||
attributes = {"xmult", "enhancements", "bakery_double_sided"},
|
attributes = {"xmult", "enhancements", "bakery_double_sided"},
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
blueprint_compat = false,
|
blueprint_compat = true,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
loc_vars = function(_, info_queue, card)
|
loc_vars = function(_, info_queue, card)
|
||||||
local extra = card.ability.extra
|
local extra = card.ability.extra
|
||||||
|
|
@ -1286,7 +1337,7 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "oops",
|
key = "oops",
|
||||||
pronouns = "she_they",
|
pronouns = "she_they",
|
||||||
artist = "char",
|
artist = "ghostlyfield",
|
||||||
cost = 7,
|
cost = 7,
|
||||||
rarity = 3,
|
rarity = 3,
|
||||||
config = {extra = {probability = 1, probability_mult = 2, reset = 1}},
|
config = {extra = {probability = 1, probability_mult = 2, reset = 1}},
|
||||||
|
|
@ -1320,15 +1371,3 @@ joker {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
q {
|
|
||||||
blocking = false,
|
|
||||||
no_delete = true,
|
|
||||||
func = function()
|
|
||||||
if not Bakery_API then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(Bakery_API.econ_only_items, "j_Roland_artemis")
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,42 @@
|
||||||
local f = {}
|
local f = {}
|
||||||
|
|
||||||
if not f then
|
if not f then
|
||||||
|
---@generic T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R
|
||||||
|
---@param self F
|
||||||
|
---@param first? T1
|
||||||
|
---@param second? T2
|
||||||
|
---@param third? T3
|
||||||
|
---@param fourth? T4
|
||||||
|
---@param fifth? T5
|
||||||
|
---@param sixth? T6
|
||||||
|
---@param seventh? T7
|
||||||
|
---@param eighth? T8
|
||||||
|
---@param ninth? T9
|
||||||
|
---@param tenth? T10
|
||||||
|
---@return fun(v: fun(first: T1, second: T2, third: T3, fourth: T4, fifth: T5, sixth: T6, seventh: T7, eighth: T8, ninth: T9, tenth: T10): R): R
|
||||||
|
---@nodiscard
|
||||||
|
function f:call(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth)
|
||||||
|
error {first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R
|
||||||
|
---@param self string
|
||||||
|
---@param first? T1
|
||||||
|
---@param second? T2
|
||||||
|
---@param third? T3
|
||||||
|
---@param fourth? T4
|
||||||
|
---@param fifth? T5
|
||||||
|
---@param sixth? T6
|
||||||
|
---@param seventh? T7
|
||||||
|
---@param eighth? T8
|
||||||
|
---@param ninth? T9
|
||||||
|
---@param tenth? T10
|
||||||
|
---@return fun(v: {[string]: fun(self: self, first: T1, second: T2, third: T3, fourth: T4, fifth: T5, sixth: T6, seventh: T7, eighth: T8, ninth: T9, tenth: T10): R}): R
|
||||||
|
---@nodiscard
|
||||||
|
function f.call(self, first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth)
|
||||||
|
error {self, first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth}
|
||||||
|
end
|
||||||
|
|
||||||
---@generic I, O
|
---@generic I, O
|
||||||
---@param first integer|string|fun(v: I): O
|
---@param first integer|string|fun(v: I): O
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
|
@ -98,6 +134,96 @@ if not f then
|
||||||
error(all)
|
error(all)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@generic I, O
|
||||||
|
---@param first integer|string|fun(v: I): O
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(first)
|
||||||
|
error {first}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T, O
|
||||||
|
---@param first integer|string|fun(v: T): O
|
||||||
|
---@param second integer|string|fun(v: I): T
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(first, second)
|
||||||
|
error {first, second}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T1, T2, O
|
||||||
|
---@param first integer|string|fun(v: T2): O
|
||||||
|
---@param second integer|string|fun(v: T1): T2
|
||||||
|
---@param third integer|string|fun(v: I): T1
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(first, second, third)
|
||||||
|
error {first, second, third}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T1, T2, T3, O
|
||||||
|
---@param first integer|string|fun(v: T3): O
|
||||||
|
---@param second integer|string|fun(v: T2): T3
|
||||||
|
---@param third integer|string|fun(v: T1): T2
|
||||||
|
---@param fourth integer|string|fun(v: I): T1
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(first, second, third, fourth)
|
||||||
|
error {first, second, third, fourth}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T1, T2, T3, T4, O
|
||||||
|
---@param first integer|string|fun(v: T4): O
|
||||||
|
---@param second integer|string|fun(v: T3): T4
|
||||||
|
---@param third integer|string|fun(v: T2): T3
|
||||||
|
---@param fourth integer|string|fun(v: T1): T2
|
||||||
|
---@param fifth integer|string|fun(v: I): T1
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(first, second, third, fourth, fifth)
|
||||||
|
error {first, second, third, fourth, fifth}
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, O
|
||||||
|
---@param all { [1]: (integer|string|fun(v: I): O) }
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(all)
|
||||||
|
error(all)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T, O
|
||||||
|
---@param all { [1]: (integer|string|fun(v: T): O), [2]: (integer|string|fun(v: I): T) }
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(all)
|
||||||
|
error(all)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T1, T2, O
|
||||||
|
---@param all { [1]: (integer|string|fun(v: T2): O), [2]: (integer|string|fun(v: T1): T2), [3]: (integer|string|fun(v: I): T1) }
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(all)
|
||||||
|
error(all)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T1, T2, T3, O
|
||||||
|
---@param all { [1]: (integer|string|fun(v: T3): O), [2]: (integer|string|fun(v: T2): T3), [3]: (integer|string|fun(v: T1): T2), [4]: (integer|string|fun(v: I): T1) }
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(all)
|
||||||
|
error(all)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@generic I, T1, T2, T3, T4, O
|
||||||
|
---@param all { [1]: (integer|string|fun(v: T4): O), [2]: (integer|string|fun(v: T3): T4), [3]: (integer|string|fun(v: T2): T3), [4]: (integer|string|fun(v: T1): T2), [4]: (integer|string|fun(v: I): T1) }
|
||||||
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
|
function f.compose(all)
|
||||||
|
error(all)
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F | { [K]: V }
|
---@param self F | { [K]: V }
|
||||||
---@return K?, V?
|
---@return K?, V?
|
||||||
|
|
@ -135,7 +261,7 @@ end
|
||||||
---@return V
|
---@return V
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
local function autopairs(tbl, fpairs)
|
local function autopairs(tbl, fpairs)
|
||||||
return (fpairs or (tbl[#tbl] and ipairs or pairs))(tbl)
|
return (fpairs or (tbl[1] and ipairs or pairs))(tbl)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Always returns nil.
|
--- Always returns nil.
|
||||||
|
|
@ -169,7 +295,7 @@ end
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param value T
|
---@param value T
|
||||||
---@return fun(T): boolean
|
---@return fun(v: T): boolean
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f.eq(value)
|
function f.eq(value)
|
||||||
return function(v)
|
return function(v)
|
||||||
|
|
@ -240,11 +366,11 @@ end
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f.indices(v)
|
function f.indices(v)
|
||||||
return function(x)
|
return function(x)
|
||||||
if type(x) ~= "table" then
|
|
||||||
return x
|
|
||||||
end
|
|
||||||
|
|
||||||
for i in v:gmatch "[^.]+" do
|
for i in v:gmatch "[^.]+" do
|
||||||
|
if type(x) ~= "table" then
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
|
||||||
x = x[i]
|
x = x[i]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -252,6 +378,36 @@ function f.indices(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@generic K, V
|
||||||
|
---@param v V
|
||||||
|
---@param k K
|
||||||
|
---@return fun(x: { [K]: V }): { [K]: V }
|
||||||
|
---@nodiscard
|
||||||
|
function f.insert(v, k)
|
||||||
|
return function(x)
|
||||||
|
if type(x) == "table" then
|
||||||
|
x[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
return x
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
---@param any any
|
---@param any any
|
||||||
---@return boolean
|
---@return boolean
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
|
|
@ -259,10 +415,24 @@ function f.isf(any)
|
||||||
return type(any) == "table" and any.from == f.from and any.new == f.new
|
return type(any) == "table" and any.from == f.from and any.new == f.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local unpack = table.unpack or unpack
|
||||||
|
|
||||||
|
f[true and "call"] = function(self, ...)
|
||||||
|
local args = {...}
|
||||||
|
|
||||||
|
return type(self) == "string" and function(v)
|
||||||
|
return v[self](v, unpack(args))
|
||||||
|
end or function(v)
|
||||||
|
return v(unpack(args))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
f[true and "chain"] = function(...)
|
f[true and "chain"] = function(...)
|
||||||
local ret
|
local ret
|
||||||
|
|
||||||
for _, v in ipairs {...} do
|
for _, v in ipairs {...} do
|
||||||
|
v = f.isf(v) and v:table() or v
|
||||||
|
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
for _, vv in ipairs(v) do
|
for _, vv in ipairs(v) do
|
||||||
local copy = ret
|
local copy = ret
|
||||||
|
|
@ -285,6 +455,10 @@ f[true and "chain"] = function(...)
|
||||||
return ret or f.noop
|
return ret or f.noop
|
||||||
end
|
end
|
||||||
|
|
||||||
|
f[true and "compose"] = function(...)
|
||||||
|
return f.chain(f.from({...}, f.revpairs):values())
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param fnext? fun(): K?, V?
|
---@param fnext? fun(): K?, V?
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
|
|
@ -295,7 +469,9 @@ function f.new(fnext)
|
||||||
all = f.all,
|
all = f.all,
|
||||||
any = f.any,
|
any = f.any,
|
||||||
arg = f.arg,
|
arg = f.arg,
|
||||||
|
call = f.call,
|
||||||
chain = f.chain,
|
chain = f.chain,
|
||||||
|
compose = f.compose,
|
||||||
concat = f.concat,
|
concat = f.concat,
|
||||||
const = f.const,
|
const = f.const,
|
||||||
count = f.count,
|
count = f.count,
|
||||||
|
|
@ -310,6 +486,7 @@ function f.new(fnext)
|
||||||
index = f.index,
|
index = f.index,
|
||||||
index_into = f.index_into,
|
index_into = f.index_into,
|
||||||
indices = f.indices,
|
indices = f.indices,
|
||||||
|
insert = f.insert,
|
||||||
isf = f.isf,
|
isf = f.isf,
|
||||||
keys = f.keys,
|
keys = f.keys,
|
||||||
map = f.map,
|
map = f.map,
|
||||||
|
|
@ -319,6 +496,8 @@ function f.new(fnext)
|
||||||
nq = f.nq,
|
nq = f.nq,
|
||||||
peek = f.peek,
|
peek = f.peek,
|
||||||
pun = f.pun,
|
pun = f.pun,
|
||||||
|
rev = f.rev,
|
||||||
|
revpairs = f.revpairs,
|
||||||
skip = f.skip,
|
skip = f.skip,
|
||||||
slice = f.slice,
|
slice = f.slice,
|
||||||
string = f.string,
|
string = f.string,
|
||||||
|
|
@ -377,10 +556,10 @@ function f.from(iter, fpairs, step)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
else
|
else
|
||||||
local next, context, k, v = autopairs(iter, type(fpairs) == "function" and fpairs or nil)
|
local next, tbl, k, v = autopairs(iter, type(fpairs) == "function" and fpairs or nil)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
k, v = next(context, k)
|
k, v = next(tbl, k)
|
||||||
return k, v
|
return k, v
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
@ -392,12 +571,14 @@ end
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:concat(...)
|
function f:concat(...)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
local fsi = 0
|
local fsi = 0
|
||||||
local fs = {...}
|
local fs = {...}
|
||||||
local sum, last = 0, 0
|
local sum, last = 0, 0
|
||||||
|
|
||||||
for i = 1, #fs do
|
for i = 1, #fs do
|
||||||
fs[i] = f.isf(fs[i]) and fs[i] or f.from(fs[i])
|
local s = fs[i]
|
||||||
|
fs[i] = f.isf(s) and s or f.from(s)
|
||||||
end
|
end
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -431,6 +612,7 @@ end
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:peek(func)
|
function f:peek(func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -450,6 +632,7 @@ end
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U }
|
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:map(func)
|
function f:map(func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -469,11 +652,14 @@ end
|
||||||
---@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: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)): F|{ [K]: U }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:flatmap(func, fpairs)
|
function f:flatmap(func, fpairs)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
-- local i = 0
|
-- local i = 0
|
||||||
local vt, vk, vv, vp
|
local vt, vk, vp
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
local vv
|
||||||
|
|
||||||
if vk then
|
if vk then
|
||||||
vk, vv = vp(vt, vk)
|
vk, vv = vp(vt, vk)
|
||||||
|
|
||||||
|
|
@ -519,6 +705,7 @@ end
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string, is?: any): F|{ [K]: V }
|
---@overload fun(self: F|{ [K]: V }, func: string, is?: any): F|{ [K]: V }
|
||||||
function f:where(func, is)
|
function f:where(func, is)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -551,6 +738,7 @@ end
|
||||||
---@return F|{ [integer]: K }
|
---@return F|{ [integer]: K }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:keys()
|
function f:keys()
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
local i = 0
|
local i = 0
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -568,6 +756,7 @@ end
|
||||||
---@return F|{ [integer]: V }
|
---@return F|{ [integer]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:values()
|
function f:values()
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
local i = 0
|
local i = 0
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -585,6 +774,8 @@ end
|
||||||
---@return F|{ [V]: K }
|
---@return F|{ [V]: K }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:swap()
|
function f:swap()
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
local k, v = self:next()
|
local k, v = self:next()
|
||||||
|
|
||||||
|
|
@ -594,6 +785,28 @@ function f:swap()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@generic K, V
|
||||||
|
---@param self F|{ [K]: V }
|
||||||
|
---@return F|{ [K]: V }
|
||||||
|
---@nodiscard
|
||||||
|
function f:rev()
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
|
local t, p, k
|
||||||
|
|
||||||
|
return f.new(function()
|
||||||
|
if not t then
|
||||||
|
p, t = f.revpairs(self:table())
|
||||||
|
end
|
||||||
|
|
||||||
|
local v
|
||||||
|
k, v = p(t, k)
|
||||||
|
|
||||||
|
if k ~= nil then
|
||||||
|
return k, v
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param skip? integer
|
---@param skip? integer
|
||||||
|
|
@ -601,6 +814,8 @@ end
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:slice(skip, take)
|
function f:slice(skip, take)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
|
|
||||||
if (not skip or skip <= 0) and not take then
|
if (not skip or skip <= 0) and not take then
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
@ -632,6 +847,7 @@ end
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:skip(n)
|
function f:skip(n)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
return self:slice(n)
|
return self:slice(n)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -641,6 +857,7 @@ end
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:take(n)
|
function f:take(n)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
return self:slice(0, n)
|
return self:slice(0, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -652,6 +869,7 @@ end
|
||||||
---@overload fun(self: F|{ [K]: V }, seed: fun(a: A, v: V, k: K): A): A
|
---@overload fun(self: F|{ [K]: V }, seed: fun(a: A, v: V, k: K): A): A
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:fold(seed, func)
|
function f:fold(seed, func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
local k, v
|
local k, v
|
||||||
|
|
||||||
if not func then
|
if not func then
|
||||||
|
|
@ -681,6 +899,7 @@ end
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:any(func)
|
function f:any(func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
for k, v in self.next do
|
for k, v in self.next do
|
||||||
|
|
@ -699,6 +918,7 @@ end
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:all(func)
|
function f:all(func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
for k, v in self.next do
|
for k, v in self.next do
|
||||||
|
|
@ -717,8 +937,9 @@ end
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:count(func)
|
function f:count(func)
|
||||||
local ret = 0
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
local ret = 0
|
||||||
|
|
||||||
for k, v in self.next do
|
for k, v in self.next do
|
||||||
if not func or func(v, k) then
|
if not func or func(v, k) then
|
||||||
|
|
@ -733,15 +954,16 @@ end
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param other { [K]: V }
|
---@param other { [K]: V }
|
||||||
---@param func? fun(v: V, k: K): any
|
---@param func? fun(v: V, k: K): any
|
||||||
---@return K?
|
---@return K?, V?
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:diff(other, func)
|
function f:diff(other, func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
for k, v in self.next do
|
for k, v in self.next do
|
||||||
if (not func or func(v, k)) and other[k] ~= v then
|
if (not func or func(v, k)) and other[k] ~= v then
|
||||||
return k
|
return k, v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -760,6 +982,7 @@ end
|
||||||
---@return string
|
---@return string
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:string()
|
function f:string()
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
local k, v = self:next()
|
local k, v = self:next()
|
||||||
|
|
||||||
if k == nil then
|
if k == nil then
|
||||||
|
|
@ -784,6 +1007,7 @@ end
|
||||||
---@return { [K]: V }
|
---@return { [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
function f:table()
|
function f:table()
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
local ret = {}
|
local ret = {}
|
||||||
|
|
||||||
for k, v in self.next do
|
for k, v in self.next do
|
||||||
|
|
@ -797,6 +1021,8 @@ end
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func? fun(v: V, k: K): nil
|
---@param func? fun(v: V, k: K): nil
|
||||||
function f:each(func)
|
function f:each(func)
|
||||||
|
self = f.isf(self) and self or f.from(self)
|
||||||
|
|
||||||
for k, v in self.next do
|
for k, v in self.next do
|
||||||
if func then
|
if func then
|
||||||
func(v, k)
|
func(v, k)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@ CardSleeves.Sleeve = CardSleeves.Sleeve
|
||||||
--- @type {aliases: { [string]: [string] }}
|
--- @type {aliases: { [string]: [string] }}
|
||||||
Cryptid = Cryptid
|
Cryptid = Cryptid
|
||||||
|
|
||||||
|
---@return Card
|
||||||
|
function copy_card(...)
|
||||||
|
error(...)
|
||||||
|
end
|
||||||
|
|
||||||
--- @type fun(area: CardArea, ...: ...): Card
|
--- @type fun(area: CardArea, ...: ...): Card
|
||||||
create_card_for_shop = create_card_for_shop
|
create_card_for_shop = create_card_for_shop
|
||||||
|
|
||||||
|
|
@ -40,11 +45,21 @@ G.Bakery_charm_area.cards[1].ability.extra = G.Bakery_charm_area.cards[1].abilit
|
||||||
---@type Card[]
|
---@type Card[]
|
||||||
G.playing_cards = G.playing_cards
|
G.playing_cards = G.playing_cards
|
||||||
|
|
||||||
SMODS.Mods.Roland.config = require "config"
|
|
||||||
|
|
||||||
---@type userdata|{getWidth: fun(self: self): number}
|
---@type userdata|{getWidth: fun(self: self): number}
|
||||||
SMODS.Atlas.image_data = SMODS.Atlas.image_data
|
SMODS.Atlas.image_data = SMODS.Atlas.image_data
|
||||||
|
|
||||||
|
---@param context CalcContext|table|{hand_drawn: true, other_drawn: true}
|
||||||
|
---@param return_table? table
|
||||||
|
---@return table?
|
||||||
|
function SMODS.calculate_context(context, return_table)
|
||||||
|
error {context, return_table}
|
||||||
|
end
|
||||||
|
|
||||||
|
SMODS.Mods.Roland.config = require "config"
|
||||||
|
|
||||||
|
---@type (fun(rem: number): number|table)[]
|
||||||
|
SMODS.Mods.Roland.harsh_ante_scaling = SMODS.Mods.Roland.harsh_ante_scaling
|
||||||
|
|
||||||
--- @type table
|
--- @type table
|
||||||
Talisman = Talisman
|
Talisman = Talisman
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,26 @@ local function add(v)
|
||||||
return xop
|
return xop
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if G.P_BLINDS[v] then
|
||||||
|
if G.STATE ~= G.STATES.MENU then
|
||||||
|
G.from_boss_tag = true
|
||||||
|
G.GAME.perscribed_bosses = G.GAME.perscribed_bosses or {}
|
||||||
|
G.GAME.perscribed_bosses[G.GAME.round_resets.ante] = v
|
||||||
|
G.FUNCS.reroll_boss()
|
||||||
|
end
|
||||||
|
|
||||||
|
return G.P_BLINDS[v]
|
||||||
|
end
|
||||||
|
|
||||||
if not G.P_TAGS[v] then
|
if not G.P_TAGS[v] then
|
||||||
return SMODS.add_card {no_edition = true, key = v}
|
return SMODS.add_card {
|
||||||
|
no_edition = true,
|
||||||
|
key = v,
|
||||||
|
area = G.P_CENTERS[v] and
|
||||||
|
(({Default = true, Enhanced = true})[G.P_CENTERS[v].set] and G.hand or
|
||||||
|
G.P_CENTERS[v].set == "Booster" and G.shop_booster or
|
||||||
|
G.P_CENTERS[v].set == "Voucher" and G.shop_vouchers) or nil,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local tag = Tag(v)
|
local tag = Tag(v)
|
||||||
|
|
@ -43,7 +61,9 @@ local function find(it)
|
||||||
end
|
end
|
||||||
|
|
||||||
local match = simplify(it)
|
local match = simplify(it)
|
||||||
local pool = f(G.P_CENTER_POOLS):any(f.chain(f.arg(2), simplify, f.eq(match)))
|
|
||||||
|
local pool = match == "Blind" and G.P_BLINDS or
|
||||||
|
f(G.P_CENTER_POOLS):any(f.chain(f.arg(2), simplify, f.eq(match)))
|
||||||
|
|
||||||
if type(pool) == "table" and next(pool) then
|
if type(pool) == "table" and next(pool) then
|
||||||
return pseudorandom_element(pool, pseudoseed "Roland_c").key
|
return pseudorandom_element(pool, pseudoseed "Roland_c").key
|
||||||
|
|
@ -56,9 +76,9 @@ local function find(it)
|
||||||
return f(G.localization.descriptions)
|
return f(G.localization.descriptions)
|
||||||
:flatmap(flatten)
|
:flatmap(flatten)
|
||||||
:where(type, "table")
|
:where(type, "table")
|
||||||
:where(f.chain(f.arg(2), f.index_into(G.P_CENTERS), "config"))
|
|
||||||
:where(function(v, k)
|
:where(function(v, k)
|
||||||
return match == simplify(k) or match == simplify(v.name)
|
return ((G.P_CENTERS[k] or {}).config or G.P_BLINDS[k]) and
|
||||||
|
(match == simplify(k) or match == simplify(v.name))
|
||||||
end)
|
end)
|
||||||
:keys()
|
:keys()
|
||||||
:any()
|
:any()
|
||||||
|
|
|
||||||
130
src/main.lua
|
|
@ -1,4 +1,6 @@
|
||||||
local qol = assert(SMODS.load_file "src/lib/shared.lua")() or require "lib.shared"
|
local qol = assert(SMODS.load_file "src/lib/shared.lua")() or require "lib.shared"
|
||||||
|
local animated = SMODS.current_mod.config.animated_icon
|
||||||
|
SMODS.current_mod.qol = qol
|
||||||
local f, q = qol[1], qol[2]
|
local f, q = qol[1], qol[2]
|
||||||
|
|
||||||
q {
|
q {
|
||||||
|
|
@ -13,88 +15,46 @@ q {
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Special shoutout to all contributors. <3
|
f(assert(SMODS.load_file("src/credits.lua", "Roland"))() or require "credits"):each(function(v, k)
|
||||||
local credits = {
|
|
||||||
aster = {
|
|
||||||
name = "asterSSH",
|
|
||||||
fg = HEX "f8f8f2ff",
|
|
||||||
bg = HEX "bd93f9ff",
|
|
||||||
},
|
|
||||||
bakersdozenbagels = {
|
|
||||||
name = "BakersDozenBagels",
|
|
||||||
fg = HEX "362708ff",
|
|
||||||
bg = HEX "edd198ff",
|
|
||||||
},
|
|
||||||
char = {
|
|
||||||
name = "char (@irregulester)",
|
|
||||||
fg = HEX "f8f8f2ff",
|
|
||||||
bg = HEX "ff79c6ff",
|
|
||||||
},
|
|
||||||
ghostlyfield = {
|
|
||||||
name = "ghostlyfield",
|
|
||||||
fg = HEX "ffffffff",
|
|
||||||
bg = HEX "b290e6ff",
|
|
||||||
},
|
|
||||||
hamester = {
|
|
||||||
name = "Hamester",
|
|
||||||
fg = HEX "ffffffff",
|
|
||||||
bg = HEX "ffa100ff",
|
|
||||||
},
|
|
||||||
redstoad = {
|
|
||||||
name = "RedsToad",
|
|
||||||
fg = HEX "ffffffff",
|
|
||||||
bg = HEX "da4044ff",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
f(credits):each(function(v, k)
|
|
||||||
contributors["Roland_" .. k] = v
|
contributors["Roland_" .. k] = v
|
||||||
-- G.ARGS.LOC_COLOURS["Bakery_credit_fg_Roland_" .. k] = v.fg
|
|
||||||
-- G.ARGS.LOC_COLOURS["Bakery_credit_bg_Roland_" .. k] = v.bg
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if not SMODS.Mods.DebugPlus or not SMODS.Mods.Roland.config.import_funky then
|
if SMODS.Mods.DebugPlus and SMODS.Mods.Roland.config.import_funky then
|
||||||
return
|
_G.f, _G.q, _G.u, _G.c = unpack(qol)
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.f, _G.q, _G.u, _G.c = unpack(qol)
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
f {
|
f {"challenge", "spectral", "edition", "voucher", "tweaks", "blind", "charm", "joker", "tarot", "back", "seal", "tag"}
|
||||||
"challenge",
|
:each(function(v)
|
||||||
"spectral",
|
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
||||||
"edition",
|
end)
|
||||||
"tweaks",
|
|
||||||
"blind",
|
local _ = Balatest and f {"joker", "blind", "spectral"}:each(function(v)
|
||||||
"charm",
|
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
|
||||||
"joker",
|
|
||||||
"tarot",
|
|
||||||
"back",
|
|
||||||
"seal",
|
|
||||||
"tag",
|
|
||||||
"voucher",
|
|
||||||
}:each(function(v)
|
|
||||||
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if Balatest then
|
local function realign(tbl)
|
||||||
f {"joker", "blind", "spectral"}:each(function(v)
|
f(tbl):where(function(v, k)
|
||||||
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
|
if k == "align" and type(v) == "string" then
|
||||||
end)
|
tbl[k] = "tr"
|
||||||
|
end
|
||||||
|
|
||||||
|
return k ~= "nodes" and type(v) == "table"
|
||||||
|
end):each(realign)
|
||||||
|
|
||||||
|
return tbl
|
||||||
end
|
end
|
||||||
|
|
||||||
local function toggle(id)
|
local function toggle(id)
|
||||||
return create_toggle {
|
return realign(create_toggle {
|
||||||
label = localize {type = "variable", key = "b_Roland_" .. id},
|
label = localize {type = "variable", key = "b_Roland_" .. id},
|
||||||
ref_table = SMODS.Mods.Roland.config,
|
ref_table = SMODS.Mods.Roland.config,
|
||||||
ref_value = id,
|
ref_value = id,
|
||||||
scale = 1.5,
|
scale = 1.5,
|
||||||
}
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
local animated = SMODS.Mods.Roland.config.animated_icon
|
|
||||||
|
|
||||||
SMODS.Atlas {
|
SMODS.Atlas {
|
||||||
px = 256,
|
px = 256,
|
||||||
py = 256,
|
py = 256,
|
||||||
|
|
@ -108,24 +68,30 @@ SMODS.Atlas {
|
||||||
function SMODS.current_mod.config_tab()
|
function SMODS.current_mod.config_tab()
|
||||||
return {
|
return {
|
||||||
n = G.UIT.ROOT,
|
n = G.UIT.ROOT,
|
||||||
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.BLACK},
|
config = {minw = 1, minh = 1, align = "tr", padding = 0.1, colour = G.C.BLACK},
|
||||||
nodes = {{
|
nodes = {
|
||||||
n = G.UIT.C,
|
{
|
||||||
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.CLEAR},
|
n = G.UIT.C,
|
||||||
nodes = {
|
config = {minw = 1, minh = 1, align = "tr", padding = 0.1, colour = G.C.CLEAR},
|
||||||
toggle "animated_icon",
|
nodes = {
|
||||||
toggle "cool_phones",
|
toggle "animated_icon",
|
||||||
toggle "faster_planets",
|
toggle "cool_phones",
|
||||||
-- toggle "illusion_seal",
|
toggle "vitriol",
|
||||||
-- toggle "no_wild_debuff",
|
toggle "equinox_assist",
|
||||||
toggle "vitriol",
|
G.P_CENTERS.c_Bakery_Scribe and toggle "scribable_basket",
|
||||||
toggle "equinox_assist",
|
},
|
||||||
SMODS.Mods.DebugPlus and toggle "import_funky",
|
|
||||||
G.P_CENTERS.c_Bakery_Scribe and toggle "scribable_basket",
|
|
||||||
Talisman and toggle "harsh_ante_scaling",
|
|
||||||
},
|
},
|
||||||
}},
|
{
|
||||||
|
n = G.UIT.C,
|
||||||
|
config = {minw = 1, minh = 1, align = "tr", padding = 0.1, colour = G.C.CLEAR},
|
||||||
|
nodes = {
|
||||||
|
toggle "faster_planets",
|
||||||
|
toggle "illusion_seal",
|
||||||
|
toggle "no_wild_debuff",
|
||||||
|
SMODS.Mods.DebugPlus and toggle "import_funky",
|
||||||
|
Talisman and toggle "harsh_ante_scaling",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
SMODS.current_mod.qol = qol
|
|
||||||
|
|
|
||||||
|
|
@ -38,26 +38,32 @@ spectral {
|
||||||
return {vars = {card.ability.extra.amount}}
|
return {vars = {card.ability.extra.amount}}
|
||||||
end,
|
end,
|
||||||
can_use = function()
|
can_use = function()
|
||||||
return u() and #G.hand.cards > 0
|
return next(G.hand.cards) and u()
|
||||||
end,
|
end,
|
||||||
use = function(_, card, _)
|
use = function(_, card)
|
||||||
local cards = f(G.hand.cards):table()
|
local cards = f(G.hand.cards):table()
|
||||||
pseudoshuffle(cards, pseudoseed "RolandDual")
|
pseudoshuffle(cards, pseudoseed "RolandDual")
|
||||||
|
|
||||||
f(cards):take(card.ability.extra.amount):each(function(v)
|
f(cards):take(card.ability.extra.amount):each(function(v)
|
||||||
local seal
|
local seal = SMODS.poll_seal {
|
||||||
|
guaranteed = true,
|
||||||
|
options = f(G.P_SEALS):keys():where(f.nq "Roland_glass"):values():table(),
|
||||||
|
}
|
||||||
|
|
||||||
for _ = 1, 64 do
|
local _ = not card.Roland_immediate and q {
|
||||||
seal = SMODS.poll_seal {guaranteed = true}
|
delay = 0.5,
|
||||||
|
trigger = "after",
|
||||||
if seal ~= "Roland_glass" then
|
func = function()
|
||||||
break
|
v:set_seal(seal, nil, true)
|
||||||
end
|
end,
|
||||||
end
|
} or v:set_seal(seal, true, true)
|
||||||
|
|
||||||
v:set_seal(seal == "Roland_glass" and "Red" or seal)
|
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
|
bulk_use = function(self, card, area, copier, number)
|
||||||
|
card.Roland_immediate = true
|
||||||
|
f(number):map(f.const(self)):each(f.call("use", card, area, copier))
|
||||||
|
card.Roland_immediate = nil
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
spectral {
|
spectral {
|
||||||
|
|
@ -77,7 +83,7 @@ spectral {
|
||||||
delay = 0.4,
|
delay = 0.4,
|
||||||
func = function()
|
func = function()
|
||||||
card:juice_up(0.3, 0.5)
|
card:juice_up(0.3, 0.5)
|
||||||
play_sound("tarot1")
|
play_sound "tarot1"
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,9 +138,10 @@ spectral {
|
||||||
return {vars = {card.ability.extra.amount}}
|
return {vars = {card.ability.extra.amount}}
|
||||||
end,
|
end,
|
||||||
can_use = function(_, card)
|
can_use = function(_, card)
|
||||||
return u() and #Bakery_API.get_highlighted() == card.ability.extra.amount
|
local count = #Bakery_API.get_highlighted()
|
||||||
|
return u() and count > 0 and count <= card.ability.extra.amount
|
||||||
end,
|
end,
|
||||||
use = function(_, _, _)
|
use = function()
|
||||||
f(Bakery_API.get_highlighted()):each(function(v)
|
f(Bakery_API.get_highlighted()):each(function(v)
|
||||||
v:set_seal "Roland_glass"
|
v:set_seal "Roland_glass"
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
10
src/tag.lua
|
|
@ -60,8 +60,8 @@ SMODS.Tag {
|
||||||
pos = {x = 0, y = 0},
|
pos = {x = 0, y = 0},
|
||||||
config = {amount = 5},
|
config = {amount = 5},
|
||||||
loc_vars = function(self, info_queue, tag)
|
loc_vars = function(self, info_queue, tag)
|
||||||
info_queue[#info_queue + 1] = G.P_CENTERS.e_Roland_frozen
|
|
||||||
tag.ability = tag.ability or {}
|
tag.ability = tag.ability or {}
|
||||||
|
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||||
return {vars = {tag.ability.amount or self.config.amount}}
|
return {vars = {tag.ability.amount or self.config.amount}}
|
||||||
end,
|
end,
|
||||||
apply = function(self, tag, context)
|
apply = function(self, tag, context)
|
||||||
|
|
@ -73,9 +73,10 @@ SMODS.Tag {
|
||||||
end
|
end
|
||||||
|
|
||||||
if tag.triggered or
|
if tag.triggered or
|
||||||
(tag.ability.amount or self.config.amount) <= 0 or
|
not context.card or
|
||||||
((context.card or {}).edition or {}).Roland_frozen or
|
context.card.edition or
|
||||||
context.type ~= "Bakery_score_card" then
|
context.type ~= "Bakery_score_card" or
|
||||||
|
(tag.ability.amount or self.config.amount) <= 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -121,6 +122,7 @@ SMODS.Tag {
|
||||||
ab.total_rounds = ab.total_rounds or self.config.total_rounds
|
ab.total_rounds = ab.total_rounds or self.config.total_rounds
|
||||||
|
|
||||||
if tag.triggered or
|
if tag.triggered or
|
||||||
|
not G.jokers or
|
||||||
not next(G.jokers.cards) or
|
not next(G.jokers.cards) or
|
||||||
ab.invis_rounds < ab.total_rounds or
|
ab.invis_rounds < ab.total_rounds or
|
||||||
#G.jokers.cards + (modifiers.Roland_invisible or 0) >= G.jokers.config.card_limit then
|
#G.jokers.cards + (modifiers.Roland_invisible or 0) >= G.jokers.config.card_limit then
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,9 @@ q(SMODS.Consumable {
|
||||||
end
|
end
|
||||||
|
|
||||||
local highlighted = Bakery_API.get_highlighted()
|
local highlighted = Bakery_API.get_highlighted()
|
||||||
|
local count = #G.jokers.highlighted + #highlighted
|
||||||
|
|
||||||
return #G.jokers.highlighted + #highlighted == card.ability.extra.amount and
|
return count > 0 and count <= card.ability.extra.amount and
|
||||||
f(G.jokers.highlighted):concat(highlighted):all(function(v)
|
f(G.jokers.highlighted):concat(highlighted):all(function(v)
|
||||||
return not v.edition
|
return not v.edition
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,7 @@ Balatest.TestPlay {
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Balatest.wait_for_input()
|
Balatest.wait_for_input(G.STATES.ROUND_EVAL)
|
||||||
Balatest.wait()
|
|
||||||
end,
|
end,
|
||||||
assert = function()
|
assert = function()
|
||||||
Balatest.assert_chips(2720)
|
Balatest.assert_chips(2720)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ local orig_use_consumeable = Card.use_consumeable
|
||||||
function Card:use_consumeable(area, copier, ...)
|
function Card:use_consumeable(area, copier, ...)
|
||||||
if SMODS.Mods.Roland.config.faster_planets and self.ability.consumeable.hand_type then
|
if SMODS.Mods.Roland.config.faster_planets and self.ability.consumeable.hand_type then
|
||||||
set_consumeable_usage(self)
|
set_consumeable_usage(self)
|
||||||
level_up_hand(copier or self, self.ability.consumeable.hand_type, true)
|
level_up_hand(copier or self, self.ability.consumeable.hand_type, true, self.ability.qty or 1)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -110,21 +110,35 @@ local function no_harsh_ante_scaling()
|
||||||
return not Talisman or not SMODS.Mods.Roland.config.harsh_ante_scaling
|
return not Talisman or not SMODS.Mods.Roland.config.harsh_ante_scaling
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_blind_amount(ante, ...)
|
---@type (fun(rem: number): number|table)[]
|
||||||
local loop = 39
|
SMODS.current_mod.harsh_ante_scaling = {
|
||||||
|
function(rem)
|
||||||
|
return (Big.constants and Big.constants.TEN or Big:new {10}):pow(blind(rem + 1))
|
||||||
|
end,
|
||||||
|
function(rem)
|
||||||
|
return Big:new {1, rem + 2}
|
||||||
|
end,
|
||||||
|
function(rem)
|
||||||
|
return Big:new {1, 1, [rem + 2] = 1}
|
||||||
|
end,
|
||||||
|
function(rem)
|
||||||
|
return Big:new {1, 1, [blind(rem) + 2] = 1}
|
||||||
|
end,
|
||||||
|
function(rem)
|
||||||
|
return rem <= 1 and Big:new {1.7976931348623157e308, 1, [1.7975e308] = 1} or 1 / 0
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
if ante < loop or no_harsh_ante_scaling() then
|
function get_blind_amount(ante, ...)
|
||||||
|
local offset = 40
|
||||||
|
|
||||||
|
if ante < offset or no_harsh_ante_scaling() then
|
||||||
return orig_get_blind_amount(ante, ...)
|
return orig_get_blind_amount(ante, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (ante - 9) / 15 >= loop then
|
local loop = 10
|
||||||
return 1 / 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local rem = tonumber(blind((ante % loop) + 1))
|
return f(SMODS.Mods.Roland.harsh_ante_scaling, f.revpairs):any(function(_, k)
|
||||||
|
return (ante - offset) / loop + 1 >= k
|
||||||
return ante / 15 >= loop and Big:new(f(blind(ante - (loop * 15))):map(f.const(10)):table()) or
|
end)((ante - offset) % loop + 1)
|
||||||
(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
|
end
|
||||||
|
|
|
||||||