Compare commits
No commits in common. "main" and "2.9.29" have entirely different histories.
|
|
@ -33,7 +33,7 @@ table_separator_style = none
|
|||
trailing_table_separator = smart
|
||||
|
||||
# keep/remove/remove_table_only/remove_string_only
|
||||
call_arg_parentheses = remove
|
||||
call_arg_parentheses = keep
|
||||
|
||||
detect_end_of_line = false
|
||||
|
||||
|
|
|
|||
52
README.md
|
|
@ -1,52 +0,0 @@
|
|||
# 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: 13 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
|
@ -1,19 +1,8 @@
|
|||
#!/bin/sh
|
||||
cd "$(dirname "$0")"
|
||||
directory=$(dirname $(readlink -f "$0"))
|
||||
|
||||
for file in 2x/*.png; do
|
||||
for file in "$directory"/1x/*.png; do
|
||||
filename=$(basename "$file")
|
||||
if [ ! -f "1x/${filename}" ]; then
|
||||
echo "Removing deleted file ${file} from 2x"
|
||||
rm "2x/${filename}"
|
||||
fi
|
||||
done
|
||||
|
||||
for file in 1x/*.png; do
|
||||
filename=$(basename "$file")
|
||||
output_file="2x/${filename}"
|
||||
if [ ! -f "$output_file" ] || [ "$file" -nt "$output_file" ]; then
|
||||
echo "Updating changed file ${file} in 2x/"
|
||||
magick "$file" -filter point -resize 200% "$output_file"
|
||||
fi
|
||||
output_file="$directory/2x/${filename}"
|
||||
magick "$file" -filter point -resize 200% "$output_file"
|
||||
done
|
||||
|
|
|
|||
|
|
@ -6,21 +6,11 @@ return {
|
|||
text = {
|
||||
"{C:attention}Small{} and {C:attention}Big Blinds{} are",
|
||||
"replaced with {C:attention}Boss Blinds",
|
||||
"that are {C:dark_edition}debuffed thrice",
|
||||
"that are {C:dark_edition}debuffed twice",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
},
|
||||
b_Roland_dropship = {
|
||||
name = "Dropship Deck",
|
||||
text = {
|
||||
"{C:attention}Jokers {}are {C:money}free",
|
||||
"and {C:attention}Perishable",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
unlock = {"Have exclusively", "{C:attention}Perishable Jokers"},
|
||||
},
|
||||
b_Roland_swapper = {
|
||||
name = "Swapper Deck",
|
||||
text = {
|
||||
|
|
@ -30,18 +20,6 @@ return {
|
|||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
},
|
||||
b_Roland_wish = {
|
||||
name = "Wish Deck",
|
||||
text = {
|
||||
"Redeem a random {C:attention}Voucher",
|
||||
"after {C:attention}Small {}and {C:attention}Big Blinds",
|
||||
"{C:attention}Vouchers {}no longer",
|
||||
"appear in the shop",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
unlock = {"Discover all {C:attention}Vouchers"},
|
||||
},
|
||||
},
|
||||
BakeryCharm = {
|
||||
BakeryCharm_Roland_cocacola = {
|
||||
|
|
@ -160,7 +138,6 @@ return {
|
|||
"Moves before",
|
||||
"hand is played",
|
||||
},
|
||||
unlock = {"Defeat {C:attention}#1#"},
|
||||
},
|
||||
j_Roland_arctic = {
|
||||
name = "Arctic Circle",
|
||||
|
|
@ -187,9 +164,9 @@ return {
|
|||
j_Roland_bulldozer = {
|
||||
name = "Bulldozer",
|
||||
text = {
|
||||
"Give the {C:attention}Blind",
|
||||
"{C:attention}Base {}as {X:red,C:white}XMult",
|
||||
"{C:inactive}(Currently {X:red,C:white}X#1#{C:inactive} Mult)",
|
||||
"Give {X:red,C:white}XMult{} equal to",
|
||||
"the current {C:attention}Blind Size{C:attention}",
|
||||
"{C:inactive}(Currently {X:red,C:white}X#1#{C:inactive})",
|
||||
},
|
||||
},
|
||||
j_Roland_cold = {
|
||||
|
|
@ -207,7 +184,6 @@ return {
|
|||
"All other {C:attention}Jokers {}cannot",
|
||||
"be selected or dragged",
|
||||
},
|
||||
unlock = {"Defeat {C:blue}#1#"},
|
||||
},
|
||||
j_Roland_crimson = {
|
||||
name = "Crimson Heart",
|
||||
|
|
@ -216,7 +192,6 @@ return {
|
|||
"{C:red}Debuffs {C:attention}Joker",
|
||||
"to the left",
|
||||
},
|
||||
unlock = {"Defeat {C:red}#1#"},
|
||||
},
|
||||
j_Roland_domino = {
|
||||
name = "Domino",
|
||||
|
|
@ -288,8 +263,9 @@ return {
|
|||
j_Roland_misfortune = {
|
||||
name = "Misfortune Cookie",
|
||||
text = {
|
||||
"Cards created by",
|
||||
"{C:attention}Seals {}become {C:dark_edition}Negative",
|
||||
"{C:tarot}Tarot{} cards created",
|
||||
"by {C:tarot}Purple Seals",
|
||||
"become {C:dark_edition}Negative",
|
||||
},
|
||||
},
|
||||
j_Roland_monomino = {
|
||||
|
|
@ -335,14 +311,6 @@ return {
|
|||
name = "Phytoestrogens",
|
||||
text = {"{C:mult}+Chips{} Mult, {X:mult,C:white}X#1#{} Mult"},
|
||||
},
|
||||
j_Roland_polaris = {
|
||||
name = "Polaris",
|
||||
text = {
|
||||
"The {C:attention}first {}scored",
|
||||
"card each round",
|
||||
"becomes {C:dark_edition}Frozen",
|
||||
},
|
||||
},
|
||||
j_Roland_sapling = {
|
||||
name = "Sapling",
|
||||
text = {
|
||||
|
|
@ -398,7 +366,6 @@ return {
|
|||
"{C:red}Debuffs {}the {C:attention}first",
|
||||
"{C:attention}#2# {}scored cards",
|
||||
},
|
||||
unlock = {"Defeat {C:green}#1#"},
|
||||
},
|
||||
j_Roland_violet = {
|
||||
name = "Violet Vessel",
|
||||
|
|
@ -407,22 +374,18 @@ return {
|
|||
"but {X:mult,C:white}X#2#{} Mult",
|
||||
"{C:attention}before {}scoring",
|
||||
},
|
||||
unlock = {"Defeat {C:purple}#1#"},
|
||||
},
|
||||
j_Roland_venerable = {
|
||||
name = "Venerable Visage",
|
||||
text = {"{X:red,C:white}X#1#{} discards each round"},
|
||||
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",
|
||||
"card is {C:attention}removed",
|
||||
"from the deck",
|
||||
},
|
||||
unlock = {"Complete the", "{C:attention}#1#", "challenge"},
|
||||
},
|
||||
},
|
||||
Other = {
|
||||
|
|
@ -441,7 +404,7 @@ return {
|
|||
text = {
|
||||
"{C:attention}Small{} and {C:attention}Big Blinds{} are",
|
||||
"replaced with {C:attention}Boss Blinds",
|
||||
"that are {C:dark_edition}debuffed thrice",
|
||||
"that are {C:dark_edition}debuffed twice",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
|
|
@ -450,31 +413,11 @@ return {
|
|||
name = "Efflorescent Sleeve",
|
||||
text = {
|
||||
"{C:dark_edition}Debuff {X:dark_edition,C:white}#1#X<ante>{C:dark_edition} times",
|
||||
"{C:inactive}(Instead of thrice)",
|
||||
"{C:inactive}(Instead of twice)",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
},
|
||||
sleeve_Roland_dropship = {
|
||||
name = "Dropship Sleeve",
|
||||
text = {
|
||||
"{C:attention}Jokers {}are {C:money}free",
|
||||
"and {C:attention}Perishable",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
unlock = {"Have exclusively", "{C:attention}Perishable Jokers"},
|
||||
},
|
||||
sleeve_Roland_dropship_alt = {
|
||||
name = "Business Sleeve",
|
||||
text = {
|
||||
"{C:attention}Jokers {}are instead",
|
||||
"{C:dark_edition}Negative {}and {C:money}Rental",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
unlock = {"Have exclusively", "{C:attention}Perishable Jokers"},
|
||||
},
|
||||
sleeve_Roland_swapper = {
|
||||
name = "Swapper Sleeve",
|
||||
text = {
|
||||
|
|
@ -492,29 +435,6 @@ return {
|
|||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
},
|
||||
sleeve_Roland_wish = {
|
||||
name = "Wish Sleeve",
|
||||
text = {
|
||||
"A random {C:attention}voucher{} is",
|
||||
"{C:attention}redeemed {}at the end",
|
||||
"of {C:attention}Small {}and {C:attention}Big Blinds",
|
||||
"{C:attention}Vouchers {}no longer",
|
||||
"appear in the shop",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
unlock = {"Discover all {C:attention}Vouchers"},
|
||||
},
|
||||
sleeve_Roland_wish_alt = {
|
||||
name = "Miracle Sleeve",
|
||||
text = {
|
||||
"All {C:attention}vouchers",
|
||||
"start {C:attention}redeemed",
|
||||
"",
|
||||
"{C:Bakery_credit_fg_Roland_bakersdozenbagels,s:0.75}Art: BakersDozenBagels",
|
||||
},
|
||||
unlock = {"Discover all {C:attention}Vouchers"},
|
||||
},
|
||||
},
|
||||
Spectral = {
|
||||
c_Roland_afterimage = {
|
||||
|
|
@ -604,7 +524,6 @@ return {
|
|||
c_Roland_Jokerful = "Jokerful",
|
||||
c_Roland_Pastries = "Sweet Pastries",
|
||||
c_Roland_Spin_To_Win = "Spin to Win",
|
||||
c_Roland_Spring_Cleaning = "Spring Cleaning",
|
||||
},
|
||||
v_dictionary = {
|
||||
b_Roland_add = "ADD",
|
||||
|
|
@ -618,7 +537,6 @@ return {
|
|||
b_Roland_entering_shop = "Entering shop!",
|
||||
b_Roland_equinox_assist = "Assist: Only hide text (Equinox)",
|
||||
b_Roland_faster_planets = "Faster Planets",
|
||||
b_Roland_frozen = "Frozen!",
|
||||
b_Roland_full = "FULL",
|
||||
b_Roland_scribable_basket = "Scribable Basket (overpowered)",
|
||||
b_Roland_harsh_ante_scaling = "Harsh ante scaling (Ante 40+)",
|
||||
|
|
@ -652,7 +570,6 @@ return {
|
|||
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_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"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
83
lovely.toml
|
|
@ -65,19 +65,6 @@ position = "at"
|
|||
payload = "elseif G.GAME.blind_on_deck == 'Big' then"
|
||||
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
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "card.lua"
|
||||
|
|
@ -95,33 +82,10 @@ pattern = "local card = create_card('Tarot',G.consumeables, nil, nil, nil, nil,
|
|||
position = "after"
|
||||
times = 1
|
||||
payload = """if next(SMODS.find_card "j_Roland_misfortune") then
|
||||
card:set_edition("e_negative", true, true)
|
||||
card:set_edition "e_negative"
|
||||
end"""
|
||||
match_indent = true
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "card.lua"
|
||||
pattern = "if self.seal == 'Blue' and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit and not self.ability.extra_enhancement then"
|
||||
position = "at"
|
||||
payload = """if self.seal == 'Blue' and
|
||||
(next(SMODS.find_card "j_Roland_misfortune") or
|
||||
#G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit and
|
||||
not self.ability.extra_enhancement) then
|
||||
"""
|
||||
match_indent = true
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "card.lua"
|
||||
pattern = "local card = create_card(card_type,G.consumeables, nil, nil, nil, nil, _planet, 'blusl')"
|
||||
position = "after"
|
||||
payload = """if next(SMODS.find_card "j_Roland_misfortune") then
|
||||
card:set_edition("e_negative", true, true)
|
||||
end"""
|
||||
match_indent = true
|
||||
|
||||
# Frozen
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "card.lua"
|
||||
|
|
@ -166,49 +130,4 @@ target = "card.lua"
|
|||
pattern = "math\\.floor\\(\\(G\\.GAME\\.dollars \\+ \\(G\\.GAME\\.dollar_buffer or 0\\)\\)/self\\.ability\\.extra\\.dollars\\)"
|
||||
position = "at"
|
||||
payload = "SMODS.Mods.Roland.bootstraps_mult(self)"
|
||||
|
||||
[[patches]]
|
||||
[patches.regex]
|
||||
target = "card.lua"
|
||||
pattern = "if self\\.ability\\.h_size ~= 0 then"
|
||||
position = "at"
|
||||
payload = "if self.ability.h_size and self.ability.h_size ~= 0 then"
|
||||
|
||||
[[patches]]
|
||||
[patches.regex]
|
||||
target = "card.lua"
|
||||
pattern = "if self\\.ability\\.d_size > 0 then"
|
||||
position = "at"
|
||||
payload = "if self.ability.d_size and self.ability.d_size > 0 then"
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = '=[SMODS _ "src/utils.lua"]'
|
||||
pattern = "value = value + card.ability[property]"
|
||||
position = "at"
|
||||
payload = "value = value + (card.ability[property] or 0)"
|
||||
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",
|
||||
"name": "Roland",
|
||||
"prefix": "Roland",
|
||||
"version": "3.0.2",
|
||||
"version": "2.9.29",
|
||||
"badge_colour": "8BE9FD",
|
||||
"display_name": "Roland",
|
||||
"main_file": "src/main.lua",
|
||||
|
|
|
|||
1
refs/src
|
|
@ -1 +0,0 @@
|
|||
../../smods/src
|
||||
218
src/back.lua
|
|
@ -8,7 +8,7 @@ end
|
|||
local back = (function()
|
||||
local x = 0
|
||||
|
||||
---@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?}
|
||||
---@param tbl SMODS.Back|{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)
|
||||
local key = tbl.key
|
||||
local apply = tbl.apply
|
||||
|
|
@ -32,7 +32,6 @@ local back = (function()
|
|||
key = key,
|
||||
pos = tbl.pos,
|
||||
atlas = "sleeve",
|
||||
pronouns = tbl.pronouns,
|
||||
config = tbl.config and f(tbl.config):table() or nil,
|
||||
loc_vars = function(self, ...)
|
||||
local ret = tbl.loc_vars and tbl.loc_vars(self, ...) or {}
|
||||
|
|
@ -40,7 +39,7 @@ local back = (function()
|
|||
return ret
|
||||
end,
|
||||
apply = function(self, ...)
|
||||
return save((tbl.alt_apply and self:is_alt() and tbl.alt_apply or apply)(self, ...))
|
||||
return (tbl.alt_apply and self:is_alt() and tbl.alt_apply or apply)(self, ...)
|
||||
end,
|
||||
calculate = function(self, ...)
|
||||
return (tbl.alt_calculate and self:is_alt() and tbl.alt_calculate or calculate)(self, ...)
|
||||
|
|
@ -54,20 +53,13 @@ local back = (function()
|
|||
end
|
||||
end)()
|
||||
|
||||
local back_atlas = SMODS.Atlas {
|
||||
SMODS.Atlas {
|
||||
key = "back",
|
||||
path = "back.png",
|
||||
px = 71,
|
||||
py = 95,
|
||||
}
|
||||
|
||||
local extra_atlas = SMODS.Atlas {
|
||||
key = "back_extra",
|
||||
path = "backExtra.png",
|
||||
px = 71,
|
||||
py = 95,
|
||||
}
|
||||
|
||||
local _ = CardSleeves and SMODS.Atlas {
|
||||
key = "sleeve",
|
||||
path = "sleeve.png",
|
||||
|
|
@ -78,53 +70,49 @@ local _ = CardSleeves and SMODS.Atlas {
|
|||
back {
|
||||
key = "blossom",
|
||||
pronouns = "any_all",
|
||||
config = {extra = {alt_times = 9, times = 3}},
|
||||
attributes = {"passive", "boss_blind"},
|
||||
loc_vars = function(self)
|
||||
config = {extra = {alt_times = 4, times = 2}},
|
||||
attributes = {"boss_blind"},
|
||||
loc_vars = function(self, _, _)
|
||||
return {vars = {self.config.extra.alt_times}}
|
||||
end,
|
||||
apply = function()
|
||||
apply = function(_, _)
|
||||
G.GAME.modifiers.Roland_blossom_deck = true
|
||||
end,
|
||||
calculate = function(self, b, context)
|
||||
if not context.forcetrigger and not context.setting_blind then
|
||||
calculate = function(self, card, context)
|
||||
if not context.setting_blind then
|
||||
return
|
||||
end
|
||||
|
||||
local blinds = G.GAME.round_resets.blind_states
|
||||
|
||||
if not context.forcetrigger and
|
||||
blinds.Small ~= "Current" and
|
||||
blinds.Big ~= "Current" then
|
||||
if blinds.Small ~= "Current" and blinds.Big ~= "Current" then
|
||||
return
|
||||
end
|
||||
|
||||
local function debuff(times)
|
||||
return function()
|
||||
if times <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
G.GAME.blind:disable()
|
||||
SMODS.calculate_effect({message = localize "ph_boss_disabled"}, b)
|
||||
G.GAME.blind:wiggle()
|
||||
play_sound "timpani"
|
||||
q {func = debuff(times - 1)}
|
||||
end
|
||||
end
|
||||
|
||||
local times = self:is_alt() and
|
||||
local count = self:is_alt() and
|
||||
G.GAME.round_resets.ante * self.config.extra.alt_times or
|
||||
self.config.extra.times
|
||||
|
||||
debuff(times)()
|
||||
f(count):each(function(i)
|
||||
local _ = i == 1 and G.GAME.blind:disable()
|
||||
|
||||
q {
|
||||
delay = 0.4,
|
||||
func = function()
|
||||
local _ = i ~= 1 and G.GAME.blind:disable()
|
||||
SMODS.calculate_effect({message = localize "ph_boss_disabled"}, card)
|
||||
G.GAME.blind:wiggle()
|
||||
play_sound "timpani"
|
||||
end,
|
||||
}
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
back {
|
||||
key = "swapper",
|
||||
pronouns = "he_him",
|
||||
attributes = {"passive", "editions", "sell_value"},
|
||||
attributes = {"spectral", "tarot"},
|
||||
apply = function(self)
|
||||
local modifiers = G.GAME.modifiers
|
||||
modifiers.Roland_swapper_deck = true
|
||||
|
|
@ -133,92 +121,16 @@ back {
|
|||
calculate = f.noop,
|
||||
}
|
||||
|
||||
local b_dropship = back {
|
||||
key = "dropship",
|
||||
pronouns = "he_him",
|
||||
attributes = {"passive", "generation"},
|
||||
unlocked = false,
|
||||
discovered = false,
|
||||
check_for_unlock = function(_, args)
|
||||
return args ~= "Bakery_nothing" and
|
||||
G.jokers and
|
||||
next((G.jokers or {}).cards) and
|
||||
not not f(G.jokers.cards):map "ability":all "perishable"
|
||||
end,
|
||||
apply = function(self)
|
||||
G.GAME.modifiers.Roland_dropship = not self:is_alt()
|
||||
G.GAME.modifiers.Roland_dropship_alt = self:is_alt()
|
||||
end,
|
||||
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 orig_create_card = create_card
|
||||
|
||||
local function create_dropshipped_card(_type, ...)
|
||||
local ret = orig_create_card(_type, ...)
|
||||
local ok = _type == "Joker" and ret.ability
|
||||
|
||||
if ok and G.GAME.modifiers.Roland_dropship_alt then
|
||||
ret.ability.rental = true
|
||||
local _ = ret:set_edition({negative = true}, true, true)
|
||||
end
|
||||
|
||||
if ok and G.GAME.modifiers.Roland_dropship then
|
||||
ret.ability.perish_tally = 5
|
||||
ret.ability.perishable = true
|
||||
ret.cost, ret.sell_cost = 0, 0
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function create_card(_type, ...)
|
||||
if not G.GAME.modifiers.Roland_swapper_deck then
|
||||
return create_dropshipped_card(_type, ...)
|
||||
return orig_create_card(_type, ...)
|
||||
end
|
||||
|
||||
if not G.GAME.modifiers.Roland_alt_swapper_deck then
|
||||
return create_dropshipped_card(swapper[_type] or _type, ...)
|
||||
return orig_create_card(swapper[_type] or _type, ...)
|
||||
end
|
||||
|
||||
local type = f(SMODS.ConsumableTypes):keys():where(function(v)
|
||||
|
|
@ -226,79 +138,5 @@ function create_card(_type, ...)
|
|||
end):table()
|
||||
|
||||
local has_type = SMODS.ConsumableTypes[_type]
|
||||
return create_dropshipped_card(
|
||||
has_type and pseudorandom_element(type, pseudoseed "Roland_alt_swapper_deck") or _type, ...)
|
||||
end
|
||||
|
||||
local function redeem(key, fast)
|
||||
if fast then
|
||||
G.GAME.used_vouchers[key] = true
|
||||
end
|
||||
|
||||
q {
|
||||
delay = 1,
|
||||
func = function()
|
||||
local voucher = SMODS.create_card {key = key, set = "Voucher"}
|
||||
voucher.cost = 0
|
||||
voucher.T.x = (fast and pseudorandom(pseudoseed "Roland_wish_deck") + 0.5 or 1) * 9
|
||||
voucher.T.y = (fast and pseudorandom(pseudoseed "Roland_wish_deck") + 0.5 or 1) * 4.25
|
||||
voucher:start_materialize()
|
||||
|
||||
q {
|
||||
delay = 1,
|
||||
func = function()
|
||||
if fast then
|
||||
play_sound "card1"
|
||||
voucher:apply_to_run()
|
||||
voucher:juice_up(0.3, 0.5)
|
||||
else
|
||||
local state = G.STATE
|
||||
voucher:redeem()
|
||||
G.STATE = state
|
||||
end
|
||||
|
||||
q {
|
||||
delay = 1,
|
||||
func = function()
|
||||
voucher:start_dissolve()
|
||||
end,
|
||||
}
|
||||
end,
|
||||
}
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
back {
|
||||
key = "wish",
|
||||
pronouns = "he_him",
|
||||
attributes = {"passive", "generation"},
|
||||
unlocked = false,
|
||||
discovered = false,
|
||||
check_for_unlock = function(_, args)
|
||||
return args ~= "Bakery_nothing" and f(G.P_CENTER_POOLS.Voucher):all "discovered"
|
||||
end,
|
||||
apply = function(self)
|
||||
G.GAME.modifiers.Roland_no_voucher = true
|
||||
local _ = self:is_alt() and f(G.P_CENTER_POOLS.Voucher):map "key":each(redeem)
|
||||
end,
|
||||
calculate = function(_, _, context)
|
||||
local _ = (context.forcetrigger or
|
||||
context.blind_defeated and
|
||||
not context.repetition and
|
||||
not G.GAME.blind.boss) and
|
||||
f(G.P_CENTER_POOLS.Voucher)
|
||||
:map "key"
|
||||
:where(f.index_into(G.GAME.used_vouchers), false)
|
||||
:any() and
|
||||
redeem(get_next_voucher_key())
|
||||
end,
|
||||
}
|
||||
|
||||
local orig_add_voucher_to_shop = SMODS.add_voucher_to_shop
|
||||
|
||||
function SMODS.add_voucher_to_shop(...)
|
||||
if not G.GAME.modifiers.Roland_no_voucher then
|
||||
return orig_add_voucher_to_shop(...)
|
||||
end
|
||||
return orig_create_card(has_type and pseudorandom_element(type, pseudoseed "Roland_alt_swapper_deck") or _type, ...)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ blind {
|
|||
local _ = not b.disabled and context.drawing_cards and table.sort(G.deck.cards, sort_by_enhancement)
|
||||
end,
|
||||
in_pool = function()
|
||||
return G.playing_cards and not not f(G.playing_cards):any(has_enhancement)
|
||||
return G.playing_cards and f(G.playing_cards):any(has_enhancement)
|
||||
end,
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ blind {
|
|||
boss = {min = 6},
|
||||
boss_colour = HEX "bdaeccff",
|
||||
pronouns = "they_them",
|
||||
collection_loc_vars = function()
|
||||
collection_loc_vars = function(_)
|
||||
return {
|
||||
vars = {localize {
|
||||
type = "variable",
|
||||
|
|
@ -265,7 +265,7 @@ blind {
|
|||
}},
|
||||
}
|
||||
end,
|
||||
loc_vars = function()
|
||||
loc_vars = function(_)
|
||||
local _, name = common_rank()
|
||||
return {vars = {localize(name or "Ace", "ranks")}}
|
||||
end,
|
||||
|
|
@ -319,7 +319,7 @@ blind {
|
|||
dollars = 5,
|
||||
defeat = disable_improbable,
|
||||
disable = disable_improbable,
|
||||
set_blind = function()
|
||||
set_blind = function(_)
|
||||
G.GAME.modifiers.Roland_improbable = true
|
||||
end,
|
||||
}
|
||||
|
|
@ -332,47 +332,23 @@ if cry_prob then
|
|||
end
|
||||
end
|
||||
|
||||
local function call(key, value)
|
||||
local obj = G[key .. "obj"]
|
||||
local _ = type(obj) == "function" and obj(value)
|
||||
function SMODS.current_mod:calculate(context)
|
||||
local _ = type(G.calccontext) == "function" and G.calccontext(context)
|
||||
|
||||
if not G[key] or value == "Bakery_nothing" then
|
||||
return
|
||||
if type(G.calc) == "function" then
|
||||
G.calc = {G.calc}
|
||||
end
|
||||
|
||||
if type(G[key]) == "function" then
|
||||
G[key] = {G[key]}
|
||||
end
|
||||
if type(G.calc) == "table" then
|
||||
local str
|
||||
|
||||
if type(G[key]) ~= "table" then
|
||||
return
|
||||
end
|
||||
|
||||
local str
|
||||
|
||||
local _ = f(type(value) == "table" and value or {[value] = true})
|
||||
:keys()
|
||||
:map(f.index_into(G[key]))
|
||||
:where(type, "function")
|
||||
:each(function(v)
|
||||
str = str or type(value) == "table" and f(value):keys():string() or value
|
||||
f(context):keys():map(f.index_into(G.calc)):where(type, "function"):each(function(v)
|
||||
str = str or f(context):keys():string()
|
||||
v(str)
|
||||
end)
|
||||
|
||||
local _ = not str and
|
||||
type(G[key][1]) == "function" and
|
||||
G[key][1](type(value) == "table" and f(value):keys():string() or value)
|
||||
end
|
||||
|
||||
local orig_check_for_unlock = check_for_unlock
|
||||
|
||||
function check_for_unlock(args, ...)
|
||||
call("lock", type(args) == "table" and args.type or args)
|
||||
return orig_check_for_unlock(args, ...)
|
||||
end
|
||||
|
||||
function SMODS.current_mod:calculate(context)
|
||||
call("calc", 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"}
|
||||
|
|
@ -380,8 +356,8 @@ function SMODS.current_mod:calculate(context)
|
|||
:map(f.index_into(G.P_CENTERS))
|
||||
:where("config.extra.hand_type", context.scoring_name)
|
||||
:pun "SMODS.Voucher"
|
||||
:each(function(v)
|
||||
SMODS.smart_level_up_hand(nil, v.config.extra.hand_type, false, v.config.extra.amount)
|
||||
:each(function(v, _)
|
||||
SMODS.smart_level_up_hand(nil, v.config.extra.hand_type, nil, v.config.extra.amount)
|
||||
end)
|
||||
|
||||
local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities
|
||||
|
|
@ -404,7 +380,7 @@ function SMODS.current_mod:calculate(context)
|
|||
|
||||
local normal = orig.normal
|
||||
|
||||
G.GAME.probabilities = setmetatable({}, {
|
||||
local mt = {
|
||||
orig = orig,
|
||||
__index = function(_, k)
|
||||
return k == "normal" and 0 or orig[k]
|
||||
|
|
@ -412,7 +388,11 @@ function SMODS.current_mod:calculate(context)
|
|||
__newindex = function(_, k, v)
|
||||
orig[k] = (k == "normal" and v == 0) and normal or v
|
||||
end,
|
||||
})
|
||||
}
|
||||
|
||||
local proxy = {}
|
||||
setmetatable(proxy, mt)
|
||||
G.GAME.probabilities = proxy
|
||||
end
|
||||
|
||||
blind {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,19 @@
|
|||
local f, q = (... or require "lib.shared")[1], (... or require "lib.shared")[2]
|
||||
|
||||
---@return {banned_cards: {}, banned_tags: {}, banned_other: {}}
|
||||
local function bans()
|
||||
return {banned_cards = {}, banned_tags = {}, banned_other = {}}
|
||||
end
|
||||
|
||||
---@param tbl table
|
||||
---@return fun(v: SMODS.GameObject)
|
||||
local function adder(tbl)
|
||||
return function(v)
|
||||
table.insert(tbl, {id = v.key, type = "blind"})
|
||||
end
|
||||
end
|
||||
|
||||
---@param v SMODS.GameObject
|
||||
---@return boolean
|
||||
local function is_banned_from_pastry(v)
|
||||
return not ({Bakery = true, Roland = true})[(v.mod or {}).id]
|
||||
end
|
||||
|
||||
---@param v SMODS.Center
|
||||
---@return boolean
|
||||
local function is_center_banned_from_pastry(v)
|
||||
local arcana_boosters = {
|
||||
p_arcana_normal_1 = true,
|
||||
|
|
@ -37,35 +30,21 @@ local function is_center_banned_from_pastry(v)
|
|||
return arcana_boosters[v.key] or pastries_targets[v.set] and is_banned_from_pastry(v)
|
||||
end
|
||||
|
||||
---@param v SMODS.GameObject
|
||||
---@return boolean|string
|
||||
local function is_economy(v)
|
||||
return f(Bakery_API.econ_only_items):where(f.eq(v.key)):any()
|
||||
end
|
||||
|
||||
---@param key string
|
||||
---@return fun(v: SMODS.Blind, k: string): boolean?
|
||||
local function is_showdown_except(key)
|
||||
---@param v SMODS.Blind
|
||||
---@param k string
|
||||
---@return boolean?
|
||||
return function(v, k)
|
||||
return v.boss and v.boss.showdown and key ~= k
|
||||
end
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@param amount number
|
||||
---@return {id: string}[]
|
||||
local function multirule(name, amount)
|
||||
return f(amount):map(function(v)
|
||||
return {id = "Roland_" .. name .. v}
|
||||
end):table()
|
||||
end
|
||||
|
||||
local pastries, amber, cerulean, crimson, verdant, violet, yard =
|
||||
bans(), bans(), bans(), bans(), bans(), bans(), bans()
|
||||
local pastries, amber, cerulean, crimson, verdant, violet =
|
||||
bans(), bans(), bans(), bans(), bans(), bans()
|
||||
|
||||
SMODS.Challenge {
|
||||
key = "Glass",
|
||||
rules = {custom = multirule("Glass", 2)},
|
||||
rules = {custom = {{id = "Roland_Glass1"}, {id = "Roland_Glass2"}}},
|
||||
pronouns = "they_them",
|
||||
config = {extra = {odds = 2}},
|
||||
calculate = function(self, context)
|
||||
|
|
@ -82,24 +61,6 @@ SMODS.Challenge {
|
|||
end,
|
||||
}
|
||||
|
||||
SMODS.Challenge {
|
||||
key = "Spring_Cleaning",
|
||||
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"}},
|
||||
rules = {custom = {{id = "Roland_Spring_Cleaning"}}},
|
||||
restrictions = yard,
|
||||
apply = function()
|
||||
G.GAME.modifiers.no_blind_reward = {Small = true, Big = true, Boss = true}
|
||||
G.GAME.modifiers.no_extra_hand_money = true
|
||||
|
||||
f(Bakery_API.econ_only_items):keys():where(f.nq "j_Roland_yard"):each(function(v)
|
||||
G.GAME.banned_keys[v] = true
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
SMODS.Challenge {
|
||||
key = "Go",
|
||||
rules = {custom = {{id = "Roland_Go"}}},
|
||||
|
|
@ -155,9 +116,6 @@ SMODS.Challenge {
|
|||
jokers = {{id = "j_Roland_amber"}},
|
||||
restrictions = amber,
|
||||
pronouns = "they_them",
|
||||
unlocked = function()
|
||||
return G.P_CENTERS.j_Roland_amber and G.P_CENTERS.j_Roland_amber.check_for_unlock()
|
||||
end,
|
||||
calculate = function(_, context)
|
||||
local function slide(pitch)
|
||||
q(function()
|
||||
|
|
@ -197,9 +155,6 @@ SMODS.Challenge {
|
|||
jokers = {{id = "j_Roland_cerulean"}},
|
||||
restrictions = cerulean,
|
||||
pronouns = "she_her",
|
||||
unlocked = function()
|
||||
return G.P_CENTERS.j_Roland_cerulean and G.P_CENTERS.j_Roland_cerulean.check_for_unlock()
|
||||
end,
|
||||
calculate = function(_, context)
|
||||
if not context.hand_drawn then
|
||||
return
|
||||
|
|
@ -227,9 +182,6 @@ SMODS.Challenge {
|
|||
jokers = {{id = "j_Roland_crimson"}},
|
||||
restrictions = crimson,
|
||||
pronouns = "she_her",
|
||||
unlocked = function()
|
||||
return G.P_CENTERS.j_Roland_crimson and G.P_CENTERS.j_Roland_crimson.check_for_unlock()
|
||||
end,
|
||||
calculate = function(_, context)
|
||||
local _ = context.blind_defeated and f(G.jokers.cards):each(function(v)
|
||||
v.ability.Roland_crimson_heart_chosen = nil
|
||||
|
|
@ -290,9 +242,6 @@ SMODS.Challenge {
|
|||
jokers = {{id = "j_Roland_verdant"}},
|
||||
restrictions = verdant,
|
||||
pronouns = "she_her",
|
||||
unlocked = function()
|
||||
return G.P_CENTERS.j_Roland_verdant and G.P_CENTERS.j_Roland_verdant.check_for_unlock()
|
||||
end,
|
||||
calculate = function(_, context)
|
||||
if context.setting_blind then
|
||||
G.GAME.modifiers.Roland_Eternally_Verdant = true
|
||||
|
|
@ -316,9 +265,6 @@ SMODS.Challenge {
|
|||
jokers = {{id = "j_joker"}, {id = "j_Roland_violet"}},
|
||||
restrictions = violet,
|
||||
pronouns = "she_they",
|
||||
unlocked = function()
|
||||
return G.P_CENTERS.j_Roland_violet and G.P_CENTERS.j_Roland_violet.check_for_unlock()
|
||||
end,
|
||||
calculate = function(_, context)
|
||||
if not context.setting_blind then
|
||||
return
|
||||
|
|
@ -330,43 +276,27 @@ SMODS.Challenge {
|
|||
end,
|
||||
}
|
||||
|
||||
q {
|
||||
blocking = false,
|
||||
no_delete = true,
|
||||
func = function()
|
||||
if not Bakery_API or not Bakery_API.no_money_decks then
|
||||
return false
|
||||
end
|
||||
q(function()
|
||||
f {
|
||||
{G.P_TAGS, is_banned_from_pastry, pastries.banned_tags},
|
||||
{G.P_BLINDS, is_banned_from_pastry, pastries.banned_other},
|
||||
{G.P_CENTERS, is_center_banned_from_pastry, pastries.banned_cards},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_acorn", amber.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_bell", cerulean.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_heart", crimson.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_leaf", verdant.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_vessel", violet.banned_other},
|
||||
}:each(function(v)
|
||||
f(v[1]):where(v[2]):each(adder(v[3]))
|
||||
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
|
||||
q(function()
|
||||
if not G.P_CENTERS.j_Bakery_Spinner then
|
||||
return true
|
||||
end
|
||||
|
||||
Bakery_API.no_money_decks = setmetatable({}, {
|
||||
orig = orig,
|
||||
__index = function(_, k)
|
||||
return (G.GAME or {}).challenge == "c_Roland_Spring_Cleaning" or orig[k]
|
||||
end,
|
||||
})
|
||||
|
||||
f(spin_to_win.jokers):each(function(v)
|
||||
v.id = G.P_CENTERS.j_Bakery_Spinner and "j_Bakery_Spinner" or v.id
|
||||
end)
|
||||
|
||||
f {
|
||||
{G.P_TAGS, is_economy, yard.banned_tags},
|
||||
{G.P_BLINDS, is_economy, yard.banned_other},
|
||||
{G.P_CENTERS, is_economy, yard.banned_cards},
|
||||
{G.P_TAGS, is_banned_from_pastry, pastries.banned_tags},
|
||||
{G.P_BLINDS, is_banned_from_pastry, pastries.banned_other},
|
||||
{G.P_CENTERS, is_center_banned_from_pastry, pastries.banned_cards},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_acorn", amber.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_bell", cerulean.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_heart", crimson.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_leaf", verdant.banned_other},
|
||||
{G.P_BLINDS, is_showdown_except "bl_final_vessel", violet.banned_other},
|
||||
}:each(function(v)
|
||||
f(v[1]):where(v[2]):each(adder(v[3]))
|
||||
end)
|
||||
end,
|
||||
}
|
||||
f(spin_to_win.jokers):each(function(v)
|
||||
v.id = "j_Bakery_Spinner"
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -250,13 +250,7 @@ charm {
|
|||
delay(1)
|
||||
|
||||
q(function()
|
||||
f((G.GAME.modifiers.extra_boosters or 0) + 2)
|
||||
:map(f.const(nil))
|
||||
:each(SMODS.add_booster_to_shop)
|
||||
|
||||
q(function()
|
||||
card.ability.extra.active = false
|
||||
end)
|
||||
card.ability.extra.active = false
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
-- 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",
|
||||
},
|
||||
}
|
||||
|
|
@ -53,25 +53,10 @@ local function freeze(card)
|
|||
return card.ability
|
||||
end
|
||||
|
||||
local config = card.config or {}
|
||||
|
||||
(card.ability or {}).Roland_crimson = not not (card.ability or {}).Roland_crimson
|
||||
card.Roland_frozen_base = card.Roland_frozen_base or copy(card.base)
|
||||
card.Roland_frozen_card = card.Roland_frozen_card or copy(config.card)
|
||||
card.Roland_frozen_ability = card.Roland_frozen_ability or copy(card.ability)
|
||||
card.base = card.Roland_frozen_base and copy(card.Roland_frozen_base) or card.base
|
||||
|
||||
local diff = type(card.set_sprites) == "function" and
|
||||
f(card.Roland_frozen_card):diff(config.card, f.chain(type, f.nq "table"))
|
||||
|
||||
config.card = card.Roland_frozen_card and copy(card.Roland_frozen_card) or config.card
|
||||
card.ability = card.Roland_frozen_ability and copy(card.Roland_frozen_ability) or card.ability
|
||||
card.Roland_frozen = card.Roland_frozen or {probability = SMODS.get_probability_vars(card, 1, 1)}
|
||||
|
||||
if diff then
|
||||
card:set_sprites(card.config.center, card.config.card)
|
||||
end
|
||||
|
||||
local ability, ret = card.ability, card.Roland_frozen_ability
|
||||
ability.extra = ability.extra == nil and {} or ability.extra
|
||||
|
||||
|
|
@ -211,14 +196,10 @@ SMODS.Edition {
|
|||
local _ = not context.fix_probability and not context.mod_probability and freeze(card)
|
||||
end,
|
||||
on_remove = function(card)
|
||||
card.Roland_frozen,
|
||||
card.Roland_frozen_base,
|
||||
card.Roland_frozen_card,
|
||||
card.Roland_frozen_ability,
|
||||
card.Roland_frozen_current_round = nil, nil, nil, nil, nil
|
||||
card.Roland_frozen, card.Roland_frozen_ability, card.Roland_frozen_current_round = nil, nil, nil
|
||||
end,
|
||||
get_weight = function(self)
|
||||
return self.weight * G.GAME.edition_rate
|
||||
return G.GAME.edition_rate * self.weight
|
||||
end,
|
||||
}
|
||||
|
||||
|
|
@ -250,31 +231,6 @@ function Card:click(...)
|
|||
return ret
|
||||
end
|
||||
|
||||
local orig_save = Card.save
|
||||
|
||||
function Card:save(...)
|
||||
if false then
|
||||
---@type Card|{Roland_frozen: table, Roland_frozen_ability: table, Roland_frozen_base: table, Roland_frozen_card: table, Roland_frozen_current_round: table}
|
||||
self = self
|
||||
end
|
||||
|
||||
local ret = orig_save(self, ...)
|
||||
|
||||
ret.Roland_frozen,
|
||||
ret.Roland_frozen_base,
|
||||
ret.Roland_frozen_card,
|
||||
ret.Roland_frozen_ability,
|
||||
ret.Roland_frozen_current_round =
|
||||
self.Roland_frozen,
|
||||
self.Roland_frozen_base,
|
||||
self.Roland_frozen_card,
|
||||
self.Roland_frozen_ability,
|
||||
self.Roland_frozen_current_round
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
local is_bean = {["Turtle Bean"] = true, j_mp_turtle_bean = true}
|
||||
local orig_calculate_joker = Card.calculate_joker
|
||||
|
||||
---@param self Card|{Roland_frozen_ability?: table}
|
||||
|
|
@ -286,7 +242,7 @@ function Card:calculate_joker(context, ...)
|
|||
{xmult = self.ability.extra.Xmult} or nil
|
||||
end
|
||||
|
||||
if is_frozen and is_bean[self.ability.name] then
|
||||
if is_frozen and self.ability.name == "Turtle Bean" then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -329,6 +285,8 @@ function Card:calculate_dollar_bonus(...)
|
|||
return orig_calculate_dollar_bonus(self, ...)
|
||||
end
|
||||
|
||||
local orig_get_probability_vars = SMODS.get_probability_vars
|
||||
|
||||
function SMODS.current_mod.bootstraps_mult(card)
|
||||
local ability = card.Roland_frozen_ability
|
||||
local ret = math.floor((G.GAME.dollars + (G.GAME.dollar_buffer or 0)) / card.ability.extra.dollars)
|
||||
|
|
@ -341,17 +299,9 @@ function SMODS.current_mod.bootstraps_mult(card)
|
|||
return ability.Roland_bootstraps_mult
|
||||
end
|
||||
|
||||
local orig_get_probability_vars = SMODS.get_probability_vars
|
||||
|
||||
function SMODS.get_probability_vars(trigger_obj, ...)
|
||||
local numerator, denominator = orig_get_probability_vars(trigger_obj, ...)
|
||||
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
|
||||
return trigger_obj and (trigger_obj.Roland_frozen or {}).probability or numerator, denominator
|
||||
end
|
||||
|
||||
q {
|
||||
|
|
|
|||
296
src/joker.lua
|
|
@ -22,7 +22,7 @@ local joker = (function()
|
|||
return ret
|
||||
end
|
||||
|
||||
---@param tbl SMODS.Joker|{artist?: string, defeated_blind: string?, idea?: string, Bakery_can_use: (fun(self: self, card: Card): boolean?), Bakery_use_button_text: (fun(self: self, card: Card): string|table|nil), Bakery_use_joker: fun(self: self, card: Card), attributes?: Attributes[]}
|
||||
---@param tbl SMODS.Joker|{artist?: string, idea?: string, Bakery_can_use: (fun(self: self, card: Card): boolean?), Bakery_use_button_text: (fun(self: self, card: Card): string|table|nil), Bakery_use_joker: fun(self: self, card: Card), attributes?: Attributes[]}
|
||||
return function(tbl)
|
||||
tbl.pos = inc()
|
||||
tbl.atlas = "joker"
|
||||
|
|
@ -34,30 +34,28 @@ local joker = (function()
|
|||
tbl.config.extra.back_pos = inc()
|
||||
end
|
||||
|
||||
if tbl.defeated_blind then
|
||||
function tbl.check_for_unlock()
|
||||
return Bakery_API.defeated_blinds[tbl.defeated_blind] > 0
|
||||
end
|
||||
|
||||
function tbl.locked_loc_vars()
|
||||
return G.P_BLINDS[tbl.defeated_blind].discovered and
|
||||
{vars = {localize {type = "name_text", key = tbl.defeated_blind, set = "Blind"}}} or
|
||||
{vars = {localize "k_unknown"}}
|
||||
end
|
||||
end
|
||||
|
||||
if tbl.check_for_unlock then
|
||||
tbl.discovered, tbl.unlocked = false, false
|
||||
end
|
||||
|
||||
return q(SMODS.Joker(tbl))
|
||||
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
|
||||
---@return boolean
|
||||
local function is_frozen(card)
|
||||
return card and card.edition and card.edition.Roland_frozen
|
||||
return card.edition and card.edition.key == "e_Roland_frozen"
|
||||
end
|
||||
|
||||
---@param card? Card|false|{suit: string, value: string}
|
||||
|
|
@ -196,8 +194,8 @@ joker {
|
|||
joker {
|
||||
key = "sunny",
|
||||
pronouns = "it_its",
|
||||
artist = "char",
|
||||
idea = "redstoad",
|
||||
artist = "ghostlyfield",
|
||||
attributes = {"food", "on_sell"},
|
||||
cost = 2,
|
||||
rarity = 1,
|
||||
|
|
@ -218,8 +216,8 @@ joker {
|
|||
SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}}
|
||||
|
||||
SMODS.calculate_context {
|
||||
hand_drawn = facing_blind and {G.deck.cards[1]} or true,
|
||||
other_drawn = not facing_blind and {G.deck.cards[1]} or true,
|
||||
hand_drawn = facing_blind and {G.deck.cards[1]} and true,
|
||||
other_drawn = not facing_blind and {G.deck.cards[1]} and true,
|
||||
first_hand_drawn = not current_round.any_hand_drawn and facing_blind or nil,
|
||||
}
|
||||
|
||||
|
|
@ -243,15 +241,14 @@ joker {
|
|||
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||
end,
|
||||
calculate = function(_, _, context)
|
||||
return (context.selling_self or context.forcetrigger) and
|
||||
f(G.hand.cards):where("edition", false):each(function(v)
|
||||
q {
|
||||
delay = 0.1,
|
||||
func = function()
|
||||
v:set_edition {Roland_frozen = true}
|
||||
end,
|
||||
}
|
||||
end) or nil
|
||||
return (context.selling_self or context.forcetrigger) and f(G.hand.cards):each(function(v)
|
||||
q {
|
||||
delay = 0.1,
|
||||
func = function()
|
||||
v:set_edition {Roland_frozen = true}
|
||||
end,
|
||||
}
|
||||
end) or nil
|
||||
end,
|
||||
}
|
||||
|
||||
|
|
@ -274,9 +271,7 @@ joker {
|
|||
delay = 1,
|
||||
func = function()
|
||||
play_sound "timpani"
|
||||
|
||||
SMODS.add_card {edition = "e_negative", key = v.config.center.key, silent = true}
|
||||
.ability.qty = v.ability.qty
|
||||
SMODS.add_card {edition = "e_negative", key = v.config.center.key}
|
||||
end,
|
||||
}
|
||||
end) or nil
|
||||
|
|
@ -286,7 +281,7 @@ joker {
|
|||
joker {
|
||||
key = "monomino",
|
||||
pronouns = "it_its",
|
||||
artist = "ghostlyfield",
|
||||
artist = "char",
|
||||
config = {extra = {price = 4, hand_name = "Four of a Kind"}},
|
||||
attributes = {"sell_value", "scaling", "economy", "hand_type"},
|
||||
cost = 4,
|
||||
|
|
@ -315,7 +310,7 @@ joker {
|
|||
joker {
|
||||
key = "domino",
|
||||
pronouns = "it_its",
|
||||
artist = "ghostlyfield",
|
||||
artist = "char",
|
||||
config = {extra = {mult_gain = 4, hand_name = "Four of a Kind", mult = 0}},
|
||||
attributes = {"mult", "scaling", "hand_type"},
|
||||
cost = 4,
|
||||
|
|
@ -346,7 +341,7 @@ joker {
|
|||
joker {
|
||||
key = "trimino",
|
||||
pronouns = "it_its",
|
||||
artist = "ghostlyfield",
|
||||
artist = "char",
|
||||
config = {extra = {times = 4, hand_name = "Four of a Kind"}},
|
||||
attributes = {"generation", "hand_type"},
|
||||
cost = 8,
|
||||
|
|
@ -402,72 +397,6 @@ joker {
|
|||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "misfortune",
|
||||
pronouns = "she_they",
|
||||
artist = "ghostlyfield",
|
||||
attributes = {"discard", "passive", "tarot", "planet", "generation", "seals"},
|
||||
cost = 6,
|
||||
rarity = 2,
|
||||
eternal_compat = true,
|
||||
blueprint_compat = false,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, info_queue)
|
||||
table.insert(info_queue, G.P_SEALS.Purple)
|
||||
table.insert(info_queue, G.P_SEALS.Blue)
|
||||
table.insert(info_queue, negative)
|
||||
end,
|
||||
in_pool = function()
|
||||
return not not f(G.playing_cards):map "seal":any(f.index_into {Blue = true, Purple = true})
|
||||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "polaris",
|
||||
pronouns = "he_him",
|
||||
artist = "ghostlyfield",
|
||||
attributes = {"editions", "space"},
|
||||
cost = 6,
|
||||
rarity = 1,
|
||||
eternal_compat = true,
|
||||
blueprint_compat = false,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, info_queue)
|
||||
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||
return {vars = {}}
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
if context.end_of_round then
|
||||
card.Roland_polaris = nil
|
||||
return
|
||||
end
|
||||
|
||||
local no = context.blueprint or not context.before or card.Roland_polaris
|
||||
|
||||
if no and not context.forcetrigger then
|
||||
return
|
||||
end
|
||||
|
||||
card.Roland_polaris = true
|
||||
local first = context.scoring_hand[1]
|
||||
|
||||
if not first or first.edition then
|
||||
return
|
||||
end
|
||||
|
||||
q {
|
||||
delay = 0.1,
|
||||
func = function()
|
||||
card:juice_up()
|
||||
first:juice_up()
|
||||
first:set_edition {Roland_frozen = true}
|
||||
end,
|
||||
}
|
||||
|
||||
return {message = localize {type = "variable", key = "b_Roland_frozen"}, colour = G.C.DARK_EDITION}
|
||||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "cold",
|
||||
pronouns = "he_him",
|
||||
|
|
@ -498,7 +427,6 @@ joker {
|
|||
joker {
|
||||
key = "snowsquall",
|
||||
pronouns = "he_they",
|
||||
artist = "ghostlyfield",
|
||||
config = {extra = {mult_gain = 3, mult = 0}},
|
||||
attributes = {"mult", "scaling", "hand_type"},
|
||||
cost = 6,
|
||||
|
|
@ -530,37 +458,13 @@ joker {
|
|||
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 {
|
||||
key = "arctic",
|
||||
pronouns = "they_them",
|
||||
artist = "ghostlyfield",
|
||||
cost = 10,
|
||||
rarity = 3,
|
||||
config = {extra = {frozen = 1, non_frozen = 0, color = "DARK_EDITION"}},
|
||||
attributes = {"retrigger", "editions", "copying"},
|
||||
config = {extra = {frozen = 1, non_frozen = 0, max_stack = 6, color = "DARK_EDITION"}},
|
||||
attributes = {"retrigger", "editions"},
|
||||
eternal_compat = true,
|
||||
blueprint_compat = true,
|
||||
perishable_compat = true,
|
||||
|
|
@ -570,9 +474,9 @@ joker {
|
|||
calculate = function(_, card, context)
|
||||
local extra = card.ability.extra
|
||||
|
||||
if f(context.blueprint_copiers_stack)
|
||||
:where("config.center.key", card.config.center.key)
|
||||
:any() then
|
||||
if extra.max_stack and
|
||||
context.blueprint_copiers_stack and
|
||||
extra.max_stack < #context.blueprint_copiers_stack then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -585,15 +489,14 @@ joker {
|
|||
end
|
||||
|
||||
return SMODS.merge_effects(
|
||||
f(G)
|
||||
:where(getmetatable, CardArea)
|
||||
:flatmap("cards", ipairs)
|
||||
:where(is_frozen)
|
||||
:map(copy(card, context))
|
||||
:where(type, "table")
|
||||
:map(f.insert(G.C[extra.color], "colour"))
|
||||
:values()
|
||||
:table()
|
||||
f(G.jokers.cards):where(is_frozen):where(function(v)
|
||||
return v.config.center.key ~= card.config.center.key
|
||||
end):map(function(v)
|
||||
return SMODS.blueprint_effect(card, v, context)
|
||||
end):where(type, "table"):map(function(v)
|
||||
v.colour = G.C[extra.color]
|
||||
return v
|
||||
end):values():table()
|
||||
)
|
||||
end,
|
||||
}
|
||||
|
|
@ -601,8 +504,8 @@ joker {
|
|||
joker {
|
||||
key = "sapling",
|
||||
pronouns = "they_them",
|
||||
artist = "char",
|
||||
idea = "redstoad",
|
||||
artist = "ghostlyfield",
|
||||
attributes = {"mult", "suit"},
|
||||
cost = 4,
|
||||
rarity = 1,
|
||||
|
|
@ -633,10 +536,49 @@ joker {
|
|||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "yard",
|
||||
pronouns = "he_him",
|
||||
config = {extra = {money = 2}},
|
||||
attributes = {"economy"},
|
||||
cost = 4,
|
||||
rarity = 1,
|
||||
eternal_compat = true,
|
||||
blueprint_compat = true,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, _, card)
|
||||
return {vars = {card.ability.extra.money}}
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
return (context.remove_playing_cards or context.forcetrigger) and
|
||||
{dollars = card.ability.extra.money * #context.removed, card = card} or nil
|
||||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "misfortune",
|
||||
pronouns = "she_they",
|
||||
artist = "char",
|
||||
attributes = {"discard", "generation", "seals"},
|
||||
cost = 6,
|
||||
rarity = 2,
|
||||
eternal_compat = true,
|
||||
blueprint_compat = false,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, info_queue)
|
||||
table.insert(info_queue, G.P_SEALS.Purple)
|
||||
table.insert(info_queue, negative)
|
||||
end,
|
||||
in_pool = function()
|
||||
return f(G.playing_cards):any(function(v)
|
||||
return v.seal == "Purple"
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "amber",
|
||||
pronouns = "they_them",
|
||||
defeated_blind = "bl_final_acorn",
|
||||
config = {extra = {xmult = 3}},
|
||||
pixel_size = {w = 68, h = 68},
|
||||
attributes = {"xmult"},
|
||||
|
|
@ -684,7 +626,6 @@ joker {
|
|||
joker {
|
||||
key = "cerulean",
|
||||
pronouns = "she_her",
|
||||
defeated_blind = "bl_final_bell",
|
||||
config = {extra = {xmult = 3}},
|
||||
pixel_size = {w = 68, h = 68},
|
||||
attributes = {"xmult"},
|
||||
|
|
@ -704,7 +645,7 @@ joker {
|
|||
{card = card, xmult = card.ability.extra.xmult} or nil
|
||||
end,
|
||||
update = function(self, card)
|
||||
local _ = card.area == G.jokers and self:cerulean(not not card.debuff)
|
||||
local _ = card.area == G.jokers and self:cerulean(false)
|
||||
end,
|
||||
cerulean = function(_, value)
|
||||
local _ = G.jokers and f(G.jokers.cards):each(function(v)
|
||||
|
|
@ -718,7 +659,6 @@ joker {
|
|||
joker {
|
||||
key = "crimson",
|
||||
pronouns = "she_her",
|
||||
defeated_blind = "bl_final_heart",
|
||||
config = {extra = {xmult = 3}},
|
||||
pixel_size = {w = 68, h = 68},
|
||||
attributes = {"xmult"},
|
||||
|
|
@ -735,9 +675,13 @@ joker {
|
|||
{card = card, xmult = card.ability.extra.xmult} or nil
|
||||
end,
|
||||
crimson = function()
|
||||
local _ = G.jokers and f(G.jokers.cards, f.revpairs):where(is_frozen, false):each(function(v)
|
||||
local _ = G.jokers and f(G.jokers.cards, ipairs_reversed):where(is_frozen, false):each(function(v)
|
||||
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
|
||||
v.config.center.key ~= "j_turtle_bean" and
|
||||
right.config.center.key == "j_Roland_crimson"
|
||||
|
||||
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
|
||||
local debuff = not not v.debuff
|
||||
|
|
@ -762,7 +706,6 @@ end
|
|||
joker {
|
||||
key = "verdant",
|
||||
pronouns = "she_her",
|
||||
defeated_blind = "bl_final_leaf",
|
||||
config = {extra = {debuffs = 2, xmult = 3}},
|
||||
pixel_size = {w = 68, h = 68},
|
||||
attributes = {"xmult"},
|
||||
|
|
@ -813,7 +756,6 @@ end
|
|||
joker {
|
||||
key = "violet",
|
||||
pronouns = "she_they",
|
||||
defeated_blind = "bl_final_vessel",
|
||||
idea = "hamester",
|
||||
config = {extra = {before = 0.1, xmult = 6}},
|
||||
pixel_size = {w = 68, h = 68},
|
||||
|
|
@ -839,8 +781,6 @@ joker {
|
|||
joker {
|
||||
key = "venerable",
|
||||
pronouns = "any_all",
|
||||
artist = "ghostlyfield",
|
||||
defeated_blind = "bl_Roland_venerable_visage",
|
||||
config = {extra = {xdiscard = 3}},
|
||||
pixel_size = {w = 68, h = 68},
|
||||
attributes = {"discard", "passive"},
|
||||
|
|
@ -866,45 +806,11 @@ joker {
|
|||
ease_discard(round_resets.discards - discards)
|
||||
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 {
|
||||
key = "bulldozer",
|
||||
pronouns = "she_her",
|
||||
idea = "redstoad",
|
||||
artist = "ghostlyfield",
|
||||
attributes = {"xmult"},
|
||||
cost = 6,
|
||||
rarity = 2,
|
||||
|
|
@ -967,8 +873,8 @@ joker {
|
|||
joker {
|
||||
key = "nilly",
|
||||
pronouns = "any_all",
|
||||
idea = "redstoad",
|
||||
artist = "ghostlyfield",
|
||||
idea = "redstoad",
|
||||
config = {extra = {flipped = false}},
|
||||
attributes = {"xmult", "bakery_double_sided"},
|
||||
cost = 0,
|
||||
|
|
@ -1004,7 +910,6 @@ joker {
|
|||
key = "martingale",
|
||||
pronouns = "he_him",
|
||||
idea = "redstoad",
|
||||
artist = "ghostlyfield",
|
||||
config = {extra = {odds = 2}},
|
||||
attributes = {"xmult", "chance"},
|
||||
cost = 8,
|
||||
|
|
@ -1068,7 +973,6 @@ joker {
|
|||
joker {
|
||||
key = "idle",
|
||||
pronouns = "any_all",
|
||||
artist = "ghostlyfield",
|
||||
rarity = 2,
|
||||
Roland_idle_capacity = 6,
|
||||
cost = G.P_CENTERS.j_idol.cost,
|
||||
|
|
@ -1145,7 +1049,6 @@ joker {
|
|||
joker {
|
||||
key = "suitable",
|
||||
pronouns = "she_they",
|
||||
artist = "ghostlyfield",
|
||||
attributes = {"suit", "passive", "hearts", "diamonds", "spades", "clubs"},
|
||||
cost = 4,
|
||||
rarity = 2,
|
||||
|
|
@ -1198,8 +1101,8 @@ end
|
|||
joker {
|
||||
key = "artemis",
|
||||
pronouns = "any_all",
|
||||
idea = "redstoad",
|
||||
artist = "hamester",
|
||||
idea = "redstoad",
|
||||
cost = 6,
|
||||
rarity = 2,
|
||||
config = {extra = {
|
||||
|
|
@ -1265,7 +1168,6 @@ joker {
|
|||
key = "excalibur",
|
||||
pronouns = "he_him",
|
||||
idea = "redstoad",
|
||||
artist = "ghostlyfield",
|
||||
cost = 8,
|
||||
rarity = 3,
|
||||
config = {extra = {
|
||||
|
|
@ -1276,17 +1178,13 @@ joker {
|
|||
}},
|
||||
attributes = {"xmult", "enhancements", "bakery_double_sided"},
|
||||
eternal_compat = true,
|
||||
blueprint_compat = true,
|
||||
blueprint_compat = false,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, info_queue, card)
|
||||
local extra = card.ability.extra
|
||||
local _ = card.fake_card or table.insert(info_queue, G.P_CENTERS.m_stone)
|
||||
return {vars = {extra.required, extra.scored, extra.xmult}}
|
||||
end,
|
||||
locked_loc_vars = function(_, info_queue, card)
|
||||
local _ = card.fake_card or table.insert(info_queue, G.P_CENTERS.m_stone)
|
||||
return {vars = {}}
|
||||
end,
|
||||
generate_ui = function(self, info_queue, card, ...)
|
||||
Bakery_API.werewolf_ui "j_Roland_excalibur_Back" (self, info_queue, card, ...)
|
||||
|
||||
|
|
@ -1337,7 +1235,7 @@ joker {
|
|||
joker {
|
||||
key = "oops",
|
||||
pronouns = "she_they",
|
||||
artist = "ghostlyfield",
|
||||
artist = "char",
|
||||
cost = 7,
|
||||
rarity = 3,
|
||||
config = {extra = {probability = 1, probability_mult = 2, reset = 1}},
|
||||
|
|
|
|||
|
|
@ -8,44 +8,8 @@
|
|||
local f = {}
|
||||
|
||||
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
|
||||
---@param first integer|string|fun(v: I): O
|
||||
---@param first string|fun(v: I): O
|
||||
---@return fun(v: I): O
|
||||
---@nodiscard
|
||||
function f.chain(first)
|
||||
|
|
@ -53,8 +17,8 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T, O
|
||||
---@param first integer|string|fun(v: I): T
|
||||
---@param second integer|string|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)
|
||||
|
|
@ -62,9 +26,9 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T1, T2, O
|
||||
---@param first integer|string|fun(v: I): T1
|
||||
---@param second integer|string|fun(v: T1): T2
|
||||
---@param third integer|string|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)
|
||||
|
|
@ -72,10 +36,10 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T1, T2, T3, O
|
||||
---@param first integer|string|fun(v: I): T1
|
||||
---@param second integer|string|fun(v: T1): T2
|
||||
---@param third integer|string|fun(v: T2): T3
|
||||
---@param fourth integer|string|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)
|
||||
|
|
@ -83,11 +47,11 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T1, T2, T3, T4, O
|
||||
---@param first integer|string|fun(v: I): T1
|
||||
---@param second integer|string|fun(v: T1): T2
|
||||
---@param third integer|string|fun(v: T2): T3
|
||||
---@param fourth integer|string|fun(v: T3): T4
|
||||
---@param fifth integer|string|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)
|
||||
|
|
@ -95,7 +59,7 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, O
|
||||
---@param all { [1]: (integer|string|fun(v: I): O) }
|
||||
---@param all { [1]: (string|fun(v: I): O) }
|
||||
---@return fun(v: I): O
|
||||
---@nodiscard
|
||||
function f.chain(all)
|
||||
|
|
@ -103,7 +67,7 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T, O
|
||||
---@param all { [1]: (integer|string|fun(v: I): T), [2]: (integer|string|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)
|
||||
|
|
@ -111,7 +75,7 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T1, T2, O
|
||||
---@param all { [1]: (integer|string|fun(v: I): T1), [2]: (integer|string|fun(v: T1): T2), [3]: (integer|string|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)
|
||||
|
|
@ -119,7 +83,7 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T1, T2, T3, O
|
||||
---@param all { [1]: (integer|string|fun(v: I): T1), [2]: (integer|string|fun(v: T1): T2), [3]: (integer|string|fun(v: T2): T3), [4]: (integer|string|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)
|
||||
|
|
@ -127,103 +91,13 @@ if not f then
|
|||
end
|
||||
|
||||
---@generic I, T1, T2, T3, T4, O
|
||||
---@param all { [1]: (integer|string|fun(v: I): T1), [2]: (integer|string|fun(v: T1): T2), [3]: (integer|string|fun(v: T2): T3), [4]: (integer|string|fun(v: T3): T4), [4]: (integer|string|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
|
||||
|
||||
---@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
|
||||
---@param self F | { [K]: V }
|
||||
---@return K?, V?
|
||||
|
|
@ -240,17 +114,7 @@ local none
|
|||
---@return T
|
||||
---@nodiscard
|
||||
local function autofunc(func)
|
||||
if func == false then
|
||||
return f.fals
|
||||
elseif func == true then
|
||||
return f.tru
|
||||
elseif type(func) == "number" then
|
||||
return f.arg(func)
|
||||
elseif type(func) == "string" then
|
||||
return f.indices(func)
|
||||
else
|
||||
return func or f.id
|
||||
end
|
||||
return type(func) == "string" and f.indices(func) or func or f.id
|
||||
end
|
||||
|
||||
---@generic K, V
|
||||
|
|
@ -261,7 +125,7 @@ end
|
|||
---@return V
|
||||
---@nodiscard
|
||||
local function autopairs(tbl, fpairs)
|
||||
return (fpairs or (tbl[1] and ipairs or pairs))(tbl)
|
||||
return (fpairs or (tbl[#tbl] and ipairs or pairs))(tbl)
|
||||
end
|
||||
|
||||
--- Always returns nil.
|
||||
|
|
@ -295,7 +159,7 @@ end
|
|||
|
||||
---@generic T
|
||||
---@param value T
|
||||
---@return fun(v: T): boolean
|
||||
---@return fun(T): boolean
|
||||
---@nodiscard
|
||||
function f.eq(value)
|
||||
return function(v)
|
||||
|
|
@ -366,11 +230,11 @@ end
|
|||
---@nodiscard
|
||||
function f.indices(v)
|
||||
return function(x)
|
||||
for i in v:gmatch "[^.]+" do
|
||||
if type(x) ~= "table" then
|
||||
return x
|
||||
end
|
||||
if type(x) ~= "table" then
|
||||
return x
|
||||
end
|
||||
|
||||
for i in v:gmatch "[^.]+" do
|
||||
x = x[i]
|
||||
end
|
||||
|
||||
|
|
@ -378,36 +242,6 @@ function f.indices(v)
|
|||
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
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
|
|
@ -415,24 +249,10 @@ function f.isf(any)
|
|||
return type(any) == "table" and any.from == f.from and any.new == f.new
|
||||
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(...)
|
||||
local ret
|
||||
|
||||
for _, v in ipairs {...} do
|
||||
v = f.isf(v) and v:table() or v
|
||||
|
||||
if type(v) == "table" then
|
||||
for _, vv in ipairs(v) do
|
||||
local copy = ret
|
||||
|
|
@ -455,10 +275,6 @@ f[true and "chain"] = function(...)
|
|||
return ret or f.noop
|
||||
end
|
||||
|
||||
f[true and "compose"] = function(...)
|
||||
return f.chain(f.from({...}, f.revpairs):values())
|
||||
end
|
||||
|
||||
---@generic K, V
|
||||
---@param fnext? fun(): K?, V?
|
||||
---@return F|{ [K]: V }
|
||||
|
|
@ -469,13 +285,10 @@ function f.new(fnext)
|
|||
all = f.all,
|
||||
any = f.any,
|
||||
arg = f.arg,
|
||||
call = f.call,
|
||||
chain = f.chain,
|
||||
compose = f.compose,
|
||||
concat = f.concat,
|
||||
const = f.const,
|
||||
count = f.count,
|
||||
diff = f.diff,
|
||||
each = f.each,
|
||||
eq = f.eq,
|
||||
fals = f.fals,
|
||||
|
|
@ -486,7 +299,6 @@ function f.new(fnext)
|
|||
index = f.index,
|
||||
index_into = f.index_into,
|
||||
indices = f.indices,
|
||||
insert = f.insert,
|
||||
isf = f.isf,
|
||||
keys = f.keys,
|
||||
map = f.map,
|
||||
|
|
@ -496,8 +308,6 @@ function f.new(fnext)
|
|||
nq = f.nq,
|
||||
peek = f.peek,
|
||||
pun = f.pun,
|
||||
rev = f.rev,
|
||||
revpairs = f.revpairs,
|
||||
skip = f.skip,
|
||||
slice = f.slice,
|
||||
string = f.string,
|
||||
|
|
@ -556,10 +366,10 @@ function f.from(iter, fpairs, step)
|
|||
end
|
||||
end)
|
||||
else
|
||||
local next, tbl, k, v = autopairs(iter, type(fpairs) == "function" and fpairs or nil)
|
||||
local next, context, k, v = autopairs(iter, type(fpairs) == "function" and fpairs or nil)
|
||||
|
||||
return f.new(function()
|
||||
k, v = next(tbl, k)
|
||||
k, v = next(context, k)
|
||||
return k, v
|
||||
end)
|
||||
end
|
||||
|
|
@ -571,14 +381,12 @@ end
|
|||
---@return F|{ [K]: V }
|
||||
---@nodiscard
|
||||
function f:concat(...)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
local fsi = 0
|
||||
local fs = {...}
|
||||
local sum, last = 0, 0
|
||||
|
||||
for i = 1, #fs do
|
||||
local s = fs[i]
|
||||
fs[i] = f.isf(s) and s or f.from(s)
|
||||
fs[i] = f.isf(fs[i]) and fs[i] or f.from(fs[i])
|
||||
end
|
||||
|
||||
return f.new(function()
|
||||
|
|
@ -612,7 +420,6 @@ end
|
|||
---@return F|{ [K]: V }
|
||||
---@nodiscard
|
||||
function f:peek(func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
|
||||
return f.new(function()
|
||||
|
|
@ -632,7 +439,6 @@ end
|
|||
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U }
|
||||
---@nodiscard
|
||||
function f:map(func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
|
||||
return f.new(function()
|
||||
|
|
@ -652,14 +458,11 @@ 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 }
|
||||
---@nodiscard
|
||||
function f:flatmap(func, fpairs)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
-- local i = 0
|
||||
local vt, vk, vp
|
||||
local vt, vk, vv, vp
|
||||
func = autofunc(func)
|
||||
|
||||
return f.new(function()
|
||||
local vv
|
||||
|
||||
if vk then
|
||||
vk, vv = vp(vt, vk)
|
||||
|
||||
|
|
@ -705,7 +508,6 @@ end
|
|||
---@nodiscard
|
||||
---@overload fun(self: F|{ [K]: V }, func: string, is?: any): F|{ [K]: V }
|
||||
function f:where(func, is)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
|
||||
return f.new(function()
|
||||
|
|
@ -738,7 +540,6 @@ end
|
|||
---@return F|{ [integer]: K }
|
||||
---@nodiscard
|
||||
function f:keys()
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
local i = 0
|
||||
|
||||
return f.new(function()
|
||||
|
|
@ -756,7 +557,6 @@ end
|
|||
---@return F|{ [integer]: V }
|
||||
---@nodiscard
|
||||
function f:values()
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
local i = 0
|
||||
|
||||
return f.new(function()
|
||||
|
|
@ -774,8 +574,6 @@ end
|
|||
---@return F|{ [V]: K }
|
||||
---@nodiscard
|
||||
function f:swap()
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
|
||||
return f.new(function()
|
||||
local k, v = self:next()
|
||||
|
||||
|
|
@ -785,28 +583,6 @@ function f:swap()
|
|||
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
|
||||
---@param self F|{ [K]: V }
|
||||
---@param skip? integer
|
||||
|
|
@ -814,8 +590,6 @@ end
|
|||
---@return F|{ [K]: V }
|
||||
---@nodiscard
|
||||
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
|
||||
return self
|
||||
end
|
||||
|
|
@ -847,7 +621,6 @@ end
|
|||
---@return F|{ [K]: V }
|
||||
---@nodiscard
|
||||
function f:skip(n)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
return self:slice(n)
|
||||
end
|
||||
|
||||
|
|
@ -857,7 +630,6 @@ end
|
|||
---@return F|{ [K]: V }
|
||||
---@nodiscard
|
||||
function f:take(n)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
return self:slice(0, n)
|
||||
end
|
||||
|
||||
|
|
@ -869,7 +641,6 @@ end
|
|||
---@overload fun(self: F|{ [K]: V }, seed: fun(a: A, v: V, k: K): A): A
|
||||
---@nodiscard
|
||||
function f:fold(seed, func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
local k, v
|
||||
|
||||
if not func then
|
||||
|
|
@ -899,7 +670,6 @@ end
|
|||
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||
---@nodiscard
|
||||
function f:any(func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
|
||||
for k, v in self.next do
|
||||
|
|
@ -918,7 +688,6 @@ end
|
|||
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||
---@nodiscard
|
||||
function f:all(func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
|
||||
for k, v in self.next do
|
||||
|
|
@ -937,9 +706,8 @@ end
|
|||
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
||||
---@nodiscard
|
||||
function f:count(func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
local ret = 0
|
||||
func = autofunc(func)
|
||||
|
||||
for k, v in self.next do
|
||||
if not func or func(v, k) then
|
||||
|
|
@ -950,24 +718,6 @@ function f:count(func)
|
|||
return ret
|
||||
end
|
||||
|
||||
---@generic K, V
|
||||
---@param self F|{ [K]: V }
|
||||
---@param other { [K]: V }
|
||||
---@param func? fun(v: V, k: K): any
|
||||
---@return K?, V?
|
||||
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
||||
---@nodiscard
|
||||
function f:diff(other, func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
func = autofunc(func)
|
||||
|
||||
for k, v in self.next do
|
||||
if (not func or func(v, k)) and other[k] ~= v then
|
||||
return k, v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@generic K, V, T
|
||||
---@param self F|{ [K]: V }
|
||||
---@param _ `T`
|
||||
|
|
@ -982,7 +732,6 @@ end
|
|||
---@return string
|
||||
---@nodiscard
|
||||
function f:string()
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
local k, v = self:next()
|
||||
|
||||
if k == nil then
|
||||
|
|
@ -1007,7 +756,6 @@ end
|
|||
---@return { [K]: V }
|
||||
---@nodiscard
|
||||
function f:table()
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
local ret = {}
|
||||
|
||||
for k, v in self.next do
|
||||
|
|
@ -1021,8 +769,6 @@ end
|
|||
---@param self F|{ [K]: V }
|
||||
---@param func? fun(v: V, k: K): nil
|
||||
function f:each(func)
|
||||
self = f.isf(self) and self or f.from(self)
|
||||
|
||||
for k, v in self.next do
|
||||
if func then
|
||||
func(v, k)
|
||||
|
|
|
|||
|
|
@ -28,38 +28,17 @@ CardSleeves.Sleeve = CardSleeves.Sleeve
|
|||
--- @type {aliases: { [string]: [string] }}
|
||||
Cryptid = Cryptid
|
||||
|
||||
---@return Card
|
||||
function copy_card(...)
|
||||
error(...)
|
||||
end
|
||||
|
||||
--- @type fun(area: CardArea, ...: ...): Card
|
||||
create_card_for_shop = create_card_for_shop
|
||||
|
||||
--- @type CardArea
|
||||
G.Bakery_charm_area = G.Bakery_charm_area
|
||||
|
||||
--- @type boolean|table
|
||||
G.Bakery_charm_area.cards[1].ability.extra = G.Bakery_charm_area.cards[1].ability.extra
|
||||
|
||||
---@type Card[]
|
||||
G.playing_cards = G.playing_cards
|
||||
SMODS.Mods.Roland.config = require "config"
|
||||
|
||||
---@type userdata|{getWidth: fun(self: self): number}
|
||||
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
|
||||
Talisman = Talisman
|
||||
|
||||
|
|
|
|||
|
|
@ -13,26 +13,8 @@ local function add(v)
|
|||
return xop
|
||||
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
|
||||
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,
|
||||
}
|
||||
return SMODS.add_card {no_edition = true, key = v}
|
||||
end
|
||||
|
||||
local tag = Tag(v)
|
||||
|
|
@ -61,9 +43,7 @@ local function find(it)
|
|||
end
|
||||
|
||||
local match = simplify(it)
|
||||
|
||||
local pool = match == "Blind" and G.P_BLINDS or
|
||||
f(G.P_CENTER_POOLS):any(f.chain(f.arg(2), simplify, f.eq(match)))
|
||||
local pool = f(G.P_CENTER_POOLS):any(f.chain(f.arg(2), simplify, f.eq(match)))
|
||||
|
||||
if type(pool) == "table" and next(pool) then
|
||||
return pseudorandom_element(pool, pseudoseed "Roland_c").key
|
||||
|
|
@ -76,9 +56,9 @@ local function find(it)
|
|||
return f(G.localization.descriptions)
|
||||
:flatmap(flatten)
|
||||
:where(type, "table")
|
||||
:where(f.chain(f.arg(2), f.index_into(G.P_CENTERS), "config"))
|
||||
:where(function(v, k)
|
||||
return ((G.P_CENTERS[k] or {}).config or G.P_BLINDS[k]) and
|
||||
(match == simplify(k) or match == simplify(v.name))
|
||||
return match == simplify(k) or match == simplify(v.name)
|
||||
end)
|
||||
:keys()
|
||||
:any()
|
||||
|
|
|
|||
131
src/main.lua
|
|
@ -1,13 +1,10 @@
|
|||
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]
|
||||
|
||||
q {
|
||||
front = true,
|
||||
no_delete = true,
|
||||
blocking = false,
|
||||
blockable = false,
|
||||
func = function()
|
||||
local contributors = (Bakery_API or {}).contributors
|
||||
|
||||
|
|
@ -15,46 +12,88 @@ q {
|
|||
return false
|
||||
end
|
||||
|
||||
f(assert(SMODS.load_file("src/credits.lua", "Roland"))() or require "credits"):each(function(v, k)
|
||||
-- Special shoutout to all contributors. <3
|
||||
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
|
||||
-- G.ARGS.LOC_COLOURS["Bakery_credit_fg_Roland_" .. k] = v.fg
|
||||
-- G.ARGS.LOC_COLOURS["Bakery_credit_bg_Roland_" .. k] = v.bg
|
||||
end)
|
||||
|
||||
if SMODS.Mods.DebugPlus and SMODS.Mods.Roland.config.import_funky then
|
||||
_G.f, _G.q, _G.u, _G.c = unpack(qol)
|
||||
if not SMODS.Mods.DebugPlus or not SMODS.Mods.Roland.config.import_funky then
|
||||
return
|
||||
end
|
||||
|
||||
_G.f, _G.q, _G.u, _G.c = unpack(qol)
|
||||
end,
|
||||
}
|
||||
|
||||
f {"challenge", "spectral", "edition", "voucher", "tweaks", "blind", "charm", "joker", "tarot", "back", "seal", "tag"}
|
||||
:each(function(v)
|
||||
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
||||
end)
|
||||
|
||||
local _ = Balatest and f {"joker", "blind", "spectral"}:each(function(v)
|
||||
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
|
||||
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)
|
||||
|
||||
local function realign(tbl)
|
||||
f(tbl):where(function(v, k)
|
||||
if k == "align" and type(v) == "string" then
|
||||
tbl[k] = "tr"
|
||||
end
|
||||
|
||||
return k ~= "nodes" and type(v) == "table"
|
||||
end):each(realign)
|
||||
|
||||
return tbl
|
||||
if Balatest then
|
||||
f {"joker", "blind", "spectral"}:each(function(v)
|
||||
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
|
||||
end)
|
||||
end
|
||||
|
||||
local function toggle(id)
|
||||
return realign(create_toggle {
|
||||
return create_toggle {
|
||||
label = localize {type = "variable", key = "b_Roland_" .. id},
|
||||
ref_table = SMODS.Mods.Roland.config,
|
||||
ref_value = id,
|
||||
scale = 1.5,
|
||||
})
|
||||
}
|
||||
end
|
||||
|
||||
local animated = SMODS.Mods.Roland.config.animated_icon
|
||||
|
||||
SMODS.Atlas {
|
||||
px = 256,
|
||||
py = 256,
|
||||
|
|
@ -68,30 +107,24 @@ SMODS.Atlas {
|
|||
function SMODS.current_mod.config_tab()
|
||||
return {
|
||||
n = G.UIT.ROOT,
|
||||
config = {minw = 1, minh = 1, align = "tr", padding = 0.1, colour = G.C.BLACK},
|
||||
nodes = {
|
||||
{
|
||||
n = G.UIT.C,
|
||||
config = {minw = 1, minh = 1, align = "tr", padding = 0.1, colour = G.C.CLEAR},
|
||||
nodes = {
|
||||
toggle "animated_icon",
|
||||
toggle "cool_phones",
|
||||
toggle "vitriol",
|
||||
toggle "equinox_assist",
|
||||
G.P_CENTERS.c_Bakery_Scribe and toggle "scribable_basket",
|
||||
},
|
||||
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.BLACK},
|
||||
nodes = {{
|
||||
n = G.UIT.C,
|
||||
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.CLEAR},
|
||||
nodes = {
|
||||
toggle "animated_icon",
|
||||
toggle "cool_phones",
|
||||
toggle "faster_planets",
|
||||
-- toggle "illusion_seal",
|
||||
-- toggle "no_wild_debuff",
|
||||
toggle "vitriol",
|
||||
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
|
||||
|
||||
SMODS.current_mod.qol = qol
|
||||
|
|
|
|||
|
|
@ -38,32 +38,26 @@ spectral {
|
|||
return {vars = {card.ability.extra.amount}}
|
||||
end,
|
||||
can_use = function()
|
||||
return next(G.hand.cards) and u()
|
||||
return u() and #G.hand.cards > 0
|
||||
end,
|
||||
use = function(_, card)
|
||||
use = function(_, card, _)
|
||||
local cards = f(G.hand.cards):table()
|
||||
pseudoshuffle(cards, pseudoseed "RolandDual")
|
||||
|
||||
f(cards):take(card.ability.extra.amount):each(function(v)
|
||||
local seal = SMODS.poll_seal {
|
||||
guaranteed = true,
|
||||
options = f(G.P_SEALS):keys():where(f.nq "Roland_glass"):values():table(),
|
||||
}
|
||||
local seal
|
||||
|
||||
local _ = not card.Roland_immediate and q {
|
||||
delay = 0.5,
|
||||
trigger = "after",
|
||||
func = function()
|
||||
v:set_seal(seal, nil, true)
|
||||
end,
|
||||
} or v:set_seal(seal, true, true)
|
||||
for _ = 1, 64 do
|
||||
seal = SMODS.poll_seal {guaranteed = true}
|
||||
|
||||
if seal ~= "Roland_glass" then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
v:set_seal(seal == "Roland_glass" and "Red" or seal)
|
||||
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 {
|
||||
|
|
@ -83,7 +77,7 @@ spectral {
|
|||
delay = 0.4,
|
||||
func = function()
|
||||
card:juice_up(0.3, 0.5)
|
||||
play_sound "tarot1"
|
||||
play_sound("tarot1")
|
||||
end,
|
||||
}
|
||||
|
||||
|
|
@ -138,10 +132,9 @@ spectral {
|
|||
return {vars = {card.ability.extra.amount}}
|
||||
end,
|
||||
can_use = function(_, card)
|
||||
local count = #Bakery_API.get_highlighted()
|
||||
return u() and count > 0 and count <= card.ability.extra.amount
|
||||
return u() and #Bakery_API.get_highlighted() == card.ability.extra.amount
|
||||
end,
|
||||
use = function()
|
||||
use = function(_, _, _)
|
||||
f(Bakery_API.get_highlighted()):each(function(v)
|
||||
v:set_seal "Roland_glass"
|
||||
end)
|
||||
|
|
@ -152,7 +145,6 @@ spectral {
|
|||
key = "void",
|
||||
pronouns = "it_its",
|
||||
artist = "aster",
|
||||
hidden = true,
|
||||
soul_rate = 0.003,
|
||||
soul_set = "Spectral",
|
||||
config = {extra = {amount = 2}},
|
||||
|
|
|
|||
10
src/tag.lua
|
|
@ -60,8 +60,8 @@ SMODS.Tag {
|
|||
pos = {x = 0, y = 0},
|
||||
config = {amount = 5},
|
||||
loc_vars = function(self, info_queue, tag)
|
||||
info_queue[#info_queue + 1] = G.P_CENTERS.e_Roland_frozen
|
||||
tag.ability = tag.ability or {}
|
||||
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||
return {vars = {tag.ability.amount or self.config.amount}}
|
||||
end,
|
||||
apply = function(self, tag, context)
|
||||
|
|
@ -73,10 +73,9 @@ SMODS.Tag {
|
|||
end
|
||||
|
||||
if tag.triggered or
|
||||
not context.card or
|
||||
context.card.edition or
|
||||
context.type ~= "Bakery_score_card" or
|
||||
(tag.ability.amount or self.config.amount) <= 0 then
|
||||
(tag.ability.amount or self.config.amount) <= 0 or
|
||||
((context.card or {}).edition or {}).Roland_frozen or
|
||||
context.type ~= "Bakery_score_card" then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -122,7 +121,6 @@ SMODS.Tag {
|
|||
ab.total_rounds = ab.total_rounds or self.config.total_rounds
|
||||
|
||||
if tag.triggered or
|
||||
not G.jokers or
|
||||
not next(G.jokers.cards) or
|
||||
ab.invis_rounds < ab.total_rounds or
|
||||
#G.jokers.cards + (modifiers.Roland_invisible or 0) >= G.jokers.config.card_limit then
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@ q(SMODS.Consumable {
|
|||
end
|
||||
|
||||
local highlighted = Bakery_API.get_highlighted()
|
||||
local count = #G.jokers.highlighted + #highlighted
|
||||
|
||||
return count > 0 and count <= card.ability.extra.amount and
|
||||
return #G.jokers.highlighted + #highlighted == card.ability.extra.amount and
|
||||
f(G.jokers.highlighted):concat(highlighted):all(function(v)
|
||||
return not v.edition
|
||||
end)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ Balatest.TestPlay {
|
|||
}
|
||||
end)
|
||||
|
||||
Balatest.wait_for_input(G.STATES.ROUND_EVAL)
|
||||
Balatest.wait_for_input()
|
||||
Balatest.wait()
|
||||
end,
|
||||
assert = function()
|
||||
Balatest.assert_chips(2720)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ local orig_use_consumeable = Card.use_consumeable
|
|||
function Card:use_consumeable(area, copier, ...)
|
||||
if SMODS.Mods.Roland.config.faster_planets and self.ability.consumeable.hand_type then
|
||||
set_consumeable_usage(self)
|
||||
level_up_hand(copier or self, self.ability.consumeable.hand_type, true, self.ability.qty or 1)
|
||||
level_up_hand(copier or self, self.ability.consumeable.hand_type, true)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -61,17 +61,16 @@ function G.FUNCS.use_card(e, ...)
|
|||
return orig_use_card(e, ...)
|
||||
end
|
||||
|
||||
local normal = G.STATE == G.STATES.SHOP or
|
||||
ref.area ~= G.pack_cards or
|
||||
not G.GAME.pack_choices or
|
||||
G.GAME.pack_choices <= 0
|
||||
|
||||
local normal = ref.area ~= G.pack_cards or not G.GAME.pack_choices or G.GAME.pack_choices <= 0
|
||||
ref.from_area = ref.from_area or ref.area
|
||||
play_sound("tarot1", percent, 0.6)
|
||||
discover_card(ref.config.center)
|
||||
ref:use_consumeable(ref.area)
|
||||
SMODS.calculate_context {area = ref.area, consumeable = ref, using_consumeable = true}
|
||||
ref:remove()
|
||||
|
||||
q(function()
|
||||
ref:remove()
|
||||
end)
|
||||
|
||||
if normal then
|
||||
return
|
||||
|
|
@ -110,35 +109,21 @@ local function no_harsh_ante_scaling()
|
|||
return not Talisman or not SMODS.Mods.Roland.config.harsh_ante_scaling
|
||||
end
|
||||
|
||||
---@type (fun(rem: number): number|table)[]
|
||||
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,
|
||||
}
|
||||
|
||||
function get_blind_amount(ante, ...)
|
||||
local offset = 40
|
||||
local loop = 39
|
||||
|
||||
if ante < offset or no_harsh_ante_scaling() then
|
||||
if ante < loop or no_harsh_ante_scaling() then
|
||||
return orig_get_blind_amount(ante, ...)
|
||||
end
|
||||
|
||||
local loop = 10
|
||||
if (ante - 9) / 15 >= loop then
|
||||
return 1 / 0
|
||||
end
|
||||
|
||||
return f(SMODS.Mods.Roland.harsh_ante_scaling, f.revpairs):any(function(_, k)
|
||||
return (ante - offset) / loop + 1 >= k
|
||||
end)((ante - offset) % loop + 1)
|
||||
local rem = tonumber(blind((ante % loop) + 1))
|
||||
|
||||
return ante / 15 >= loop and Big:new(f(blind(ante - (loop * 15))):map(f.const(10)):table()) or
|
||||
(ante / 9 >= loop and Big:new(f(ante / loop - 8):map(f.const(10)):concat {rem}:table()) or
|
||||
(ante / 2 >= loop and Big:new {rem, ante / loop} or
|
||||
(Big.constants and Big.constants.TEN or Big:new {10}):pow(rem)))
|
||||
end
|
||||
|
|
|
|||