Compare commits

..

No commits in common. "main" and "2.9.15" have entirely different histories.
main ... 2.9.15

32 changed files with 413 additions and 201 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 72 KiB

BIN
assets/1x/voucher.png.kra Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View file

@ -500,14 +500,14 @@ return {
name = "Ceres",
text = {
"Level up {C:attention}Flush House",
"by {C:attention}#1# {}when it is played",
"when it is played",
},
},
v_Roland_neptune = {
name = "Neptune",
text = {
"Level up {C:attention}Straight Flush",
"by {C:attention}#1# {}when it is played",
"when it is played",
},
},
},

View file

@ -3,7 +3,7 @@
"id": "Roland",
"name": "Roland",
"prefix": "Roland",
"version": "2.9.28",
"version": "2.9.15",
"badge_colour": "8BE9FD",
"display_name": "Roland",
"main_file": "src/main.lua",

View file

@ -52,7 +52,7 @@ end
local function has_enhancement(card)
local e = SMODS.get_enhancements(card)
return e and next(e)
return not not (e and next(e))
end
local function set_freeze(state)
@ -239,16 +239,16 @@ blind {
disable = function(self)
self:defeat()
end,
calculate = function(self, b, context)
return not b.disabled and
context.hand_drawn and
self.cards()
calculate = function(self, b)
return not b.disabled and self.cards()
:where("Roland_blizzard", false)
:where("facing", "front")
:each(set_freeze(true)) or nil
end,
cards = function()
return f(G):where(getmetatable, CardArea):flatmap("cards", ipairs)
return f(G):where(function(v)
return type(v) == "table" and type(v.cards) == "table"
end):flatmap("cards", ipairs)
end,
}
@ -354,11 +354,13 @@ function SMODS.current_mod:calculate(context)
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)
:where("config.hand_type", context.scoring_name)
:any() and
SMODS.calculate_effect {
level_up = true,
message = localize "k_level_up_ex",
card = G.play.cards[math.ceil(#G.play.cards / 2)] or G.deck.cards[#G.deck.cards] or {},
}
local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities

View file

@ -188,7 +188,7 @@ SMODS.Challenge {
end)
local mod = G.GAME.modifiers
mod.Roland_Eternally_Crimson = context.setting_blind and true or mod.Roland_Eternally_Crimson
mod.Roland_Eternally_Crimson = not context.setting_blind and mod.Roland_Eternally_Crimson or nil
local debuff = context.debuff_card
local cards = G.jokers.cards
@ -262,7 +262,7 @@ SMODS.Challenge {
SMODS.Challenge {
key = "Eternally_Violet",
rules = {custom = {{id = "Roland_Eternally_Violet"}, {id = "Roland_Showdown_Violet"}}},
jokers = {{id = "j_joker"}, {id = "j_Roland_violet"}},
jokers = {{id = "j_Roland_violet"}},
restrictions = violet,
pronouns = "she_they",
calculate = function(_, context)

View file

@ -261,7 +261,7 @@ 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
G.Bakery_charm_area.cards[1].config.center.ability.extra.active then
return
end

View file

@ -13,7 +13,7 @@ end
frozen_sound "_click"
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 = {
Bull = true,
@ -144,7 +144,7 @@ local function hook_proxy()
local orig_calculate = proxy.calculate
function proxy:calculate(card, context, ...)
if not (card or {}).Roland_frozen or not (card.edition or {}).Roland_frozen then
if not card or not card.edition or not card.edition.Roland_frozen then
return orig_calculate(self, card, context, ...)
else
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
function proxy:loc_vars(info_queue, card, ...)
if not (card or {}).Roland_frozen or not (card.edition or {}).Roland_frozen then
if not card or not card.edition or not card.edition.Roland_frozen then
return orig_loc_vars(self, info_queue, card, ...)
end

View file

@ -216,9 +216,9 @@ joker {
SMODS.calculate_context {drawing_cards = true, draw = {G.deck.cards}}
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,
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
@ -488,9 +488,11 @@ joker {
end
end
return SMODS.merge_effects(
local key = card.config.center.key
local merged = SMODS.merge_effects(
f(G.jokers.cards):where(is_frozen):where(function(v)
return v.config.center.key ~= card.config.center.key
return v.config.center.key ~= key
end):map(function(v)
return SMODS.blueprint_effect(card, v, context)
end):where(type, "table"):map(function(v)
@ -498,6 +500,8 @@ joker {
return v
end):values():table()
)
return merged
end,
}
@ -648,7 +652,7 @@ joker {
local _ = card.area == G.jokers and self:cerulean(false)
end,
cerulean = function(_, value)
local _ = G.jokers and f(G.jokers.cards):each(function(v)
f(G.jokers.cards):each(function(v)
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"
end)
@ -675,7 +679,7 @@ joker {
{card = card, xmult = card.ability.extra.xmult} or nil
end,
crimson = function()
local _ = G.jokers and f(G.jokers.cards, ipairs_reversed):where(is_frozen, false):each(function(v)
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
@ -684,13 +688,11 @@ joker {
right.config.center.key == "j_Roland_crimson"
if debuffed_by_crimson and v.ability.Roland_crimson == nil then
local debuff = not not v.debuff
v.ability.Roland_crimson = not not v.debuff
v:set_debuff(true)
v.ability.Roland_crimson = debuff
elseif not debuffed_by_crimson and v.ability.Roland_crimson ~= nil then
local debuff = v.ability.Roland_crimson
v:set_debuff(v.ability.Roland_crimson)
v.ability.Roland_crimson = nil
v:set_debuff(debuff)
end
end)
end,
@ -757,7 +759,7 @@ joker {
key = "violet",
pronouns = "she_they",
idea = "hamester",
config = {extra = {before = 0.1, xmult = 6}},
config = {extra = {before = 0.1, xmult = 9}},
pixel_size = {w = 68, h = 68},
attributes = {"xmult"},
cost = 6,
@ -936,14 +938,10 @@ joker {
local extra, numerator, xmult = card.ability.extra, 1, 1
if G.GAME.blind.name == "bl_mp_nemesis" then
local n, d = SMODS.get_probability_vars(card, 1, extra.odds, self.key)
return n < d and {card = card, xmult = extra.odds} or nil
return {card = card, xmult = extra.odds}
end
-- 2^38 is the first iteration displayed as scientific notation.
local max, overflown = 38, false
for i = 1, max do
for _ = 1, 256 do
local key = "RolandMartingale" .. tostring(G.GAME.modifiers.Roland_martingale_seed or "")
if SMODS.pseudorandom_probability(card, self.key, 1, extra.odds, key) then
@ -955,18 +953,9 @@ joker {
xmult = xmult * extra.odds
local message = number_format(numerator) .. "/" .. number_format(xmult)
SMODS.calculate_effect({card = card, repetitions = 1, message = message, message_card = card}, card)
overflown = overflown or i == max
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)
end
end,
}
@ -1258,7 +1247,7 @@ joker {
return {card = card, numerator = extra.probability}
end
if context.end_of_round and not context.repetition and extra.probability ~= extra.reset then
if context.end_of_round and extra.probability ~= extra.reset then
extra.probability = extra.reset
return {message = localize "k_reset", colour = G.C.RED, message_card = card, repetitions = 0}
end

View file

@ -128,6 +128,13 @@ local function autopairs(tbl, fpairs)
return (fpairs or (tbl[#tbl] and ipairs or pairs))(tbl)
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.
---@return nil
---@nodiscard
@ -195,15 +202,6 @@ function f.const(v)
end
end
---@param i integer
---@return fun(...: any): any
---@nodiscard
function f.arg(i)
return function(...)
return ({...})[i]
end
end
---@generic K, V
---@param v K
---@return fun(x: { [K]: V }): V
@ -242,32 +240,21 @@ function f.indices(v)
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(...)
local ret
for _, v in ipairs {...} do
for _, v in ipairs(...) do
if type(v) == "table" then
for _, vv in ipairs(v) do
local copy = ret
vv = autofunc(vv)
ret = ret and function(...)
return vv(copy(...))
return vv(ret(...))
end or vv
end
else
local copy = ret
v = autofunc(v)
ret = ret and function(...)
return v(copy(...))
return v(ret(...))
end or v
end
end
@ -284,7 +271,6 @@ function f.new(fnext)
return {
all = f.all,
any = f.any,
arg = f.arg,
chain = f.chain,
concat = f.concat,
const = f.const,
@ -299,7 +285,6 @@ function f.new(fnext)
index = f.index,
index_into = f.index_into,
indices = f.indices,
isf = f.isf,
keys = f.keys,
map = f.map,
new = f.new,
@ -386,7 +371,7 @@ function f:concat(...)
local sum, last = 0, 0
for i = 1, #fs do
fs[i] = f.isf(fs[i]) and fs[i] or f.from(fs[i])
fs[i] = is_f(fs[i]) and fs[i] or f.from(fs[i])
end
return f.new(function()

View file

@ -19,21 +19,15 @@ 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?
--- @type table
CardSleeves = CardSleeves
--- @type table|fun(obj: SMODS.Back): SMODS.Back
--- @type 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}

View file

@ -1,59 +1,5 @@
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)
return function()
local res, ret = pcall(fun)
@ -110,35 +56,4 @@ local function u()
G.STATE ~= G.STATES.PLAY_TAROT)
end
--- 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,
})}
return {f, q, u}

View file

@ -52,11 +52,9 @@ q {
-- G.ARGS.LOC_COLOURS["Bakery_credit_bg_Roland_" .. k] = v.bg
end)
if not SMODS.Mods.DebugPlus or not SMODS.Mods.Roland.config.import_funky then
return
if SMODS.Mods.DebugPlus and SMODS.Mods.Roland.config.import_funky then
_G.f, _G.q, _G.u = unpack(qol)
end
_G.f, _G.q, _G.u, _G.c = unpack(qol)
end,
}

View file

@ -69,15 +69,15 @@ spectral {
table.insert(info_queue, G.P_CENTERS.m_stone)
end,
can_use = function()
return next(G.hand.cards) and u()
return u() and not not next(G.hand.cards)
end,
use = function(_, card)
q {
trigger = "after",
delay = 0.4,
func = function()
card:juice_up(0.3, 0.5)
play_sound("tarot1")
card:juice_up(0.3, 0.5)
end,
}
@ -89,8 +89,8 @@ spectral {
delay = 0.15,
func = function()
v:flip()
v:juice_up(0.3, 0.3)
play_sound("card1", percent)
v:juice_up(0.3, 0.3)
return true
end,
}
@ -110,8 +110,8 @@ spectral {
delay = 0.15,
func = function()
v:flip()
v:juice_up(0.3, 0.3)
play_sound("tarot2", percent, 0.6)
v:juice_up(0.3, 0.3)
return true
end,
}
@ -155,7 +155,7 @@ spectral {
return {vars = {card.ability.extra.amount}}
end,
can_use = function()
return next(G.playing_cards) and u()
return #G.playing_cards > 1 and not not u()
end,
use = function(_, card)
local function destructible(v)

View file

@ -192,9 +192,9 @@ Balatest.TestPlay {
}
Balatest.TestPlay {
category = {"blind", "mitotic"},
name = "mitotic",
blind = "bl_Roland_mitotic",
category = {"blind", "xerox"},
name = "xerox",
blind = "bl_Roland_xerox",
execute = function()
Balatest.discard {"2S"}
end,
@ -204,9 +204,9 @@ Balatest.TestPlay {
}
Balatest.TestPlay {
category = {"blind", "mitotic"},
name = "mitotic_disabled",
blind = "bl_Roland_mitotic",
category = {"blind", "xerox"},
name = "xerox_disabled",
blind = "bl_Roland_xerox",
jokers = {"j_chicot"},
execute = function()
Balatest.discard {"2S"}

View file

@ -2,6 +2,330 @@ if not Balatest then
return
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 {
category = {"joker", "martingale"},
name = "martingale_oops",
@ -10,7 +334,7 @@ Balatest.TestPlay {
Balatest.play_hand {"2S"}
end,
assert = function()
Balatest.assert_chips(7)
Balatest.assert_chips(7 * 2)
end,
}
@ -23,6 +347,6 @@ Balatest.TestPlay {
Balatest.play_hand {"2S"}
end,
assert = function()
Balatest.assert_chips(1 / 0)
Balatest.assert_chips(7 * math.pow(2, 32))
end,
}

View file

@ -2,6 +2,22 @@ if not Balatest then
return
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 {
category = {"spectral", "void"},
name = "spectral",

View file

@ -2,16 +2,11 @@ local f, q = (... or require "lib.shared")[1], (... or require "lib.shared")[2]
SMODS.Joker:take_ownership("joker", {cost = 1}, true)
local orig_set_debuff = 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
function Card:set_debuff(...)
if SMODS.get_enhancements(self).m_wild and SMODS.Mods.Roland.config.no_wild_debuff then
self.debuff = false
else
orig_set_debuff(self, should_debuff, ...)
orig_set_debuff(self, ...)
end
end

View file

@ -22,13 +22,10 @@ SMODS.Atlas {
voucher {
key = "ceres",
pronouns = "it_its",
config = {extra = {amount = 1, hand_type = "Flush House"}},
config = {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
return G.GAME.hands[self.config.hand_type].visible
end,
}
@ -36,9 +33,6 @@ voucher {
key = "neptune",
pronouns = "it_its",
requires = {"v_Roland_ceres"},
config = {extra = {amount = 2, hand_type = "Straight Flush"}},
config = {hand_type = "Straight Flush"},
attributes = {"planet", "passive", "hand_type", "space"},
loc_vars = function(_, _, card)
return {vars = {card.ability.extra.amount}}
end,
}