Compare commits
54 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 918ebbc30b | |||
| 8bcd0e074d | |||
| f23dad31cc | |||
| 7da197900e | |||
| 5d096d5f58 | |||
| e74f4d44c9 | |||
| 21952a529b | |||
| 4ac13e249c | |||
| 8d8574bf86 | |||
| 2bd613b458 | |||
| dd71145698 | |||
| 51ad870d8c | |||
| f77dbe3ac8 | |||
| d219e79c89 | |||
| 11120727f6 | |||
| 59e9d43703 | |||
| 78136a494c | |||
| 1869e60d91 | |||
| 286d1c6dc7 | |||
| 455e08bbf7 | |||
| 87be46c360 | |||
| 1bf6ac6a91 | |||
| 9595a18864 | |||
| b21f20b127 | |||
| bea00f493b | |||
| 5c76ee60d2 | |||
| 3f05ac6238 | |||
| 8533e4c146 | |||
| 4bf3ef046e | |||
| 5466b2dc35 | |||
| 9a5c531a02 | |||
| a04ac56169 | |||
| 2fb6606748 | |||
| 6585e1fcc4 | |||
| 2a865afc3a | |||
| 8531bde452 | |||
| 42aef4aaee | |||
| f2210f56e7 | |||
| e5e68cce2a | |||
| 2a3c1338de | |||
| 5b3aad7081 | |||
| 5a1ca3c73e | |||
| e0e1e4c889 | |||
| a466a8f032 | |||
| 49a24ea636 | |||
| f0d127f2e5 | |||
| 2526bee0b6 | |||
| 04e131f449 | |||
| 8fdd9a4062 | |||
| 52e7cf3387 | |||
| 6d65d92fa0 | |||
| 0e0410ad75 | |||
| b6fc62521c | |||
| 76e95e9725 |
2
.gitignore
vendored
|
|
@ -39,3 +39,5 @@ luac.out
|
||||||
*.x86_64
|
*.x86_64
|
||||||
*.hex
|
*.hex
|
||||||
|
|
||||||
|
# Syncthing
|
||||||
|
.stfolder
|
||||||
|
|
|
||||||
8
.vscode/settings.json
vendored
|
|
@ -1,4 +1,8 @@
|
||||||
{
|
{
|
||||||
|
"Lua.diagnostics.disable": [
|
||||||
|
"duplicate-set-field",
|
||||||
|
"lowercase-global",
|
||||||
|
],
|
||||||
"Lua.diagnostics.severity": {
|
"Lua.diagnostics.severity": {
|
||||||
"ambiguity-1": "Error",
|
"ambiguity-1": "Error",
|
||||||
"assign-type-mismatch": "Error",
|
"assign-type-mismatch": "Error",
|
||||||
|
|
@ -18,14 +22,12 @@
|
||||||
"duplicate-doc-field": "Error",
|
"duplicate-doc-field": "Error",
|
||||||
"duplicate-doc-param": "Error",
|
"duplicate-doc-param": "Error",
|
||||||
"duplicate-index": "Error",
|
"duplicate-index": "Error",
|
||||||
"duplicate-set-field": "Error",
|
|
||||||
"empty-block": "Error",
|
"empty-block": "Error",
|
||||||
"global-element": "Error",
|
"global-element": "Error",
|
||||||
"global-in-nil-env": "Error",
|
"global-in-nil-env": "Error",
|
||||||
"incomplete-signature-doc": "Error",
|
"incomplete-signature-doc": "Error",
|
||||||
"inject-field": "Error",
|
"inject-field": "Error",
|
||||||
"invisible": "Error",
|
"invisible": "Error",
|
||||||
"lowercase-global": "Error",
|
|
||||||
"missing-fields": "Error",
|
"missing-fields": "Error",
|
||||||
"missing-global-doc": "Error",
|
"missing-global-doc": "Error",
|
||||||
"missing-local-export-doc": "Error",
|
"missing-local-export-doc": "Error",
|
||||||
|
|
@ -62,5 +64,5 @@
|
||||||
"unused-label": "Error",
|
"unused-label": "Error",
|
||||||
"unused-local": "Error",
|
"unused-local": "Error",
|
||||||
"unused-vararg": "Error",
|
"unused-vararg": "Error",
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 904 B After Width: | Height: | Size: 897 B |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 29 KiB |
BIN
assets/1x/tag.png
Normal file
|
After Width: | Height: | Size: 644 B |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 62 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: 53 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 41 KiB |
BIN
assets/2x/tag.png
Normal file
|
After Width: | Height: | Size: 611 B |
199
assets/shaders/frozen.fs
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
|
||||||
|
#define MY_HIGHP_OR_MEDIUMP highp
|
||||||
|
#else
|
||||||
|
#define MY_HIGHP_OR_MEDIUMP mediump
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP vec2 frozen;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP number dissolve;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP number time;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP vec4 texture_details;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP vec2 image_details;
|
||||||
|
extern bool shadow;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP vec4 burn_colour_1;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP vec4 burn_colour_2;
|
||||||
|
|
||||||
|
vec4 dissolve_mask(vec4 tex, vec2 texture_coords, vec2 uv)
|
||||||
|
{
|
||||||
|
if (dissolve < 0.001) {
|
||||||
|
return vec4(shadow ? vec3(0.,0.,0.) : tex.xyz, shadow ? tex.a*0.3: tex.a);
|
||||||
|
}
|
||||||
|
|
||||||
|
float adjusted_dissolve = (dissolve*dissolve*(3.-2.*dissolve))*1.02 - 0.01;
|
||||||
|
|
||||||
|
float t = time * 10.0 + 2003.;
|
||||||
|
vec2 floored_uv = (floor((uv*texture_details.ba)))/max(texture_details.b, texture_details.a);
|
||||||
|
vec2 uv_scaled_centered = (floored_uv - 0.5) * 2.3 * max(texture_details.b, texture_details.a);
|
||||||
|
|
||||||
|
vec2 field_part1 = uv_scaled_centered + 50.*vec2(sin(-t / 143.6340), cos(-t / 99.4324));
|
||||||
|
vec2 field_part2 = uv_scaled_centered + 50.*vec2(cos( t / 53.1532), cos( t / 61.4532));
|
||||||
|
vec2 field_part3 = uv_scaled_centered + 50.*vec2(sin(-t / 87.53218), sin(-t / 49.0000));
|
||||||
|
|
||||||
|
float field = (1.+ (
|
||||||
|
cos(length(field_part1) / 19.483) + sin(length(field_part2) / 33.155) * cos(field_part2.y / 15.73) +
|
||||||
|
cos(length(field_part3) / 27.193) * sin(field_part3.x / 21.92) ))/2.;
|
||||||
|
vec2 borders = vec2(0.2, 0.8);
|
||||||
|
|
||||||
|
float res = (.5 + .5* cos( (adjusted_dissolve) / 82.612 + ( field + -.5 ) *3.14))
|
||||||
|
- (floored_uv.x > borders.y ? (floored_uv.x - borders.y)*(5. + 5.*dissolve) : 0.)*(dissolve)
|
||||||
|
- (floored_uv.y > borders.y ? (floored_uv.y - borders.y)*(5. + 5.*dissolve) : 0.)*(dissolve)
|
||||||
|
- (floored_uv.x < borders.x ? (borders.x - floored_uv.x)*(5. + 5.*dissolve) : 0.)*(dissolve)
|
||||||
|
- (floored_uv.y < borders.x ? (borders.x - floored_uv.y)*(5. + 5.*dissolve) : 0.)*(dissolve);
|
||||||
|
|
||||||
|
if (tex.a > 0.01 && burn_colour_1.a > 0.01 && !shadow && res < adjusted_dissolve + 0.8*(0.5-abs(adjusted_dissolve-0.5)) && res > adjusted_dissolve) {
|
||||||
|
if (!shadow && res < adjusted_dissolve + 0.5*(0.5-abs(adjusted_dissolve-0.5)) && res > adjusted_dissolve) {
|
||||||
|
tex.rgba = burn_colour_1.rgba;
|
||||||
|
} else if (burn_colour_2.a > 0.01) {
|
||||||
|
tex.rgba = burn_colour_2.rgba;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec4(shadow ? vec3(0.,6.,0.) : tex.xyz, res > adjusted_dissolve ? (shadow ? tex.a*0.3: tex.a) : .0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEPTH 21
|
||||||
|
#define PHI ((1. + sqrt(5.)) / 2.)
|
||||||
|
#define PI 3.141592653589
|
||||||
|
#define S(M, O) (0.5 + 0.5 * sin(O + M * pos.x)) / 6.
|
||||||
|
#define C(M, O) (0.5 + 0.5 * cos(O + M * pos.y)) / 6.
|
||||||
|
|
||||||
|
vec2 rotate(vec2 v, float a)
|
||||||
|
{
|
||||||
|
float s = sin(a);
|
||||||
|
float c = cos(a);
|
||||||
|
mat2 m = mat2(c, -s, s, c);
|
||||||
|
return m * v;
|
||||||
|
}
|
||||||
|
|
||||||
|
float cr(vec2 a, vec2 b)
|
||||||
|
{
|
||||||
|
return a.x * b.y - b.x * a.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float cr(vec2 a, vec2 b, vec2 c)
|
||||||
|
{
|
||||||
|
return cr(b - a, c - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 effect(vec4 colour, Image texture, vec2 texture_coords, vec2 screen_coords)
|
||||||
|
{
|
||||||
|
vec4 tex = Texel(texture, texture_coords);
|
||||||
|
vec2 uv = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
|
||||||
|
|
||||||
|
if (uv.x > uv.x * 2.) {
|
||||||
|
uv = frozen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slightly adapted from 'snowflake lattice' by pali6.
|
||||||
|
// https://www.shadertoy.com/view/7sG3zd
|
||||||
|
// https://www.shadertoy.com/user/pali6
|
||||||
|
float iTime = 0.0;
|
||||||
|
vec2 pos = (((texture_coords)*(image_details)) - texture_details.xx*texture_details.ba)/texture_details.ba;
|
||||||
|
|
||||||
|
float scale = 72. + 18. * sin(iTime / 10.) + 20. * sin(4. + iTime / 15.) + 30. * sin(iTime / 6.);
|
||||||
|
vec2 camPos = vec2(0.5, 0.5);
|
||||||
|
float SF = 1. / pow(scale, 0.3);
|
||||||
|
camPos += vec2(0.02 * sin(iTime / 15.), -0.07 * cos(iTime / 19.)) * SF;
|
||||||
|
camPos += vec2(-0.1 * sin(3. + iTime / 37.), -0.1 * cos(4. + iTime / 27.)) * SF;
|
||||||
|
camPos += vec2(0.07 * sin(9. + iTime / 47.), -0.08 * cos(20. + iTime / 31.)) * SF;
|
||||||
|
camPos += vec2(0.04 * sin(19. + iTime / 7.), 0.06 * cos(25. + iTime / 5.)) * SF;
|
||||||
|
pos -= vec2(0.5, 0.5);
|
||||||
|
pos = rotate(pos, iTime / 30. + PI * cos(iTime / 37.) + 2. * PI * sin(iTime / 87. + 10.));
|
||||||
|
pos /= scale;
|
||||||
|
pos += camPos;
|
||||||
|
vec2 ota = vec2(-1., 0.);
|
||||||
|
vec2 otb = vec2(2., 0.);
|
||||||
|
vec2 ta = ota;
|
||||||
|
vec2 tb = otb;
|
||||||
|
vec2 tc;
|
||||||
|
bool gn = true;
|
||||||
|
float fl = -1.;
|
||||||
|
float f = 0.;
|
||||||
|
float nDark = 0.;
|
||||||
|
|
||||||
|
for (int i = 0; i < DEPTH; i++)
|
||||||
|
{
|
||||||
|
vec2 next;
|
||||||
|
|
||||||
|
if (gn)
|
||||||
|
tc = ta + rotate(tb - ta, fl * PI / 5.) / PHI;
|
||||||
|
else
|
||||||
|
tc = ta + rotate(tb - ta, fl * 2. * PI / 5.) * PHI;
|
||||||
|
|
||||||
|
if(!(gn && min(length(pos - ta), length(pos - tb)) > length(ta - tb) / 3. || !gn && length(pos - tb) <= length(tc - tb) * PHI / 3.5))
|
||||||
|
{
|
||||||
|
nDark += 1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gn)
|
||||||
|
{
|
||||||
|
next = tb + (ta - tb) / PHI;
|
||||||
|
|
||||||
|
if (abs(cr(next, tc, pos)) * float(i + 1) < 0.000001)
|
||||||
|
f = 1.;
|
||||||
|
|
||||||
|
if (cr(next, tc, pos) * cr(next, tc, tb) > 0.)
|
||||||
|
{
|
||||||
|
gn = false;
|
||||||
|
ta = next;
|
||||||
|
tb = tc;
|
||||||
|
fl *= -1.;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gn = true;
|
||||||
|
tb = ta;
|
||||||
|
ta = tc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
next = tc + (tb - tc) / PHI;
|
||||||
|
|
||||||
|
if (abs(cr(ta, next, pos)) * float(i + 1) < 0.000001)
|
||||||
|
f = 1.;
|
||||||
|
|
||||||
|
if (cr(ta, next, pos) * cr(ta, next, tb) > 0.)
|
||||||
|
{
|
||||||
|
gn = false;
|
||||||
|
ta = tb;
|
||||||
|
tb = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gn = true;
|
||||||
|
tb = ta;
|
||||||
|
ta = tc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
colour = (nDark / float(DEPTH)) * vec4(
|
||||||
|
0.1 + S(30., 10.) + C(10., 11.) + S(50., 16.) + S(99., 15.) + S(1., 42.) + C(1.5, 73.),
|
||||||
|
0.1 + C(20., 10.) + S(70., 12.) + C(23., 18.) + C(67., 119.) + S(1.2, 49.) + C(0.9, 79.),
|
||||||
|
0.15 + S(70., 10.5) + C(31., 17.) + S(55., 135.) + C(123., 15.) + S(0.7, 13.) + C(0.11, 31.),
|
||||||
|
1.
|
||||||
|
) * 1.5;
|
||||||
|
|
||||||
|
return dissolve_mask(tex*colour, texture_coords, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP vec2 mouse_screen_pos;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP float hovering;
|
||||||
|
extern MY_HIGHP_OR_MEDIUMP float screen_scale;
|
||||||
|
|
||||||
|
#ifdef VERTEX
|
||||||
|
vec4 position( mat4 transform_projection, vec4 vertex_position )
|
||||||
|
{
|
||||||
|
if (hovering <= 0.){
|
||||||
|
return transform_projection * vertex_position;
|
||||||
|
}
|
||||||
|
float mid_dist = length(vertex_position.xy - 0.5*love_ScreenSize.xy)/length(love_ScreenSize.xy);
|
||||||
|
vec2 mouse_offset = (vertex_position.xy - mouse_screen_pos.xy)/screen_scale;
|
||||||
|
float scale = 0.2*(-0.03 - 0.3*max(0., 0.3-mid_dist))
|
||||||
|
*hovering*(length(mouse_offset)*length(mouse_offset))/(2. -mid_dist);
|
||||||
|
|
||||||
|
return transform_projection * vertex_position + vec4(0.,0.,0.,scale);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
BIN
assets/sounds/frozen1.ogg
Normal file
BIN
assets/sounds/frozen2.ogg
Normal file
BIN
assets/sounds/frozen3.ogg
Normal file
BIN
assets/sounds/frozen4.ogg
Normal file
BIN
assets/sounds/frozen_click.ogg
Normal file
BIN
assets/sounds/nilly.ogg
Normal file
11
config.lua
|
|
@ -1 +1,10 @@
|
||||||
return {escapey_debugger = false, equinox_assist = false}
|
return {
|
||||||
|
equinox_assist = false,
|
||||||
|
fusable_escapey = false,
|
||||||
|
harsh_ante_scaling = true,
|
||||||
|
illusion_seal = true,
|
||||||
|
import_funky = false,
|
||||||
|
no_highlight_limit = true,
|
||||||
|
no_wild_debuff = true,
|
||||||
|
scribable_basket = false,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,6 @@ return {
|
||||||
"that are {C:dark_edition}debuffed #1# times",
|
"that are {C:dark_edition}debuffed #1# times",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
b_Roland_go = {
|
|
||||||
name = "Pass GO Deck",
|
|
||||||
text = {
|
|
||||||
"Start with a {C:attention}Credit Card",
|
|
||||||
"Set money to {C:money}$0",
|
|
||||||
"when entering the shop",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
b_Roland_swapper = {
|
b_Roland_swapper = {
|
||||||
name = "Swapper Deck",
|
name = "Swapper Deck",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -28,12 +20,16 @@ return {
|
||||||
BakeryCharm = {
|
BakeryCharm = {
|
||||||
BakeryCharm_Roland_cocacola = {
|
BakeryCharm_Roland_cocacola = {
|
||||||
name = "coca cola phone",
|
name = "coca cola phone",
|
||||||
text = {"Values on consumables", "increase by {C:attention}1"},
|
text = {
|
||||||
|
"Values on consumables",
|
||||||
|
"increase by {C:attention}1",
|
||||||
|
"{C:inactive}(excluding {C:planet}Planets{C:inactive})",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
BakeryCharm_Roland_fat = {
|
BakeryCharm_Roland_fat = {
|
||||||
name = "fat i phone",
|
name = "fat i phone",
|
||||||
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",
|
||||||
"{C:inactive}(Whenever applicable)",
|
"{C:inactive}(Whenever applicable)",
|
||||||
},
|
},
|
||||||
|
|
@ -56,6 +52,10 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Blind = {
|
Blind = {
|
||||||
|
bl_Roland_blizzard = {
|
||||||
|
name = "The Blizzard",
|
||||||
|
text = {"All cards", "are Frozen"},
|
||||||
|
},
|
||||||
bl_Roland_divide = {
|
bl_Roland_divide = {
|
||||||
name = "The Great Divide",
|
name = "The Great Divide",
|
||||||
text = {"Half of the deck", "is discarded"},
|
text = {"Half of the deck", "is discarded"},
|
||||||
|
|
@ -105,6 +105,12 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Edition = {
|
||||||
|
e_Roland_frozen = {
|
||||||
|
name = "Frozen",
|
||||||
|
text = {"Values on", "this card do", "not change"},
|
||||||
|
},
|
||||||
|
},
|
||||||
Enhanced = {
|
Enhanced = {
|
||||||
m_wild = {
|
m_wild = {
|
||||||
name = "Wild Card",
|
name = "Wild Card",
|
||||||
|
|
@ -112,6 +118,18 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Joker = {
|
Joker = {
|
||||||
|
j_Roland_arctic = {
|
||||||
|
name = "Arctic Circle",
|
||||||
|
text = {"Retrigger all", "{C:dark_edition}Frozen {}cards"},
|
||||||
|
},
|
||||||
|
j_Roland_basket = {
|
||||||
|
name = "Basket",
|
||||||
|
text = {
|
||||||
|
"Sell this Joker to",
|
||||||
|
"create {C:dark_edition}Negative {}copies",
|
||||||
|
"of every consumable",
|
||||||
|
},
|
||||||
|
},
|
||||||
j_Roland_bulldozer = {
|
j_Roland_bulldozer = {
|
||||||
name = "Bulldozer",
|
name = "Bulldozer",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -120,6 +138,15 @@ return {
|
||||||
"{C:inactive}(Currently {X:red,C:white}X#1#{C:inactive})",
|
"{C:inactive}(Currently {X:red,C:white}X#1#{C:inactive})",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
j_Roland_domino = {
|
||||||
|
name = "Domino",
|
||||||
|
text = {
|
||||||
|
"This Joker gains {C:mult}+#1# {}Mult",
|
||||||
|
"if played hand is a",
|
||||||
|
"{C:attention}#2#",
|
||||||
|
"{C:inactive}(Currently {C:red}+#3#{C:inactive} Mult)",
|
||||||
|
},
|
||||||
|
},
|
||||||
j_Roland_escapey = {
|
j_Roland_escapey = {
|
||||||
name = "Escapey",
|
name = "Escapey",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -146,45 +173,17 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
j_Roland_phytoestrogens = {
|
j_Roland_hardboiled = {
|
||||||
name = "Phytoestrogens",
|
name = "Hard-Boiled",
|
||||||
text = {"{C:mult}+Chips{} Mult", "{X:mult,C:white}X#1#{} Mult"},
|
|
||||||
},
|
|
||||||
j_Roland_monomino = {
|
|
||||||
name = "Monomino",
|
|
||||||
text = {
|
text = {
|
||||||
"Gains {C:money}$#1#{} of",
|
"Sell this Joker to",
|
||||||
"{C:attention}sell value{} if",
|
"turn all cards in",
|
||||||
"played hand is a",
|
"hand {C:dark_edition}Frozen",
|
||||||
"{C:attention}#2#",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
j_Roland_domino = {
|
j_Roland_jokersr = {
|
||||||
name = "Domino",
|
name = "Joker Sr.",
|
||||||
text = {
|
text = {"{X:mult,C:white}X#1#{} Mult"},
|
||||||
"This Joker gains {C:mult}+#1# {}Mult",
|
|
||||||
"if played hand is a",
|
|
||||||
"{C:attention}#2#",
|
|
||||||
"{C:inactive}(Currently {C:red}+#3#{C:inactive} Mult)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
j_Roland_trimino = {
|
|
||||||
name = "Trimino",
|
|
||||||
text = {
|
|
||||||
"Copies {C:attention}#1# {C:green}random",
|
|
||||||
"scoring cards and",
|
|
||||||
"{C:red,E:1}self-destructs {}if",
|
|
||||||
"played hand is a",
|
|
||||||
"{C:attention}#2#",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
j_Roland_misfortune = {
|
|
||||||
name = "Misfortune Cookie",
|
|
||||||
text = {
|
|
||||||
"{C:tarot}Tarot{} cards created",
|
|
||||||
"by {C:tarot}Purple Seals",
|
|
||||||
"become {C:dark_edition}Negative",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
j_Roland_martingale = {
|
j_Roland_martingale = {
|
||||||
name = "Martingale",
|
name = "Martingale",
|
||||||
|
|
@ -199,6 +198,23 @@ return {
|
||||||
"{s:0}Otherwise, {C:green,s:0}#1# in #3#{s:0} chance to give {X:mult,C:white,s:0}X#9#{s:0} Mult",
|
"{s:0}Otherwise, {C:green,s:0}#1# in #3#{s:0} chance to give {X:mult,C:white,s:0}X#9#{s:0} Mult",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
j_Roland_misfortune = {
|
||||||
|
name = "Misfortune Cookie",
|
||||||
|
text = {
|
||||||
|
"{C:tarot}Tarot{} cards created",
|
||||||
|
"by {C:tarot}Purple Seals",
|
||||||
|
"become {C:dark_edition}Negative",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
j_Roland_monomino = {
|
||||||
|
name = "Monomino",
|
||||||
|
text = {
|
||||||
|
"Gains {C:money}$#1#{} of",
|
||||||
|
"{C:attention}sell value{} if",
|
||||||
|
"played hand is a",
|
||||||
|
"{C:attention}#2#",
|
||||||
|
},
|
||||||
|
},
|
||||||
j_Roland_mrsbones = {
|
j_Roland_mrsbones = {
|
||||||
name = "Mrs. Bones",
|
name = "Mrs. Bones",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -213,6 +229,14 @@ return {
|
||||||
name = "Ms. Joker",
|
name = "Ms. Joker",
|
||||||
text = {"{C:chips}+#1#{} Chips"},
|
text = {"{C:chips}+#1#{} Chips"},
|
||||||
},
|
},
|
||||||
|
j_Roland_nilly = {
|
||||||
|
name = "Nilly",
|
||||||
|
text = {
|
||||||
|
"Toggleable {X:mult,C:white}X0{} Mult",
|
||||||
|
"{C:inactive}(Currently {C:attention}#1#{C:inactive})",
|
||||||
|
"{C:inactive,s:0.75,E:1}Wait... what?",
|
||||||
|
},
|
||||||
|
},
|
||||||
j_Roland_oops = {
|
j_Roland_oops = {
|
||||||
name = "Oops! All 7s",
|
name = "Oops! All 7s",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -221,6 +245,10 @@ return {
|
||||||
"{C:inactive}(Currently {X:green,C:white}X#2#{C:inactive})",
|
"{C:inactive}(Currently {X:green,C:white}X#2#{C:inactive})",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
j_Roland_phytoestrogens = {
|
||||||
|
name = "Phytoestrogens",
|
||||||
|
text = {"{C:mult}+Chips{} Mult", "{X:mult,C:white}X#1#{} Mult"},
|
||||||
|
},
|
||||||
j_Roland_sapling = {
|
j_Roland_sapling = {
|
||||||
name = "Sapling",
|
name = "Sapling",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -230,9 +258,9 @@ return {
|
||||||
"least {C:attention}#2# suits",
|
"least {C:attention}#2# suits",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
j_Roland_srjoker = {
|
j_Roland_suitable = {
|
||||||
name = "Sr. Joker",
|
name = "Suitable",
|
||||||
text = {"{X:mult,C:white}X#1#{} Mult"},
|
text = {"{V:1}#1# {}are {C:attention}Wild", "Suit changes", "every round"},
|
||||||
},
|
},
|
||||||
j_Roland_sunny = {
|
j_Roland_sunny = {
|
||||||
name = "Sunny Side Up",
|
name = "Sunny Side Up",
|
||||||
|
|
@ -250,6 +278,16 @@ return {
|
||||||
"give {X:red,C:white}X#1#{} Mult",
|
"give {X:red,C:white}X#1#{} Mult",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
j_Roland_trimino = {
|
||||||
|
name = "Trimino",
|
||||||
|
text = {
|
||||||
|
"Copies {C:attention}#1# {C:green}random",
|
||||||
|
"scoring cards and",
|
||||||
|
"{C:red,E:1}self-destructs {}if",
|
||||||
|
"played hand is a",
|
||||||
|
"{C:attention}#2#",
|
||||||
|
},
|
||||||
|
},
|
||||||
j_Roland_yard = {
|
j_Roland_yard = {
|
||||||
name = "Yard Sale",
|
name = "Yard Sale",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -282,25 +320,10 @@ return {
|
||||||
name = "Efflorescent Sleeve",
|
name = "Efflorescent Sleeve",
|
||||||
text = {
|
text = {
|
||||||
"{C:attention}Blinds{} are {C:dark_edition}debuffed",
|
"{C:attention}Blinds{} are {C:dark_edition}debuffed",
|
||||||
"{C:dark_edition}({X:dark_edition,C:white}ante{} {X:dark_edition,C:white}number{C:dark_edition}) times",
|
"{C:dark_edition}({X:dark_edition,C:white}(ante * #2#){C:dark_edition}) times",
|
||||||
"{C:inactive}(Instead of #1#)",
|
"{C:inactive}(Instead of #1#)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
sleeve_Roland_go = {
|
|
||||||
name = "Pass GO Sleeve",
|
|
||||||
text = {
|
|
||||||
"Start with a {C:attention}Credit Card",
|
|
||||||
"Set money to {C:money}$0",
|
|
||||||
"when entering the shop",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
sleeve_Roland_go_alt = {
|
|
||||||
name = "Free Parking Sleeve",
|
|
||||||
text = {
|
|
||||||
"Start with an additional",
|
|
||||||
"{X:attention,C:white}#1#{C:attention} Credit Cards",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
sleeve_Roland_swapper = {
|
sleeve_Roland_swapper = {
|
||||||
name = "Swapper Sleeve",
|
name = "Swapper Sleeve",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -333,6 +356,14 @@ return {
|
||||||
"cards in {C:hands}hand",
|
"cards in {C:hands}hand",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
c_Roland_coolheaded = {
|
||||||
|
name = "Coolheaded",
|
||||||
|
text = {
|
||||||
|
"Add {C:dark_edition}Frozen {}to {C:attention}#1#",
|
||||||
|
"selected {C:attention}playing",
|
||||||
|
"{C:attention}card {}or {C:attention}Joker",
|
||||||
|
},
|
||||||
|
},
|
||||||
c_Roland_mirror = {
|
c_Roland_mirror = {
|
||||||
name = "Mirror",
|
name = "Mirror",
|
||||||
text = {
|
text = {
|
||||||
|
|
@ -350,6 +381,12 @@ return {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Tag = {
|
||||||
|
tag_Roland_invisible = {
|
||||||
|
name = "Invisible Tag",
|
||||||
|
text = {"{C:attention}Duplicate {}a random Joker", "{C:inactive}(Must have room)"},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
misc = {
|
misc = {
|
||||||
challenge_names = {
|
challenge_names = {
|
||||||
|
|
@ -358,6 +395,7 @@ return {
|
||||||
c_Roland_Eternally_Crimson = "Eternally Crimson",
|
c_Roland_Eternally_Crimson = "Eternally Crimson",
|
||||||
c_Roland_Eternally_Verdant = "Eternally Verdant",
|
c_Roland_Eternally_Verdant = "Eternally Verdant",
|
||||||
c_Roland_Eternally_Violet = "Eternally Violet",
|
c_Roland_Eternally_Violet = "Eternally Violet",
|
||||||
|
c_Roland_Go = "Pass GO",
|
||||||
c_Roland_Jokerful = "Jokerful",
|
c_Roland_Jokerful = "Jokerful",
|
||||||
c_Roland_Ornate = "Ornate",
|
c_Roland_Ornate = "Ornate",
|
||||||
c_Roland_Pastries = "Sweet Pastries",
|
c_Roland_Pastries = "Sweet Pastries",
|
||||||
|
|
@ -365,18 +403,28 @@ return {
|
||||||
},
|
},
|
||||||
v_dictionary = {
|
v_dictionary = {
|
||||||
b_Roland_bye = "Bye!",
|
b_Roland_bye = "Bye!",
|
||||||
|
b_Roland_disabled = "Disabled",
|
||||||
|
b_Roland_enabled = "Enabled",
|
||||||
b_Roland_comma = ", ",
|
b_Roland_comma = ", ",
|
||||||
b_Roland_debuffed = "DEBUFFED",
|
b_Roland_debuffed = "DEBUFFED",
|
||||||
b_Roland_entering_shop = "Entering shop!",
|
b_Roland_entering_shop = "Entering shop!",
|
||||||
b_Roland_escape = "ESCAPE",
|
b_Roland_escape = "ESCAPE",
|
||||||
b_Roland_fuse = "FUSE",
|
b_Roland_fuse = "FUSE",
|
||||||
b_Roland_debug_export = "Debug: Import funky.lua to _G",
|
b_Roland_equinox_assist = "Assist: Only hide text (Equinox)",
|
||||||
b_Roland_equinox_assist = "Assist: Only hide text during Equinox",
|
b_Roland_fusable_escapey = "Fusable Escapey (overpowered)",
|
||||||
|
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",
|
||||||
|
b_Roland_import_funky = "Debug: Import funky.lua",
|
||||||
b_Roland_most_common_card = "(Rank)",
|
b_Roland_most_common_card = "(Rank)",
|
||||||
|
b_Roland_no_highlight_limit = "No consumable highlight limit",
|
||||||
|
b_Roland_no_wild_debuff = "No wild card debuffs",
|
||||||
b_Roland_na = "N/A",
|
b_Roland_na = "N/A",
|
||||||
b_Roland_of = " of ",
|
b_Roland_of = " of ",
|
||||||
|
b_Roland_toggle = "TOGGLE",
|
||||||
},
|
},
|
||||||
labels = {
|
labels = {
|
||||||
|
Roland_frozen = "Frozen",
|
||||||
roland_glass_seal = "Glass Seal",
|
roland_glass_seal = "Glass Seal",
|
||||||
},
|
},
|
||||||
v_text = {
|
v_text = {
|
||||||
|
|
@ -385,6 +433,7 @@ return {
|
||||||
ch_c_Roland_Eternally_Crimson = {"{C:attention}Crimson Heart{}'s effect is active every blind"},
|
ch_c_Roland_Eternally_Crimson = {"{C:attention}Crimson Heart{}'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_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_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_Ornate = {"Anything vanilla is banned"},
|
ch_c_Roland_Ornate = {"Anything vanilla is banned"},
|
||||||
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"},
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
"author": [
|
"author": [
|
||||||
"Emik"
|
"Emik"
|
||||||
],
|
],
|
||||||
"version": "2.0.0~dev",
|
"version": "2.2.12",
|
||||||
"badge_colour": "8BE9FD",
|
"badge_colour": "8BE9FD",
|
||||||
"main_file": "src/main.lua",
|
"main_file": "src/main.lua",
|
||||||
"badge_text_colour": "44475A",
|
"badge_text_colour": "44475A",
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
"provides": [],
|
"provides": [],
|
||||||
"conflicts": [],
|
"conflicts": [],
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
"Steamodded (>=1.*)",
|
"Steamodded (>=1.0~*)",
|
||||||
"Lovely (>=0.6)",
|
"Lovely (>=0.6)",
|
||||||
"Bakery (>=1.3.2~*)"
|
"Bakery (>=0.1.26~*)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../Cryptid/
|
|
||||||
66
src/back.lua
|
|
@ -15,13 +15,11 @@ local back = (function()
|
||||||
local calculate = tbl.calculate
|
local calculate = tbl.calculate
|
||||||
|
|
||||||
function tbl:apply(...)
|
function tbl:apply(...)
|
||||||
---@diagnostic disable-next-line: redundant-return-value
|
local _ = apply and G.GAME.selected_sleeve ~= "sleeve_Roland_" .. key and save(apply(self, ...))
|
||||||
return apply and G.GAME.selected_sleeve ~= "sleeve_Roland_" .. key and save(apply(self, ...))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function tbl:calculate(...)
|
function tbl:calculate(...)
|
||||||
---@diagnostic disable-next-line: return-type-mismatch
|
return (calculate and G.GAME.selected_sleeve ~= "sleeve_Roland_" .. key) and calculate(self, ...) or nil
|
||||||
return calculate and G.GAME.selected_sleeve ~= "sleeve_Roland_" .. key and calculate(self, ...)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
tbl.pos = {x = x, y = 0}
|
tbl.pos = {x = x, y = 0}
|
||||||
|
|
@ -34,16 +32,15 @@ local back = (function()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local sleeve = (_G["CardSleeves"] or {}).Sleeve
|
||||||
SMODS.Back(tbl)
|
SMODS.Back(tbl)
|
||||||
x = x + 1
|
x = x + 1
|
||||||
|
|
||||||
---@diagnostic disable-next-line: undefined-global
|
if not sleeve then
|
||||||
if not CardSleeves then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
---@diagnostic disable-next-line: undefined-global
|
sleeve {
|
||||||
CardSleeves.Sleeve {
|
|
||||||
key = key,
|
key = key,
|
||||||
pos = tbl.pos,
|
pos = tbl.pos,
|
||||||
atlas = "back",
|
atlas = "back",
|
||||||
|
|
@ -77,8 +74,9 @@ back {
|
||||||
key = "blossom",
|
key = "blossom",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
config = {extra = {times = 2}},
|
config = {extra = {times = 2}},
|
||||||
|
attributes = {"boss_blind"},
|
||||||
loc_vars = function(self, _, _)
|
loc_vars = function(self, _, _)
|
||||||
return {vars = {self.config.extra.times}}
|
return {vars = {self.config.extra.times, self.config.extra.alt_times}}
|
||||||
end,
|
end,
|
||||||
apply = function(_, _)
|
apply = function(_, _)
|
||||||
G.GAME.modifiers.Roland_blossom_deck = true
|
G.GAME.modifiers.Roland_blossom_deck = true
|
||||||
|
|
@ -94,9 +92,11 @@ back {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local count = self:is_alt() and G.GAME.round_resets.ante or self.config.extra.times
|
local count = self:is_alt() and
|
||||||
|
G.GAME.round_resets.ante * self.config.extra.alt_times or
|
||||||
|
self.config.extra.times
|
||||||
|
|
||||||
for _ = 1, count do
|
f(count):each(function()
|
||||||
G.GAME.blind:disable()
|
G.GAME.blind:disable()
|
||||||
|
|
||||||
q {
|
q {
|
||||||
|
|
@ -107,65 +107,25 @@ back {
|
||||||
play_sound "timpani"
|
play_sound "timpani"
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
back {
|
|
||||||
key = "go",
|
|
||||||
pronouns = "he_him",
|
|
||||||
config = {extra = {times = 1, alt_times = 5}},
|
|
||||||
loc_vars = function(self, info_queue, _)
|
|
||||||
local _ = info_queue and table.insert(info_queue, G.P_CENTERS.j_credit_card)
|
|
||||||
return {vars = {self.config.extra.alt_times - self.config.extra.times}}
|
|
||||||
end,
|
|
||||||
apply = function(self)
|
|
||||||
q(function()
|
|
||||||
local count = self:is_alt() and self.config.extra.alt_times or self.config.extra.times
|
|
||||||
|
|
||||||
for _ = 1, count do
|
|
||||||
local c = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_credit_card", "Roland_go")
|
|
||||||
c:add_to_deck()
|
|
||||||
c:start_materialize()
|
|
||||||
G.jokers:emplace(c)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
calculate = function(_, card, context)
|
|
||||||
if not context.starting_shop then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
ease_dollars(-G.GAME.dollars)
|
|
||||||
|
|
||||||
attention_text {
|
|
||||||
text = localize "k_nope_ex",
|
|
||||||
backdrop_colour = G.C.MONEY,
|
|
||||||
offset = {x = 0, y = 0},
|
|
||||||
silent = true,
|
|
||||||
major = card,
|
|
||||||
align = "cm",
|
|
||||||
scale = 1.3,
|
|
||||||
hold = 1.4,
|
|
||||||
}
|
|
||||||
end,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
back {
|
back {
|
||||||
key = "swapper",
|
key = "swapper",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
|
attributes = {"spectral", "tarot"},
|
||||||
apply = function(self)
|
apply = function(self)
|
||||||
local modifiers = G.GAME.modifiers
|
local modifiers = G.GAME.modifiers
|
||||||
modifiers.Roland_swapper_deck = true
|
modifiers.Roland_swapper_deck = true
|
||||||
modifiers.Roland_alt_swapper_deck = modifiers.Roland_alt_swapper_deck or self:is_alt()
|
modifiers.Roland_alt_swapper_deck = modifiers.Roland_alt_swapper_deck or self:is_alt()
|
||||||
end,
|
end,
|
||||||
calculate = function() end,
|
calculate = f().noop,
|
||||||
}
|
}
|
||||||
|
|
||||||
local swapper = {Spectral = "Tarot", Tarot = "Spectral"}
|
local swapper = {Spectral = "Tarot", Tarot = "Spectral"}
|
||||||
local orig_create_card = create_card
|
local orig_create_card = create_card
|
||||||
|
|
||||||
---@diagnostic disable-next-line: lowercase-global
|
|
||||||
function create_card(_type, ...)
|
function create_card(_type, ...)
|
||||||
if not G.GAME.modifiers.Roland_swapper_deck then
|
if not G.GAME.modifiers.Roland_swapper_deck then
|
||||||
return orig_create_card(_type, ...)
|
return orig_create_card(_type, ...)
|
||||||
|
|
|
||||||
125
src/blind.lua
|
|
@ -29,31 +29,19 @@ SMODS.Sound {
|
||||||
}
|
}
|
||||||
|
|
||||||
local function common_rank()
|
local function common_rank()
|
||||||
local tally = {}
|
---@type { [integer]: integer }, { [integer]: string }
|
||||||
local to_name = {}
|
local tally, to_name = {}, {}
|
||||||
|
|
||||||
--- Tallies up a card area's cards.
|
f(G.playing_cards):where(function(v)
|
||||||
---@param card_area CardArea
|
|
||||||
local function tally_up(card_area)
|
|
||||||
f(card_area.cards):where(function(v)
|
|
||||||
return not SMODS.has_no_rank(v)
|
return not SMODS.has_no_rank(v)
|
||||||
end):each(function(v)
|
end):each(function(v)
|
||||||
local id = v:get_id()
|
local id = v:get_id()
|
||||||
to_name[id] = v.base.value
|
to_name[id] = v.base.value
|
||||||
tally[id] = (tally[id] or 0) + 1
|
tally[id] = (tally[id] or 0) + 1
|
||||||
end)
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
tally_up(G.deck)
|
local max_key = f(tally, pairs):fold({-1 / 0, -1 / 0}, function(a, v, k)
|
||||||
tally_up(G.hand)
|
return (v > a[1] or v == a[1] and k > a[2]) and {v, k} or a
|
||||||
tally_up(G.discard)
|
|
||||||
|
|
||||||
local max_key = f(tally):fold({-1 / 0, -1 / 0}, function(a, v, k)
|
|
||||||
if v > a[1] or k > a[2] and v == a[1] then
|
|
||||||
return {v, k}
|
|
||||||
end
|
|
||||||
|
|
||||||
return a
|
|
||||||
end)[2]
|
end)[2]
|
||||||
|
|
||||||
return max_key, to_name[max_key]
|
return max_key, to_name[max_key]
|
||||||
|
|
@ -73,6 +61,30 @@ local function has_enhancement(card)
|
||||||
return not not (e and next(e))
|
return not not (e and next(e))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function set_freeze(state)
|
||||||
|
local function copy(x)
|
||||||
|
return type(x) == "table" and f(x):map(copy):table() or x
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param card Card|{ Roland_blizzard: true|nil }
|
||||||
|
return function(card)
|
||||||
|
local last_edition = card.Roland_blizzard
|
||||||
|
card.Roland_blizzard = state and (copy(card.edition) or true) or nil
|
||||||
|
|
||||||
|
q {
|
||||||
|
delay = 0.1,
|
||||||
|
func = function()
|
||||||
|
local edition = state and {Roland_frozen = true} or last_edition or card.Roland_blizzard
|
||||||
|
card:set_edition(edition ~= true and edition or nil)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function sort_by_enhancement(v1, v2)
|
||||||
|
return has_enhancement(v1) and not has_enhancement(v2)
|
||||||
|
end
|
||||||
|
|
||||||
local function hsv_to_rgb(h, s, v)
|
local function hsv_to_rgb(h, s, v)
|
||||||
s, v = s or 1, v or 1
|
s, v = s or 1, v or 1
|
||||||
|
|
||||||
|
|
@ -112,28 +124,23 @@ blind {
|
||||||
boss_colour = HEX "0291fbff",
|
boss_colour = HEX "0291fbff",
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
config = {draw = 5},
|
config = {draw = 5},
|
||||||
defeat = function()
|
|
||||||
G.GAME.Roland_nimble_disabled = nil
|
|
||||||
end,
|
|
||||||
disable = function()
|
|
||||||
G.GAME.Roland_nimble_disabled = true
|
|
||||||
end,
|
|
||||||
drawn_to_hand = function(self)
|
drawn_to_hand = function(self)
|
||||||
local function force_hand()
|
local function force_hand()
|
||||||
if is_locked() then
|
if is_locked() then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
f(G.hand.cards, ipairs):take(self.config.draw):each(function(v)
|
f(G.hand.cards):take(self.config.draw):each(function(v)
|
||||||
G.hand:add_to_highlighted(v, true)
|
G.hand:add_to_highlighted(v, true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
G.FUNCS.play_cards_from_highlighted(nil)
|
G.FUNCS.play_cards_from_highlighted()
|
||||||
self:disable()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if not G.GAME.Roland_nimble_disabled then
|
local g = G.GAME
|
||||||
G.GAME.Roland_nimble_disabled = true
|
|
||||||
|
if not g.blind.disabled and not g.Roland_nimble_disabled then
|
||||||
|
g.Roland_nimble_disabled = true
|
||||||
q {func = force_hand, blocking = false}
|
q {func = force_hand, blocking = false}
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
@ -148,29 +155,14 @@ blind {
|
||||||
boss_colour = HEX "ff7f3dff",
|
boss_colour = HEX "ff7f3dff",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
disable = function()
|
disable = function()
|
||||||
q(function()
|
G.FUNCS.draw_from_hand_to_deck()
|
||||||
f(G.hand.cards):each(function(v, i)
|
|
||||||
draw_card(G.hand, G.deck, i / #G.hand.cards * 100, "up", false, v)
|
|
||||||
end)
|
|
||||||
end)
|
|
||||||
|
|
||||||
q(function()
|
q(function()
|
||||||
pseudoshuffle(G.deck.cards, pseudoseed "RolandFalseShuffle")
|
pseudoshuffle(G.deck.cards, pseudoseed "RolandFalseShuffle")
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
calculate = function(_, b, context)
|
calculate = function(_, b, context)
|
||||||
if b.disabled or not context.drawing_cards then
|
local _ = not b.disabled and context.drawing_cards and table.sort(G.deck.cards, sort_by_enhancement)
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
b:wiggle()
|
|
||||||
|
|
||||||
table.sort(
|
|
||||||
G.deck.cards,
|
|
||||||
function(v1, v2)
|
|
||||||
return has_enhancement(v1) and not has_enhancement(v2)
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end,
|
end,
|
||||||
in_pool = function()
|
in_pool = function()
|
||||||
return G.playing_cards and f(G.playing_cards):any(has_enhancement)
|
return G.playing_cards and f(G.playing_cards):any(has_enhancement)
|
||||||
|
|
@ -223,7 +215,7 @@ blind {
|
||||||
local cards_added = {}
|
local cards_added = {}
|
||||||
local count = #G.hand.highlighted
|
local count = #G.hand.highlighted
|
||||||
|
|
||||||
f(G.hand.highlighted, ipairs):take(count):each(function(v, i)
|
f(G.hand.highlighted):take(count):each(function(v, i)
|
||||||
local copy = copy_card(v)
|
local copy = copy_card(v)
|
||||||
copy:add_to_deck()
|
copy:add_to_deck()
|
||||||
table.insert(G.hand, copy)
|
table.insert(G.hand, copy)
|
||||||
|
|
@ -238,6 +230,30 @@ blind {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blind {
|
||||||
|
key = "blizzard",
|
||||||
|
boss = {min = 3},
|
||||||
|
boss_colour = HEX "102a41ff",
|
||||||
|
pronouns = "it_its",
|
||||||
|
defeat = function(self)
|
||||||
|
self.cards():each(set_freeze())
|
||||||
|
G.GAME.blind.disabled = true
|
||||||
|
end,
|
||||||
|
disable = function(self)
|
||||||
|
self:defeat()
|
||||||
|
end,
|
||||||
|
calculate = function(self, b)
|
||||||
|
return not b.disabled and self.cards():where(function(v)
|
||||||
|
return not v.Roland_blizzard and v.facing == "front"
|
||||||
|
end):each(set_freeze(true)) or nil
|
||||||
|
end,
|
||||||
|
cards = function()
|
||||||
|
return f(G):where(function(v)
|
||||||
|
return type(v) == "table" and type(v.cards) == "table"
|
||||||
|
end):flatmap("cards", ipairs)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
blind {
|
blind {
|
||||||
key = "tranquilizer",
|
key = "tranquilizer",
|
||||||
boss = {min = 6},
|
boss = {min = 6},
|
||||||
|
|
@ -255,9 +271,6 @@ blind {
|
||||||
local _, name = common_rank()
|
local _, name = common_rank()
|
||||||
return {vars = {localize(name or "Ace", "ranks")}}
|
return {vars = {localize(name or "Ace", "ranks")}}
|
||||||
end,
|
end,
|
||||||
disable = function(self)
|
|
||||||
self.disabled = true
|
|
||||||
end,
|
|
||||||
calculate = function(self, b, context)
|
calculate = function(self, b, context)
|
||||||
if not context.card_added and
|
if not context.card_added and
|
||||||
not context.drawing_cards and
|
not context.drawing_cards and
|
||||||
|
|
@ -298,7 +311,7 @@ blind {
|
||||||
|
|
||||||
blind {
|
blind {
|
||||||
key = "improbable",
|
key = "improbable",
|
||||||
boss = {min = 4},
|
boss = {min = 3},
|
||||||
boss_colour = HEX "009966ff",
|
boss_colour = HEX "009966ff",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
mult = 2,
|
mult = 2,
|
||||||
|
|
@ -313,7 +326,6 @@ blind {
|
||||||
if cry_prob then
|
if cry_prob then
|
||||||
local orig_cry_prob = cry_prob
|
local orig_cry_prob = cry_prob
|
||||||
|
|
||||||
---@diagnostic disable-next-line: lowercase-global
|
|
||||||
function cry_prob(...)
|
function cry_prob(...)
|
||||||
return G.GAME.modifiers.Roland_improbable and 0 or orig_cry_prob(...)
|
return G.GAME.modifiers.Roland_improbable and 0 or orig_cry_prob(...)
|
||||||
end
|
end
|
||||||
|
|
@ -325,6 +337,8 @@ function SMODS.current_mod:calculate(context)
|
||||||
modifiers.Roland_martingale_seed = (modifiers.Roland_martingale_seed or 0) + 1
|
modifiers.Roland_martingale_seed = (modifiers.Roland_martingale_seed or 0) + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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())
|
local _ = type(G.calc) == "function" and G.calc(f(context):keys():string())
|
||||||
local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities
|
local improbable, orig = G.GAME.modifiers.Roland_improbable, G.GAME.probabilities
|
||||||
|
|
||||||
|
|
@ -382,7 +396,6 @@ end
|
||||||
|
|
||||||
local orig_draw = Card.draw
|
local orig_draw = Card.draw
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Card:draw(...)
|
function Card:draw(...)
|
||||||
if equinox() and
|
if equinox() and
|
||||||
not SMODS.Mods.Roland.config.equinox_assist and
|
not SMODS.Mods.Roland.config.equinox_assist and
|
||||||
|
|
@ -396,7 +409,6 @@ end
|
||||||
|
|
||||||
local orig_draw_self = UIElement.draw_self
|
local orig_draw_self = UIElement.draw_self
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function UIElement:draw_self(...)
|
function UIElement:draw_self(...)
|
||||||
if equinox() and
|
if equinox() and
|
||||||
not self.config.button and
|
not self.config.button and
|
||||||
|
|
@ -412,6 +424,7 @@ local venerable_visage = blind {
|
||||||
boss = {showdown = true},
|
boss = {showdown = true},
|
||||||
boss_colour = HEX "f6f6f2ff",
|
boss_colour = HEX "f6f6f2ff",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
|
dollars = 8,
|
||||||
calculate = function(self, b, context)
|
calculate = function(self, b, context)
|
||||||
if b.disabled then
|
if b.disabled then
|
||||||
return
|
return
|
||||||
|
|
@ -424,7 +437,10 @@ local venerable_visage = blind {
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
if b.Roland_vitriol or not context.end_of_round or not next(G.deck.cards) or not next(G.hand.cards) then
|
if b.Roland_vitriol or
|
||||||
|
not context.end_of_round or
|
||||||
|
G.GAME.chips == G.GAME.blind.chips or
|
||||||
|
not (next(G.deck.cards) or next(G.hand.cards)) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -503,7 +519,6 @@ local venerable_visage = blind {
|
||||||
|
|
||||||
local orig_game_draw = Game.draw
|
local orig_game_draw = Game.draw
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Game.draw(...)
|
function Game.draw(...)
|
||||||
orig_game_draw(...)
|
orig_game_draw(...)
|
||||||
local boss_colour = venerable_visage.boss_colour
|
local boss_colour = venerable_visage.boss_colour
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,29 @@ end
|
||||||
local jokerful, vanillas, pastries, amber, cerulean, crimson, verdant, violet, final
|
local jokerful, vanillas, pastries, amber, cerulean, crimson, verdant, violet, final
|
||||||
= bans(), bans(), bans(), bans(), bans(), bans(), bans(), bans(), bans()
|
= bans(), bans(), bans(), bans(), bans(), bans(), bans(), bans(), bans()
|
||||||
|
|
||||||
|
SMODS.Challenge {
|
||||||
|
key = "Go",
|
||||||
|
rules = {custom = {{id = "Roland_Go"}}},
|
||||||
|
jokers = {{id = "j_credit_card"}},
|
||||||
|
pronouns = "he_him",
|
||||||
|
calculate = function(self, context)
|
||||||
|
if context.starting_shop then
|
||||||
|
ease_dollars(-G.GAME.dollars)
|
||||||
|
|
||||||
|
attention_text {
|
||||||
|
text = localize "k_nope_ex",
|
||||||
|
backdrop_colour = G.C.MONEY,
|
||||||
|
offset = {x = 0, y = 0},
|
||||||
|
silent = true,
|
||||||
|
major = self,
|
||||||
|
align = "cm",
|
||||||
|
scale = 1.3,
|
||||||
|
hold = 1.4,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
SMODS.Challenge {
|
SMODS.Challenge {
|
||||||
key = "Jokerful",
|
key = "Jokerful",
|
||||||
rules = {custom = {{id = "Roland_Jokerful"}}},
|
rules = {custom = {{id = "Roland_Jokerful"}}},
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ end
|
||||||
charm {
|
charm {
|
||||||
key = "wii",
|
key = "wii",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
|
attributes = {"skip"},
|
||||||
calculate = function(_, card, context)
|
calculate = function(_, card, context)
|
||||||
if not context.skip_blind then
|
if not context.skip_blind then
|
||||||
return
|
return
|
||||||
|
|
@ -109,7 +110,6 @@ charm {
|
||||||
|
|
||||||
local orig_showman = SMODS.showman
|
local orig_showman = SMODS.showman
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function SMODS.showman(...)
|
function SMODS.showman(...)
|
||||||
return G.GAME.Bakery_charm == "BakeryCharm_Roland_flexible" or orig_showman(...)
|
return G.GAME.Bakery_charm == "BakeryCharm_Roland_flexible" or orig_showman(...)
|
||||||
end
|
end
|
||||||
|
|
@ -117,21 +117,21 @@ end
|
||||||
charm {
|
charm {
|
||||||
key = "fat",
|
key = "fat",
|
||||||
pronouns = "he_they",
|
pronouns = "he_they",
|
||||||
-- config = {extra = {mod = 1}},
|
attributes = {"passive"},
|
||||||
-- loc_vars = function(_, _, card)
|
config = {extra = {mod = 1}},
|
||||||
-- return {vars = {card.ability.extra.mod}}
|
loc_vars = function(_, _, card)
|
||||||
-- end,
|
return {vars = {card.ability.extra.mod}}
|
||||||
-- equip = function(_, card)
|
end,
|
||||||
-- SMODS.change_booster_limit(card.ability.extra.mod)
|
equip = function(_, card)
|
||||||
-- end,
|
SMODS.change_booster_limit(card.ability.extra.mod)
|
||||||
-- unequip = function(card)
|
end,
|
||||||
-- SMODS.change_booster_limit(-card.ability.extra.mod)
|
unequip = function(card)
|
||||||
-- end,
|
SMODS.change_booster_limit(-card.ability.extra.mod)
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local orig_init = Card.init
|
local orig_init = Card.init
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Card:init(X, Y, W, H, card, center, params, ...)
|
function Card:init(X, Y, W, H, card, center, params, ...)
|
||||||
if G.GAME.Bakery_charm ~= "BakeryCharm_Roland_fat" or center.set ~= "Booster" then
|
if G.GAME.Bakery_charm ~= "BakeryCharm_Roland_fat" or center.set ~= "Booster" then
|
||||||
return orig_init(self, X, Y, W, H, card, center, params, ...)
|
return orig_init(self, X, Y, W, H, card, center, params, ...)
|
||||||
|
|
@ -162,6 +162,7 @@ end
|
||||||
charm {
|
charm {
|
||||||
key = "cocacola",
|
key = "cocacola",
|
||||||
pronouns = "he_they",
|
pronouns = "he_they",
|
||||||
|
attributes = {"passive", "tarot", "spectral"},
|
||||||
equip = function()
|
equip = function()
|
||||||
f(G.consumeables.cards):each(add_to_consumable_ability_by(1))
|
f(G.consumeables.cards):each(add_to_consumable_ability_by(1))
|
||||||
end,
|
end,
|
||||||
|
|
@ -172,7 +173,6 @@ charm {
|
||||||
|
|
||||||
local orig_set_ability = Card.set_ability
|
local orig_set_ability = Card.set_ability
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Card:set_ability(center, initial, delay_sprites, ...)
|
function Card:set_ability(center, initial, delay_sprites, ...)
|
||||||
local ret = orig_set_ability(self, center, initial, delay_sprites, ...)
|
local ret = orig_set_ability(self, center, initial, delay_sprites, ...)
|
||||||
|
|
||||||
|
|
@ -187,6 +187,7 @@ charm {
|
||||||
key = "hand",
|
key = "hand",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
config = {extra = {hands = -2, hand_size = 5}},
|
config = {extra = {hands = -2, hand_size = 5}},
|
||||||
|
attributes = {"hands", "hand_size", "passive"},
|
||||||
loc_vars = function(_, _, card)
|
loc_vars = function(_, _, card)
|
||||||
local extra = card.ability.extra
|
local extra = card.ability.extra
|
||||||
return {vars = {extra.hand_size, extra.hands}}
|
return {vars = {extra.hand_size, extra.hands}}
|
||||||
|
|
|
||||||
312
src/edition.lua
Normal file
|
|
@ -0,0 +1,312 @@
|
||||||
|
local f, q = unpack(... or require "lib.shared")
|
||||||
|
|
||||||
|
SMODS.Shader {
|
||||||
|
key = "frozen",
|
||||||
|
path = "frozen.fs",
|
||||||
|
}
|
||||||
|
|
||||||
|
---@param suffix string
|
||||||
|
local function frozen_sound(suffix)
|
||||||
|
local key = "frozen" .. suffix
|
||||||
|
return SMODS.Sound {key = key, path = key .. ".ogg"}
|
||||||
|
end
|
||||||
|
|
||||||
|
frozen_sound "_click"
|
||||||
|
local frozen_sounds = f(4):map(frozen_sound):map("key"):table()
|
||||||
|
|
||||||
|
local needs_chip_mult_override = {
|
||||||
|
Bull = true,
|
||||||
|
Erosion = true,
|
||||||
|
Misprint = true,
|
||||||
|
TierList = true,
|
||||||
|
Bootstraps = true,
|
||||||
|
["Blue Joker"] = true,
|
||||||
|
["Abstract Joker"] = true,
|
||||||
|
["Fortune Teller"] = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
local current_round_overrides = {
|
||||||
|
Castle = "castle_card",
|
||||||
|
Farmer = "farmer_card",
|
||||||
|
Tuxedo = "tuxedo_card",
|
||||||
|
["Go Fish"] = "fish_rank",
|
||||||
|
["The Idol"] = "idol_card",
|
||||||
|
["Mail-In Rebate"] = "mail_card",
|
||||||
|
Obelisk = "most_played_poker_hand",
|
||||||
|
["Ancient Joker"] = "ancient_card",
|
||||||
|
Wherewolf = "Bakery_Wherewolf_card",
|
||||||
|
j_Roland_suitable = "Roland_suitable",
|
||||||
|
}
|
||||||
|
|
||||||
|
SMODS.current_mod.frozen_chip_mult = needs_chip_mult_override
|
||||||
|
SMODS.current_mod.frozen_current_round = current_round_overrides
|
||||||
|
|
||||||
|
local function freeze(card)
|
||||||
|
---@generic T
|
||||||
|
---@param x T
|
||||||
|
---@return T
|
||||||
|
local function copy(x)
|
||||||
|
return type(x) == "table" and f(x):map(copy):where(function(v, k)
|
||||||
|
return k ~= "Roland_frozen_proxy" and (k ~= "nine_tally" or v ~= 0)
|
||||||
|
end):table() or x
|
||||||
|
end
|
||||||
|
|
||||||
|
card.Roland_frozen_ability = card.Roland_frozen_ability or copy(card.ability)
|
||||||
|
card.ability = card.Roland_frozen_ability and copy(card.Roland_frozen_ability) or card.ability
|
||||||
|
local ability, ret = card.ability, card.Roland_frozen_ability
|
||||||
|
|
||||||
|
if type(ability) ~= "table" then
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
ability.seal = ability.seal or {}
|
||||||
|
|
||||||
|
if not ability.name or not G.GAME.current_round then
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local key = current_round_overrides[ability.name]
|
||||||
|
|
||||||
|
if not key then
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
card.Roland_frozen_current_round = card.Roland_frozen_current_round or copy(G.GAME.current_round[key])
|
||||||
|
G.GAME.current_round[key] = copy(card.Roland_frozen_current_round)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
SMODS.Edition {
|
||||||
|
key = "frozen",
|
||||||
|
shader = "frozen",
|
||||||
|
sound = {sound = "Roland_frozen", per = 1, vol = 0.8},
|
||||||
|
attributes = {"passive", "scaling"},
|
||||||
|
weight = 8,
|
||||||
|
extra_cost = 4,
|
||||||
|
in_shop = true,
|
||||||
|
apply_to_float = false,
|
||||||
|
calculate = function(_, card)
|
||||||
|
freeze(card)
|
||||||
|
end,
|
||||||
|
on_remove = function(card)
|
||||||
|
card.Roland_frozen_proxy = nil
|
||||||
|
card.Roland_frozen_estate = nil
|
||||||
|
card.Roland_frozen_ability = nil
|
||||||
|
end,
|
||||||
|
get_weight = function(self)
|
||||||
|
return G.GAME.edition_rate * self.weight
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
local orig_play_sound = play_sound
|
||||||
|
|
||||||
|
function play_sound(sound, pitch, ...)
|
||||||
|
if sound ~= "Roland_frozen" and sound ~= "Roland_frozen_click" then
|
||||||
|
return orig_play_sound(sound, pitch, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local overriden_sound = sound == "Roland_frozen" and
|
||||||
|
pseudorandom_element(frozen_sounds, pseudoseed "Roland_frozen") or
|
||||||
|
sound
|
||||||
|
|
||||||
|
local added_pitch = pseudorandom(pseudoseed "Roland_frozen_pitch") / 4 + 0.8
|
||||||
|
return orig_play_sound(overriden_sound, pitch + added_pitch, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_click = Card.click
|
||||||
|
|
||||||
|
function Card:click(...)
|
||||||
|
local highlight = self.highlighted
|
||||||
|
local ret = orig_click(self, ...)
|
||||||
|
|
||||||
|
if self.edition and self.edition.Roland_frozen and highlight ~= self.highlighted then
|
||||||
|
play_sound("Roland_frozen_click", highlight and 0 or 0.5, 0.6)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_calculate_joker = Card.calculate_joker
|
||||||
|
|
||||||
|
---@param self Card|{Roland_frozen_ability?: table}
|
||||||
|
function Card:calculate_joker(context, ...)
|
||||||
|
local is_frozen = self.edition and self.edition.Roland_frozen
|
||||||
|
|
||||||
|
if is_frozen and self.ability.name == "Loyalty Card" then
|
||||||
|
return (context.joker_main and self.ability.loyalty_remaining == 0) and
|
||||||
|
{xmult = self.ability.extra.Xmult} or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_frozen and self.ability.name == "Turtle Bean" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local ret = {orig_calculate_joker(self, context, ...)}
|
||||||
|
|
||||||
|
if not is_frozen or not ret[1] then
|
||||||
|
return unpack(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ability = freeze(self)
|
||||||
|
|
||||||
|
if not needs_chip_mult_override[ability.name] then
|
||||||
|
return unpack(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
ability.Roland_frozen_mult_mod = ability.Roland_frozen_mult_mod or ret[1].mult_mod
|
||||||
|
ability.Roland_frozen_chip_mod = ability.Roland_frozen_chip_mod or ret[1].chip_mod
|
||||||
|
ability.Roland_frozen_xmult = ability.Roland_frozen_xmult or ret[1].xmult
|
||||||
|
|
||||||
|
return {
|
||||||
|
chip_mod = ability.Roland_frozen_chip_mod,
|
||||||
|
mult_mod = ability.Roland_frozen_mult_mod,
|
||||||
|
xmult = ability.Roland_frozen_xmult,
|
||||||
|
message = localize {
|
||||||
|
type = "variable",
|
||||||
|
key = "a_mult",
|
||||||
|
vars = {
|
||||||
|
ability.Roland_frozen_mult_mod or
|
||||||
|
ability.Roland_frozen_chip_mod or
|
||||||
|
ability.Roland_frozen_xmult,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_calculate_dollar_bonus = Card.calculate_dollar_bonus
|
||||||
|
|
||||||
|
---@param self Card|{Roland_frozen_ability?: table}
|
||||||
|
function Card:calculate_dollar_bonus(...)
|
||||||
|
if not self.edition or not self.edition.Roland_frozen then
|
||||||
|
return orig_calculate_dollar_bonus(self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ability = freeze(self)
|
||||||
|
|
||||||
|
if ability.name == "Satellite" then
|
||||||
|
ability.Roland_frozen_planets_used = ability.Roland_frozen_planets_used or
|
||||||
|
orig_calculate_dollar_bonus(self, ...)
|
||||||
|
|
||||||
|
return self.ability.extra * ability.Roland_frozen_planets_used
|
||||||
|
end
|
||||||
|
|
||||||
|
return orig_calculate_dollar_bonus(self, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
local estate = G.P_CENTERS.j_Bakery_Estate
|
||||||
|
|
||||||
|
if not estate then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param card Card|{ Roland_frozen_estate: integer }
|
||||||
|
local function estate_pos(card)
|
||||||
|
if card.area ~= G.jokers and card.area.config.type ~= "title" then
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
card.Roland_frozen_estate = card.Roland_frozen_estate and
|
||||||
|
card.Roland_frozen_estate or
|
||||||
|
(f(card.area.cards):swap():any(function(_, k)
|
||||||
|
return k == card
|
||||||
|
end) or 1)
|
||||||
|
|
||||||
|
return card.Roland_frozen_estate
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_calculate = estate.calculate
|
||||||
|
|
||||||
|
function estate:calculate(card, context, ...)
|
||||||
|
if not card or not card.edition or not card.edition.Roland_frozen then
|
||||||
|
return orig_calculate(self, card, context, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not context.joker_main then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local joker_count = estate_pos(card)
|
||||||
|
local extra = card.ability.extra or {}
|
||||||
|
return {chips = extra.chips * joker_count, mult = extra.mult * joker_count}
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_loc_vars = estate.loc_vars
|
||||||
|
|
||||||
|
function estate:loc_vars(info_queue, card, ...)
|
||||||
|
if not card or not card.edition or not card.edition.Roland_frozen then
|
||||||
|
return orig_loc_vars(self, info_queue, card, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local joker_count = estate_pos(card)
|
||||||
|
local extra = card.ability.extra or {}
|
||||||
|
return {vars = {extra.chips * joker_count, extra.mult * joker_count}}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
local proxy = G.P_CENTERS.j_Bakery_Proxy
|
||||||
|
|
||||||
|
if not proxy then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param card Card|{ Roland_frozen_proxy: number }
|
||||||
|
local function get_proxied_joker(card)
|
||||||
|
if not G.jokers or not G.jokers.cards then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
card.Roland_frozen_proxy = card.Roland_frozen_proxy or
|
||||||
|
(Bakery_API.get_proxied_joker() or card).unique_val
|
||||||
|
|
||||||
|
---@param v Card
|
||||||
|
local function eq(v)
|
||||||
|
return v.unique_val == card.Roland_frozen_proxy
|
||||||
|
end
|
||||||
|
|
||||||
|
return f(G.jokers.cards):any(eq) ---@type Card?
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_calculate = proxy.calculate
|
||||||
|
|
||||||
|
function proxy:calculate(card, context, ...)
|
||||||
|
if not card or not card.edition or not card.edition.Roland_frozen then
|
||||||
|
return orig_calculate(self, card, context, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
return SMODS.blueprint_effect(card, get_proxied_joker(card), context)
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_loc_vars = proxy.loc_vars
|
||||||
|
|
||||||
|
function proxy:loc_vars(info_queue, card, ...)
|
||||||
|
if not card or not card.edition or not card.edition.Roland_frozen then
|
||||||
|
return orig_loc_vars(self, info_queue, card, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local other = get_proxied_joker(card)
|
||||||
|
|
||||||
|
local var = (other and other ~= card) and localize {
|
||||||
|
type = "name_text",
|
||||||
|
set = other.config.center.set,
|
||||||
|
key = other.config.center.key,
|
||||||
|
} or localize "k_none"
|
||||||
|
|
||||||
|
return {vars = {var}}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
local orig_flip_double_sided = (Bakery_API or {}).flip_double_sided
|
||||||
|
|
||||||
|
if not orig_flip_double_sided then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
function Bakery_API.flip_double_sided(card, ...)
|
||||||
|
if not card.edition or not card.edition.Roland_frozen then
|
||||||
|
return orig_flip_double_sided(card, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
353
src/joker.lua
|
|
@ -12,13 +12,19 @@ local joker = (function()
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param tbl SMODS.Joker|{artist?: string, sinis?: boolean|{x: number, y: number}, soul_pos?: boolean|{x: number, y: number}}
|
---@param tbl SMODS.Joker|{artist?: string, sinis?: boolean|{x: number, y: number}, soul_pos?: boolean|{x: number, y: number}, attributes?: Attributes[]}
|
||||||
return function(tbl)
|
return function(tbl)
|
||||||
tbl.pos = inc()
|
tbl.pos = inc()
|
||||||
tbl.atlas = "joker"
|
tbl.atlas = "joker"
|
||||||
tbl.artist = tbl.artist and "Roland_" .. tbl.artist or nil
|
tbl.artist = tbl.artist and "Roland_" .. tbl.artist or nil
|
||||||
tbl.soul_pos = tbl.soul_pos and inc() or nil
|
tbl.soul_pos = tbl.soul_pos and inc() or nil
|
||||||
tbl.sinis = tbl.sinis and inc() or nil
|
tbl.sinis = tbl.sinis and inc() or nil
|
||||||
|
|
||||||
|
if ((tbl.config or {}).extra or {}).flipped ~= nil then
|
||||||
|
tbl.config.extra.front_pos = tbl.pos
|
||||||
|
tbl.config.extra.back_pos = inc()
|
||||||
|
end
|
||||||
|
|
||||||
local joker = SMODS.Joker(tbl)
|
local joker = SMODS.Joker(tbl)
|
||||||
|
|
||||||
q(function()
|
q(function()
|
||||||
|
|
@ -31,16 +37,27 @@ local function destructible(card)
|
||||||
return not card.highlighted and not (card.ability or {}).eternal
|
return not card.highlighted and not (card.ability or {}).eternal
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param card Card
|
||||||
local function is_carbon(card)
|
local function is_carbon(card)
|
||||||
return card.edition and card.edition.key == "e_Bakery_Carbon"
|
return card.edition and card.edition.key == "e_Bakery_Carbon"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param card Card
|
||||||
|
local function is_frozen(card)
|
||||||
|
return card.edition and card.edition.key == "e_Roland_frozen"
|
||||||
|
end
|
||||||
|
|
||||||
local function is_mergeable_with(x)
|
local function is_mergeable_with(x)
|
||||||
return function(y)
|
return function(y)
|
||||||
return x.rank ~= y.rank and y.label == "j_Roland_escapey" and not (y.ability or {}).eternal
|
return x.rank ~= y.rank and
|
||||||
|
y.label == "j_Roland_escapey" and
|
||||||
|
not (y.ability or {}).eternal
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param hand? string|true
|
||||||
|
---@param by integer
|
||||||
|
---@param card Card
|
||||||
local function level_up(hand, by, card)
|
local function level_up(hand, by, card)
|
||||||
local function update(handname, chips, mult, level, pitch)
|
local function update(handname, chips, mult, level, pitch)
|
||||||
update_hand_text(
|
update_hand_text(
|
||||||
|
|
@ -56,11 +73,12 @@ local function level_up(hand, by, card)
|
||||||
hand = hand or "NO_HAND_SPECIFIED"
|
hand = hand or "NO_HAND_SPECIFIED"
|
||||||
local hand_obj = G.GAME.hands[hand]
|
local hand_obj = G.GAME.hands[hand]
|
||||||
|
|
||||||
if hand == "all" or hand == "allhands" or hand == "all_hands" then
|
if hand == true then
|
||||||
update(localize "k_all_hands", "...", "...", "")
|
update(localize "k_all_hands", "...", "...", "")
|
||||||
|
delay(2)
|
||||||
|
|
||||||
f(G.GAME.hands):keys():each(function(k)
|
f(G.GAME.hands):where "visible":keys():each(function(k)
|
||||||
level_up_hand(card, k, nil, by)
|
level_up_hand(card, k, true, by)
|
||||||
end)
|
end)
|
||||||
elseif hand_obj then
|
elseif hand_obj then
|
||||||
update(localize(hand, "poker_hands"), hand_obj.chips, hand_obj.mult, hand_obj.level)
|
update(localize(hand, "poker_hands"), hand_obj.chips, hand_obj.mult, hand_obj.level)
|
||||||
|
|
@ -77,10 +95,16 @@ SMODS.Atlas {
|
||||||
py = 95,
|
py = 95,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMODS.Sound {
|
||||||
|
key = "nilly",
|
||||||
|
path = "nilly.ogg",
|
||||||
|
}
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "escapey",
|
key = "escapey",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
config = {extra = {hands = 2}},
|
config = {extra = {hands = 2}},
|
||||||
|
attributes = {"destroy_card", "tarot", "planet", "spectral", "tag"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
sinis = true,
|
sinis = true,
|
||||||
|
|
@ -88,16 +112,11 @@ joker {
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
blueprint_compat = false,
|
blueprint_compat = false,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
loc_vars = function(_, _, card)
|
loc_vars = function(self, _, card)
|
||||||
local loc_self = G.localization.descriptions.Joker.j_Roland_escapey
|
local sinister = (_G["Jen"] or _G["pwx"] or {}).sinister or G.escapey_sinister
|
||||||
|
local loc = G.localization.descriptions.Joker.j_Roland_escapey
|
||||||
---@diagnostic disable-next-line: undefined-global
|
local merge = self.fusable(card) and loc.merge or {}
|
||||||
local sinister = (Jen or {}).sinister or G.escapey_sinister
|
local quotes = loc.quotes
|
||||||
local quotes = loc_self.quotes
|
|
||||||
|
|
||||||
local merge = G.jokers
|
|
||||||
and f(G.jokers.cards):any(is_mergeable_with(card))
|
|
||||||
and loc_self.merge or {}
|
|
||||||
|
|
||||||
local normal = (merge[1] or sinister) and "" or
|
local normal = (merge[1] or sinister) and "" or
|
||||||
pseudorandom_element(quotes.normal, pseudoseed "EscapeyQuotes") or ""
|
pseudorandom_element(quotes.normal, pseudoseed "EscapeyQuotes") or ""
|
||||||
|
|
@ -111,43 +130,31 @@ joker {
|
||||||
normal,
|
normal,
|
||||||
scared,
|
scared,
|
||||||
merge[1] or "",
|
merge[1] or "",
|
||||||
merge[1] and loc_self.name or "",
|
merge[1] and loc.name or "",
|
||||||
merge[2] or "",
|
merge[2] or "",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
Bakery_can_use = function(_, card)
|
calculate = function(self, card, context)
|
||||||
return not card.debuff and u() and (
|
return context.forcetrigger and self.proc(card) or nil
|
||||||
#G.GAME.tags ~= 0 or
|
|
||||||
f(G.consumeables.cards):any(destructible) or
|
|
||||||
f(G.jokers.cards):any(is_mergeable_with(card))
|
|
||||||
)
|
|
||||||
end,
|
end,
|
||||||
Bakery_use_button_text = function(_, card)
|
Bakery_can_use = function(self, card)
|
||||||
|
return not card.debuff and u() and (self.exchangable() or self.fusable(card))
|
||||||
|
end,
|
||||||
|
Bakery_use_button_text = function(self, card)
|
||||||
return localize {
|
return localize {
|
||||||
type = "variable",
|
type = "variable",
|
||||||
key = card.debuff and "b_Roland_debuffed" or
|
key = card.debuff and "b_Roland_debuffed" or
|
||||||
(#G.GAME.tags == 0 and not
|
((not self.exchangable() and self.fusable(card)) and
|
||||||
f(G.consumeables.cards):any(destructible) and
|
|
||||||
f(G.jokers.cards):any(is_mergeable_with(card)) and
|
|
||||||
"b_Roland_fuse" or "b_Roland_escape"),
|
"b_Roland_fuse" or "b_Roland_escape"),
|
||||||
}
|
}
|
||||||
end,
|
end,
|
||||||
calculate = function(self, card, context)
|
|
||||||
if context.forcetrigger then
|
|
||||||
return self.proc(card)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
Bakery_use_joker = function(self, card)
|
Bakery_use_joker = function(self, card)
|
||||||
if card.debuff then
|
if card.debuff then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local consumables = f(G.consumeables.cards):where(destructible):table()
|
if not self.exchangable() then
|
||||||
local consumable_count = #consumables
|
|
||||||
local tag_count = #G.GAME.tags
|
|
||||||
|
|
||||||
if consumable_count == 0 and tag_count == 0 then
|
|
||||||
local level_sum, sell_sum = 0, 0
|
local level_sum, sell_sum = 0, 0
|
||||||
local any_carbon = is_carbon(card)
|
local any_carbon = is_carbon(card)
|
||||||
|
|
||||||
|
|
@ -166,30 +173,34 @@ joker {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local function fast_delete(v)
|
local function fast_delete(tag)
|
||||||
return function()
|
return function()
|
||||||
attention_text {
|
attention_text {
|
||||||
scale = 0.7,
|
scale = 0.7,
|
||||||
align = "cm",
|
align = "cm",
|
||||||
text = "ESC",
|
text = "ESC",
|
||||||
cover = v.HUD_tag,
|
cover = tag.HUD_tag,
|
||||||
colour = G.C.WHITE,
|
colour = G.C.WHITE,
|
||||||
cover_colour = G.C.BLACK,
|
cover_colour = G.C.BLACK,
|
||||||
hold = 0.3 / G.SETTINGS.GAMESPEED,
|
hold = 0.3 / G.SETTINGS.GAMESPEED,
|
||||||
}
|
}
|
||||||
|
|
||||||
play_sound("cancel", 1.66, 0.5)
|
play_sound("cancel", 1.66, 0.5)
|
||||||
v.HUD_tag.states.visible = false
|
tag.HUD_tag.states.visible = false
|
||||||
v:remove()
|
tag:remove()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local destroyed = 0
|
local destroyed = 0
|
||||||
|
|
||||||
if consumable_count == 0 then
|
f(G.consumeables.cards):where(destructible):each(function(v)
|
||||||
local threshold = 30
|
v:start_dissolve({HEX "57ecabff"}, nil, 1.6)
|
||||||
local delay = #G.GAME.tags >= threshold and 0 or 1 / #G.GAME.tags
|
destroyed = destroyed + 1
|
||||||
local trigger = #G.GAME.tags >= threshold and "immediate" or "before"
|
end)
|
||||||
|
|
||||||
|
if destroyed == 0 then
|
||||||
|
local delay = #G.GAME.tags >= self.tag_threshold and 0 or 1 / #G.GAME.tags
|
||||||
|
local trigger = #G.GAME.tags >= self.tag_threshold and "immediate" or "before"
|
||||||
|
|
||||||
f(G.GAME.tags):each(function(v)
|
f(G.GAME.tags):each(function(v)
|
||||||
q {
|
q {
|
||||||
|
|
@ -199,29 +210,33 @@ joker {
|
||||||
func = fast_delete(v),
|
func = fast_delete(v),
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyed = destroyed + 1
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
f(consumables):each(function(v)
|
|
||||||
v:start_dissolve({HEX "57ecabff"}, nil, 1.6)
|
|
||||||
destroyed = destroyed + 1
|
destroyed = destroyed + 1
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.proc(card, destroyed)
|
self.proc(card, destroyed)
|
||||||
end,
|
end,
|
||||||
|
exchangable = function()
|
||||||
|
return next(G.GAME.tags) or f(G.consumeables.cards):any(destructible)
|
||||||
|
end,
|
||||||
|
---@param card Card
|
||||||
|
fusable = function(card)
|
||||||
|
return SMODS.Mods.Roland.config.fusable_escapey and
|
||||||
|
f((G.jokers or {}).cards):any(is_mergeable_with(card))
|
||||||
|
end,
|
||||||
---@param card Card
|
---@param card Card
|
||||||
---@param times? integer
|
---@param times? integer
|
||||||
proc = function(card, times)
|
proc = function(card, times)
|
||||||
local hands = f(G.GAME.hands):where "visible":keys():table()
|
local hands = f(G.GAME.hands):where "visible":keys():table()
|
||||||
pseudoshuffle(hands, pseudoseed "RolandEscapey")
|
|
||||||
local levels = card.ability.extra.hands * (times or 1)
|
local levels = card.ability.extra.hands * (times or 1)
|
||||||
level_up("all", math.floor(levels / #hands), card)
|
pseudoshuffle(hands, pseudoseed "RolandEscapey")
|
||||||
|
level_up(true, math.floor(levels / #hands), card)
|
||||||
|
|
||||||
f(hands):take(levels % #hands):each(function(v)
|
f(hands):take(levels % #hands):each(function(v)
|
||||||
level_up(v, 1, card)
|
level_up(v, 1, card)
|
||||||
end)
|
end)
|
||||||
end,
|
end,
|
||||||
|
tag_threshold = 30,
|
||||||
}
|
}
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
|
|
@ -233,6 +248,7 @@ joker {
|
||||||
blueprint_compat = true,
|
blueprint_compat = true,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
config = {extra = {chips = 30}},
|
config = {extra = {chips = 30}},
|
||||||
|
attributes = {"chips"},
|
||||||
loc_vars = function(_, _, card)
|
loc_vars = function(_, _, card)
|
||||||
return {vars = {card.ability.extra.chips}}
|
return {vars = {card.ability.extra.chips}}
|
||||||
end,
|
end,
|
||||||
|
|
@ -245,7 +261,9 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "mrsbones",
|
key = "mrsbones",
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
|
artist = "char",
|
||||||
config = {extra = {xmult = 4, requirement = 4}},
|
config = {extra = {xmult = 4, requirement = 4}},
|
||||||
|
attributes = {"xmult"},
|
||||||
cost = G.P_CENTERS.j_mr_bones.cost - 1,
|
cost = G.P_CENTERS.j_mr_bones.cost - 1,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = false,
|
eternal_compat = false,
|
||||||
|
|
@ -280,6 +298,7 @@ joker {
|
||||||
key = "phytoestrogens",
|
key = "phytoestrogens",
|
||||||
pronouns = "she_her",
|
pronouns = "she_her",
|
||||||
config = {extra = {xmult = 0.25}},
|
config = {extra = {xmult = 0.25}},
|
||||||
|
attributes = {"mult", "xmult"},
|
||||||
cost = 8,
|
cost = 8,
|
||||||
rarity = 3,
|
rarity = 3,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -303,6 +322,7 @@ joker {
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
artist = "char",
|
artist = "char",
|
||||||
config = {extra = {price = 4, hand_name = "Four of a Kind"}},
|
config = {extra = {price = 4, hand_name = "Four of a Kind"}},
|
||||||
|
attributes = {"sell_value", "scaling", "economy", "hand_type"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
rarity = 1,
|
rarity = 1,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -319,8 +339,9 @@ joker {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
card.ability.extra_value = card.ability.extra_value + extra.price
|
local c = context.blueprint_card or card
|
||||||
card:set_cost()
|
c.ability.extra_value = c.ability.extra_value + extra.price
|
||||||
|
c:set_cost()
|
||||||
return {message = localize "k_val_up", colour = G.C.MONEY}
|
return {message = localize "k_val_up", colour = G.C.MONEY}
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
@ -328,7 +349,9 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "domino",
|
key = "domino",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
|
artist = "char",
|
||||||
config = {extra = {mult_gain = 4, hand_name = "Four of a Kind", mult = 0}},
|
config = {extra = {mult_gain = 4, hand_name = "Four of a Kind", mult = 0}},
|
||||||
|
attributes = {"mult", "scaling", "hand_type"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -357,7 +380,9 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "trimino",
|
key = "trimino",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
|
artist = "char",
|
||||||
config = {extra = {times = 4, hand_name = "Four of a Kind"}},
|
config = {extra = {times = 4, hand_name = "Four of a Kind"}},
|
||||||
|
attributes = {"generation", "hand_type"},
|
||||||
cost = 8,
|
cost = 8,
|
||||||
rarity = 3,
|
rarity = 3,
|
||||||
eternal_compat = false,
|
eternal_compat = false,
|
||||||
|
|
@ -385,7 +410,7 @@ joker {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
for _ = 1, extra.times do
|
f(extra.times):each(function()
|
||||||
G.playing_card = (G.playing_card or 0) + 1
|
G.playing_card = (G.playing_card or 0) + 1
|
||||||
G.deck.config.card_limit = G.deck.config.card_limit + 1
|
G.deck.config.card_limit = G.deck.config.card_limit + 1
|
||||||
local chosen = pseudorandom_element(scored_cards, pseudoseed "Roland_trimino")
|
local chosen = pseudorandom_element(scored_cards, pseudoseed "Roland_trimino")
|
||||||
|
|
@ -395,7 +420,7 @@ joker {
|
||||||
copy:start_materialize()
|
copy:start_materialize()
|
||||||
table.insert(copied, copy)
|
table.insert(copied, copy)
|
||||||
table.insert(G.playing_cards, copy)
|
table.insert(G.playing_cards, copy)
|
||||||
end
|
end)
|
||||||
|
|
||||||
SMODS.calculate_effect({{message = localize "k_copied_ex", message_card = card}}, card)
|
SMODS.calculate_effect({{message = localize "k_copied_ex", message_card = card}}, card)
|
||||||
playing_card_joker_effects(copied)
|
playing_card_joker_effects(copied)
|
||||||
|
|
@ -408,8 +433,10 @@ joker {
|
||||||
}
|
}
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "sunny", -- Cracked egg
|
key = "sunny",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
|
artist = "char",
|
||||||
|
attributes = {"food", "on_sell"},
|
||||||
cost = 2,
|
cost = 2,
|
||||||
rarity = 1,
|
rarity = 1,
|
||||||
eternal_compat = false,
|
eternal_compat = false,
|
||||||
|
|
@ -455,23 +482,71 @@ 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 {
|
||||||
---@diagnostic disable-next-line: assign-type-mismatch
|
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,
|
hand_drawn = facing_blind and {G.deck.cards[1]} --[[@as true]],
|
||||||
---@diagnostic disable-next-line: assign-type-mismatch
|
|
||||||
hand_drawn = facing_blind and {G.deck.cards[1]},
|
|
||||||
other_drawn = not facing_blind and {G.deck.cards[1]},
|
other_drawn = not facing_blind and {G.deck.cards[1]},
|
||||||
}
|
}
|
||||||
|
|
||||||
if type(facing_blind) == "table" then
|
if type(facing_blind) == "table" then
|
||||||
---@diagnostic disable-next-line: inject-field
|
|
||||||
facing_blind.any_hand_drawn = facing_blind.any_hand_drawn or facing_blind
|
facing_blind.any_hand_drawn = facing_blind.any_hand_drawn or facing_blind
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joker {
|
||||||
|
key = "hardboiled",
|
||||||
|
pronouns = "they_them",
|
||||||
|
attributes = {"food", "editions", "modify_card", "on_sell"},
|
||||||
|
cost = 5,
|
||||||
|
rarity = 2,
|
||||||
|
eternal_compat = false,
|
||||||
|
blueprint_compat = true,
|
||||||
|
perishable_compat = true,
|
||||||
|
loc_vars = function(_, info_queue)
|
||||||
|
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||||
|
end,
|
||||||
|
calculate = function(_, _, context)
|
||||||
|
return (context.selling_self or context.forcetrigger) and f(G.hand.cards):each(function(v)
|
||||||
|
q {
|
||||||
|
delay = 0.1,
|
||||||
|
func = function()
|
||||||
|
v:set_edition {Roland_frozen = true}
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end) or nil
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
joker {
|
||||||
|
key = "basket",
|
||||||
|
pronouns = "they_them",
|
||||||
|
attributes = {"food", "generation", "on_sell"},
|
||||||
|
cost = 8,
|
||||||
|
rarity = 3,
|
||||||
|
eternal_compat = false,
|
||||||
|
blueprint_compat = true,
|
||||||
|
perishable_compat = true,
|
||||||
|
loc_vars = function(_, info_queue)
|
||||||
|
table.insert(info_queue, negative)
|
||||||
|
end,
|
||||||
|
calculate = function(_, _, context)
|
||||||
|
return (context.selling_self or context.forcetrigger) and f(G.consumeables.cards):each(function(v)
|
||||||
|
q {
|
||||||
|
delay = 1,
|
||||||
|
func = function()
|
||||||
|
play_sound "timpani"
|
||||||
|
SMODS.add_card {edition = "e_negative", key = v.config.center.key}
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end) or nil
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "sapling",
|
key = "sapling",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
|
artist = "char",
|
||||||
|
attributes = {"mult", "suit"},
|
||||||
cost = 4,
|
cost = 4,
|
||||||
rarity = 1,
|
rarity = 1,
|
||||||
config = {extra = {mult = 15, suits = 3}},
|
config = {extra = {mult = 15, suits = 3}},
|
||||||
|
|
@ -505,8 +580,9 @@ joker {
|
||||||
key = "yard",
|
key = "yard",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
config = {extra = {money = 2}},
|
config = {extra = {money = 2}},
|
||||||
cost = 6,
|
attributes = {"economy"},
|
||||||
rarity = 2,
|
cost = 4,
|
||||||
|
rarity = 1,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
blueprint_compat = true,
|
blueprint_compat = true,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
|
|
@ -519,9 +595,63 @@ joker {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joker {
|
||||||
|
key = "suitable",
|
||||||
|
pronouns = "she_they",
|
||||||
|
attributes = {"suit", "passive", "hearts", "diamonds", "spades", "clubs"},
|
||||||
|
cost = 4,
|
||||||
|
rarity = 2,
|
||||||
|
eternal_compat = true,
|
||||||
|
blueprint_compat = false,
|
||||||
|
perishable_compat = true,
|
||||||
|
loc_vars = function(_, info_queue)
|
||||||
|
table.insert(info_queue, G.P_CENTERS.m_wild)
|
||||||
|
local suit = (G.GAME.current_round.Roland_suitable or {}).suit or "Spades"
|
||||||
|
return {vars = {localize(suit, "suits_plural"), colours = {G.C.SUITS[suit]}}}
|
||||||
|
end,
|
||||||
|
add_to_deck = function()
|
||||||
|
G.GAME.modifiers.Roland_suitable = (G.GAME.modifiers.Roland_suitable or 0) + 1
|
||||||
|
end,
|
||||||
|
remove_from_deck = function()
|
||||||
|
G.GAME.modifiers.Roland_suitable = (G.GAME.modifiers.Roland_suitable or 0) - 1
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
function SMODS.current_mod.reset_game_globals()
|
||||||
|
local immutable = f(SMODS.find_card "j_Roland_suitable"):any(is_frozen)
|
||||||
|
local suitable = {suit = "Spades"}
|
||||||
|
|
||||||
|
G.GAME.current_round.Roland_suitable = immutable and
|
||||||
|
G.GAME.current_round.Roland_suitable or suitable
|
||||||
|
|
||||||
|
if immutable then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local suits = f(G.playing_cards):where(SMODS.has_no_suit, false):table()
|
||||||
|
local card = pseudorandom_element(suits, "Roland_suitable" .. G.GAME.round_resets.ante)
|
||||||
|
suitable.suit = card and card.base.suit or suitable.suit
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_get_enhancements = SMODS.get_enhancements
|
||||||
|
|
||||||
|
function SMODS.get_enhancements(card, ...)
|
||||||
|
if (G.GAME.modifiers.Roland_suitable or 0) <= 0 or
|
||||||
|
card.base.suit ~= G.GAME.current_round.Roland_suitable.suit or
|
||||||
|
(card.area ~= G.hand and card.area ~= G.play) then
|
||||||
|
return orig_get_enhancements(card, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ret = orig_get_enhancements(card, ...) or {}
|
||||||
|
ret.m_wild = true
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "misfortune",
|
key = "misfortune",
|
||||||
pronouns = "she_they",
|
pronouns = "she_they",
|
||||||
|
artist = "char",
|
||||||
|
attributes = {"discard", "generation", "seals"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -541,7 +671,8 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "temple",
|
key = "temple",
|
||||||
pronouns = "any_all",
|
pronouns = "any_all",
|
||||||
config = {extra = {xmult = 1.5}},
|
config = {extra = {xmult = 2}},
|
||||||
|
attributes = {"xmult", "enhancements"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -565,9 +696,10 @@ joker {
|
||||||
}
|
}
|
||||||
|
|
||||||
joker {
|
joker {
|
||||||
key = "srjoker",
|
key = "jokersr",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
config = {extra = {xmult = 1.25}},
|
config = {extra = {xmult = 1.25}},
|
||||||
|
attributes = {"xmult"},
|
||||||
cost = 2,
|
cost = 2,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -585,16 +717,27 @@ joker {
|
||||||
joker {
|
joker {
|
||||||
key = "bulldozer",
|
key = "bulldozer",
|
||||||
pronouns = "it_its",
|
pronouns = "it_its",
|
||||||
|
attributes = {"xmult"},
|
||||||
cost = 6,
|
cost = 6,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
blueprint_compat = true,
|
blueprint_compat = true,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
loc_vars = function(self, _, _)
|
loc_vars = function(self, _, card)
|
||||||
return {vars = {self.xmult()}}
|
return {vars = {self:xmult_frozen(card)}}
|
||||||
end,
|
end,
|
||||||
calculate = function(self, card, context)
|
calculate = function(self, card, context)
|
||||||
return (context.joker_main or context.forcetrigger) and {card = card, xmult = self.xmult()} or nil
|
return (context.joker_main or context.forcetrigger) and {card = card, xmult = self:xmult_frozen(card)} or nil
|
||||||
|
end,
|
||||||
|
xmult_frozen = function(self, card)
|
||||||
|
if not is_frozen(card) then
|
||||||
|
return self.xmult()
|
||||||
|
end
|
||||||
|
|
||||||
|
local ability = card.Roland_frozen_ability or {}
|
||||||
|
card.Roland_frozen_ability = ability
|
||||||
|
ability.Roland_frozen_xmult = ability.Roland_frozen_xmult or self.xmult()
|
||||||
|
return ability.Roland_frozen_xmult
|
||||||
end,
|
end,
|
||||||
xmult = function()
|
xmult = function()
|
||||||
local function mult(id)
|
local function mult(id)
|
||||||
|
|
@ -613,6 +756,7 @@ joker {
|
||||||
key = "martingale",
|
key = "martingale",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
config = {extra = {odds = 2}},
|
config = {extra = {odds = 2}},
|
||||||
|
attributes = {"xmult", "chance"},
|
||||||
cost = 8,
|
cost = 8,
|
||||||
rarity = 2,
|
rarity = 2,
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
|
|
@ -661,6 +805,7 @@ joker {
|
||||||
cost = 7,
|
cost = 7,
|
||||||
rarity = 3,
|
rarity = 3,
|
||||||
config = {extra = {probability = 1, probability_mult = 2, reset = 1}},
|
config = {extra = {probability = 1, probability_mult = 2, reset = 1}},
|
||||||
|
attributes = {"hands", "mod_chance", "scaling"},
|
||||||
eternal_compat = true,
|
eternal_compat = true,
|
||||||
blueprint_compat = false,
|
blueprint_compat = false,
|
||||||
perishable_compat = true,
|
perishable_compat = true,
|
||||||
|
|
@ -690,3 +835,75 @@ joker {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joker {
|
||||||
|
key = "nilly",
|
||||||
|
pronouns = "any_all",
|
||||||
|
config = {extra = {flipped = false}},
|
||||||
|
attributes = {"xmult"},
|
||||||
|
cost = 0,
|
||||||
|
rarity = 3,
|
||||||
|
eternal_compat = true,
|
||||||
|
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",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
inject = function(...)
|
||||||
|
SMODS.Joker.inject(...)
|
||||||
|
Bakery_API.double_sided_jokers.j_Roland_nilly = true
|
||||||
|
end,
|
||||||
|
calculate = function(_, card, context)
|
||||||
|
if (not context.joker_main or not card.ability.extra.flipped) and not context.forcetrigger then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
mult = mod_mult(0)
|
||||||
|
update_hand_text({delay = 0}, {chips = hand_chips, mult = mult})
|
||||||
|
return {sound = "Roland_nilly", message = "0X " .. localize "k_mult", colour = G.C.MULT, card = card}
|
||||||
|
end,
|
||||||
|
Bakery_can_use = function(_, card)
|
||||||
|
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",
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
Bakery_use_joker = function(_, card)
|
||||||
|
local _ = card.debuff or Bakery_API.flip_double_sided(card)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
joker {
|
||||||
|
key = "arctic",
|
||||||
|
pronouns = "it_its",
|
||||||
|
cost = 10,
|
||||||
|
rarity = 3,
|
||||||
|
config = {extra = {repetitions = 1}},
|
||||||
|
attributes = {"retrigger", "editions"},
|
||||||
|
eternal_compat = true,
|
||||||
|
blueprint_compat = true,
|
||||||
|
perishable_compat = true,
|
||||||
|
loc_vars = function(_, info_queue)
|
||||||
|
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||||
|
end,
|
||||||
|
calculate = function(_, card, context)
|
||||||
|
return (context.repetition and is_frozen(context.other_card)) and {repetitions = 1} or SMODS.merge_effects(
|
||||||
|
f(G.jokers.cards):where(is_frozen):map(function(v)
|
||||||
|
return SMODS.blueprint_effect(card, v, context) or true
|
||||||
|
end):where(function(v)
|
||||||
|
return type(v) == "table"
|
||||||
|
end):map(function(v)
|
||||||
|
v.colour = G.C.BLACK
|
||||||
|
return v
|
||||||
|
end):table()
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,14 @@ function f.tru()
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the arguments.
|
||||||
|
---@generic T
|
||||||
|
---@param ... T
|
||||||
|
---@return T
|
||||||
|
function f.id(...)
|
||||||
|
return ...
|
||||||
|
end
|
||||||
|
|
||||||
---@generic T
|
---@generic T
|
||||||
---@param v T
|
---@param v T
|
||||||
---@return fun(): T
|
---@return fun(): T
|
||||||
|
|
@ -95,41 +103,41 @@ end
|
||||||
|
|
||||||
--- Creates an enumeration.
|
--- Creates an enumeration.
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param tbl table<K, V>
|
---@param iter table<K, V>
|
||||||
---@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?)
|
||||||
---@param step? nil
|
---@param step? nil
|
||||||
---@return F | { [K]: V }
|
---@return F | { [K]: V }
|
||||||
---@overload fun(tbl: number, fpairs?: number, step?: number): F | { [number]: number }
|
---@overload fun(iter: number, fpairs?: number, step?: number): F | { [number]: number }
|
||||||
---@overload fun(tbl: string): (fun(table: { [string]: V }): V)
|
---@overload fun(iter: string): (fun(table: { [string]: V }): V)
|
||||||
---@overload fun(tbl: false): fun(): false
|
---@overload fun(iter: fun(): K, V): F | { [K]: V }
|
||||||
---@overload fun(tbl: true): fun(): true
|
---@overload fun(iter: false): fun(): false
|
||||||
---@overload fun(tbl: nil): F
|
---@overload fun(iter: true): fun(): true
|
||||||
function f.from(tbl, fpairs, step)
|
---@overload fun(iter: nil): F
|
||||||
if tbl == true then
|
function f.from(iter, fpairs, step)
|
||||||
|
if iter == true then
|
||||||
return f.tru
|
return f.tru
|
||||||
elseif tbl == false then
|
elseif iter == false then
|
||||||
return f.fals
|
return f.fals
|
||||||
elseif tbl == nil then
|
elseif iter == nil then
|
||||||
return none
|
return none
|
||||||
end
|
end
|
||||||
|
|
||||||
local tbl_type = type(tbl)
|
local t = type(iter)
|
||||||
|
|
||||||
if tbl_type == "string" then
|
if t == "string" then
|
||||||
return f.index(tbl)
|
return f.index(iter)
|
||||||
elseif tbl_type == "number" then
|
elseif t == "number" then
|
||||||
local ik = 0
|
local ik, is, start = 0, step or 1, fpairs and iter or 1
|
||||||
local start = fpairs and tbl or 1
|
|
||||||
|
|
||||||
local stop = not fpairs and tbl or
|
local stop = not fpairs and iter or
|
||||||
(type(fpairs) == "number") and fpairs or error("Invalid argument type for 'fpairs': " .. type(fpairs))
|
(type(fpairs) == "number") and fpairs or error("Invalid argument type for 'fpairs': " .. type(fpairs))
|
||||||
|
|
||||||
if step and step ~= 0 and ((step < 0) == (start < stop)) then
|
if start ~= stop and (is == 0 or ((is < 0) == (start < stop))) then
|
||||||
return none
|
return none
|
||||||
end
|
end
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
local iv = tbl + ik * (step or 1)
|
local iv = start + ik * is
|
||||||
ik = ik + 1
|
ik = ik + 1
|
||||||
|
|
||||||
if start > stop and iv >= stop or
|
if start > stop and iv >= stop or
|
||||||
|
|
@ -138,17 +146,25 @@ function f.from(tbl, fpairs, step)
|
||||||
return ik, iv
|
return ik, iv
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
elseif tbl_type ~= "table" then
|
elseif t == "function" then
|
||||||
error("Invalid argument type for 'tbl': " .. type(tbl))
|
return f.new(iter)
|
||||||
end
|
elseif t == "thread" then
|
||||||
|
return f.new(function()
|
||||||
|
local s, k, v = coroutine.resume(iter)
|
||||||
|
|
||||||
local next, context, k, v = autopairs(tbl, fpairs)
|
if s then
|
||||||
|
return k, v
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
local next, context, k, v = autopairs(iter, fpairs)
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
k, v = next(context, k)
|
k, v = next(context, k)
|
||||||
return k, v
|
return k, v
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
|
|
@ -158,32 +174,33 @@ end
|
||||||
function f:concat(...)
|
function f:concat(...)
|
||||||
local fsi = 0
|
local fsi = 0
|
||||||
local fs = {...}
|
local fs = {...}
|
||||||
|
local sum, last = 0, 0
|
||||||
|
|
||||||
for i = 1, #fs do
|
for i = 1, #fs do
|
||||||
if not is_f(fs[i]) then ---@diagnostic disable-next-line: assign-type-mismatch
|
fs[i] = is_f(fs[i]) and fs[i] or f.from(fs[i])
|
||||||
fs[i] = f.from(fs[i])
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
if fsi == 0 then
|
if fsi == 0 then
|
||||||
local k, v = self:next()
|
local k, v = self:next()
|
||||||
|
last = type(k) == "number" and math.max(k, last) or last
|
||||||
|
|
||||||
if k ~= nil then
|
if k ~= nil then
|
||||||
return k, v
|
return k, v
|
||||||
end
|
end
|
||||||
|
|
||||||
fsi = 1
|
fsi, sum, last = 1, last, 0
|
||||||
end
|
end
|
||||||
|
|
||||||
while fsi <= #fs do
|
while fsi <= #fs do
|
||||||
local k, v = fs[fsi]:next()
|
local k, v = fs[fsi]:next()
|
||||||
|
last = type(k) == "number" and math.max(k, last) or last
|
||||||
|
|
||||||
if k ~= nil then
|
if k ~= nil then
|
||||||
return k, v
|
return type(k) == "number" and k + sum or k, v
|
||||||
end
|
end
|
||||||
|
|
||||||
fsi = fsi + 1
|
fsi, sum, last = fsi + 1, sum + last, 0
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
@ -212,7 +229,7 @@ end
|
||||||
---@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
|
---@nodiscard
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): 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)
|
function f:flatmap(func, fpairs)
|
||||||
-- local i = 0
|
-- local i = 0
|
||||||
local vt, vk, vv, vp
|
local vt, vk, vv, vp
|
||||||
|
|
@ -259,10 +276,11 @@ 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 F|fun(v: V, k: K): boolean
|
||||||
|
---@param is? any
|
||||||
---@return F|{ [K]: V }
|
---@return F|{ [K]: V }
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): F|{ [K]: V }
|
---@overload fun(self: F|{ [K]: V }, func: string, is?: any): F|{ [K]: V }
|
||||||
function f:where(func)
|
function f:where(func, is)
|
||||||
func = type(func) == "string" and f.index(func) or func
|
func = type(func) == "string" and f.index(func) or func
|
||||||
|
|
||||||
return f.new(function()
|
return f.new(function()
|
||||||
|
|
@ -275,9 +293,17 @@ function f:where(func)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if is == nil then
|
||||||
if func(v, k) then
|
if func(v, k) then
|
||||||
return k, v
|
return k, v
|
||||||
end
|
end
|
||||||
|
elseif is == false then
|
||||||
|
if not func(v, k) then
|
||||||
|
return k, v
|
||||||
|
end
|
||||||
|
elseif is == func(v, k) then
|
||||||
|
return k, v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
@ -316,6 +342,20 @@ function f:values()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@generic K, V
|
||||||
|
---@param self F|{ [K]: V }
|
||||||
|
---@return F|{ [V]: K }
|
||||||
|
---@nodiscard
|
||||||
|
function f:swap()
|
||||||
|
return f.new(function()
|
||||||
|
local k, v = self:next()
|
||||||
|
|
||||||
|
if k ~= nil then
|
||||||
|
return v, k
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
---@generic K, V
|
---@generic K, V
|
||||||
---@param self F|{ [K]: V }
|
---@param self F|{ [K]: V }
|
||||||
---@param skip? integer
|
---@param skip? integer
|
||||||
|
|
@ -401,7 +441,7 @@ end
|
||||||
---@param func F|fun(v: V, k: K): boolean
|
---@param func F|fun(v: V, k: K): boolean
|
||||||
---@return boolean|V
|
---@return boolean|V
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): boolean
|
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||||
function f:any(func)
|
function f:any(func)
|
||||||
func = type(func) == "string" and f.index(func) or func
|
func = type(func) == "string" and f.index(func) or func
|
||||||
|
|
||||||
|
|
@ -419,7 +459,7 @@ end
|
||||||
---@param func F|fun(v: V, k: K): boolean
|
---@param func F|fun(v: V, k: K): boolean
|
||||||
---@return boolean|V
|
---@return boolean|V
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@overload fun(self: F|{ [K]: V }, func: string): boolean
|
---@overload fun(self: F|{ [K]: V }, func: string?): boolean|V
|
||||||
function f:all(func)
|
function f:all(func)
|
||||||
func = type(func) == "string" and f.index(func) or func
|
func = type(func) == "string" and f.index(func) or func
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,12 @@ local function protect_ev(fun)
|
||||||
return fun
|
return fun
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This exists to remove the @deprecated warning.
|
---@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"
|
||||||
if false then
|
if false then
|
||||||
|
-- This allows for better type inference.
|
||||||
|
SMODS.Mods.Roland.config = require "config"
|
||||||
|
|
||||||
|
-- This exists to remove the @deprecated warning.
|
||||||
---Returns the elements from the given `list`. This function is equivalent to
|
---Returns the elements from the given `list`. This function is equivalent to
|
||||||
---```lua
|
---```lua
|
||||||
--- return list[i], list[i+1], ···, list[j]
|
--- return list[i], list[i+1], ···, list[j]
|
||||||
|
|
|
||||||
57
src/main.lua
|
|
@ -1,18 +1,19 @@
|
||||||
local qol = assert(SMODS.load_file "src/lib/shared.lua")() or require "lib.shared"
|
local qol = assert(SMODS.load_file "src/lib/shared.lua")() or require "lib.shared"
|
||||||
|
local f, q = unpack(qol)
|
||||||
|
|
||||||
qol[1] {"challenge", "spectral", "tweaks", "blind", "charm", "joker", "back", "seal"}:each(function(v)
|
f {"challenge", "spectral", "edition", "tweaks", "blind", "charm", "joker", "back", "seal", "tag"}:each(function(v)
|
||||||
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
assert(SMODS.load_file("src/" .. v .. ".lua"))(qol)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if Balatest then
|
if _G["Balatest"] then
|
||||||
qol[1] {"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)
|
||||||
end
|
end
|
||||||
|
|
||||||
qol[2](function()
|
q(function()
|
||||||
---@type table<string, {name: string, fg: table, bg: table}>
|
---@type table<string, {name: string, fg: table, bg: table}>
|
||||||
local contributors = Bakery_API.contributors
|
local contributors, mods = Bakery_API.contributors, SMODS.Mods
|
||||||
|
|
||||||
contributors.Roland_aster = {
|
contributors.Roland_aster = {
|
||||||
name = "asterSSH",
|
name = "asterSSH",
|
||||||
|
|
@ -25,8 +26,21 @@ qol[2](function()
|
||||||
fg = HEX "f8f8f2ff",
|
fg = HEX "f8f8f2ff",
|
||||||
bg = HEX "ff79c6ff",
|
bg = HEX "ff79c6ff",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mods.DebugPlus and mods.Roland.config.import_funky then
|
||||||
|
_G.f, _G.q, _G.u = unpack(qol)
|
||||||
|
end
|
||||||
end, true)
|
end, true)
|
||||||
|
|
||||||
|
local function toggle(id)
|
||||||
|
return create_toggle {
|
||||||
|
label = localize {type = "variable", key = "b_Roland_" .. id},
|
||||||
|
ref_table = SMODS.Mods.Roland.config,
|
||||||
|
ref_value = id,
|
||||||
|
scale = 1.5,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
SMODS.Atlas {
|
SMODS.Atlas {
|
||||||
px = 256,
|
px = 256,
|
||||||
py = 256,
|
py = 256,
|
||||||
|
|
@ -34,30 +48,22 @@ SMODS.Atlas {
|
||||||
path = "icon.png",
|
path = "icon.png",
|
||||||
}
|
}
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function SMODS.current_mod.config_tab()
|
function SMODS.current_mod.config_tab()
|
||||||
return {
|
return {
|
||||||
n = G.UIT.ROOT,
|
n = G.UIT.ROOT,
|
||||||
config = {r = 0.1, minw = 4, minh = 4, align = "tr", padding = 0.2, colour = G.C.BLACK},
|
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.BLACK},
|
||||||
nodes = {{
|
nodes = {{
|
||||||
n = G.UIT.C,
|
n = G.UIT.C,
|
||||||
config = {minw = 1, minh = 1, align = "tr", padding = 0.2, colour = G.C.CLEAR},
|
config = {minw = 1, minh = 1, align = "tl", padding = 0.1, colour = G.C.CLEAR},
|
||||||
nodes = {
|
nodes = {
|
||||||
create_toggle {
|
toggle "illusion_seal",
|
||||||
label = localize {type = "variable", key = "b_Roland_equinox_assist"},
|
toggle "no_wild_debuff",
|
||||||
ref_table = SMODS.Mods.Roland.config,
|
toggle "no_highlight_limit",
|
||||||
ref_value = "equinox_assist",
|
_G["Talisman"] and toggle "harsh_ante_scaling",
|
||||||
scale = 2,
|
toggle "fusable_escapey",
|
||||||
},
|
G.P_CENTERS.c_Bakery_Scribe and toggle "scribable_basket",
|
||||||
SMODS.Mods.DebugPlus and UIBox_button {
|
toggle "equinox_assist",
|
||||||
label = {localize {type = "variable", key = "b_Roland_debug_export"}},
|
SMODS.Mods.DebugPlus and toggle "import_funky",
|
||||||
func = G.P_CENTERS.j_Roland_escapey.debug_export,
|
|
||||||
button = "Roland_debug_export",
|
|
||||||
colour = G.C.MULT,
|
|
||||||
col = true,
|
|
||||||
scale = 5,
|
|
||||||
minw = 5,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +72,3 @@ end
|
||||||
function SMODS.current_mod.optional_features()
|
function SMODS.current_mod.optional_features()
|
||||||
return {cardareas = {deck = true, unscored = true}}
|
return {cardareas = {deck = true, unscored = true}}
|
||||||
end
|
end
|
||||||
|
|
||||||
function G.FUNCS.Roland_debug_export(_, tbl)
|
|
||||||
local to = tbl or _G
|
|
||||||
to.f, to.q, to.u = unpack(qol)
|
|
||||||
end
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ SMODS.Seal {
|
||||||
key = "glass",
|
key = "glass",
|
||||||
atlas = "seal",
|
atlas = "seal",
|
||||||
pos = {x = 0, y = 0},
|
pos = {x = 0, y = 0},
|
||||||
|
attributes = {"destroy_card", "tag"},
|
||||||
badge_colour = HEX "a6a6a6ff",
|
badge_colour = HEX "a6a6a6ff",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
calculate = function(_, card, context)
|
calculate = function(_, card, context)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
local f, q, u = unpack(... or require "lib.shared")
|
local f, q, u = unpack(... or require "lib.shared")
|
||||||
|
|
||||||
local negative = {key = "e_negative_consumable", set = "Edition", config = {extra = 1}}
|
|
||||||
|
|
||||||
local spectral = (function()
|
local spectral = (function()
|
||||||
local x = 0
|
local x = 0
|
||||||
|
|
||||||
|
|
@ -40,9 +38,10 @@ spectral {
|
||||||
key = "afterimage",
|
key = "afterimage",
|
||||||
pronouns = "he_they",
|
pronouns = "he_they",
|
||||||
artist = "aster",
|
artist = "aster",
|
||||||
|
attributes = {"editions", "modify_card", "hand_size", "spectral"},
|
||||||
config = {extra = {amount = 1, hand = -2}},
|
config = {extra = {amount = 1, hand = -2}},
|
||||||
loc_vars = function(_, info_queue, card)
|
loc_vars = function(_, info_queue, card)
|
||||||
table.insert(info_queue, negative)
|
table.insert(info_queue, {key = "e_negative_playing_card", set = "Edition", config = {extra = 1}})
|
||||||
return {vars = {card.ability.extra.amount, card.ability.extra.hand}}
|
return {vars = {card.ability.extra.amount, card.ability.extra.hand}}
|
||||||
end,
|
end,
|
||||||
can_use = function(_, card)
|
can_use = function(_, card)
|
||||||
|
|
@ -54,7 +53,6 @@ spectral {
|
||||||
delay = 0.1,
|
delay = 0.1,
|
||||||
func = function()
|
func = function()
|
||||||
v:set_edition {negative = true}
|
v:set_edition {negative = true}
|
||||||
v:juice_up(0.5, 0.5)
|
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
@ -69,10 +67,36 @@ spectral {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spectral {
|
||||||
|
key = "coolheaded",
|
||||||
|
config = {extra = {amount = 1}},
|
||||||
|
attributes = {"editions", "modify_card", "spectral"},
|
||||||
|
loc_vars = function(_, info_queue, card)
|
||||||
|
table.insert(info_queue, G.P_CENTERS.e_Roland_frozen)
|
||||||
|
return {vars = {card.ability.extra.amount}}
|
||||||
|
end,
|
||||||
|
can_use = function(_, card)
|
||||||
|
return u() and f(G.jokers.highlighted):concat(Bakery_API.get_highlighted()):count(function(v)
|
||||||
|
return not v.edition
|
||||||
|
end) == card.ability.extra.amount
|
||||||
|
end,
|
||||||
|
use = function()
|
||||||
|
f(G.jokers.highlighted):concat(Bakery_API.get_highlighted()):each(function(v)
|
||||||
|
q {
|
||||||
|
delay = 0.1,
|
||||||
|
func = function()
|
||||||
|
v:set_edition {Roland_frozen = true}
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
spectral {
|
spectral {
|
||||||
key = "dual",
|
key = "dual",
|
||||||
pronouns = "they_them",
|
pronouns = "they_them",
|
||||||
config = {extra = {amount = 2}},
|
config = {extra = {amount = 2}},
|
||||||
|
attributes = {"seal", "modify_card", "spectral"},
|
||||||
loc_vars = function(_, _, card)
|
loc_vars = function(_, _, card)
|
||||||
return {vars = {card.ability.extra.amount}}
|
return {vars = {card.ability.extra.amount}}
|
||||||
end,
|
end,
|
||||||
|
|
@ -80,13 +104,13 @@ spectral {
|
||||||
return u() and #G.hand.cards > 0
|
return u() and #G.hand.cards > 0
|
||||||
end,
|
end,
|
||||||
use = function(_, card, _)
|
use = function(_, card, _)
|
||||||
local cards = f(G.hand.cards, ipairs):table()
|
local cards = f(G.hand.cards):table()
|
||||||
pseudoshuffle(cards, pseudoseed "RolandDual")
|
pseudoshuffle(cards, pseudoseed "RolandDual")
|
||||||
|
|
||||||
f(cards):take(card.ability.extra.amount):each(function(v)
|
f(cards):take(card.ability.extra.amount):each(function(v)
|
||||||
local seal
|
local seal
|
||||||
|
|
||||||
for _ = 1, 31 do
|
for _ = 1, 64 do
|
||||||
seal = SMODS.poll_seal {guaranteed = true}
|
seal = SMODS.poll_seal {guaranteed = true}
|
||||||
|
|
||||||
if seal ~= "Roland_glass" then
|
if seal ~= "Roland_glass" then
|
||||||
|
|
@ -103,6 +127,7 @@ spectral {
|
||||||
key = "mirror",
|
key = "mirror",
|
||||||
pronouns = "he_him",
|
pronouns = "he_him",
|
||||||
config = {extra = {amount = 1}},
|
config = {extra = {amount = 1}},
|
||||||
|
attributes = {"seal", "modify_card", "spectral"},
|
||||||
loc_vars = function(_, info_queue, card)
|
loc_vars = function(_, info_queue, card)
|
||||||
table.insert(info_queue, G.P_SEALS.Roland_glass)
|
table.insert(info_queue, G.P_SEALS.Roland_glass)
|
||||||
return {vars = {card.ability.extra.amount}}
|
return {vars = {card.ability.extra.amount}}
|
||||||
|
|
@ -124,8 +149,9 @@ local void = spectral {
|
||||||
soul_rate = 0.003,
|
soul_rate = 0.003,
|
||||||
soul_set = "Spectral",
|
soul_set = "Spectral",
|
||||||
config = {extra = {amount = 2}},
|
config = {extra = {amount = 2}},
|
||||||
|
attributes = {"destroy_card", "generation", "spectral"},
|
||||||
loc_vars = function(_, info_queue, card)
|
loc_vars = function(_, info_queue, card)
|
||||||
table.insert(info_queue, negative)
|
table.insert(info_queue, {key = "e_negative_consumable", set = "Edition", config = {extra = 1}})
|
||||||
table.insert(info_queue, G.P_CENTERS.c_cryptid)
|
table.insert(info_queue, G.P_CENTERS.c_cryptid)
|
||||||
return {vars = {card.ability.extra.amount}}
|
return {vars = {card.ability.extra.amount}}
|
||||||
end,
|
end,
|
||||||
|
|
@ -156,12 +182,12 @@ local void = spectral {
|
||||||
f(cards):each(destroy)
|
f(cards):each(destroy)
|
||||||
f(G.jokers.cards):each(calculate_joker)
|
f(G.jokers.cards):each(calculate_joker)
|
||||||
|
|
||||||
for _ = 1, card.ability.extra.amount do
|
f(card.ability.extra.amount):each(function()
|
||||||
local cryptid = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_cryptid", "void")
|
local cryptid = create_card(nil, G.consumeables, nil, nil, nil, nil, "c_cryptid", "void")
|
||||||
cryptid:set_edition({negative = true}, true)
|
cryptid:set_edition({negative = true}, true)
|
||||||
cryptid:add_to_deck()
|
cryptid:add_to_deck()
|
||||||
G.consumeables:emplace(cryptid)
|
G.consumeables:emplace(cryptid)
|
||||||
end
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
play_sound("Roland_void", 1, 0.7)
|
play_sound("Roland_void", 1, 0.7)
|
||||||
|
|
|
||||||
34
src/tag.lua
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
SMODS.Atlas {
|
||||||
|
px = 34,
|
||||||
|
py = 34,
|
||||||
|
key = "tag",
|
||||||
|
path = "tag.png",
|
||||||
|
}
|
||||||
|
|
||||||
|
SMODS.Tag {
|
||||||
|
key = "invisible",
|
||||||
|
atlas = "tag",
|
||||||
|
min_ante = 2,
|
||||||
|
pos = {x = 0, y = 0},
|
||||||
|
apply = function(_, tag)
|
||||||
|
local modifiers = G.GAME.modifiers
|
||||||
|
|
||||||
|
if tag.triggered or
|
||||||
|
not next(G.jokers.cards) or
|
||||||
|
#G.jokers.cards + (modifiers.Roland_invisible or 0) >= G.jokers.config.card_limit then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
tag.triggered = true
|
||||||
|
modifiers.Roland_invisible = (modifiers.Roland_invisible or 0) + 1
|
||||||
|
|
||||||
|
tag:yep("!", G.C.GREY, function()
|
||||||
|
local copied = pseudorandom_element(G.jokers.cards, pseudoseed "Roland_invisible")
|
||||||
|
local copy = copy_card(copied)
|
||||||
|
G.jokers:emplace(copy)
|
||||||
|
copy:add_to_deck()
|
||||||
|
modifiers.Roland_invisible = (modifiers.Roland_invisible or 0) - 1
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,8 @@ local orig_set_debuff = Card.set_debuff
|
||||||
local orig_highlight = Card.highlight
|
local orig_highlight = Card.highlight
|
||||||
local orig_copy_card = copy_card
|
local orig_copy_card = copy_card
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function CardArea:can_highlight(...)
|
function CardArea:can_highlight(...)
|
||||||
if self ~= G.consumeables then
|
if self ~= G.consumeables or not SMODS.Mods.Roland.config.no_highlight_limit then
|
||||||
return orig_can_highlight(self, ...)
|
return orig_can_highlight(self, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -17,27 +16,24 @@ function CardArea:can_highlight(...)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Card:set_debuff(...)
|
function Card:set_debuff(...)
|
||||||
if self.config and self.config.center_key == "m_wild" 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, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Card:highlight(is_highlighted, ...)
|
function Card:highlight(is_highlighted, ...)
|
||||||
self.highlighted = is_highlighted
|
self.highlighted = is_highlighted
|
||||||
|
|
||||||
if not G.CONTROLLER.HID.controller then
|
if not G.CONTROLLER.HID.controller or not SMODS.Mods.Roland.config.no_highlight_limit then
|
||||||
return orig_highlight(self, is_highlighted, ...)
|
return orig_highlight(self, is_highlighted, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local orig_use_consumeable = Card.use_consumeable
|
local orig_use_consumeable = Card.use_consumeable
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Card:use_consumeable(area, copier, ...)
|
function Card:use_consumeable(area, copier, ...)
|
||||||
local seal_spectrals = {["Deja Vu"] = true, Medium = true, Talisman = true, Trance = true}
|
local seal_spectrals = {["Deja Vu"] = true, Medium = true, Talisman = true, Trance = true}
|
||||||
|
|
||||||
|
|
@ -70,14 +66,14 @@ function Card:use_consumeable(area, copier, ...)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
---@diagnostic disable-next-line: lowercase-global
|
|
||||||
function copy_card(other, new_card, ...)
|
function copy_card(other, new_card, ...)
|
||||||
local ret = orig_copy_card(other, new_card, ...)
|
local ret = orig_copy_card(other, new_card, ...)
|
||||||
|
|
||||||
if new_card and new_card.edition and new_card.edition.key == "e_negative" then
|
if new_card and new_card.edition and new_card.edition.key == "e_negative" then
|
||||||
--- Fixes an issue where using 'c_death' will make negative
|
--- Fixes an issue where using 'c_death' will make negative
|
||||||
--- cards do the inverse of what they're supposed to do.
|
--- cards do the inverse of what they're supposed to do.
|
||||||
new_card.ability.card_limit = math.max(new_card.ability.card_limit, 1)
|
local ability = new_card.ability
|
||||||
|
ability.card_limit = math.max(ability.card_limit, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
@ -86,20 +82,21 @@ end
|
||||||
q(function()
|
q(function()
|
||||||
local orig_can_highlight_area = Bakery_API.can_highlight_area
|
local orig_can_highlight_area = Bakery_API.can_highlight_area
|
||||||
|
|
||||||
---@diagnostic disable-next-line: duplicate-set-field
|
|
||||||
function Bakery_API.can_highlight_area(area, ...)
|
function Bakery_API.can_highlight_area(area, ...)
|
||||||
return area == G.consumeables or orig_can_highlight_area(area, ...)
|
return (area == G.consumeables and
|
||||||
|
SMODS.Mods.Roland.config.no_highlight_limit) or
|
||||||
|
orig_can_highlight_area(area, ...)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local orig_create_card_for_shop = create_card_for_shop
|
local orig_create_card_for_shop = create_card_for_shop
|
||||||
|
|
||||||
---@diagnostic disable-next-line: lowercase-global
|
|
||||||
function create_card_for_shop(...)
|
function create_card_for_shop(...)
|
||||||
---@type Card
|
---@type Card
|
||||||
local ret = orig_create_card_for_shop(...)
|
local ret = orig_create_card_for_shop(...)
|
||||||
|
|
||||||
if not G.GAME.used_vouchers.v_illusion or
|
if not SMODS.Mods.Roland.config.illusion_seal or
|
||||||
|
not G.GAME.used_vouchers.v_illusion or
|
||||||
not ({Default = true, Enhanced = true})[(((ret or {}).config or {}).center or {}).set] or
|
not ({Default = true, Enhanced = true})[(((ret or {}).config or {}).center or {}).set] or
|
||||||
pseudorandom(pseudoseed "Roland_illusion") <= 0.8 then
|
pseudorandom(pseudoseed "Roland_illusion") <= 0.8 then
|
||||||
return ret
|
return ret
|
||||||
|
|
@ -113,3 +110,50 @@ function create_card_for_shop(...)
|
||||||
ret:set_seal(seal, true, true)
|
ret:set_seal(seal, true, true)
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local orig_get_blind_amount = get_blind_amount
|
||||||
|
|
||||||
|
---@param ante number
|
||||||
|
---@return table|number
|
||||||
|
local function blind(ante)
|
||||||
|
return ante == 39 and 1e294 or (_G["to_number"] or f().id)(orig_get_blind_amount(ante))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function no_harsh_ante_scaling()
|
||||||
|
return not _G["Talisman"] or not SMODS.Mods.Roland.config.harsh_ante_scaling
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_blind_amount(ante, ...)
|
||||||
|
local loop = 39
|
||||||
|
|
||||||
|
if ante < loop or no_harsh_ante_scaling() then
|
||||||
|
return orig_get_blind_amount(ante, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
if (ante - 9) / 15 >= loop then
|
||||||
|
return 1 / 0
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @type { constants?: { TEN: table }, new: (fun(self: self, arr?: number[], sign?: number, noNormalize?: boolean): table), pow: (fun(x: number, y: number): number) }
|
||||||
|
local big, rem = _G["Big"], tonumber(blind((ante % loop) + 1))
|
||||||
|
|
||||||
|
return ante / 15 >= loop and big:new(f(blind(ante - (loop * 15))):map(f().const(10)):table()) or
|
||||||
|
(ante / 9 >= loop and big:new(f(ante / loop - 8):map(f().const(10)):concat {rem}:table()) or
|
||||||
|
(ante / 2 >= loop and big:new {rem, ante / loop} or
|
||||||
|
(big.constants and big.constants.TEN or big:new {10}):pow(rem)))
|
||||||
|
end
|
||||||
|
|
||||||
|
q(function()
|
||||||
|
if not G.P_CENTERS.c_Bakery_Scribe then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local orig_can_use = G.P_CENTERS.c_Bakery_Scribe.can_use
|
||||||
|
|
||||||
|
function G.P_CENTERS.c_Bakery_Scribe.can_use(...)
|
||||||
|
return orig_can_use(...) and
|
||||||
|
(SMODS.Mods.Roland.config.scribable_basket or f(G.jokers.highlighted):all(function(v)
|
||||||
|
return v.config.center.key ~= "j_Roland_basket"
|
||||||
|
end))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
|
||||||