Add new joker
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 611 B After Width: | Height: | Size: 611 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
|
@ -2,7 +2,7 @@
|
|||
directory=$(dirname $(readlink -f "$0"))
|
||||
mkdir -p "$directory/1x/jokers"
|
||||
|
||||
for i in $(seq 0 25); do
|
||||
for i in $(seq 0 $(find *.png | tail -n +2 | wc -l)); do
|
||||
files="$files $directory/1x/jokers/$i.png";
|
||||
done
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ return {
|
|||
},
|
||||
},
|
||||
Joker = {
|
||||
j_Roland_amberacorn = {
|
||||
j_Roland_amber = {
|
||||
name = "Amber Acorn",
|
||||
text = {"{X:mult,C:white}X#1#{} Mult", "Moves before", "hand is played"},
|
||||
},
|
||||
|
|
@ -152,7 +152,7 @@ return {
|
|||
"{C:inactive}(Currently {X:red,C:white}X#1#{C:inactive})",
|
||||
},
|
||||
},
|
||||
j_Roland_coldturkey = {
|
||||
j_Roland_cold = {
|
||||
name = "Cold Turkey",
|
||||
text = {
|
||||
"Third scored card",
|
||||
|
|
@ -177,6 +177,23 @@ return {
|
|||
"hand {C:dark_edition}Frozen",
|
||||
},
|
||||
},
|
||||
j_Roland_idle = {
|
||||
name = "The Idle",
|
||||
text = {
|
||||
"Use to add card's",
|
||||
"rank and suit",
|
||||
"First {C:attention}scoring {}card",
|
||||
"of each entry",
|
||||
"gives {X:mult,C:white}X#19#{} Mult",
|
||||
"{C:inactive}(Must be distinct)",
|
||||
"{V:1,s:0.75}#1#{C:inactive,s:0.75}#2#{V:2,s:0.75}#3#{C:inactive,s:0.75}, " ..
|
||||
"{V:3,s:0.75}#4#{C:inactive,s:0.75}#5#{V:4,s:0.75}#6#{C:inactive,s:0.75}",
|
||||
"{V:5,s:0.75}#7#{C:inactive,s:0.75}#8#{V:6,s:0.75}#9#, " ..
|
||||
"{V:7,s:0.75}#10#{C:inactive,s:0.75}#11#{V:8,s:0.75}#12#{C:inactive,s:0.75}",
|
||||
"{V:9,s:0.75}#13#{C:inactive,s:0.75}#14#{V:10,s:0.75}#15#{C:inactive,s:0.75}, " ..
|
||||
"{V:11,s:0.75}#16#{C:inactive,s:0.75}#17#{V:12,s:0.75}#18#",
|
||||
},
|
||||
},
|
||||
j_Roland_jokersr = {
|
||||
name = "Joker Sr.",
|
||||
text = {"{X:mult,C:white}X#1#{} Mult"},
|
||||
|
|
@ -401,12 +418,15 @@ return {
|
|||
c_Roland_Showdown = "Showdown",
|
||||
},
|
||||
v_dictionary = {
|
||||
b_Roland_add = "ADD",
|
||||
b_Roland_bye = "Bye!",
|
||||
b_Roland_comma = ", ",
|
||||
b_Roland_debuffed = "DEBUFFED",
|
||||
b_Roland_disabled = "Disabled",
|
||||
b_Roland_enabled = "Enabled",
|
||||
b_Roland_comma = ", ",
|
||||
b_Roland_entering_shop = "Entering shop!",
|
||||
b_Roland_equinox_assist = "Assist: Only hide text (Equinox)",
|
||||
b_Roland_full = "FULL",
|
||||
b_Roland_scribable_basket = "Scribable Basket (overpowered)",
|
||||
b_Roland_harsh_ante_scaling = "Harsh ante scaling (Ante 40+)",
|
||||
b_Roland_illusion_seal = "Allow seals from Illusion voucher",
|
||||
|
|
@ -416,6 +436,7 @@ return {
|
|||
b_Roland_na = "N/A",
|
||||
b_Roland_of = " of ",
|
||||
b_Roland_toggle = "TOGGLE",
|
||||
b_Roland_unassigned = "(Unassigned)",
|
||||
},
|
||||
labels = {
|
||||
Roland_frozen = "Frozen",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
"author": [
|
||||
"Emik"
|
||||
],
|
||||
"version": "2.5.2",
|
||||
"version": "2.5.3",
|
||||
"badge_colour": "8BE9FD",
|
||||
"main_file": "src/main.lua",
|
||||
"badge_text_colour": "44475A",
|
||||
|
|
|
|||
146
src/joker.lua
|
|
@ -12,7 +12,7 @@ local joker = (function()
|
|||
return ret
|
||||
end
|
||||
|
||||
---@param tbl SMODS.Joker|{artist?: string, sinis?: boolean|{x: number, y: number}, soul_pos?: boolean|{x: number, y: number}, attributes?: Attributes[]}
|
||||
---@param tbl SMODS.Joker|{artist?: string, Bakery_can_use: (fun(self: self, card: Card): boolean?), Bakery_use_button_text: (fun(self: self, card: Card): string|table|nil), Bakery_use_joker: fun(self: self, card: Card), sinis?: boolean|{x: number, y: number}, soul_pos?: boolean|{x: number, y: number}, attributes?: Attributes[]}
|
||||
return function(tbl)
|
||||
tbl.pos = inc()
|
||||
tbl.atlas = "joker"
|
||||
|
|
@ -38,6 +38,37 @@ local function is_frozen(card)
|
|||
return card.edition and card.edition.key == "e_Roland_frozen"
|
||||
end
|
||||
|
||||
---@param card? Card|false|{suit: string, value: string}
|
||||
---@param fallback? string
|
||||
---@return {vars: {[number]: string|table|nil}|{colours: {[number]: {[1]: number, [2]: number, [3]: number, [4]: number}}}}
|
||||
local function localize_card(card, fallback)
|
||||
if not card then
|
||||
return {
|
||||
vars = {
|
||||
"",
|
||||
localize {type = "variable", key = fallback or "b_Roland_na"},
|
||||
"",
|
||||
colours = {G.C.JOKER_GREY, G.C.JOKER_GREY},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local suit = (card.base or card).suit
|
||||
local value = (card.base or card).value
|
||||
local name = (card.ability or card).name or ""
|
||||
local no_suit = card.base and SMODS.has_no_suit(card) or not suit
|
||||
local no_rank = card.base and SMODS.has_no_rank(card) or not value
|
||||
|
||||
return {
|
||||
vars = {
|
||||
(value and not no_rank) and localize(value or 14, "ranks") or name,
|
||||
(not no_rank and not no_suit) and localize {type = "variable", key = "b_Roland_of"} or "",
|
||||
no_suit and "" or localize(suit, "suits_plural"),
|
||||
colours = {G.C.IMPORTANT, G.C.SUITS[suit] or G.C.JOKER_GREY},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
SMODS.Atlas {
|
||||
key = "joker",
|
||||
path = "joker.png",
|
||||
|
|
@ -135,33 +166,7 @@ joker {
|
|||
blueprint_compat = true,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, _, card)
|
||||
local last = ((G.deck or {}).cards or {})[1]
|
||||
|
||||
if not last or card.area ~= G.jokers then
|
||||
return {
|
||||
vars = {
|
||||
"",
|
||||
localize {type = "variable", key = "b_Roland_na"},
|
||||
"",
|
||||
colours = {G.C.JOKER_GREY, G.C.JOKER_GREY},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local suit = last.base.suit
|
||||
local value = last.base.value
|
||||
local name = last.ability.name or ""
|
||||
local no_rank = SMODS.has_no_rank(last)
|
||||
local no_suit = SMODS.has_no_suit(last)
|
||||
|
||||
return {
|
||||
vars = {
|
||||
value and not no_rank and localize(value or 14, "ranks") or name,
|
||||
not no_rank and not no_suit and localize {type = "variable", key = "b_Roland_of"} or "",
|
||||
no_suit and "" or localize(suit, "suits_plural"),
|
||||
colours = {G.C.IMPORTANT, G.C.SUITS[suit] or G.C.JOKER_GREY},
|
||||
},
|
||||
}
|
||||
return localize_card(card.area == G.jokers and ((G.deck or {}).cards or {})[1])
|
||||
end,
|
||||
calculate = function(_, _, context)
|
||||
if not context.selling_self and not context.forcetrigger then
|
||||
|
|
@ -350,7 +355,7 @@ joker {
|
|||
}
|
||||
|
||||
joker {
|
||||
key = "coldturkey",
|
||||
key = "cold",
|
||||
pronouns = "he_him",
|
||||
config = {extra = {xmult = 2}},
|
||||
attributes = {"xmult"},
|
||||
|
|
@ -613,12 +618,8 @@ joker {
|
|||
blueprint_compat = true,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(_, _, card)
|
||||
return {
|
||||
vars = {localize {
|
||||
type = "variable",
|
||||
key = card.ability.extra.flipped and "b_Roland_enabled" or "b_Roland_disabled",
|
||||
}},
|
||||
}
|
||||
local key = card.ability.extra.flipped and "b_Roland_enabled" or "b_Roland_disabled"
|
||||
return {vars = {localize {type = "variable", key = key}}}
|
||||
end,
|
||||
inject = function(...)
|
||||
SMODS.Joker.inject(...)
|
||||
|
|
@ -637,10 +638,7 @@ joker {
|
|||
return not card.debuff
|
||||
end,
|
||||
Bakery_use_button_text = function(_, card)
|
||||
return localize {
|
||||
type = "variable",
|
||||
key = card.debuff and "b_Roland_debuffed" or "b_Roland_toggle",
|
||||
}
|
||||
return localize {type = "variable", key = card.debuff and "b_Roland_debuffed" or "b_Roland_toggle"}
|
||||
end,
|
||||
Bakery_use_joker = function(_, card)
|
||||
local _ = card.debuff or Bakery_API.flip_double_sided(card)
|
||||
|
|
@ -648,7 +646,7 @@ joker {
|
|||
}
|
||||
|
||||
joker {
|
||||
key = "amberacorn",
|
||||
key = "amber",
|
||||
pronouns = "he_they",
|
||||
config = {extra = {xmult = 3}},
|
||||
attributes = {"xmult"},
|
||||
|
|
@ -670,7 +668,7 @@ joker {
|
|||
end
|
||||
|
||||
local keys = f(card.area.cards):where(f().nq(card)):keys():table()
|
||||
local k = pseudorandom_element(keys, pseudoseed "Roland_stubborn") or card.rank
|
||||
local k = pseudorandom_element(keys, pseudoseed "Roland_amber") or card.rank
|
||||
|
||||
card.area.cards[k], card.area.cards[card.rank] =
|
||||
card.area.cards[card.rank], card.area.cards[k]
|
||||
|
|
@ -869,3 +867,69 @@ joker {
|
|||
end
|
||||
end,
|
||||
}
|
||||
|
||||
joker {
|
||||
key = "idle",
|
||||
pronouns = "they_them",
|
||||
cost = 9,
|
||||
rarity = 3,
|
||||
Roland_idle_capacity = 6,
|
||||
config = {extra = {cards = {}, xmult = 2}},
|
||||
attributes = {"rank", "suit", "xmult"},
|
||||
eternal_compat = true,
|
||||
blueprint_compat = true,
|
||||
perishable_compat = true,
|
||||
loc_vars = function(self, _, card)
|
||||
local extra = card.ability.extra
|
||||
local col = {}
|
||||
|
||||
---@type { [number]: string|table|nil }|{colours: {[number]: {[1]: number, [2]: number, [3]: number, [4]: number}}}
|
||||
local vars = f(self.Roland_idle_capacity):flatmap(function(v)
|
||||
local l = localize_card(extra.cards[v], "b_Roland_unassigned").vars
|
||||
|
||||
f(l.colours):each(function(c)
|
||||
col[#col + 1] = c
|
||||
end)
|
||||
|
||||
l.colours = nil
|
||||
return l
|
||||
end):values():table()
|
||||
|
||||
table.insert(vars, extra.xmult)
|
||||
vars.colours = col
|
||||
return {vars = vars}
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
return context.forcetrigger or
|
||||
context.individual and
|
||||
context.cardarea == G.play and
|
||||
f(card.ability.extra.cards or {}):map(function(v)
|
||||
return f(context.scoring_hand):any(function(x)
|
||||
return x:is_suit(v.suit) and x.base.value == v.value
|
||||
end) or {}
|
||||
end):any(f().eq(context.other_card)) and {xmult = card.ability.extra.xmult} or nil
|
||||
end,
|
||||
Bakery_can_use = function(self, card)
|
||||
return not card.debuff and
|
||||
next(G.hand.highlighted) and
|
||||
self.Roland_idle_capacity - #card.ability.extra.cards - #G.hand.highlighted >= 0 and
|
||||
f(G.hand.highlighted):all(function(v)
|
||||
return not SMODS.has_no_rank(v) and
|
||||
not SMODS.has_no_suit(v) and
|
||||
f(card.ability.extra.cards or {}):all(function(o)
|
||||
return v.base.suit ~= o.suit or v.base.value ~= o.value
|
||||
end)
|
||||
end)
|
||||
end,
|
||||
Bakery_use_button_text = function(self, card)
|
||||
local key = card.debuff and "b_Roland_debuffed" or
|
||||
(self.Roland_idle_capacity - #card.ability.extra.cards > 0 and "b_Roland_add" or "b_Roland_full")
|
||||
|
||||
return localize {type = "variable", key = key}
|
||||
end,
|
||||
Bakery_use_joker = function(_, card)
|
||||
f(G.hand.highlighted):each(function(v)
|
||||
table.insert(card.ability.extra.cards, {suit = v.base.suit, value = v.base.value})
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ local none
|
|||
---@param tbl table<K, V>
|
||||
---@param fpairs? fun(t: table<K, V>): (fun(table: table<K, V>, index?: K): K, V)
|
||||
---@return fun(tbl: table<K, V>, key: K): K, V
|
||||
---@return K
|
||||
---@return table<K, V>
|
||||
---@return V
|
||||
---@nodiscard
|
||||
local function autopairs(tbl, fpairs)
|
||||
|
|
@ -297,6 +297,56 @@ function f:flatmap(func, fpairs)
|
|||
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
|
||||
---@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 = type(func) == "string" and f.index(func) or 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
|
||||
---@param self F|{ [K]: V }
|
||||
---@param func F|fun(v: V, k: K): boolean
|
||||
|
|
|
|||