Compare commits
23 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 91660bfeea | |||
| 7c64a5d8fa | |||
| dcf9d55fcf | |||
| 2f55344a90 | |||
| 0bb1eed9d5 | |||
| d118a17e3f | |||
| 77f308685a | |||
| 2b78455ff8 | |||
| 480c4ffd45 | |||
| b1c7ffffbe | |||
| c9f282bdf2 | |||
| 4230a1a4b1 | |||
| 0bf2093d7d | |||
| ee57c92608 | |||
| 67826c039c | |||
| a6e6289349 | |||
| 18e763be35 | |||
| 7d4198efbd | |||
| 169ec336ae | |||
| 4a76ca294c | |||
| e9201b3f78 | |||
| ce395aedb3 | |||
| eb232c1c77 |
4
.vscode/settings.json
vendored
|
|
@ -65,4 +65,8 @@
|
||||||
"unused-local": "Error",
|
"unused-local": "Error",
|
||||||
"unused-vararg": "Error",
|
"unused-vararg": "Error",
|
||||||
},
|
},
|
||||||
|
"Lua.runtime.version": "LuaJIT",
|
||||||
|
"Lua.workspace.library": [
|
||||||
|
"${3rd}/love2d/library"
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
assets/1x/phorm.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
assets/1x/voucher.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
BIN
assets/2x/phorm.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 3.3 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 |
BIN
assets/2x/voucher.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
|
|
@ -1,5 +1,6 @@
|
||||||
return {
|
return {
|
||||||
animated_icon = true,
|
animated_icon = true,
|
||||||
|
cool_phones = true,
|
||||||
equinox_assist = false,
|
equinox_assist = false,
|
||||||
faster_planets = false,
|
faster_planets = false,
|
||||||
harsh_ante_scaling = false,
|
harsh_ante_scaling = false,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ return {
|
||||||
},
|
},
|
||||||
BakeryCharm = {
|
BakeryCharm = {
|
||||||
BakeryCharm_Roland_cocacola = {
|
BakeryCharm_Roland_cocacola = {
|
||||||
name = "coca cola phone",
|
name = SMODS.Mods.Roland.config.cool_phones and "coca cola phone" or "Pentagram",
|
||||||
text = {
|
text = {
|
||||||
"{C:attention}Discard 0 cards {}to",
|
"{C:attention}Discard 0 cards {}to",
|
||||||
"gain {C:red}#1# {}discards and",
|
"gain {C:red}#1# {}discards and",
|
||||||
|
|
@ -32,7 +32,7 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BakeryCharm_Roland_fat = {
|
BakeryCharm_Roland_fat = {
|
||||||
name = "fat i phone",
|
name = SMODS.Mods.Roland.config.cool_phones and "fat i phone" or "Product",
|
||||||
text = {
|
text = {
|
||||||
"{C:attention}+#1# Booster Pack {}slots",
|
"{C:attention}+#1# Booster Pack {}slots",
|
||||||
"All {C:attention}Booster Packs {}are {C:attention}Mega",
|
"All {C:attention}Booster Packs {}are {C:attention}Mega",
|
||||||
|
|
@ -40,15 +40,15 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BakeryCharm_Roland_flexible = {
|
BakeryCharm_Roland_flexible = {
|
||||||
name = "flexi ble phone",
|
name = SMODS.Mods.Roland.config.cool_phones and "flexi ble phone" or "Ring",
|
||||||
text = {unpack(G.localization.descriptions.Joker.j_ring_master.text)},
|
text = {unpack(G.localization.descriptions.Joker.j_ring_master.text)},
|
||||||
},
|
},
|
||||||
BakeryCharm_Roland_hand = {
|
BakeryCharm_Roland_hand = {
|
||||||
name = "hand phone",
|
name = SMODS.Mods.Roland.config.cool_phones and "hand phone" or "Shell",
|
||||||
text = {"{C:attention}+#1# {}hand size", "{C:blue}#2# {}hands"},
|
text = {"{C:attention}+#1# {}hand size", "{C:blue}#2# {}hands"},
|
||||||
},
|
},
|
||||||
BakeryCharm_Roland_wii = {
|
BakeryCharm_Roland_wii = {
|
||||||
name = "wii phone",
|
name = SMODS.Mods.Roland.config.cool_phones and "wii phone" or "Tire",
|
||||||
text = {
|
text = {
|
||||||
"Enter the shop",
|
"Enter the shop",
|
||||||
"when any {C:attention}Blind",
|
"when any {C:attention}Blind",
|
||||||
|
|
@ -495,6 +495,22 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Voucher = {
|
||||||
|
v_Roland_ceres = {
|
||||||
|
name = "Ceres",
|
||||||
|
text = {
|
||||||
|
"Level up {C:attention}Flush House",
|
||||||
|
"by {C:attention}#1# {}when it is played",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
v_Roland_neptune = {
|
||||||
|
name = "Neptune",
|
||||||
|
text = {
|
||||||
|
"Level up {C:attention}Straight Flush",
|
||||||
|
"by {C:attention}#1# {}when it is played",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
misc = {
|
misc = {
|
||||||
challenge_names = {
|
challenge_names = {
|
||||||
|
|
@ -514,6 +530,7 @@ return {
|
||||||
b_Roland_animated_icon = "Animated Icon (requires restart)",
|
b_Roland_animated_icon = "Animated Icon (requires restart)",
|
||||||
b_Roland_bye = "Bye!",
|
b_Roland_bye = "Bye!",
|
||||||
b_Roland_comma = ", ",
|
b_Roland_comma = ", ",
|
||||||
|
b_Roland_cool_phones = "cool phones (requires restart)",
|
||||||
b_Roland_debuffed = "DEBUFFED",
|
b_Roland_debuffed = "DEBUFFED",
|
||||||
b_Roland_disabled = "Disabled",
|
b_Roland_disabled = "Disabled",
|
||||||
b_Roland_enabled = "Enabled",
|
b_Roland_enabled = "Enabled",
|
||||||
|
|
@ -544,7 +561,7 @@ return {
|
||||||
ch_c_Roland_Eternally_Verdant = {"{C:attention}Verdant Leaf{}'s effect is active every blind"},
|
ch_c_Roland_Eternally_Verdant = {"{C:attention}Verdant Leaf{}'s effect is active every blind"},
|
||||||
ch_c_Roland_Eternally_Violet = {"{C:attention}Violet Vessel{}'s effect is active every blind"},
|
ch_c_Roland_Eternally_Violet = {"{C:attention}Violet Vessel{}'s effect is active every blind"},
|
||||||
ch_c_Roland_Glass1 = {"Played cards with no seal have a"},
|
ch_c_Roland_Glass1 = {"Played cards with no seal have a"},
|
||||||
ch_c_Roland_Glass2 = {"{C:green}1 in 4{} chance to gain {C:dark_edition}Glass Seal"},
|
ch_c_Roland_Glass2 = {"{C:green}1 in 2{} chance to gain {C:dark_edition}Glass Seal"},
|
||||||
ch_c_Roland_Go = {"Set money to {C:money}$0 {}when entering the shop"},
|
ch_c_Roland_Go = {"Set money to {C:money}$0 {}when entering the shop"},
|
||||||
ch_c_Roland_Jokerful = {"The only jokers are {C:mult}Joker{} and {C:chips}Ms. Joker"},
|
ch_c_Roland_Jokerful = {"The only jokers are {C:mult}Joker{} and {C:chips}Ms. Joker"},
|
||||||
ch_c_Roland_Pastries = {"All blinds, cards, and tags are of {C:gold}Bakery{} or {C:blue}Roland"},
|
ch_c_Roland_Pastries = {"All blinds, cards, and tags are of {C:gold}Bakery{} or {C:blue}Roland"},
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
"id": "Roland",
|
"id": "Roland",
|
||||||
"name": "Roland",
|
"name": "Roland",
|
||||||
"prefix": "Roland",
|
"prefix": "Roland",
|
||||||
"version": "2.9.6",
|
"version": "2.9.28",
|
||||||
"badge_colour": "8BE9FD",
|
"badge_colour": "8BE9FD",
|
||||||
"display_name": "Roland",
|
"display_name": "Roland",
|
||||||
"main_file": "src/main.lua",
|
"main_file": "src/main.lua",
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,8 @@ local back = (function()
|
||||||
tbl.atlas = "back"
|
tbl.atlas = "back"
|
||||||
x = x + 1
|
x = x + 1
|
||||||
local back = q(SMODS.Back(tbl))
|
local back = q(SMODS.Back(tbl))
|
||||||
local sleeve = (_G["CardSleeves"] or {}).Sleeve
|
|
||||||
|
|
||||||
local _ = sleeve and sleeve {
|
local _ = CardSleeves and CardSleeves.Sleeve {
|
||||||
key = key,
|
key = key,
|
||||||
pos = tbl.pos,
|
pos = tbl.pos,
|
||||||
atlas = "sleeve",
|
atlas = "sleeve",
|
||||||
|
|
@ -61,7 +60,7 @@ SMODS.Atlas {
|
||||||
py = 95,
|
py = 95,
|
||||||
}
|
}
|
||||||
|
|
||||||
local _ = _G["CardSleeves"] and SMODS.Atlas {
|
local _ = CardSleeves and SMODS.Atlas {
|
||||||
key = "sleeve",
|
key = "sleeve",
|
||||||
path = "sleeve.png",
|
path = "sleeve.png",
|
||||||
px = 73,
|
px = 73,
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,7 @@ SMODS.Atlas {
|
||||||
atlas_table = "ANIMATION_ATLAS",
|
atlas_table = "ANIMATION_ATLAS",
|
||||||
}
|
}
|
||||||
|
|
||||||
SMODS.Sound {
|
SMODS.Sound {key = "kick", path = "kick.ogg"}
|
||||||
key = "kick",
|
|
||||||
path = "kick.ogg",
|
|
||||||
}
|
|
||||||
|
|
||||||
local function common_rank()
|
local function common_rank()
|
||||||
local tally, to_name = {}, {}
|
local tally, to_name = {}, {}
|
||||||
|
|
@ -55,7 +52,7 @@ end
|
||||||
|
|
||||||
local function has_enhancement(card)
|
local function has_enhancement(card)
|
||||||
local e = SMODS.get_enhancements(card)
|
local e = SMODS.get_enhancements(card)
|
||||||
return not not (e and next(e))
|
return e and next(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_freeze(state)
|
local function set_freeze(state)
|
||||||
|
|
@ -242,16 +239,16 @@ blind {
|
||||||
disable = function(self)
|
disable = function(self)
|
||||||
self:defeat()
|
self:defeat()
|
||||||
end,
|
end,
|
||||||
calculate = function(self, b)
|
calculate = function(self, b, context)
|
||||||
return not b.disabled and self.cards()
|
return not b.disabled and
|
||||||
|
context.hand_drawn and
|
||||||
|
self.cards()
|
||||||
:where("Roland_blizzard", false)
|
:where("Roland_blizzard", false)
|
||||||
:where("facing", "front")
|
:where("facing", "front")
|
||||||
:each(set_freeze(true)) or nil
|
:each(set_freeze(true)) or nil
|
||||||
end,
|
end,
|
||||||
cards = function()
|
cards = function()
|
||||||
return f(G):where(function(v)
|
return f(G):where(getmetatable, CardArea):flatmap("cards", ipairs)
|
||||||
return type(v) == "table" and type(v.cards) == "table"
|
|
||||||
end):flatmap("cards", ipairs)
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,8 +334,32 @@ end
|
||||||
|
|
||||||
function SMODS.current_mod:calculate(context)
|
function SMODS.current_mod:calculate(context)
|
||||||
local _ = type(G.calccontext) == "function" and G.calccontext(context)
|
local _ = type(G.calccontext) == "function" and G.calccontext(context)
|
||||||
local _ = type(G.calckeys) == "function" and G.calckeys(f(context):keys())
|
|
||||||
local _ = type(G.calc) == "function" and G.calc(f(context):keys():string())
|
if type(G.calc) == "function" then
|
||||||
|
G.calc = {G.calc}
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(G.calc) == "table" then
|
||||||
|
local str
|
||||||
|
|
||||||
|
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.calc[1]) == "function" and G.calc[1](f(context):keys():string())
|
||||||
|
end
|
||||||
|
|
||||||
|
local _ = context.before and
|
||||||
|
f {"v_Roland_ceres", "v_Roland_neptune"}
|
||||||
|
:where(f.index_into(G.GAME.used_vouchers))
|
||||||
|
:map(f.index_into(G.P_CENTERS))
|
||||||
|
:where("config.extra.hand_type", context.scoring_name)
|
||||||
|
:pun "SMODS.Voucher"
|
||||||
|
: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
|
local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities
|
||||||
|
|
||||||
local _ = context.end_of_round and
|
local _ = context.end_of_round and
|
||||||
|
|
@ -462,15 +483,15 @@ local venerable_visage = blind {
|
||||||
vitriol = function(b)
|
vitriol = function(b)
|
||||||
local vitriol = SMODS.Mods.Roland.config.vitriol
|
local vitriol = SMODS.Mods.Roland.config.vitriol
|
||||||
local resize_to_w, resize_to_h = 320, 200
|
local resize_to_w, resize_to_h = 320, 200
|
||||||
local is_fullscreen = _G["love"].window.getFullscreen()
|
local is_fullscreen = love.window.getFullscreen()
|
||||||
|
|
||||||
if vitriol then
|
if vitriol then
|
||||||
_G["love"].window.setFullscreen(false)
|
love.window.setFullscreen(false)
|
||||||
delay(1.5)
|
delay(1.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function jitter()
|
local function jitter()
|
||||||
local x, y = _G["love"].window.getDesktopDimensions()
|
local x, y = love.window.getDesktopDimensions()
|
||||||
|
|
||||||
return pseudorandom(pseudoseed "RolandVenerableVisageX", 0, x) - x / 2,
|
return pseudorandom(pseudoseed "RolandVenerableVisageX", 0, x) - x / 2,
|
||||||
pseudorandom(pseudoseed "RolandVenerableVisageY", 0, y) - y / 2
|
pseudorandom(pseudoseed "RolandVenerableVisageY", 0, y) - y / 2
|
||||||
|
|
@ -498,15 +519,16 @@ local venerable_visage = blind {
|
||||||
play_sound("gong", v)
|
play_sound("gong", v)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
---@type number, number, table
|
||||||
|
local w, h, flags = love.window.getMode()
|
||||||
local len = #G.playing_cards
|
local len = #G.playing_cards
|
||||||
local w, h, flags = _G["love"].window.getMode()
|
|
||||||
|
|
||||||
if vitriol then
|
if vitriol then
|
||||||
_G["love"].window.setMode(resize_to_w, resize_to_h)
|
love.window.setMode(resize_to_w, resize_to_h)
|
||||||
_G["love"].resize(resize_to_w, resize_to_h)
|
love.resize(resize_to_w, resize_to_h)
|
||||||
end
|
end
|
||||||
|
|
||||||
local x, y = _G["love"].window.getPosition()
|
local x, y = love.window.getPosition()
|
||||||
|
|
||||||
f(G.playing_cards):each(function(v, i)
|
f(G.playing_cards):each(function(v, i)
|
||||||
q {
|
q {
|
||||||
|
|
@ -515,7 +537,7 @@ local venerable_visage = blind {
|
||||||
func = function()
|
func = function()
|
||||||
if vitriol then
|
if vitriol then
|
||||||
local x_random, y_random = jitter()
|
local x_random, y_random = jitter()
|
||||||
_G["love"].window.setPosition(x + x_random * i / len, y + y_random * i / len)
|
love.window.setPosition(x + x_random * i / len, y + y_random * i / len)
|
||||||
end
|
end
|
||||||
|
|
||||||
v:start_dissolve()
|
v:start_dissolve()
|
||||||
|
|
@ -529,10 +551,10 @@ local venerable_visage = blind {
|
||||||
trigger = "before",
|
trigger = "before",
|
||||||
delay = 1.5,
|
delay = 1.5,
|
||||||
func = function()
|
func = function()
|
||||||
_G["love"].window.setPosition(x, y)
|
love.window.setPosition(x, y)
|
||||||
_G["love"].window.setMode(w, h, flags)
|
love.window.setMode(w, h, flags)
|
||||||
_G["love"].resize(w, h)
|
love.resize(w, h)
|
||||||
_G["love"].window.setFullscreen(is_fullscreen)
|
love.window.setFullscreen(is_fullscreen)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ SMODS.Challenge {
|
||||||
key = "Glass",
|
key = "Glass",
|
||||||
rules = {custom = {{id = "Roland_Glass1"}, {id = "Roland_Glass2"}}},
|
rules = {custom = {{id = "Roland_Glass1"}, {id = "Roland_Glass2"}}},
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
config = {extra = {odds = 4}},
|
config = {extra = {odds = 2}},
|
||||||
calculate = function(self, context)
|
calculate = function(self, context)
|
||||||
if not context.after or context.blueprint_card then
|
if not context.after or context.blueprint_card then
|
||||||
return
|
return
|
||||||
|
|
@ -110,12 +110,10 @@ SMODS.Challenge {
|
||||||
pronouns = "she_them",
|
pronouns = "she_them",
|
||||||
}
|
}
|
||||||
|
|
||||||
local starting_jokers = f(5):map(f.const {id = "j_joker"}):table()
|
|
||||||
|
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Eternally_Amber",
|
key = "Eternally_Amber",
|
||||||
rules = {custom = {{id = "Roland_Eternally_Amber"}, {id = "Roland_Showdown_Amber"}}},
|
rules = {custom = {{id = "Roland_Eternally_Amber"}, {id = "Roland_Showdown_Amber"}}},
|
||||||
jokers = starting_jokers,
|
jokers = {{id = "j_Roland_amber"}},
|
||||||
restrictions = amber,
|
restrictions = amber,
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
calculate = function(_, context)
|
calculate = function(_, context)
|
||||||
|
|
@ -154,7 +152,7 @@ SMODS.Challenge {
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Eternally_Cerulean",
|
key = "Eternally_Cerulean",
|
||||||
rules = {custom = {{id = "Roland_Eternally_Cerulean"}, {id = "Roland_Showdown_Cerulean"}}},
|
rules = {custom = {{id = "Roland_Eternally_Cerulean"}, {id = "Roland_Showdown_Cerulean"}}},
|
||||||
jokers = starting_jokers,
|
jokers = {{id = "j_Roland_cerulean"}},
|
||||||
restrictions = cerulean,
|
restrictions = cerulean,
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
calculate = function(_, context)
|
calculate = function(_, context)
|
||||||
|
|
@ -181,7 +179,7 @@ SMODS.Challenge {
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Eternally_Crimson",
|
key = "Eternally_Crimson",
|
||||||
rules = {custom = {{id = "Roland_Eternally_Crimson"}, {id = "Roland_Showdown_Crimson"}}},
|
rules = {custom = {{id = "Roland_Eternally_Crimson"}, {id = "Roland_Showdown_Crimson"}}},
|
||||||
jokers = starting_jokers,
|
jokers = {{id = "j_Roland_crimson"}},
|
||||||
restrictions = crimson,
|
restrictions = crimson,
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
calculate = function(_, context)
|
calculate = function(_, context)
|
||||||
|
|
@ -190,7 +188,7 @@ SMODS.Challenge {
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local mod = G.GAME.modifiers
|
local mod = G.GAME.modifiers
|
||||||
mod.Roland_Eternally_Crimson = not context.setting_blind and mod.Roland_Eternally_Crimson or nil
|
mod.Roland_Eternally_Crimson = context.setting_blind and true or mod.Roland_Eternally_Crimson
|
||||||
local debuff = context.debuff_card
|
local debuff = context.debuff_card
|
||||||
local cards = G.jokers.cards
|
local cards = G.jokers.cards
|
||||||
|
|
||||||
|
|
@ -241,7 +239,7 @@ SMODS.Challenge {
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Eternally_Verdant",
|
key = "Eternally_Verdant",
|
||||||
rules = {custom = {{id = "Roland_Eternally_Verdant"}, {id = "Roland_Showdown_Verdant"}}},
|
rules = {custom = {{id = "Roland_Eternally_Verdant"}, {id = "Roland_Showdown_Verdant"}}},
|
||||||
jokers = starting_jokers,
|
jokers = {{id = "j_Roland_verdant"}},
|
||||||
restrictions = verdant,
|
restrictions = verdant,
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
calculate = function(_, context)
|
calculate = function(_, context)
|
||||||
|
|
@ -264,7 +262,7 @@ SMODS.Challenge {
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Eternally_Violet",
|
key = "Eternally_Violet",
|
||||||
rules = {custom = {{id = "Roland_Eternally_Violet"}, {id = "Roland_Showdown_Violet"}}},
|
rules = {custom = {{id = "Roland_Eternally_Violet"}, {id = "Roland_Showdown_Violet"}}},
|
||||||
jokers = starting_jokers,
|
jokers = {{id = "j_joker"}, {id = "j_Roland_violet"}},
|
||||||
restrictions = violet,
|
restrictions = violet,
|
||||||
pronouns = "she_they",
|
pronouns = "she_they",
|
||||||
calculate = function(_, context)
|
calculate = function(_, context)
|
||||||
|
|
|
||||||
247
src/charm.lua
|
|
@ -1,14 +1,15 @@
|
||||||
local f, q = (... or require "lib.shared")[1], (... or require "lib.shared")[2]
|
local f, q = (... or require "lib.shared")[1], (... or require "lib.shared")[2]
|
||||||
local mod = SMODS.current_mod
|
local mod = SMODS.current_mod
|
||||||
|
local cool_phones = SMODS.Mods.Roland.config.cool_phones
|
||||||
|
|
||||||
SMODS.Atlas {
|
SMODS.Atlas {
|
||||||
key = "charm",
|
key = "charm",
|
||||||
path = "charm.png",
|
path = cool_phones and "phorm.png" or "charm.png",
|
||||||
px = 68,
|
px = 68,
|
||||||
py = 68,
|
py = 68,
|
||||||
}
|
}
|
||||||
|
|
||||||
SMODS.Sound {
|
local _ = cool_phones and SMODS.Sound {
|
||||||
key = "phone",
|
key = "phone",
|
||||||
path = "phone.ogg",
|
path = "phone.ogg",
|
||||||
}
|
}
|
||||||
|
|
@ -16,10 +17,9 @@ SMODS.Sound {
|
||||||
local charm = (function()
|
local charm = (function()
|
||||||
local x = 0
|
local x = 0
|
||||||
|
|
||||||
---@param tbl SMODS.Joker|{alerted?: boolean, equip?: fun(self: self, card: Card)}
|
---@param tbl SMODS.Joker|{alerted?: boolean, artist?: string, equip?: fun(self: self, card: Card)}
|
||||||
return function(tbl)
|
return function(tbl)
|
||||||
q {
|
q {
|
||||||
front = true,
|
|
||||||
blocking = false,
|
blocking = false,
|
||||||
no_delete = true,
|
no_delete = true,
|
||||||
func = function()
|
func = function()
|
||||||
|
|
@ -36,19 +36,20 @@ local charm = (function()
|
||||||
tbl.discovered = true
|
tbl.discovered = true
|
||||||
tbl.pos = {x = x, y = 0}
|
tbl.pos = {x = x, y = 0}
|
||||||
tbl.atlas = "charm"
|
tbl.atlas = "charm"
|
||||||
|
tbl.artist = not cool_phones and "Roland_bakersdozenbagels" or nil
|
||||||
x = x + 1
|
x = x + 1
|
||||||
|
|
||||||
local orig_equip = tbl.equip
|
local orig_equip = tbl.equip
|
||||||
|
|
||||||
function tbl.equip(...)
|
function tbl.equip(...)
|
||||||
play_sound("Roland_phone", 1, 0.5)
|
local _ = cool_phones and play_sound("Roland_phone", 1, 0.5)
|
||||||
|
|
||||||
if orig_equip then
|
if orig_equip then
|
||||||
return orig_equip(...)
|
return orig_equip(...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local charm = Bakery_API.Charm(tbl)
|
local charm = Bakery_API.credit(Bakery_API.Charm(tbl))
|
||||||
charm:inject()
|
charm:inject()
|
||||||
charm:process_loc_text()
|
charm:process_loc_text()
|
||||||
SMODS.current_mod = current_mod
|
SMODS.current_mod = current_mod
|
||||||
|
|
@ -65,115 +66,30 @@ local function can_discard_zero()
|
||||||
end
|
end
|
||||||
|
|
||||||
charm {
|
charm {
|
||||||
key = "wii",
|
key = "hand",
|
||||||
pronouns = "they_them",
|
pronouns = "he_him",
|
||||||
attributes = {"skip"},
|
config = {extra = {hands = -2, hand_size = 5}},
|
||||||
config = {extra = {active = true}},
|
attributes = {"hands", "hand_size", "passive"},
|
||||||
calculate = function(_, card, context)
|
|
||||||
if context.prevent_tag_trigger and card.ability.extra.active then
|
|
||||||
return {prevent_trigger = true}
|
|
||||||
end
|
|
||||||
|
|
||||||
if not context.skip_blind then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
card.ability.extra.active = true
|
|
||||||
local message = localize {type = "variable", key = "b_Roland_entering_shop"}
|
|
||||||
SMODS.calculate_effect({card = card, message = message, sound = "whoosh1"}, card)
|
|
||||||
|
|
||||||
q(function()
|
|
||||||
G.blind_prompt_box = G.blind_prompt_box and G.blind_prompt_box:remove()
|
|
||||||
G.blind_select = G.blind_select and G.blind_select:remove()
|
|
||||||
G.round_eval = G.round_eval and G.round_eval:remove()
|
|
||||||
G.GAME.current_round.jokers_purchased = 0
|
|
||||||
G.GAME.shop_free = nil
|
|
||||||
G.GAME.shop_d6ed = nil
|
|
||||||
play_sound("whoosh1", 1.33333, 0.8)
|
|
||||||
play_sound("whoosh1", 0.66666, 0.8)
|
|
||||||
|
|
||||||
q(function()
|
|
||||||
G.STATE = G.STATES.SHOP
|
|
||||||
G.STATE_COMPLETE = false
|
|
||||||
delay(1)
|
|
||||||
|
|
||||||
q(function()
|
|
||||||
card.ability.extra.active = false
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
local orig_apply_to_run = Tag.apply_to_run
|
|
||||||
|
|
||||||
function Tag:apply_to_run(...)
|
|
||||||
if G.GAME.Bakery_charm == "BakeryCharm_Roland_wii" and
|
|
||||||
G.Bakery_charm_area.cards[1].config.center.ability.extra.active then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
return orig_apply_to_run(self, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
charm {
|
|
||||||
key = "flexible",
|
|
||||||
pronouns = "any_all",
|
|
||||||
}
|
|
||||||
|
|
||||||
local orig_showman = SMODS.showman
|
|
||||||
|
|
||||||
function SMODS.showman(...)
|
|
||||||
return G.GAME.Bakery_charm == "BakeryCharm_Roland_flexible" or orig_showman(...)
|
|
||||||
end
|
|
||||||
|
|
||||||
charm {
|
|
||||||
key = "fat",
|
|
||||||
pronouns = "he_they",
|
|
||||||
attributes = {"passive"},
|
|
||||||
config = {extra = {mod = 2}},
|
|
||||||
loc_vars = function(_, _, card)
|
loc_vars = function(_, _, card)
|
||||||
return {vars = {card.ability.extra.mod}}
|
local extra = card.ability.extra
|
||||||
|
return {vars = {extra.hand_size, extra.hands}}
|
||||||
end,
|
end,
|
||||||
equip = function(_, card)
|
equip = function(_, card)
|
||||||
SMODS.change_booster_limit(card.ability.extra.mod)
|
local extra = card.ability.extra
|
||||||
|
local round = G.GAME.round_resets
|
||||||
|
ease_hands_played(extra.hands)
|
||||||
|
G.hand:change_size(extra.hand_size)
|
||||||
|
round.hands = round.hands + extra.hands
|
||||||
end,
|
end,
|
||||||
unequip = function(_, card)
|
unequip = function(_, card)
|
||||||
SMODS.change_booster_limit(-card.ability.extra.mod)
|
local extra = card.ability.extra
|
||||||
|
local round = G.GAME.round_resets
|
||||||
|
ease_hands_played(-extra.hands)
|
||||||
|
G.hand:change_size(-extra.hand_size)
|
||||||
|
round.hands = round.hands - extra.hands
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local orig_init = Card.init
|
|
||||||
|
|
||||||
function Card:init(X, Y, W, H, card, center, params, ...)
|
|
||||||
if G.GAME.Bakery_charm ~= "BakeryCharm_Roland_fat" or center.set ~= "Booster" then
|
|
||||||
return orig_init(self, X, Y, W, H, card, center, params, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
local key = f {"mini", "jumbo", "normal"}:fold(center.key, function(a, v)
|
|
||||||
return a:gsub(v, "mega")
|
|
||||||
end)
|
|
||||||
|
|
||||||
if G.P_CENTERS[key] then
|
|
||||||
return orig_init(self, X, Y, W, H, card, G.P_CENTERS[key], params, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
key = key:gsub("_?%d+$", "_1")
|
|
||||||
|
|
||||||
if G.P_CENTERS[key] then
|
|
||||||
return orig_init(self, X, Y, W, H, card, G.P_CENTERS[key], params, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
key = key:gsub("_?%d+$", "")
|
|
||||||
|
|
||||||
if G.P_CENTERS[key] then
|
|
||||||
return orig_init(self, X, Y, W, H, card, G.P_CENTERS[key], params, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.Roland_no_mega = true
|
|
||||||
return orig_init(self, X, Y, W, H, card, center, params, ...)
|
|
||||||
end
|
|
||||||
|
|
||||||
charm {
|
charm {
|
||||||
key = "cocacola",
|
key = "cocacola",
|
||||||
pronouns = "he_they",
|
pronouns = "he_they",
|
||||||
|
|
@ -243,26 +159,111 @@ G.FUNCS.Roland_cocacola = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
charm {
|
charm {
|
||||||
key = "hand",
|
key = "fat",
|
||||||
pronouns = "he_him",
|
pronouns = "he_they",
|
||||||
config = {extra = {hands = -2, hand_size = 5}},
|
attributes = {"passive"},
|
||||||
attributes = {"hands", "hand_size", "passive"},
|
config = {extra = {mod = 2}},
|
||||||
loc_vars = function(_, _, card)
|
loc_vars = function(_, _, card)
|
||||||
local extra = card.ability.extra
|
return {vars = {card.ability.extra.mod}}
|
||||||
return {vars = {extra.hand_size, extra.hands}}
|
|
||||||
end,
|
end,
|
||||||
equip = function(_, card)
|
equip = function(_, card)
|
||||||
local extra = card.ability.extra
|
SMODS.change_booster_limit(card.ability.extra.mod)
|
||||||
local round = G.GAME.round_resets
|
|
||||||
ease_hands_played(extra.hands)
|
|
||||||
G.hand:change_size(extra.hand_size)
|
|
||||||
round.hands = round.hands + extra.hands
|
|
||||||
end,
|
end,
|
||||||
unequip = function(_, card)
|
unequip = function(_, card)
|
||||||
local extra = card.ability.extra
|
SMODS.change_booster_limit(-card.ability.extra.mod)
|
||||||
local round = G.GAME.round_resets
|
|
||||||
ease_hands_played(-extra.hands)
|
|
||||||
G.hand:change_size(-extra.hand_size)
|
|
||||||
round.hands = round.hands - extra.hands
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local orig_init = Card.init
|
||||||
|
|
||||||
|
function Card:init(X, Y, W, H, card, center, params, ...)
|
||||||
|
if G.GAME.Bakery_charm ~= "BakeryCharm_Roland_fat" or center.set ~= "Booster" then
|
||||||
|
return orig_init(self, X, Y, W, H, card, center, params, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local key = f {"mini", "jumbo", "normal"}:fold(center.key, function(a, v)
|
||||||
|
return a:gsub(v, "mega")
|
||||||
|
end)
|
||||||
|
|
||||||
|
if G.P_CENTERS[key] then
|
||||||
|
return orig_init(self, X, Y, W, H, card, G.P_CENTERS[key], params, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
key = key:gsub("_?%d+$", "_1")
|
||||||
|
|
||||||
|
if G.P_CENTERS[key] then
|
||||||
|
return orig_init(self, X, Y, W, H, card, G.P_CENTERS[key], params, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
key = key:gsub("_?%d+$", "")
|
||||||
|
|
||||||
|
if G.P_CENTERS[key] then
|
||||||
|
return orig_init(self, X, Y, W, H, card, G.P_CENTERS[key], params, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.Roland_no_mega = true
|
||||||
|
return orig_init(self, X, Y, W, H, card, center, params, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
charm {
|
||||||
|
key = "flexible",
|
||||||
|
pronouns = "any_all",
|
||||||
|
}
|
||||||
|
|
||||||
|
local orig_showman = SMODS.showman
|
||||||
|
|
||||||
|
function SMODS.showman(...)
|
||||||
|
return G.GAME.Bakery_charm == "BakeryCharm_Roland_flexible" or orig_showman(...)
|
||||||
|
end
|
||||||
|
|
||||||
|
charm {
|
||||||
|
key = "wii",
|
||||||
|
pronouns = "they_them",
|
||||||
|
attributes = {"skip"},
|
||||||
|
config = {extra = {active = true}},
|
||||||
|
calculate = function(_, card, context)
|
||||||
|
if context.prevent_tag_trigger and card.ability.extra.active then
|
||||||
|
return {prevent_trigger = true}
|
||||||
|
end
|
||||||
|
|
||||||
|
if not context.skip_blind then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
card.ability.extra.active = true
|
||||||
|
local message = localize {type = "variable", key = "b_Roland_entering_shop"}
|
||||||
|
SMODS.calculate_effect({card = card, message = message, sound = "whoosh1"}, card)
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
G.blind_prompt_box = G.blind_prompt_box and G.blind_prompt_box:remove()
|
||||||
|
G.blind_select = G.blind_select and G.blind_select:remove()
|
||||||
|
G.round_eval = G.round_eval and G.round_eval:remove()
|
||||||
|
G.GAME.current_round.jokers_purchased = 0
|
||||||
|
G.GAME.shop_free = nil
|
||||||
|
G.GAME.shop_d6ed = nil
|
||||||
|
play_sound("whoosh1", 1.33333, 0.8)
|
||||||
|
play_sound("whoosh1", 0.66666, 0.8)
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
G.STATE = G.STATES.SHOP
|
||||||
|
G.STATE_COMPLETE = false
|
||||||
|
delay(1)
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
card.ability.extra.active = false
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local orig_apply_to_run = Tag.apply_to_run
|
||||||
|
|
||||||
|
function Tag:apply_to_run(...)
|
||||||
|
if G.GAME.Bakery_charm == "BakeryCharm_Roland_wii" and
|
||||||
|
G.Bakery_charm_area.cards[1].ability.extra.active then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
return orig_apply_to_run(self, ...)
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ end
|
||||||
|
|
||||||
frozen_sound "_click"
|
frozen_sound "_click"
|
||||||
local frozen_blocklist = {CardSleeve = true}
|
local frozen_blocklist = {CardSleeve = true}
|
||||||
local frozen_sounds = f(4):map(frozen_sound):map("key"):table()
|
local frozen_sounds = f(4):map(frozen_sound):map "key":table()
|
||||||
|
|
||||||
local needs_chip_mult_override = {
|
local needs_chip_mult_override = {
|
||||||
Bull = true,
|
Bull = true,
|
||||||
|
|
@ -144,7 +144,7 @@ local function hook_proxy()
|
||||||
local orig_calculate = proxy.calculate
|
local orig_calculate = proxy.calculate
|
||||||
|
|
||||||
function proxy:calculate(card, context, ...)
|
function proxy:calculate(card, context, ...)
|
||||||
if not card or not card.edition or not card.edition.Roland_frozen then
|
if not (card or {}).Roland_frozen or not (card.edition or {}).Roland_frozen then
|
||||||
return orig_calculate(self, card, context, ...)
|
return orig_calculate(self, card, context, ...)
|
||||||
else
|
else
|
||||||
return SMODS.blueprint_effect(card, get_proxied_joker(card), context)
|
return SMODS.blueprint_effect(card, get_proxied_joker(card), context)
|
||||||
|
|
@ -154,7 +154,7 @@ local function hook_proxy()
|
||||||
local orig_loc_vars = proxy.loc_vars
|
local orig_loc_vars = proxy.loc_vars
|
||||||
|
|
||||||
function proxy:loc_vars(info_queue, card, ...)
|
function proxy:loc_vars(info_queue, card, ...)
|
||||||
if not card or not card.edition or not card.edition.Roland_frozen then
|
if not (card or {}).Roland_frozen or not (card.edition or {}).Roland_frozen then
|
||||||
return orig_loc_vars(self, info_queue, card, ...)
|
return orig_loc_vars(self, info_queue, card, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -216,9 +216,9 @@ joker {
|
||||||
SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}}
|
SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}}
|
||||||
|
|
||||||
SMODS.calculate_context {
|
SMODS.calculate_context {
|
||||||
|
hand_drawn = facing_blind and {G.deck.cards[1]} and true,
|
||||||
|
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,
|
first_hand_drawn = not current_round.any_hand_drawn and facing_blind or nil,
|
||||||
hand_drawn = facing_blind and {G.deck.cards[1]} --[[@as true]],
|
|
||||||
other_drawn = not facing_blind and {G.deck.cards[1]},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if type(facing_blind) == "table" then
|
if type(facing_blind) == "table" then
|
||||||
|
|
@ -488,11 +488,9 @@ joker {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local key = card.config.center.key
|
return SMODS.merge_effects(
|
||||||
|
|
||||||
local merged = SMODS.merge_effects(
|
|
||||||
f(G.jokers.cards):where(is_frozen):where(function(v)
|
f(G.jokers.cards):where(is_frozen):where(function(v)
|
||||||
return v.config.center.key ~= key
|
return v.config.center.key ~= card.config.center.key
|
||||||
end):map(function(v)
|
end):map(function(v)
|
||||||
return SMODS.blueprint_effect(card, v, context)
|
return SMODS.blueprint_effect(card, v, context)
|
||||||
end):where(type, "table"):map(function(v)
|
end):where(type, "table"):map(function(v)
|
||||||
|
|
@ -500,8 +498,6 @@ joker {
|
||||||
return v
|
return v
|
||||||
end):values():table()
|
end):values():table()
|
||||||
)
|
)
|
||||||
|
|
||||||
return merged
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -652,7 +648,7 @@ joker {
|
||||||
local _ = card.area == G.jokers and self:cerulean(false)
|
local _ = card.area == G.jokers and self:cerulean(false)
|
||||||
end,
|
end,
|
||||||
cerulean = function(_, value)
|
cerulean = function(_, value)
|
||||||
f(G.jokers.cards):each(function(v)
|
local _ = G.jokers and f(G.jokers.cards):each(function(v)
|
||||||
f {"click", "drag", "focus", "hover"}:map(f.index_into(v.states)):each(function(s)
|
f {"click", "drag", "focus", "hover"}:map(f.index_into(v.states)):each(function(s)
|
||||||
s.can = value or v.config.center.key == "j_Roland_cerulean"
|
s.can = value or v.config.center.key == "j_Roland_cerulean"
|
||||||
end)
|
end)
|
||||||
|
|
@ -679,7 +675,7 @@ joker {
|
||||||
{card = card, xmult = card.ability.extra.xmult} or nil
|
{card = card, xmult = card.ability.extra.xmult} or nil
|
||||||
end,
|
end,
|
||||||
crimson = function()
|
crimson = function()
|
||||||
f(G.jokers.cards, ipairs_reversed):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 right = G.jokers.cards[v.rank + 1]
|
||||||
|
|
||||||
local debuffed_by_crimson = right and
|
local debuffed_by_crimson = right and
|
||||||
|
|
@ -688,11 +684,13 @@ joker {
|
||||||
right.config.center.key == "j_Roland_crimson"
|
right.config.center.key == "j_Roland_crimson"
|
||||||
|
|
||||||
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
|
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
|
||||||
v.ability.Roland_crimson = not not v.debuff
|
local debuff = not not v.debuff
|
||||||
v:set_debuff(true)
|
v:set_debuff(true)
|
||||||
|
v.ability.Roland_crimson = debuff
|
||||||
elseif not debuffed_by_crimson and v.ability.Roland_crimson ~= nil then
|
elseif not debuffed_by_crimson and v.ability.Roland_crimson ~= nil then
|
||||||
v:set_debuff(v.ability.Roland_crimson)
|
local debuff = v.ability.Roland_crimson
|
||||||
v.ability.Roland_crimson = nil
|
v.ability.Roland_crimson = nil
|
||||||
|
v:set_debuff(debuff)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
|
|
@ -759,7 +757,7 @@ joker {
|
||||||
key = "violet",
|
key = "violet",
|
||||||
pronouns = "she_they",
|
pronouns = "she_they",
|
||||||
idea = "hamester",
|
idea = "hamester",
|
||||||
config = {extra = {before = 1 / 3, xmult = 9}},
|
config = {extra = {before = 0.1, xmult = 6}},
|
||||||
pixel_size = {w = 68, h = 68},
|
pixel_size = {w = 68, h = 68},
|
||||||
attributes = {"xmult"},
|
attributes = {"xmult"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
|
|
@ -776,7 +774,7 @@ joker {
|
||||||
|
|
||||||
return (context.joker_main or context.forcetrigger) and
|
return (context.joker_main or context.forcetrigger) and
|
||||||
{card = card, xmult = extra.xmult} or
|
{card = card, xmult = extra.xmult} or
|
||||||
(context.before and {card = card, xmult = extra.before} or nil)
|
(context.initial_scoring_step and {card = card, xmult = extra.before} or nil)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -938,10 +936,14 @@ joker {
|
||||||
local extra, numerator, xmult = card.ability.extra, 1, 1
|
local extra, numerator, xmult = card.ability.extra, 1, 1
|
||||||
|
|
||||||
if G.GAME.blind.name == "bl_mp_nemesis" then
|
if G.GAME.blind.name == "bl_mp_nemesis" then
|
||||||
return {card = card, xmult = extra.odds}
|
local n, d = SMODS.get_probability_vars(card, 1, extra.odds, self.key)
|
||||||
|
return n < d and {card = card, xmult = extra.odds} or nil
|
||||||
end
|
end
|
||||||
|
|
||||||
for _ = 1, 256 do
|
-- 2^38 is the first iteration displayed as scientific notation.
|
||||||
|
local max, overflown = 38, false
|
||||||
|
|
||||||
|
for i = 1, max do
|
||||||
local key = "RolandMartingale" .. tostring(G.GAME.modifiers.Roland_martingale_seed or "")
|
local key = "RolandMartingale" .. tostring(G.GAME.modifiers.Roland_martingale_seed or "")
|
||||||
|
|
||||||
if SMODS.pseudorandom_probability(card, self.key, 1, extra.odds, key) then
|
if SMODS.pseudorandom_probability(card, self.key, 1, extra.odds, key) then
|
||||||
|
|
@ -953,9 +955,18 @@ joker {
|
||||||
xmult = xmult * extra.odds
|
xmult = xmult * extra.odds
|
||||||
local message = number_format(numerator) .. "/" .. number_format(xmult)
|
local message = number_format(numerator) .. "/" .. number_format(xmult)
|
||||||
SMODS.calculate_effect({card = card, repetitions = 1, message = message, message_card = card}, card)
|
SMODS.calculate_effect({card = card, repetitions = 1, message = message, message_card = card}, card)
|
||||||
|
overflown = overflown or i == max
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if overflown then
|
||||||
|
SMODS.calculate_effect({card = card, score = 1 / 0}, card)
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
card:shatter()
|
||||||
|
end)
|
||||||
|
else
|
||||||
SMODS.calculate_effect({card = card, xmult = xmult}, card)
|
SMODS.calculate_effect({card = card, xmult = xmult}, card)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1201,7 +1212,10 @@ joker {
|
||||||
local delta = (context.cardarea == G.play and not card.blueprint) and 1 or 0
|
local delta = (context.cardarea == G.play and not card.blueprint) and 1 or 0
|
||||||
extra.scored = extra.scored + delta
|
extra.scored = extra.scored + delta
|
||||||
|
|
||||||
if not extra.flipped and extra.scored == extra.required then
|
if not extra.getting_flipped and
|
||||||
|
not extra.flipped and
|
||||||
|
extra.scored == extra.required then
|
||||||
|
extra.getting_flipped = true
|
||||||
Bakery_API.flip_double_sided(card)
|
Bakery_API.flip_double_sided(card)
|
||||||
|
|
||||||
q(function()
|
q(function()
|
||||||
|
|
@ -1209,7 +1223,7 @@ joker {
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return extra.scored > extra.required and {card = card, xmult = card.ability.extra.xmult} or
|
return extra.scored >= extra.required and {card = card, xmult = card.ability.extra.xmult} or
|
||||||
(delta > 0 and {
|
(delta > 0 and {
|
||||||
message = extra.scored .. "/" .. extra.required,
|
message = extra.scored .. "/" .. extra.required,
|
||||||
colour = G.C.JOKER_GREY,
|
colour = G.C.JOKER_GREY,
|
||||||
|
|
@ -1244,7 +1258,7 @@ joker {
|
||||||
return {card = card, numerator = extra.probability}
|
return {card = card, numerator = extra.probability}
|
||||||
end
|
end
|
||||||
|
|
||||||
if context.end_of_round and extra.probability ~= extra.reset then
|
if context.end_of_round and not context.repetition and extra.probability ~= extra.reset then
|
||||||
extra.probability = extra.reset
|
extra.probability = extra.reset
|
||||||
return {message = localize "k_reset", colour = G.C.RED, message_card = card, repetitions = 0}
|
return {message = localize "k_reset", colour = G.C.RED, message_card = card, repetitions = 0}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,81 +9,91 @@ local f = {}
|
||||||
|
|
||||||
if not f then
|
if not f then
|
||||||
---@generic I, O
|
---@generic I, O
|
||||||
---@param first fun(v: I): O
|
---@param first string|fun(v: I): O
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(first)
|
function f.chain(first)
|
||||||
error {first}
|
error {first}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T, O
|
---@generic I, T, O
|
||||||
---@param first fun(v: I): T
|
---@param first string|fun(v: I): T
|
||||||
---@param second fun(v: T): O
|
---@param second string|fun(v: T): O
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(first, second)
|
function f.chain(first, second)
|
||||||
error {first, second}
|
error {first, second}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T1, T2, O
|
---@generic I, T1, T2, O
|
||||||
---@param first fun(v: I): T1
|
---@param first string|fun(v: I): T1
|
||||||
---@param second fun(v: T1): T2
|
---@param second string|fun(v: T1): T2
|
||||||
---@param third fun(v: T2): O
|
---@param third string|fun(v: T2): O
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(first, second, third)
|
function f.chain(first, second, third)
|
||||||
error {first, second, third}
|
error {first, second, third}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T1, T2, T3, O
|
---@generic I, T1, T2, T3, O
|
||||||
---@param first fun(v: I): T1
|
---@param first string|fun(v: I): T1
|
||||||
---@param second fun(v: T1): T2
|
---@param second string|fun(v: T1): T2
|
||||||
---@param third fun(v: T2): T3
|
---@param third string|fun(v: T2): T3
|
||||||
---@param fourth fun(v: T3): O
|
---@param fourth string|fun(v: T3): O
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(first, second, third, fourth)
|
function f.chain(first, second, third, fourth)
|
||||||
error {first, second, third, fourth}
|
error {first, second, third, fourth}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T1, T2, T3, T4, O
|
---@generic I, T1, T2, T3, T4, O
|
||||||
---@param first fun(v: I): T1
|
---@param first string|fun(v: I): T1
|
||||||
---@param second fun(v: T1): T2
|
---@param second string|fun(v: T1): T2
|
||||||
---@param third fun(v: T2): T3
|
---@param third string|fun(v: T2): T3
|
||||||
---@param fourth fun(v: T3): T4
|
---@param fourth string|fun(v: T3): T4
|
||||||
---@param fifth fun(v: T4): O
|
---@param fifth string|fun(v: T4): O
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(first, second, third, fourth, fifth)
|
function f.chain(first, second, third, fourth, fifth)
|
||||||
error {first, second, third, fourth, fifth}
|
error {first, second, third, fourth, fifth}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, O
|
---@generic I, O
|
||||||
---@param all {[1]: (fun(v: I): O)}
|
---@param all { [1]: (string|fun(v: I): O) }
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(all)
|
function f.chain(all)
|
||||||
error(all)
|
error(all)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T, O
|
---@generic I, T, O
|
||||||
---@param all {[1]: (fun(v: I): T), [2]: (fun(v: T): O)}
|
---@param all { [1]: (string|fun(v: I): T), [2]: (string|fun(v: T): O) }
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(all)
|
function f.chain(all)
|
||||||
error(all)
|
error(all)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T1, T2, O
|
---@generic I, T1, T2, O
|
||||||
---@param all {[1]: (fun(v: I): T1), [2]: (fun(v: T1): T2), [3]: (fun(v: T2): O)}
|
---@param all { [1]: (string|fun(v: I): T1), [2]: (string|fun(v: T1): T2), [3]: (string|fun(v: T2): O) }
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(all)
|
function f.chain(all)
|
||||||
error(all)
|
error(all)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T1, T2, T3, O
|
---@generic I, T1, T2, T3, O
|
||||||
---@param all {[1]: (fun(v: I): T1), [2]: (fun(v: T1): T2), [3]: (fun(v: T2): T3), [4]: (fun(v: T3): O)}
|
---@param all { [1]: (string|fun(v: I): T1), [2]: (string|fun(v: T1): T2), [3]: (string|fun(v: T2): T3), [4]: (string|fun(v: T3): O) }
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(all)
|
function f.chain(all)
|
||||||
error(all)
|
error(all)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic I, T1, T2, T3, T4, O
|
---@generic I, T1, T2, T3, T4, O
|
||||||
---@param all {[1]: (fun(v: I): T1), [2]: (fun(v: T1): T2), [3]: (fun(v: T2): T3), [4]: (fun(v: T3): T4), [4]: (fun(v: T4): O)}
|
---@param all { [1]: (string|fun(v: I): T1), [2]: (string|fun(v: T1): T2), [3]: (string|fun(v: T2): T3), [4]: (string|fun(v: T3): T4), [4]: (string|fun(v: T4): O) }
|
||||||
---@return fun(v: I): O
|
---@return fun(v: I): O
|
||||||
|
---@nodiscard
|
||||||
function f.chain(all)
|
function f.chain(all)
|
||||||
error(all)
|
error(all)
|
||||||
end
|
end
|
||||||
|
|
@ -104,7 +114,7 @@ local none
|
||||||
---@return T
|
---@return T
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
local function autofunc(func)
|
local function autofunc(func)
|
||||||
return type(func) == "string" and f.index(func) or func or f.id
|
return type(func) == "string" and f.indices(func) or func or f.id
|
||||||
end
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
|
|
@ -118,13 +128,6 @@ local function autopairs(tbl, fpairs)
|
||||||
return (fpairs or (tbl[#tbl] and ipairs or pairs))(tbl)
|
return (fpairs or (tbl[#tbl] and ipairs or pairs))(tbl)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param any any
|
|
||||||
---@return boolean
|
|
||||||
---@nodiscard
|
|
||||||
local function is_f(any)
|
|
||||||
return type(any) == "table" and any.from == f.from and any.new == f.new
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Always returns nil.
|
--- Always returns nil.
|
||||||
---@return nil
|
---@return nil
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
|
|
@ -157,6 +160,7 @@ end
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param value T
|
---@param value T
|
||||||
---@return fun(T): boolean
|
---@return fun(T): boolean
|
||||||
|
---@nodiscard
|
||||||
function f.eq(value)
|
function f.eq(value)
|
||||||
return function(v)
|
return function(v)
|
||||||
return value == v
|
return value == v
|
||||||
|
|
@ -166,6 +170,7 @@ end
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param value T
|
---@param value T
|
||||||
---@return fun(T): boolean
|
---@return fun(T): boolean
|
||||||
|
---@nodiscard
|
||||||
function f.nq(value)
|
function f.nq(value)
|
||||||
return function(v)
|
return function(v)
|
||||||
return value ~= v
|
return value ~= v
|
||||||
|
|
@ -190,6 +195,15 @@ function f.const(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param i integer
|
||||||
|
---@return fun(...: any): any
|
||||||
|
---@nodiscard
|
||||||
|
function f.arg(i)
|
||||||
|
return function(...)
|
||||||
|
return ({...})[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param v K
|
---@param v K
|
||||||
---@return fun(x: { [K]: V }): V
|
---@return fun(x: { [K]: V }): V
|
||||||
|
|
@ -228,17 +242,32 @@ function f.indices(v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param any any
|
||||||
|
---@return boolean
|
||||||
|
---@nodiscard
|
||||||
|
function f.isf(any)
|
||||||
|
return type(any) == "table" and any.from == f.from and any.new == f.new
|
||||||
|
end
|
||||||
|
|
||||||
f[true and "chain"] = function(...)
|
f[true and "chain"] = function(...)
|
||||||
for _, v in ipairs(...) do
|
local ret
|
||||||
|
|
||||||
|
for _, v in ipairs {...} do
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
for _, vv in ipairs(v) do
|
for _, vv in ipairs(v) do
|
||||||
|
local copy = ret
|
||||||
|
vv = autofunc(vv)
|
||||||
|
|
||||||
ret = ret and function(...)
|
ret = ret and function(...)
|
||||||
return vv(ret(...))
|
return vv(copy(...))
|
||||||
end or vv
|
end or vv
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
local copy = ret
|
||||||
|
v = autofunc(v)
|
||||||
|
|
||||||
ret = ret and function(...)
|
ret = ret and function(...)
|
||||||
return v(ret(...))
|
return v(copy(...))
|
||||||
end or v
|
end or v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -255,6 +284,7 @@ function f.new(fnext)
|
||||||
return {
|
return {
|
||||||
all = f.all,
|
all = f.all,
|
||||||
any = f.any,
|
any = f.any,
|
||||||
|
arg = f.arg,
|
||||||
chain = f.chain,
|
chain = f.chain,
|
||||||
concat = f.concat,
|
concat = f.concat,
|
||||||
const = f.const,
|
const = f.const,
|
||||||
|
|
@ -269,12 +299,14 @@ function f.new(fnext)
|
||||||
index = f.index,
|
index = f.index,
|
||||||
index_into = f.index_into,
|
index_into = f.index_into,
|
||||||
indices = f.indices,
|
indices = f.indices,
|
||||||
|
isf = f.isf,
|
||||||
keys = f.keys,
|
keys = f.keys,
|
||||||
map = f.map,
|
map = f.map,
|
||||||
new = f.new,
|
new = f.new,
|
||||||
next = fnext or f.noop,
|
next = fnext or f.noop,
|
||||||
noop = f.noop,
|
noop = f.noop,
|
||||||
nq = f.nq,
|
nq = f.nq,
|
||||||
|
peek = f.peek,
|
||||||
pun = f.pun,
|
pun = f.pun,
|
||||||
skip = f.skip,
|
skip = f.skip,
|
||||||
slice = f.slice,
|
slice = f.slice,
|
||||||
|
|
@ -354,7 +386,7 @@ function f:concat(...)
|
||||||
local sum, last = 0, 0
|
local sum, last = 0, 0
|
||||||
|
|
||||||
for i = 1, #fs do
|
for i = 1, #fs do
|
||||||
fs[i] = is_f(fs[i]) and fs[i] or f.from(fs[i])
|
fs[i] = f.isf(fs[i]) and fs[i] or f.from(fs[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -382,12 +414,30 @@ function f:concat(...)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@generic K, V
|
||||||
|
---@param self F|{ [K]: V }
|
||||||
|
---@param func fun(v: V, k: K): any
|
||||||
|
---@return F|{ [K]: V }
|
||||||
|
---@nodiscard
|
||||||
|
function f:peek(func)
|
||||||
|
func = autofunc(func)
|
||||||
|
|
||||||
|
return f.new(function()
|
||||||
|
local k, v = self:next()
|
||||||
|
|
||||||
|
if k ~= nil then
|
||||||
|
func(v, k)
|
||||||
|
return k, v
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V, U
|
---@generic K, V, U
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func F|fun(v: V, k: K): U
|
---@param func fun(v: V, k: K): U
|
||||||
---@return F|{ [K]: U }
|
---@return F|{ [K]: U }
|
||||||
---@nodiscard
|
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U }
|
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: U }
|
||||||
|
---@nodiscard
|
||||||
function f:map(func)
|
function f:map(func)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
|
|
@ -402,61 +452,11 @@ end
|
||||||
|
|
||||||
---@generic K, V, U
|
---@generic K, V, U
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func F|fun(v: V, k: K): { [any]: U }
|
---@param func fun(v: V, k: K): { [any]: U }
|
||||||
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
|
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
|
||||||
---@return F|{ [K]: U }
|
---@return F|{ [K]: U }
|
||||||
---@nodiscard
|
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string, fpairs?: fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)): F|{ [K]: U }
|
---@overload fun(self: F|{ [K]: V }, func: string, fpairs?: fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)): F|{ [K]: U }
|
||||||
function f:flatmap(func, fpairs)
|
|
||||||
-- local i = 0
|
|
||||||
local vt, vk, vv, vp
|
|
||||||
func = autofunc(func)
|
|
||||||
|
|
||||||
return f.new(function()
|
|
||||||
if vk then
|
|
||||||
vk, vv = vp(vt, vk)
|
|
||||||
|
|
||||||
if vk ~= nil then
|
|
||||||
-- i = i + 1
|
|
||||||
-- return i, vv
|
|
||||||
return vk, vv
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local k, v = self:next()
|
|
||||||
|
|
||||||
if k == nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
v = func(v, k)
|
|
||||||
|
|
||||||
if type(v) ~= "table" then
|
|
||||||
-- i = i + 1
|
|
||||||
-- return i, v
|
|
||||||
return k, v
|
|
||||||
end
|
|
||||||
|
|
||||||
vp, vt, vk = autopairs(v, fpairs)
|
|
||||||
vk, vv = vp(vt, vk)
|
|
||||||
|
|
||||||
if vk ~= nil then
|
|
||||||
-- i = i + 1
|
|
||||||
-- return i, vv
|
|
||||||
return vk, vv
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@generic K, V, U
|
|
||||||
---@param self F|{ [K]: V }
|
|
||||||
---@param func F|fun(v: V, k: K): { [any]: U }
|
|
||||||
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
|
|
||||||
---@return F|{ [K]: U }
|
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@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 }
|
|
||||||
function f:flatmap(func, fpairs)
|
function f:flatmap(func, fpairs)
|
||||||
-- local i = 0
|
-- local i = 0
|
||||||
local vt, vk, vv, vp
|
local vt, vk, vv, vp
|
||||||
|
|
@ -502,7 +502,7 @@ end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func F|fun(v: V, k: K): boolean
|
---@param func fun(v: V, k: K): boolean
|
||||||
---@param is? any
|
---@param is? any
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
|
|
@ -665,10 +665,10 @@ end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func F|fun(v: V, k: K): any
|
---@param func fun(v: V, k: K): any
|
||||||
---@return boolean|V
|
---@return boolean|V
|
||||||
---@nodiscard
|
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||||
|
---@nodiscard
|
||||||
function f:any(func)
|
function f:any(func)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
|
|
@ -683,10 +683,10 @@ end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func F|fun(v: V, k: K): any
|
---@param func fun(v: V, k: K): any
|
||||||
---@return boolean|V
|
---@return boolean|V
|
||||||
---@nodiscard
|
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||||
|
---@nodiscard
|
||||||
function f:all(func)
|
function f:all(func)
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
||||||
|
|
@ -701,10 +701,10 @@ end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param func F|fun(v: V, k: K): any
|
---@param func fun(v: V, k: K): any
|
||||||
---@return integer
|
---@return integer
|
||||||
---@nodiscard
|
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
---@overload fun(self: F|{ [K]: V }, func: string): integer
|
||||||
|
---@nodiscard
|
||||||
function f:count(func)
|
function f:count(func)
|
||||||
local ret = 0
|
local ret = 0
|
||||||
func = autofunc(func)
|
func = autofunc(func)
|
||||||
|
|
|
||||||
76
src/lib/intellisense.lua
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
---@meta
|
||||||
|
---@alias Attributes "mult"|"chips"|"xmult"|"xchips"|"score"|"xscore"|"blindsize"|"xblindsize"|"balance"|"swap"|"retrigger"|"scaling"|"reset"|"suit"|"diamonds"|"hearts"|"spades"|"clubs"|"hand_type"|"rank"|"ace"|"two"|"three"|"four"|"five"|"six"|"seven"|"eight"|"nine"|"ten"|"jack"|"queen"|"king"|"face"|"economy"|"generation"|"destroy_card"|"hands"|"discard"|"hand_size"|"chance"|"joker_slot"|"mod_chance"|"copying"|"full_deck"|"passive"|"joker"|"tarot"|"planet"|"spectral"|"enhancements"|"seals"|"editions"|"tag"|"skip"|"modify_card"|"perma_bonus"|"prevents_death"|"boss_blind"|"reroll"|"on_sell"|"sell_value"|"food"|"space"|"bakery_double_sided"|"bakery_usable"|"bakery_werewolf"
|
||||||
|
---@type Card[]
|
||||||
|
CardArea.cards = CardArea.cards
|
||||||
|
|
||||||
|
--- @overload fun(tbl: SMODS.Joker): SMODS.GameObject
|
||||||
|
Bakery_API.Charm = Bakery_API.Charm
|
||||||
|
|
||||||
|
--- @generic T: SMODS.GameObject
|
||||||
|
--- @param obj T
|
||||||
|
--- @return T
|
||||||
|
function Bakery_API.credit(obj)
|
||||||
|
error(obj)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@type table
|
||||||
|
Balatest = Balatest
|
||||||
|
|
||||||
|
--- @type { constants?: { TEN: table }, new: (fun(self: self, arr?: number[], sign?: number, noNormalize?: boolean): table), pow: (fun(x: number, y: number): number) }
|
||||||
|
Big = Big
|
||||||
|
|
||||||
|
--- @type table?
|
||||||
|
CardSleeves = CardSleeves
|
||||||
|
|
||||||
|
--- @type table|fun(obj: SMODS.Back): SMODS.Back
|
||||||
|
CardSleeves.Sleeve = CardSleeves.Sleeve
|
||||||
|
|
||||||
|
--- @type {aliases: { [string]: [string] }}
|
||||||
|
Cryptid = Cryptid
|
||||||
|
|
||||||
|
--- @type fun(area: CardArea, ...: ...): Card
|
||||||
|
create_card_for_shop = create_card_for_shop
|
||||||
|
|
||||||
|
--- @type boolean|table
|
||||||
|
G.Bakery_charm_area.cards[1].ability.extra = G.Bakery_charm_area.cards[1].ability.extra
|
||||||
|
|
||||||
|
SMODS.Mods.Roland.config = require "config"
|
||||||
|
|
||||||
|
---@type userdata|{getWidth: fun(self: self): number}
|
||||||
|
SMODS.Atlas.image_data = SMODS.Atlas.image_data
|
||||||
|
|
||||||
|
--- @type table
|
||||||
|
Talisman = Talisman
|
||||||
|
|
||||||
|
--- @type fun(obj: any): number
|
||||||
|
to_number = to_number
|
||||||
|
|
||||||
|
-- This exists to remove the @deprecated warning.
|
||||||
|
---Returns the elements from the given `list`. This function is equivalent to
|
||||||
|
---```lua
|
||||||
|
--- return list[i], list[i+1], ···, list[j]
|
||||||
|
---```
|
||||||
|
---
|
||||||
|
---
|
||||||
|
---[View documents](command:extension.lua.doc?["en-us/52/manual.html/pdf-unpack"])
|
||||||
|
---
|
||||||
|
---@generic T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
|
||||||
|
---@param list {
|
||||||
|
--- [1]?: T1,
|
||||||
|
--- [2]?: T2,
|
||||||
|
--- [3]?: T3,
|
||||||
|
--- [4]?: T4,
|
||||||
|
--- [5]?: T5,
|
||||||
|
--- [6]?: T6,
|
||||||
|
--- [7]?: T7,
|
||||||
|
--- [8]?: T8,
|
||||||
|
--- [9]?: T9,
|
||||||
|
--- [10]?: T10,
|
||||||
|
---}
|
||||||
|
---@param i? integer
|
||||||
|
---@param j? integer
|
||||||
|
---@return T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
|
||||||
|
---@nodiscard
|
||||||
|
function unpack(list, i, j)
|
||||||
|
error {list, i, j}
|
||||||
|
end
|
||||||
|
|
@ -1,5 +1,59 @@
|
||||||
local f = assert(SMODS.load_file "src/lib/funky.lua")() or require "lib.funky"
|
local f = assert(SMODS.load_file "src/lib/funky.lua")() or require "lib.funky"
|
||||||
|
|
||||||
|
---@param v string
|
||||||
|
---@return Card|Tag
|
||||||
|
local function add(v)
|
||||||
|
if not G.P_TAGS[v] then
|
||||||
|
return SMODS.add_card {no_edition = true, key = v}
|
||||||
|
end
|
||||||
|
|
||||||
|
local tag = Tag(v)
|
||||||
|
|
||||||
|
if tag.name == "Orbital Tag" then
|
||||||
|
local hands = f(G.GAME.hands):where "visible":keys():table()
|
||||||
|
tag.ability.orbital_hand = pseudorandom_element(hands, pseudoseed "Roland_c_orbital_tag")
|
||||||
|
end
|
||||||
|
|
||||||
|
add_tag(tag)
|
||||||
|
return tag
|
||||||
|
end
|
||||||
|
|
||||||
|
local function simplify(x)
|
||||||
|
return type(x) == "string" and x:lower():gsub("%s", ""):gsub("_", ""):gsub("^the", "") or x
|
||||||
|
end
|
||||||
|
|
||||||
|
local function flatten(v)
|
||||||
|
return type(v) ~= "table" and {v} or (f.isf(v) and v:table() or v)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param it string
|
||||||
|
local function find(it)
|
||||||
|
if (G.P_CENTERS[it] or {}).config then
|
||||||
|
return it
|
||||||
|
end
|
||||||
|
|
||||||
|
local match = simplify(it)
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
if Cryptid and Cryptid.aliases and Cryptid.aliases[it] then
|
||||||
|
return Cryptid.aliases[it]
|
||||||
|
end
|
||||||
|
|
||||||
|
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 match == simplify(k) or match == simplify(v.name)
|
||||||
|
end)
|
||||||
|
:keys()
|
||||||
|
:any()
|
||||||
|
end
|
||||||
|
|
||||||
local function protect(fun)
|
local function protect(fun)
|
||||||
return function()
|
return function()
|
||||||
local res, ret = pcall(fun)
|
local res, ret = pcall(fun)
|
||||||
|
|
@ -21,69 +75,20 @@ local function protect_ev(fun)
|
||||||
return Event {
|
return Event {
|
||||||
blocking = false,
|
blocking = false,
|
||||||
no_delete = true,
|
no_delete = true,
|
||||||
func = function()
|
func = protect(function()
|
||||||
if not Bakery_API or not Bakery_API.credit then
|
if not Bakery_API or not Bakery_API.credit then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
Bakery_API.credit(fun)
|
Bakery_API.credit(fun)
|
||||||
return true
|
end),
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fun.func = protect(fun.func)
|
fun.func = protect(fun.func or fun[1])
|
||||||
return getmetatable(fun) == Event and fun or Event(fun)
|
return getmetatable(fun) == Event and fun or Event(fun)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@alias Attributes "mult"|"chips"|"xmult"|"xchips"|"score"|"xscore"|"blindsize"|"xblindsize"|"balance"|"swap"|"retrigger"|"scaling"|"reset"|"suit"|"diamonds"|"hearts"|"spades"|"clubs"|"hand_type"|"rank"|"ace"|"two"|"three"|"four"|"five"|"six"|"seven"|"eight"|"nine"|"ten"|"jack"|"queen"|"king"|"face"|"economy"|"generation"|"destroy_card"|"hands"|"discard"|"hand_size"|"chance"|"joker_slot"|"mod_chance"|"copying"|"full_deck"|"passive"|"joker"|"tarot"|"planet"|"spectral"|"enhancements"|"seals"|"editions"|"tag"|"skip"|"modify_card"|"perma_bonus"|"prevents_death"|"boss_blind"|"reroll"|"on_sell"|"sell_value"|"food"|"space"|"bakery_double_sided"
|
|
||||||
if false then
|
|
||||||
-- This allows for better type inference.
|
|
||||||
SMODS.Mods.Roland.config = require "config"
|
|
||||||
|
|
||||||
---@type Card[]
|
|
||||||
CardArea.cards = CardArea.cards
|
|
||||||
|
|
||||||
---@type userdata|{getWidth: fun(self: self): number}
|
|
||||||
SMODS.Atlas.image_data = SMODS.Atlas.image_data
|
|
||||||
|
|
||||||
--- @type { constants?: { TEN: table }, new: (fun(self: self, arr?: number[], sign?: number, noNormalize?: boolean): table), pow: (fun(x: number, y: number): number) }
|
|
||||||
_G["Big"] = _G["Big"]
|
|
||||||
|
|
||||||
--- @type fun(area: CardArea, ...: ...): Card
|
|
||||||
create_card_for_shop = create_card_for_shop
|
|
||||||
|
|
||||||
-- This exists to remove the @deprecated warning.
|
|
||||||
---Returns the elements from the given `list`. This function is equivalent to
|
|
||||||
---```lua
|
|
||||||
--- return list[i], list[i+1], ···, list[j]
|
|
||||||
---```
|
|
||||||
---
|
|
||||||
---
|
|
||||||
---[View documents](command:extension.lua.doc?["en-us/52/manual.html/pdf-unpack"])
|
|
||||||
---
|
|
||||||
---@generic T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
|
|
||||||
---@param list {
|
|
||||||
--- [1]?: T1,
|
|
||||||
--- [2]?: T2,
|
|
||||||
--- [3]?: T3,
|
|
||||||
--- [4]?: T4,
|
|
||||||
--- [5]?: T5,
|
|
||||||
--- [6]?: T6,
|
|
||||||
--- [7]?: T7,
|
|
||||||
--- [8]?: T8,
|
|
||||||
--- [9]?: T9,
|
|
||||||
--- [10]?: T10,
|
|
||||||
---}
|
|
||||||
---@param i? integer
|
|
||||||
---@param j? integer
|
|
||||||
---@return T1, T2, T3, T4, T5, T6, T7, T8, T9, T10
|
|
||||||
---@nodiscard
|
|
||||||
function unpack(list, i, j)
|
|
||||||
error {list, i, j}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Queues an event to be run.
|
--- Queues an event to be run.
|
||||||
--- Note that events added this way implicitly `return true` unless you explicitly `return false`.
|
--- Note that events added this way implicitly `return true` unless you explicitly `return false`.
|
||||||
--- For `front`; boolean `true` to add the event to the front of the queue, rather than the end.
|
--- For `front`; boolean `true` to add the event to the front of the queue, rather than the end.
|
||||||
|
|
@ -105,4 +110,35 @@ local function u()
|
||||||
G.STATE ~= G.STATES.PLAY_TAROT)
|
G.STATE ~= G.STATES.PLAY_TAROT)
|
||||||
end
|
end
|
||||||
|
|
||||||
return {f, q, u}
|
--- Creates one or more cards.
|
||||||
|
---@param ... any
|
||||||
|
---@return Card|Tag|(Card|Tag[])
|
||||||
|
local function c(...)
|
||||||
|
local cards = f {...}
|
||||||
|
:flatmap(flatten)
|
||||||
|
:where(type, "string")
|
||||||
|
:map(string.lower)
|
||||||
|
:map(find)
|
||||||
|
:where(f.id)
|
||||||
|
:map(add)
|
||||||
|
:values()
|
||||||
|
:table()
|
||||||
|
|
||||||
|
return #cards > 1 and cards or cards[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
return {f, q, u, setmetatable({}, {
|
||||||
|
__call = function(_, ...)
|
||||||
|
return c(...)
|
||||||
|
end,
|
||||||
|
__index = function(_, k)
|
||||||
|
return c(k)
|
||||||
|
end,
|
||||||
|
__newindex = function(_, k, v)
|
||||||
|
local n = tonumber(v)
|
||||||
|
|
||||||
|
for _ = 1, type(n) == "number" and n or 1 do
|
||||||
|
c(k)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})}
|
||||||
|
|
|
||||||
27
src/main.lua
|
|
@ -52,18 +52,32 @@ q {
|
||||||
-- G.ARGS.LOC_COLOURS["Bakery_credit_bg_Roland_" .. k] = v.bg
|
-- G.ARGS.LOC_COLOURS["Bakery_credit_bg_Roland_" .. k] = v.bg
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if SMODS.Mods.DebugPlus and SMODS.Mods.Roland.config.import_funky then
|
if not SMODS.Mods.DebugPlus or not SMODS.Mods.Roland.config.import_funky then
|
||||||
_G.f, _G.q, _G.u = unpack(qol)
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
_G.f, _G.q, _G.u, _G.c = unpack(qol)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
f {"challenge", "spectral", "edition", "tweaks", "blind", "charm", "joker", "tarot", "back", "seal", "tag"}
|
f {
|
||||||
:each(function(v)
|
"challenge",
|
||||||
|
"spectral",
|
||||||
|
"edition",
|
||||||
|
"tweaks",
|
||||||
|
"blind",
|
||||||
|
"charm",
|
||||||
|
"joker",
|
||||||
|
"tarot",
|
||||||
|
"back",
|
||||||
|
"seal",
|
||||||
|
"tag",
|
||||||
|
"voucher",
|
||||||
|
}:each(function(v)
|
||||||
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if _G["Balatest"] then
|
if Balatest then
|
||||||
f {"joker", "blind", "spectral"}:each(function(v)
|
f {"joker", "blind", "spectral"}:each(function(v)
|
||||||
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
|
assert(SMODS.load_file("src/tests/" .. v .. ".tests.lua"))(qol)
|
||||||
end)
|
end)
|
||||||
|
|
@ -99,6 +113,7 @@ function SMODS.current_mod.config_tab()
|
||||||
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.CLEAR},
|
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.CLEAR},
|
||||||
nodes = {
|
nodes = {
|
||||||
toggle "animated_icon",
|
toggle "animated_icon",
|
||||||
|
toggle "cool_phones",
|
||||||
toggle "faster_planets",
|
toggle "faster_planets",
|
||||||
-- toggle "illusion_seal",
|
-- toggle "illusion_seal",
|
||||||
-- toggle "no_wild_debuff",
|
-- toggle "no_wild_debuff",
|
||||||
|
|
@ -106,7 +121,7 @@ function SMODS.current_mod.config_tab()
|
||||||
toggle "equinox_assist",
|
toggle "equinox_assist",
|
||||||
SMODS.Mods.DebugPlus and toggle "import_funky",
|
SMODS.Mods.DebugPlus and toggle "import_funky",
|
||||||
G.P_CENTERS.c_Bakery_Scribe and toggle "scribable_basket",
|
G.P_CENTERS.c_Bakery_Scribe and toggle "scribable_basket",
|
||||||
_G["Talisman"] and toggle "harsh_ante_scaling",
|
Talisman and toggle "harsh_ante_scaling",
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,15 +69,15 @@ spectral {
|
||||||
table.insert(info_queue, G.P_CENTERS.m_stone)
|
table.insert(info_queue, G.P_CENTERS.m_stone)
|
||||||
end,
|
end,
|
||||||
can_use = function()
|
can_use = function()
|
||||||
return u() and not not next(G.hand.cards)
|
return next(G.hand.cards) and u()
|
||||||
end,
|
end,
|
||||||
use = function(_, card)
|
use = function(_, card)
|
||||||
q {
|
q {
|
||||||
trigger = "after",
|
trigger = "after",
|
||||||
delay = 0.4,
|
delay = 0.4,
|
||||||
func = function()
|
func = function()
|
||||||
play_sound("tarot1")
|
|
||||||
card:juice_up(0.3, 0.5)
|
card:juice_up(0.3, 0.5)
|
||||||
|
play_sound("tarot1")
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,8 +89,8 @@ spectral {
|
||||||
delay = 0.15,
|
delay = 0.15,
|
||||||
func = function()
|
func = function()
|
||||||
v:flip()
|
v:flip()
|
||||||
play_sound("card1", percent)
|
|
||||||
v:juice_up(0.3, 0.3)
|
v:juice_up(0.3, 0.3)
|
||||||
|
play_sound("card1", percent)
|
||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
@ -110,8 +110,8 @@ spectral {
|
||||||
delay = 0.15,
|
delay = 0.15,
|
||||||
func = function()
|
func = function()
|
||||||
v:flip()
|
v:flip()
|
||||||
play_sound("tarot2", percent, 0.6)
|
|
||||||
v:juice_up(0.3, 0.3)
|
v:juice_up(0.3, 0.3)
|
||||||
|
play_sound("tarot2", percent, 0.6)
|
||||||
return true
|
return true
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +155,7 @@ spectral {
|
||||||
return {vars = {card.ability.extra.amount}}
|
return {vars = {card.ability.extra.amount}}
|
||||||
end,
|
end,
|
||||||
can_use = function()
|
can_use = function()
|
||||||
return #G.playing_cards > 1 and not not u()
|
return next(G.playing_cards) and u()
|
||||||
end,
|
end,
|
||||||
use = function(_, card)
|
use = function(_, card)
|
||||||
local function destructible(v)
|
local function destructible(v)
|
||||||
|
|
|
||||||
|
|
@ -192,9 +192,9 @@ Balatest.TestPlay {
|
||||||
}
|
}
|
||||||
|
|
||||||
Balatest.TestPlay {
|
Balatest.TestPlay {
|
||||||
category = {"blind", "xerox"},
|
category = {"blind", "mitotic"},
|
||||||
name = "xerox",
|
name = "mitotic",
|
||||||
blind = "bl_Roland_xerox",
|
blind = "bl_Roland_mitotic",
|
||||||
execute = function()
|
execute = function()
|
||||||
Balatest.discard {"2S"}
|
Balatest.discard {"2S"}
|
||||||
end,
|
end,
|
||||||
|
|
@ -204,9 +204,9 @@ Balatest.TestPlay {
|
||||||
}
|
}
|
||||||
|
|
||||||
Balatest.TestPlay {
|
Balatest.TestPlay {
|
||||||
category = {"blind", "xerox"},
|
category = {"blind", "mitotic"},
|
||||||
name = "xerox_disabled",
|
name = "mitotic_disabled",
|
||||||
blind = "bl_Roland_xerox",
|
blind = "bl_Roland_mitotic",
|
||||||
jokers = {"j_chicot"},
|
jokers = {"j_chicot"},
|
||||||
execute = function()
|
execute = function()
|
||||||
Balatest.discard {"2S"}
|
Balatest.discard {"2S"}
|
||||||
|
|
|
||||||
|
|
@ -2,330 +2,6 @@ if not Balatest then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_none",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
execute = function() end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert(not G.jokers.cards[1].config.center:Bakery_can_use(G.jokers.cards[1]))
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_one_consumable",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength"},
|
|
||||||
execute = function()
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_two_consumables",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength", "c_strength"},
|
|
||||||
execute = function()
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 3)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_one_tag",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
no_auto_start = true,
|
|
||||||
execute = function()
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_two_tags",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
no_auto_start = true,
|
|
||||||
execute = function()
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 3)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_consumables_and_tags",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength"},
|
|
||||||
no_auto_start = true,
|
|
||||||
execute = function()
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_partial_selected_consumables_and_tags",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength", "c_strength"},
|
|
||||||
no_auto_start = true,
|
|
||||||
execute = function()
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.consumeables:add_to_highlighted(G.consumeables.cards[1])
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "escape"},
|
|
||||||
name = "escapey_full_selected_consumables_and_tags",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength"},
|
|
||||||
no_auto_start = true,
|
|
||||||
execute = function()
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.consumeables:add_to_highlighted(G.consumeables.cards[1])
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 3)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "fuse"},
|
|
||||||
name = "escapey_fusion",
|
|
||||||
jokers = {"j_Roland_escapey", "j_Roland_escapey"},
|
|
||||||
execute = function()
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(#G.jokers.cards, 1)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "fuse"},
|
|
||||||
name = "escapey_consumable_takes_precedence",
|
|
||||||
jokers = {"j_Roland_escapey", "j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength"},
|
|
||||||
execute = function()
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(#G.jokers.cards, 2)
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "fuse"},
|
|
||||||
name = "escapey_tag_takes_precedence",
|
|
||||||
jokers = {"j_Roland_escapey", "j_Roland_escapey"},
|
|
||||||
no_auto_start = true,
|
|
||||||
execute = function()
|
|
||||||
Balatest.skip_blind("tag_investment")
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(#G.jokers.cards, 2)
|
|
||||||
Balatest.assert_eq(G.GAME.hands["High Card"].level, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "fuse"},
|
|
||||||
name = "escapey_fusion_takes_precedence",
|
|
||||||
jokers = {"j_Roland_escapey", "j_Roland_escapey"},
|
|
||||||
consumeables = {"c_strength"},
|
|
||||||
execute = function()
|
|
||||||
Balatest.q(function()
|
|
||||||
G.consumeables:add_to_highlighted(G.consumeables.cards[1])
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(#G.jokers.cards, 1)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 2)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "fuse"},
|
|
||||||
name = "escapey_scribe_fusion",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
execute = function()
|
|
||||||
if not G.P_CENTERS.c_Bakery_Scribe then
|
|
||||||
sendWarnMessage("escapey_scribe_fusion cannot run without c_Bakery_Scribe, skipping test.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
local scribe = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_Bakery_Scribe", "balatest")
|
|
||||||
scribe:add_to_deck()
|
|
||||||
G.consumeables:emplace(scribe)
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.jokers:add_to_highlighted(G.jokers.cards[1])
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
Balatest.use(function() return G.consumeables.cards[1] end)
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[1]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
if not G.P_CENTERS.c_Bakery_Scribe then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
Balatest.assert_eq(#G.jokers.cards, 1)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 1)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"joker", "escapey", "fuse"},
|
|
||||||
name = "escapey_scribe_fusion_alt",
|
|
||||||
jokers = {"j_Roland_escapey"},
|
|
||||||
execute = function()
|
|
||||||
if not G.P_CENTERS.c_Bakery_Scribe then
|
|
||||||
sendWarnMessage("escapey_scribe_fusion_alt cannot run without c_Bakery_Scribe, skipping test.")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
local scribe = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_Bakery_Scribe", "balatest")
|
|
||||||
scribe:add_to_deck()
|
|
||||||
G.consumeables:emplace(scribe)
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.jokers:add_to_highlighted(G.jokers.cards[1])
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
Balatest.use(function() return G.consumeables.cards[1] end)
|
|
||||||
|
|
||||||
Balatest.q(function()
|
|
||||||
G.jokers:add_to_highlighted(G.jokers.cards[2])
|
|
||||||
G.FUNCS.Bakery_use_joker {config = {ref_table = G.jokers.cards[2]}}
|
|
||||||
end)
|
|
||||||
|
|
||||||
Balatest.wait()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
if not G.P_CENTERS.c_Bakery_Scribe then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
Balatest.assert_eq(#G.jokers.cards, 1)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].sell_cost, 8)
|
|
||||||
Balatest.assert_eq(G.jokers.cards[1].ability.extra.levels, 1)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
Balatest.TestPlay {
|
||||||
category = {"joker", "martingale"},
|
category = {"joker", "martingale"},
|
||||||
name = "martingale_oops",
|
name = "martingale_oops",
|
||||||
|
|
@ -334,7 +10,7 @@ Balatest.TestPlay {
|
||||||
Balatest.play_hand {"2S"}
|
Balatest.play_hand {"2S"}
|
||||||
end,
|
end,
|
||||||
assert = function()
|
assert = function()
|
||||||
Balatest.assert_chips(7 * 2)
|
Balatest.assert_chips(7)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,6 +23,6 @@ Balatest.TestPlay {
|
||||||
Balatest.play_hand {"2S"}
|
Balatest.play_hand {"2S"}
|
||||||
end,
|
end,
|
||||||
assert = function()
|
assert = function()
|
||||||
Balatest.assert_chips(7 * math.pow(2, 32))
|
Balatest.assert_chips(1 / 0)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,6 @@ if not Balatest then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
Balatest.TestPlay {
|
|
||||||
category = {"spectral", "afterimage"},
|
|
||||||
name = "afterimage",
|
|
||||||
consumeables = {"c_Roland_afterimage"},
|
|
||||||
deck = {cards = {{s = "S", r = "2"}}},
|
|
||||||
execute = function()
|
|
||||||
Balatest.highlight({"2S"})
|
|
||||||
Balatest.use(G.consumeables.cards[1])
|
|
||||||
Balatest.end_round()
|
|
||||||
end,
|
|
||||||
assert = function()
|
|
||||||
Balatest.assert_eq(G.hand.config.card_limit, 51)
|
|
||||||
Balatest.assert(G.deck.cards[1].edition.negative)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
Balatest.TestPlay {
|
Balatest.TestPlay {
|
||||||
category = {"spectral", "void"},
|
category = {"spectral", "void"},
|
||||||
name = "spectral",
|
name = "spectral",
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,16 @@ local f, q = (... or require "lib.shared")[1], (... or require "lib.shared")[2]
|
||||||
SMODS.Joker:take_ownership("joker", {cost = 1}, true)
|
SMODS.Joker:take_ownership("joker", {cost = 1}, true)
|
||||||
local orig_set_debuff = Card.set_debuff
|
local orig_set_debuff = Card.set_debuff
|
||||||
|
|
||||||
function Card:set_debuff(...)
|
function Card:set_debuff(should_debuff, ...)
|
||||||
|
if self.ability.Roland_crimson ~= nil then
|
||||||
|
self.ability.Roland_crimson = not not should_debuff
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if SMODS.get_enhancements(self).m_wild and SMODS.Mods.Roland.config.no_wild_debuff then
|
if SMODS.get_enhancements(self).m_wild and SMODS.Mods.Roland.config.no_wild_debuff then
|
||||||
self.debuff = false
|
self.debuff = false
|
||||||
else
|
else
|
||||||
orig_set_debuff(self, ...)
|
orig_set_debuff(self, should_debuff, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -62,7 +67,10 @@ function G.FUNCS.use_card(e, ...)
|
||||||
discover_card(ref.config.center)
|
discover_card(ref.config.center)
|
||||||
ref:use_consumeable(ref.area)
|
ref:use_consumeable(ref.area)
|
||||||
SMODS.calculate_context {area = ref.area, consumeable = ref, using_consumeable = true}
|
SMODS.calculate_context {area = ref.area, consumeable = ref, using_consumeable = true}
|
||||||
|
|
||||||
|
q(function()
|
||||||
ref:remove()
|
ref:remove()
|
||||||
|
end)
|
||||||
|
|
||||||
if normal then
|
if normal then
|
||||||
return
|
return
|
||||||
|
|
@ -94,11 +102,11 @@ local orig_get_blind_amount = get_blind_amount
|
||||||
---@param ante number
|
---@param ante number
|
||||||
---@return table|number
|
---@return table|number
|
||||||
local function blind(ante)
|
local function blind(ante)
|
||||||
return ante == 39 and 1e294 or (_G["to_number"] or f.id)(orig_get_blind_amount(ante))
|
return ante == 39 and 1e294 or (to_number or f.id)(orig_get_blind_amount(ante))
|
||||||
end
|
end
|
||||||
|
|
||||||
local function no_harsh_ante_scaling()
|
local function no_harsh_ante_scaling()
|
||||||
return not _G["Talisman"] or not SMODS.Mods.Roland.config.harsh_ante_scaling
|
return not Talisman or not SMODS.Mods.Roland.config.harsh_ante_scaling
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_blind_amount(ante, ...)
|
function get_blind_amount(ante, ...)
|
||||||
|
|
@ -112,10 +120,10 @@ function get_blind_amount(ante, ...)
|
||||||
return 1 / 0
|
return 1 / 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local big, rem = _G["Big"], tonumber(blind((ante % 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
|
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 / 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
|
(ante / 2 >= loop and Big:new {rem, ante / loop} or
|
||||||
(big.constants and big.constants.TEN or big:new {10}):pow(rem)))
|
(Big.constants and Big.constants.TEN or Big:new {10}):pow(rem)))
|
||||||
end
|
end
|
||||||
|
|
|
||||||
44
src/voucher.lua
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
local voucher = (function()
|
||||||
|
local x = 0
|
||||||
|
|
||||||
|
---@param tbl SMODS.Voucher|{attributes: Attributes[]}
|
||||||
|
---@return SMODS.Voucher
|
||||||
|
return function(tbl)
|
||||||
|
tbl.pos = {x = x, y = 0}
|
||||||
|
tbl.atlas = "voucher"
|
||||||
|
tbl.cost = 10
|
||||||
|
x = x + 1
|
||||||
|
return SMODS.Voucher(tbl)
|
||||||
|
end
|
||||||
|
end)()
|
||||||
|
|
||||||
|
SMODS.Atlas {
|
||||||
|
px = 71,
|
||||||
|
py = 95,
|
||||||
|
key = "voucher",
|
||||||
|
path = "voucher.png",
|
||||||
|
}
|
||||||
|
|
||||||
|
voucher {
|
||||||
|
key = "ceres",
|
||||||
|
pronouns = "it_its",
|
||||||
|
config = {extra = {amount = 1, hand_type = "Flush House"}},
|
||||||
|
attributes = {"planet", "passive", "hand_type", "space"},
|
||||||
|
loc_vars = function(_, _, card)
|
||||||
|
return {vars = {card.ability.extra.amount}}
|
||||||
|
end,
|
||||||
|
in_pool = function(self)
|
||||||
|
return G.GAME.hands[self.config.extra.hand_type].visible
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
voucher {
|
||||||
|
key = "neptune",
|
||||||
|
pronouns = "it_its",
|
||||||
|
requires = {"v_Roland_ceres"},
|
||||||
|
config = {extra = {amount = 2, hand_type = "Straight Flush"}},
|
||||||
|
attributes = {"planet", "passive", "hand_type", "space"},
|
||||||
|
loc_vars = function(_, _, card)
|
||||||
|
return {vars = {card.ability.extra.amount}}
|
||||||
|
end,
|
||||||
|
}
|
||||||