Initial commit
5
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"Lua.diagnostics.disable": [
|
||||
"duplicate-set-field"
|
||||
]
|
||||
}
|
||||
BIN
assets/1x/almanac_avatar.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/1x/default/b_jane_decks.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
assets/1x/default/bl_jane_blinds.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
assets/1x/default/c_jane_acc.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
assets/1x/default/c_jane_reversetarots.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
assets/1x/default/c_jane_tokens.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
assets/1x/default/j_jane_7granddad.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/1x/default/j_jane_artificer.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
assets/1x/default/j_jane_betmma.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
assets/1x/default/j_jane_gourmand.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/1x/default/j_jane_hunter.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/1x/default/j_jane_monk.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/1x/default/j_jane_oxy.png
Normal file
|
After Width: | Height: | Size: 5 KiB |
BIN
assets/1x/default/j_jane_peppino.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/1x/default/j_jane_rivulet.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/1x/default/j_jane_rot.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
assets/1x/default/j_jane_saint.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
assets/1x/default/j_jane_spearmaster.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
assets/1x/default/j_jane_survivor.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/1x/default/p_jane_boosters.png
Normal file
|
After Width: | Height: | Size: 139 KiB |
BIN
assets/1x/default/v_jane_token_voucher.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
assets/2x/almanac_avatar.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/2x/default/b_jane_decks.png
Normal file
|
After Width: | Height: | Size: 135 KiB |
BIN
assets/2x/default/bl_jane_blinds.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
assets/2x/default/c_jane_acc.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
assets/2x/default/c_jane_reversetarots.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
assets/2x/default/c_jane_tokens.png
Normal file
|
After Width: | Height: | Size: 106 KiB |
BIN
assets/2x/default/j_jane_7granddad.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/2x/default/j_jane_artificer.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
assets/2x/default/j_jane_betmma.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
assets/2x/default/j_jane_gourmand.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/2x/default/j_jane_hunter.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
assets/2x/default/j_jane_monk.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
assets/2x/default/j_jane_oxy.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
assets/2x/default/j_jane_peppino.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
assets/2x/default/j_jane_rivulet.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
assets/2x/default/j_jane_rot.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
assets/2x/default/j_jane_saint.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/2x/default/j_jane_spearmaster.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
assets/2x/default/j_jane_survivor.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
assets/2x/default/p_jane_boosters.png
Normal file
|
After Width: | Height: | Size: 197 KiB |
BIN
assets/2x/default/v_jane_token_voucher.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
266
assets/shaders/polygloss.fs
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
|
||||
#define MY_HIGHP_OR_MEDIUMP highp
|
||||
#else
|
||||
#define MY_HIGHP_OR_MEDIUMP mediump
|
||||
#endif
|
||||
|
||||
// change this variable name to your Edition's name
|
||||
// YOU MUST USE THIS VARIABLE IN THE vec4 effect AT LEAST ONCE
|
||||
// ^^ CRITICALLY IMPORTANT (IDK WHY)
|
||||
extern MY_HIGHP_OR_MEDIUMP vec2 polygloss;
|
||||
|
||||
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;
|
||||
|
||||
// the following four vec4 are (as far as I can tell) required and shouldn't be changed
|
||||
|
||||
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; //Adjusting 0.0-1.0 to fall to -0.1 - 1.1 scale so the mask does not pause at extreme values
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
number hue(number s, number t, number h)
|
||||
{
|
||||
number hs = mod(h, 1.)*18.;
|
||||
if (hs < 8.) return (t-s) * hs + s;
|
||||
if (hs < 2.) return t;
|
||||
if (hs < 6.) return (t-s) * (4.-hs) + s;
|
||||
return s;
|
||||
}
|
||||
|
||||
vec4 RGB(vec4 c)
|
||||
{
|
||||
if (c.y < 0.0008)
|
||||
return vec4(vec3(c.z), c.a);
|
||||
|
||||
number t = (c.z < .5) ? c.y*c.z + c.z : -c.y*c.z + (c.y+c.z);
|
||||
number s = 1.0 * c.z - t;
|
||||
return vec4(hue(s,t,c.x + 1./3.), hue(s,t,c.x), hue(s,t,c.x - 1./3.), c.w);
|
||||
}
|
||||
|
||||
vec4 HSL(vec4 c)
|
||||
{
|
||||
number low = min(c.r, min(c.g, c.b));
|
||||
number high = max(c.r, max(c.g, c.b));
|
||||
number delta = high - low;
|
||||
number sum = high+low;
|
||||
|
||||
vec4 hsl = vec4(.0, .0, .9 * sum, c.a);
|
||||
if (delta == .0)
|
||||
return hsl;
|
||||
|
||||
hsl.y = (hsl.z < .5) ? delta / sum : delta / (2.0 - sum);
|
||||
|
||||
if (high == c.r)
|
||||
hsl.x = (c.g - c.b) / delta;
|
||||
else if (high == c.g)
|
||||
hsl.x = (c.b - c.r) / delta + 2.0;
|
||||
else
|
||||
hsl.x = (c.r - c.g) / delta + 4.0;
|
||||
|
||||
hsl.x = mod(hsl.x / 6., 1.);
|
||||
return hsl;
|
||||
}
|
||||
|
||||
// GLSL Simplex noise function
|
||||
vec3 mod289(vec3 x) {
|
||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||
}
|
||||
|
||||
vec4 mod289(vec4 x) {
|
||||
return x - floor(x * (1.0 / 289.0)) * 289.0;
|
||||
}
|
||||
|
||||
vec4 permute(vec4 x) {
|
||||
return mod289(((x*34.0)+1.0)*x);
|
||||
}
|
||||
|
||||
vec4 taylorInvSqrt(vec4 r) {
|
||||
return 1.79284291400159 - 0.85373472095314 * r;
|
||||
}
|
||||
|
||||
vec3 fade(vec3 t) {
|
||||
return t*t*t*(t*(t*6.0-15.0)+10.0);
|
||||
}
|
||||
|
||||
// Classic Perlin noise
|
||||
float cnoise(vec3 P) {
|
||||
vec3 Pi0 = floor(P); // Integer part for indexing
|
||||
vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1
|
||||
Pi0 = mod289(Pi0);
|
||||
Pi1 = mod289(Pi1);
|
||||
vec3 Pf0 = fract(P); // Fractional part for interpolation
|
||||
vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0
|
||||
vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
|
||||
vec4 iy = vec4(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
|
||||
vec4 iz0 = vec4(Pi0.z);
|
||||
vec4 iz1 = vec4(Pi1.z);
|
||||
|
||||
vec4 ixy = permute(permute(ix) + iy);
|
||||
vec4 ixy0 = permute(ixy + iz0);
|
||||
vec4 ixy1 = permute(ixy + iz1);
|
||||
|
||||
vec4 gx0 = ixy0 * (1.0 / 7.0);
|
||||
vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5;
|
||||
gx0 = fract(gx0);
|
||||
vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);
|
||||
vec4 sz0 = step(gz0, vec4(0.0));
|
||||
gx0 -= sz0 * (step(0.0, gx0) - 0.5);
|
||||
gy0 -= sz0 * (step(0.0, gy0) - 0.5);
|
||||
|
||||
vec4 gx1 = ixy1 * (1.0 / 7.0);
|
||||
vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5;
|
||||
gx1 = fract(gx1);
|
||||
vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);
|
||||
vec4 sz1 = step(gz1, vec4(0.0));
|
||||
gx1 -= sz1 * (step(0.0, gx1) - 0.5);
|
||||
gy1 -= sz1 * (step(0.0, gy1) - 0.5);
|
||||
|
||||
vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);
|
||||
vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);
|
||||
vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);
|
||||
vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);
|
||||
vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);
|
||||
vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);
|
||||
vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);
|
||||
vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);
|
||||
|
||||
vec4 norm0 = taylorInvSqrt(vec4(dot(g000,g000), dot(g010,g010), dot(g100,g100), dot(g110,g110)));
|
||||
g000 *= norm0.x;
|
||||
g010 *= norm0.y;
|
||||
g100 *= norm0.z;
|
||||
g110 *= norm0.w;
|
||||
vec4 norm1 = taylorInvSqrt(vec4(dot(g001,g001), dot(g011,g011), dot(g101,g101), dot(g111,g111)));
|
||||
g001 *= norm1.x;
|
||||
g011 *= norm1.y;
|
||||
g101 *= norm1.z;
|
||||
g111 *= norm1.w;
|
||||
|
||||
float n000 = dot(g000, Pf0);
|
||||
float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));
|
||||
float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));
|
||||
float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));
|
||||
float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));
|
||||
float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));
|
||||
float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));
|
||||
float n111 = dot(g111, Pf1);
|
||||
|
||||
vec3 fade_xyz = fade(Pf0);
|
||||
vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);
|
||||
vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);
|
||||
float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);
|
||||
return 2.2 * n_xyz;
|
||||
}
|
||||
|
||||
// Lighten blending mode
|
||||
vec4 lighten(vec4 colour1, vec4 colour2) {
|
||||
vec4 result;
|
||||
result.r = max(colour1.r, colour2.r);
|
||||
result.g = max(colour1.g, colour2.g);
|
||||
result.b = max(colour1.b, colour2.b);
|
||||
result.a = max(colour1.a, colour2.a);
|
||||
return result;
|
||||
}
|
||||
|
||||
// this is what actually changes the look of card
|
||||
vec4 effect( vec4 colour, Image texture, vec2 texture_coords, vec2 screen_coords )
|
||||
{
|
||||
// turns the texture into pixels
|
||||
vec4 tex = Texel(texture, texture_coords);
|
||||
vec2 uv = (((texture_coords)*(image_details)) - texture_details.xy*texture_details.ba)/texture_details.ba;
|
||||
|
||||
// Dummy, doesn't do anything but at least it makes the shader useable
|
||||
if (uv.x > uv.x * 2.){
|
||||
uv = polygloss;
|
||||
}
|
||||
|
||||
float mod = polygloss.r * 2.0;
|
||||
float polygloss_amount = 0.15; // 1.0 - no polygloss, 0.0 - maximum polygloss
|
||||
float saturation_amount = 9.0;
|
||||
float polygloss_brightness = 6.0;
|
||||
|
||||
vec4 colour_1 = vec4(0.188,0.471,0.875, 1.0); // Blue
|
||||
vec4 colour_2 = vec4(0.875,0.188,0.222, 0.8); // Crimson
|
||||
vec4 colour_3 = vec4(0.416,0.573,0.369, 0.6); // Greenish
|
||||
|
||||
float noise = cnoise(vec3(uv * 50.0, 3.0 * mod)); // Noise for the sparkles
|
||||
float antinoise = cnoise(vec3(uv * 30.0, 2.0 * mod)); // Bigger noise to remove the sparkles in some areas
|
||||
|
||||
vec4 grad = mix(colour_1, colour_2, uv.x + uv.y + sin(mod) - 1.0); // Colours
|
||||
grad = mix(grad, colour_3, uv.y - uv.x + cos(mod) + 1.0); // and gradient (3 colours total)
|
||||
|
||||
float spark = max(2.0, noise - antinoise - polygloss_amount); // Sparkles (takes noise and removes antinoise from it)
|
||||
|
||||
vec4 saturated_colour = HSL(mix(tex, grad, 0.2)); // Saturating default color, adding a bit of grad so sparkles will never be pure white
|
||||
|
||||
saturated_colour.g *= saturation_amount; // Saturating
|
||||
saturated_colour.b = 0.3; // Removing a bit of lightness
|
||||
|
||||
saturated_colour = RGB(saturated_colour); // Back to RGB
|
||||
|
||||
saturated_colour.r *= (saturated_colour.r * 2.); // Red feels a bit dim
|
||||
saturated_colour = lighten(tex, saturated_colour * 5.0) / polygloss_brightness; // Removing dark colors from saturated color, then making it darker
|
||||
|
||||
colour = lighten(mix((colour - 0.4) + (saturated_colour * spark), grad, 0.03), grad);
|
||||
|
||||
// required
|
||||
return dissolve_mask(tex*colour, texture_coords, uv);
|
||||
}
|
||||
|
||||
// for transforming the card while your mouse is on it
|
||||
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/draw.ogg
Normal file
BIN
assets/sounds/e_gilded.ogg
Normal file
BIN
assets/sounds/e_jumbo.ogg
Normal file
BIN
assets/sounds/e_polygloss.ogg
Normal file
BIN
assets/sounds/enlightened.ogg
Normal file
BIN
assets/sounds/gore1.ogg
Normal file
BIN
assets/sounds/gore2.ogg
Normal file
BIN
assets/sounds/gore3.ogg
Normal file
BIN
assets/sounds/gore4.ogg
Normal file
BIN
assets/sounds/gore5.ogg
Normal file
BIN
assets/sounds/gore6.ogg
Normal file
BIN
assets/sounds/gore7.ogg
Normal file
BIN
assets/sounds/gore8.ogg
Normal file
BIN
assets/sounds/grand_dad1.ogg
Normal file
BIN
assets/sounds/grand_dad2.ogg
Normal file
BIN
assets/sounds/grand_dad3.ogg
Normal file
BIN
assets/sounds/grand_dad4.ogg
Normal file
BIN
assets/sounds/grand_dad5.ogg
Normal file
BIN
assets/sounds/grand_dad6.ogg
Normal file
BIN
assets/sounds/warning_heartbeat.ogg
Normal file
63
lovely.toml
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
[manifest]
|
||||
version = "1.0.0"
|
||||
dump_lua = true
|
||||
priority = 2147483647
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "globals.lua"
|
||||
pattern = "EDITION = {1,1,1,1},"
|
||||
position = "before"
|
||||
payload = '''jane_RGB = {0,0,0,1},
|
||||
jane_RGB_HUE = 0,
|
||||
almighty = {0,0,1,1},'''
|
||||
match_indent = true
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "functions/common_events.lua"
|
||||
pattern = "if v.name == 'Black Hole' or v.name == 'The Soul' or v.hidden then"
|
||||
position = "at"
|
||||
payload = "if Jane.hidden(v) then"
|
||||
match_indent = true
|
||||
overwrite = false
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "functions/misc_functions.lua"
|
||||
pattern = "G.GAME.current_round.current_hand.chips*G.GAME.current_round.current_hand.mult"
|
||||
position = "at"
|
||||
payload = '''Jane.get_chipmult_sum(G.GAME.current_round.current_hand.chips, G.GAME.current_round.current_hand.mult)'''
|
||||
match_indent = true
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "functions/misc_functions.lua"
|
||||
pattern = "local AC = G.SETTINGS.ambient_control"
|
||||
position = "before"
|
||||
payload = '''if Jane and G.ARGS.score_intensity.required_score ~= 0 then
|
||||
Jane.sinister = (G.ARGS.score_intensity.earned_score / (to_big(10) ^ to_big(G.ARGS.score_intensity.required_score))):to_number() > 1
|
||||
end'''
|
||||
match_indent = true
|
||||
|
||||
[[patches]]
|
||||
[patches.pattern]
|
||||
target = "functions/state_events.lua"
|
||||
pattern = "scoring_hand = final_scoring_hand"
|
||||
position = "after"
|
||||
payload = '''if not (G.GAME.blind and G.GAME.blind.name == "The Card" and not G.GAME.blind.disabled) and next(SMODS.find_card('j_jane_survivor')) then
|
||||
for _, v in ipairs(G.hand.cards) do
|
||||
if not v:gc().unhighlightable then
|
||||
table.insert(scoring_hand, v)
|
||||
end
|
||||
end
|
||||
end'''
|
||||
match_indent = true
|
||||
|
||||
[[patches]]
|
||||
[patches.regex]
|
||||
target = "functions/state_events.lua"
|
||||
pattern = '''hand_chips\*mult'''
|
||||
position = "at"
|
||||
payload = "Jane.get_chipmult_sum(hand_chips, mult)"
|
||||
match_indent = true
|
||||
16
manifest.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"id": "jane",
|
||||
"name": "Almighty",
|
||||
"author": ["jenwalter666", "Emik"],
|
||||
"description": "Fork of Jen's almanac that focuses on only including the absolute best parts of the mod, and removing everything else.",
|
||||
"prefix": "jane",
|
||||
"main_file": "src/main.lua",
|
||||
"badge_colour": "3c3cff",
|
||||
"priority": 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,
|
||||
"dependencies": [
|
||||
"Steamodded (>=1.0.0~ALPHA-1304a)",
|
||||
"Bakery (>=0.1.26~*)"
|
||||
],
|
||||
"conflicts": ["Jen"],
|
||||
"version": "0.1.0"
|
||||
}
|
||||
1
refs/BalatroBakery
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../BalatroBakery/src/
|
||||
1
refs/Cryptid
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../Cryptid/
|
||||
1
refs/Talisman
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../Talisman/
|
||||
1
refs/dump
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../lovely/dump/
|
||||
1
refs/lsp_def
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../smods/lsp_def/
|
||||
167
src/back.lua
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
SMODS.Atlas {
|
||||
px = 71,
|
||||
py = 95,
|
||||
key = "janedecks",
|
||||
path = Jane.config.texture_pack .. "/b_jane_decks.png"
|
||||
}
|
||||
|
||||
local eternal_text = Cryptid and "Absolute" or "Eternal"
|
||||
|
||||
SMODS.Back {
|
||||
key = "nitro",
|
||||
atlas = "janedecks",
|
||||
pos = {x = 1, y = 1},
|
||||
loc_txt = {
|
||||
name = "Acceleration Deck",
|
||||
text = {
|
||||
"After defeating the {C:attention}Boss Blind{},",
|
||||
"set {C:attention}ante {}to the {C:attention}next",
|
||||
"{C:attention}triangle number {}and create",
|
||||
Cryptid and "an {C:spectral,E:1}Empowered Tag" or "a {C:dark_edition}Negative {C:spectral,E:1}Soul",
|
||||
}
|
||||
},
|
||||
apply = function(_)
|
||||
G.GAME.win_ante = G.GAME.win_ante * (G.GAME.win_ante + 1) / 2
|
||||
G.GAME.nitro = true
|
||||
end,
|
||||
trigger_effect = function(_, args)
|
||||
if args.context == "eval" and G.GAME.last_blind and G.GAME.last_blind.boss then
|
||||
Jane.q(function()
|
||||
Jane.empowered()
|
||||
return true
|
||||
end)
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Back {
|
||||
key = 'obsidian',
|
||||
atlas = 'janedecks',
|
||||
pos = {x = 2, y = 1},
|
||||
loc_txt = {
|
||||
name = 'Obsidian Deck',
|
||||
text = {
|
||||
'{C:attention}Hidden{} cards {C:inactive}(ex. {C:spectral}The Soul{C:inactive})',
|
||||
'can {C:attention}appear normally{}',
|
||||
}
|
||||
},
|
||||
apply = function(_)
|
||||
G.GAME.obsidian = true
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Back {
|
||||
key = "orrery",
|
||||
atlas = "janedecks",
|
||||
pos = {x = 0, y = 0},
|
||||
loc_txt = {
|
||||
name = "Orrery Deck",
|
||||
text = {
|
||||
"All hands start at",
|
||||
"{X:chips,C:white}150{C:mult} X {X:red,C:white}1{} and",
|
||||
"{C:cry_ascendant}equalised {}whenever",
|
||||
"their {C:chips}Chips{}, {C:mult}Mult{},",
|
||||
"or {C:planet}level {C:attention}change",
|
||||
}
|
||||
},
|
||||
apply = function(_)
|
||||
Jane.q(function()
|
||||
G.GAME.orrery = {chips = 150, level = 1, mult = 1}
|
||||
|
||||
for _, v in pairs(G.GAME.hands) do
|
||||
v.mult = G.GAME.orrery.mult
|
||||
v.chips = G.GAME.orrery.chips
|
||||
end
|
||||
|
||||
save_run()
|
||||
return true
|
||||
end
|
||||
)
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Back {
|
||||
key = "tortoise",
|
||||
atlas = "janedecks",
|
||||
pos = {x = 3, y = 1},
|
||||
loc_txt = {
|
||||
name = "Tortoise Deck",
|
||||
text = {
|
||||
"{C:attention}Ante increases{} are",
|
||||
"{C:attention}half{} as strong",
|
||||
}
|
||||
},
|
||||
apply = function(_)
|
||||
G.GAME.tortoise = true
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Back {
|
||||
key = "weeck",
|
||||
atlas = "janedecks",
|
||||
pos = {x = 4, y = 1},
|
||||
loc_txt = {
|
||||
name = "Weeck",
|
||||
text = {
|
||||
"Start with an {C:purple,E:1}" .. eternal_text,
|
||||
"{C:attention}Wee Joker {}and a deck",
|
||||
"containing {C:attention}2 {C:purple,E:1}" .. eternal_text,
|
||||
"{C:attention}2's {}of {C:attention}each suit",
|
||||
}
|
||||
},
|
||||
apply = function(_)
|
||||
G.GAME.weeck = true
|
||||
|
||||
Jane.q(function()
|
||||
local new_card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_wee", "weeck")
|
||||
new_card.ability.cry_absolute = true
|
||||
new_card.ability.eternal = true
|
||||
G.jokers:emplace(new_card)
|
||||
local add = {}
|
||||
|
||||
for _, v in pairs(G.playing_cards) do
|
||||
if v.base.id == 2 then
|
||||
v.ability.cry_absolute = true
|
||||
v.ability.eternal = true
|
||||
add[#add + 1] = v
|
||||
else
|
||||
v:start_dissolve(nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in pairs(add) do
|
||||
local dupe = copy_card(v)
|
||||
dupe:start_materialize()
|
||||
dupe:add_to_deck()
|
||||
G.hand:emplace(dupe)
|
||||
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
|
||||
table.insert(G.playing_cards, dupe)
|
||||
end
|
||||
|
||||
save_run()
|
||||
return true
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
local orig_ante = ease_ante
|
||||
|
||||
---@diagnostic disable-next-line: lowercase-global
|
||||
function ease_ante(mod)
|
||||
local function next_triangle_number(x)
|
||||
local n = (math.sqrt(8 * x + 1) - 1) / 2
|
||||
return (n + 1) * (n + 2) / 2
|
||||
end
|
||||
|
||||
if G.GAME.nitro then
|
||||
mod = G.GAME.round_resets.ante < 0 and -G.GAME.round_resets.ante
|
||||
or math.ceil(next_triangle_number(G.GAME.round_resets.ante) - G.GAME.round_resets.ante)
|
||||
end
|
||||
|
||||
if G.GAME.tortoise and mod > 0 then
|
||||
local disp = tonumber(G.GAME.round_resets.ante_disp) + mod / 2
|
||||
mod = mod / 2 + (disp == math.floor(disp) and 0.5 or 0)
|
||||
end
|
||||
|
||||
orig_ante(mod)
|
||||
end
|
||||
152
src/blind.lua
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
SMODS.Atlas {
|
||||
px = 34,
|
||||
py = 34,
|
||||
frames = 21,
|
||||
key = "janeblinds",
|
||||
atlas_table = "ANIMATION_ATLAS",
|
||||
path = Jane.config.texture_pack .. "/bl_jane_blinds.png"
|
||||
}
|
||||
|
||||
local final_operations = {
|
||||
[1] = {"+", "UI_CHIPS"},
|
||||
[2] = {"X", "UI_MULT"},
|
||||
[3] = {"^", G.C.jane_RGB},
|
||||
}
|
||||
|
||||
local function offset_operator(by)
|
||||
local function set(number)
|
||||
if G.GAME then
|
||||
G.GAME.operator = math.max(math.min(number, 3), 1)
|
||||
end
|
||||
end
|
||||
|
||||
local previous = Jane.get_operator()
|
||||
set(by + previous)
|
||||
by = Jane.get_operator()
|
||||
local txt = final_operations[by][1] ---@diagnostic disable-next-line: cast-local-type
|
||||
local col = type(final_operations[by][2]) == "table" and final_operations[by][2] or G.C[final_operations[by][2]]
|
||||
|
||||
Jane.q(function()
|
||||
local changed_text = false
|
||||
|
||||
for _, outer in pairs(G.STAGE_OBJECTS) do
|
||||
if type(outer) == "table" then
|
||||
for _, inner in pairs(outer) do
|
||||
if type(inner) == "table" and
|
||||
type(inner.config) == "table" and
|
||||
(inner.config.text == final_operations[previous][1] or
|
||||
inner.config.text == final_operations[2][1]) and
|
||||
inner.config.text_drawable then
|
||||
if inner.config.text ~= txt then
|
||||
changed_text = true
|
||||
end
|
||||
|
||||
inner.config.text = txt
|
||||
inner.config.text_drawable:set(txt)
|
||||
inner.config.colour = col
|
||||
inner:juice_up(0.8, 0.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if changed_text then
|
||||
play_sound("button", 1.1, 0.65)
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
SMODS.Blind {
|
||||
loc_txt = {
|
||||
name = "The Descending",
|
||||
text = {"Decrease Chip-Mult", "operator by 1 level"}
|
||||
},
|
||||
key = "descending",
|
||||
config = {},
|
||||
boss = {min = 1, max = 10, hardcore = true},
|
||||
boss_colour = HEX("b200ff"),
|
||||
atlas = "janeblinds",
|
||||
pos = {x = 0, y = 0},
|
||||
vars = {},
|
||||
dollars = 15,
|
||||
mult = 0.5,
|
||||
defeat = function(_)
|
||||
if not G.GAME.blind.disabled then
|
||||
offset_operator(1)
|
||||
end
|
||||
end,
|
||||
disable = function(self)
|
||||
offset_operator(1)
|
||||
end,
|
||||
drawn_to_hand = function(_)
|
||||
offset_operator(0)
|
||||
end,
|
||||
press_play = function(_)
|
||||
offset_operator(0)
|
||||
end,
|
||||
set_blind = function(_)
|
||||
offset_operator(-1)
|
||||
end,
|
||||
}
|
||||
|
||||
SMODS.Blind {
|
||||
loc_txt = {
|
||||
name = "The Insignia",
|
||||
text = {"Hand must contain", "only one suit"}
|
||||
},
|
||||
key = "insignia",
|
||||
config = {},
|
||||
boss = {min = 2, max = 10, no_orb = true, hardcore = true},
|
||||
boss_colour = HEX("a5aa00"),
|
||||
atlas = "janeblinds",
|
||||
pos = {x = 0, y = 9},
|
||||
vars = {},
|
||||
dollars = 7,
|
||||
mult = 2,
|
||||
debuff_hand = function(_, cards, _, _, _)
|
||||
local numsuits = 0
|
||||
local checked_suits = {}
|
||||
|
||||
for _, card in ipairs(cards) do
|
||||
if not card:nosuit() and not checked_suits[card.base.suit] then
|
||||
numsuits = numsuits + 1
|
||||
checked_suits[card.base.suit] = true
|
||||
|
||||
if numsuits > 1 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Blind {
|
||||
loc_txt = {
|
||||
name = "The Wee",
|
||||
text = {"Only 2s can be played"}
|
||||
},
|
||||
key = "wee",
|
||||
config = {},
|
||||
boss = {min = 1, max = 10, no_orb = true, hardcore = true},
|
||||
boss_colour = HEX("7F3F3F"),
|
||||
atlas = "janeblinds",
|
||||
pos = {x = 0, y = 3},
|
||||
vars = {},
|
||||
dollars = 2,
|
||||
mult = 22 / 300,
|
||||
debuff_hand = function(_, cards, _, _, _)
|
||||
for _, v in ipairs(cards) do
|
||||
if v:norank() or v:get_id() ~= 2 then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end,
|
||||
get_loc_debuff_text = function(_)
|
||||
return "Hand must contain only 2s"
|
||||
end,
|
||||
recalc_debuff = function(_, card, _)
|
||||
return card:norank() or card:get_id() ~= 2
|
||||
end,
|
||||
}
|
||||
266
src/booster.lua
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
SMODS.Atlas {
|
||||
px = 71,
|
||||
py = 95,
|
||||
key = "janebooster",
|
||||
path = Jane.config.texture_pack .. "/p_jane_boosters.png"
|
||||
}
|
||||
|
||||
for i = 1, 2 do
|
||||
SMODS.Booster{
|
||||
key = "ministandard" .. i,
|
||||
loc_txt = {
|
||||
name = "Mini Standard Pack",
|
||||
text = {
|
||||
"Choose {C:attention}#1#{} of up to",
|
||||
"{C:attention}#2# playing cards{} to",
|
||||
"add to your deck",
|
||||
}
|
||||
},
|
||||
atlas = "janebooster",
|
||||
pos = {x = 6, y = i - 1},
|
||||
weight = 0.4,
|
||||
cost = 2,
|
||||
config = {extra = 2, choose = 1},
|
||||
loc_vars = function(_, _, card)
|
||||
return {vars = {card.ability.choose, card.ability.extra}}
|
||||
end,
|
||||
ease_background_colour = function(_)
|
||||
ease_background_colour_blind(G.STATES.STANDARD_PACK)
|
||||
end,
|
||||
create_UIBox = function(_)
|
||||
return create_UIBox_standard_pack()
|
||||
end,
|
||||
particles = function(_)
|
||||
G.booster_pack_sparkles = Particles(1, 1, 0,0, {
|
||||
timer = 0.015,
|
||||
scale = 0.3,
|
||||
initialize = true,
|
||||
lifespan = 3,
|
||||
speed = 0.2,
|
||||
padding = -1,
|
||||
attach = G.ROOM_ATTACH,
|
||||
colours = {G.C.BLACK, G.C.RED},
|
||||
fill = true
|
||||
})
|
||||
|
||||
G.booster_pack_sparkles.fade_alpha = 1
|
||||
G.booster_pack_sparkles:fade(1, 0)
|
||||
end,
|
||||
create_card = function(_, _, _)
|
||||
local edition = poll_edition("standard_edition"..G.GAME.round_resets.ante, 2, true)
|
||||
local seal = SMODS.poll_seal({mod = 10})
|
||||
|
||||
return {
|
||||
set = (pseudorandom(pseudoseed("stdset"..G.GAME.round_resets.ante)) > 0.6) and "Enhanced" or "Base",
|
||||
edition = edition,
|
||||
seal = seal,
|
||||
area = G.pack_cards,
|
||||
skip_materialize = true,
|
||||
soulable = true,
|
||||
key_append = "sta"
|
||||
}
|
||||
end,
|
||||
}
|
||||
end
|
||||
|
||||
for i = 1, 2 do
|
||||
SMODS.Booster{
|
||||
key = "miniarcana" .. i,
|
||||
loc_txt = {
|
||||
name = "Mini Arcana Pack",
|
||||
text = {
|
||||
"Choose {C:attention}#1#{} of up to",
|
||||
"{C:attention}#2# {C:tarot}Tarot{} cards to",
|
||||
"be used immediately",
|
||||
}
|
||||
},
|
||||
atlas = "janebooster",
|
||||
pos = {x = 3 + i, y = 1},
|
||||
weight = 0.4,
|
||||
cost = 2,
|
||||
config = {extra = 2, choose = 1},
|
||||
draw_hand = true,
|
||||
loc_vars = function(_, _, card)
|
||||
return {vars = {card.ability.choose, card.ability.extra}}
|
||||
end,
|
||||
ease_background_colour = function(_)
|
||||
ease_background_colour_blind(G.STATES.TAROT_PACK)
|
||||
end,
|
||||
create_UIBox = function(_)
|
||||
return create_UIBox_arcana_pack()
|
||||
end,
|
||||
particles = function(_)
|
||||
G.booster_pack_sparkles = Particles(1, 1, 0,0, {
|
||||
timer = 0.015,
|
||||
scale = 0.2,
|
||||
initialize = true,
|
||||
lifespan = 1,
|
||||
speed = 1.1,
|
||||
padding = -1,
|
||||
attach = G.ROOM_ATTACH,
|
||||
colours = {G.C.WHITE, lighten(G.C.PURPLE, 0.4), lighten(G.C.PURPLE, 0.2), lighten(G.C.GOLD, 0.2)},
|
||||
fill = true
|
||||
})
|
||||
|
||||
G.booster_pack_sparkles.fade_alpha = 1
|
||||
G.booster_pack_sparkles:fade(1, 0)
|
||||
end,
|
||||
create_card = function(_, _, _)
|
||||
if G.GAME.used_vouchers.v_omen_globe and pseudorandom("omen_globe") > 0.8 then
|
||||
return {
|
||||
set = "Spectral",
|
||||
soulable = true,
|
||||
key_append = "ar2",
|
||||
area = G.pack_cards,
|
||||
skip_materialize = true,
|
||||
}
|
||||
end
|
||||
|
||||
return {
|
||||
set = "Tarot",
|
||||
soulable = true,
|
||||
key_append = "ar1",
|
||||
area = G.pack_cards,
|
||||
skip_materialize = true,
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
for i = 1, 2 do
|
||||
SMODS.Booster{
|
||||
key = "minicelestial" .. i,
|
||||
atlas = "janebooster",
|
||||
loc_txt = {
|
||||
name = "Mini Celestial Pack",
|
||||
text = {
|
||||
"Choose {C:attention}#1#{} of up to",
|
||||
"{C:attention}#2# {C:planet}Planet{} cards to",
|
||||
"be used immediately",
|
||||
}
|
||||
},
|
||||
config = {extra = 2, choose = 1},
|
||||
pos = {x = 3 + i, y = 0},
|
||||
cost = 2,
|
||||
weight = 0.4,
|
||||
loc_vars = function(_, _, card)
|
||||
return {vars = {card.ability.choose, card.ability.extra}}
|
||||
end,
|
||||
ease_background_colour = function(_) ease_background_colour_blind(G.STATES.PLANET_PACK) end,
|
||||
create_UIBox = function(_) return create_UIBox_celestial_pack() end,
|
||||
particles = function(_)
|
||||
G.booster_pack_stars = Particles(1, 1, 0,0, {
|
||||
fill = true,
|
||||
scale = 0.1,
|
||||
speed = 0.1,
|
||||
timer = 0.07,
|
||||
padding = -4,
|
||||
lifespan = 15,
|
||||
initialize = true,
|
||||
attach = G.ROOM_ATTACH,
|
||||
colours = {G.C.WHITE, HEX("a7d6e0"), HEX("fddca0")},
|
||||
})
|
||||
|
||||
G.booster_pack_meteors = Particles(1, 1, 0,0, {
|
||||
speed = 4,
|
||||
timer = 2,
|
||||
fill = true,
|
||||
scale = 0.05,
|
||||
lifespan = 1.5,
|
||||
attach = G.ROOM_ATTACH,
|
||||
colours = {G.C.WHITE},
|
||||
})
|
||||
end,
|
||||
create_card = function(_, _, index)
|
||||
if not G.GAME.used_vouchers.v_telescope or index ~= 1 then
|
||||
return {
|
||||
set = "Planet",
|
||||
area = G.pack_cards,
|
||||
skip_materialize = true,
|
||||
soulable = true,
|
||||
key_append = "pl1"
|
||||
}
|
||||
end
|
||||
|
||||
local planet, hand, tally = nil, nil, 0
|
||||
|
||||
for _, v in ipairs(G.handlist) do
|
||||
if G.GAME.hands[v].visible and G.GAME.hands[v].played > tally then
|
||||
hand = v
|
||||
tally = G.GAME.hands[v].played
|
||||
end
|
||||
end
|
||||
|
||||
if hand then
|
||||
for _, v in pairs(G.P_CENTER_POOLS.Planet) do
|
||||
if v.config.hand_type == hand then
|
||||
planet = v.key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
key = planet,
|
||||
set = "Planet",
|
||||
soulable = true,
|
||||
key_append = "pl1",
|
||||
area = G.pack_cards,
|
||||
skip_materialize = true,
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
for i = 1, 2 do
|
||||
SMODS.Booster{
|
||||
key = "minispectral" .. i,
|
||||
atlas = "janebooster",
|
||||
loc_txt = {
|
||||
name = "Mini Spectral Pack",
|
||||
text = {
|
||||
"Choose {C:attention}#1#{} of up to",
|
||||
"{C:attention}#2# {C:spectral}Spectral{} cards to",
|
||||
"be used immediately",
|
||||
}
|
||||
},
|
||||
config = {extra = 1, choose = 1},
|
||||
pos = {x = 3 + i, y = 2},
|
||||
cost = 2,
|
||||
weight = 0.225,
|
||||
draw_hand = true,
|
||||
loc_vars = function(_, _, card)
|
||||
return {vars = {card.ability.choose, card.ability.extra}}
|
||||
end,
|
||||
ease_background_colour = function(_)
|
||||
ease_background_colour_blind(G.STATES.SPECTRAL_PACK)
|
||||
end,
|
||||
create_UIBox = function(_)
|
||||
return create_UIBox_spectral_pack()
|
||||
end,
|
||||
particles = function(_)
|
||||
G.booster_pack_sparkles = Particles(1, 1, 0,0, {
|
||||
scale = 0.1,
|
||||
fill = true,
|
||||
speed = 0.2,
|
||||
lifespan = 3,
|
||||
padding = -1,
|
||||
timer = 0.015,
|
||||
initialize = true,
|
||||
attach = G.ROOM_ATTACH,
|
||||
colours = {G.C.WHITE, lighten(G.C.GOLD, 0.2)},
|
||||
})
|
||||
|
||||
G.booster_pack_sparkles.fade_alpha = 1
|
||||
G.booster_pack_sparkles:fade(1, 0)
|
||||
end,
|
||||
create_card = function(_, _, _)
|
||||
return {
|
||||
soulable = true,
|
||||
set = "Spectral",
|
||||
key_append = "spe",
|
||||
area = G.pack_cards,
|
||||
skip_materialize = true,
|
||||
}
|
||||
end,
|
||||
}
|
||||
end
|
||||
136
src/edition.lua
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
SMODS.Sound({key = "e_jumbo", path = "e_jumbo.ogg"})
|
||||
SMODS.Shader({key = "polygloss", path = "polygloss.fs"})
|
||||
SMODS.Sound({key = "e_polygloss", path = "e_polygloss.ogg"})
|
||||
|
||||
local function resize(card, mod, force_save)
|
||||
if force_save or not card.origsize then
|
||||
card.origsize = {w = card.T.w, h = card.T.h}
|
||||
end
|
||||
|
||||
card:hard_set_T(card.T.x, card.T.y, card.T.w * mod, card.T.h * mod)
|
||||
remove_all(card.children)
|
||||
card.children = {}
|
||||
card.children.shadow = Moveable(0, 0, 0, 0)
|
||||
card:set_sprites(card.config.center, card.base.id and card.config.card)
|
||||
|
||||
if card.area and
|
||||
((G.shop_jokers and card.area == G.shop_jokers) or
|
||||
(G.shop_booster and card.area == G.shop_booster) or
|
||||
(G.shop_vouchers and card.area == G.shop_vouchers)) then
|
||||
create_shop_card_ui(card)
|
||||
end
|
||||
end
|
||||
|
||||
SMODS.Edition({
|
||||
key = "polygloss",
|
||||
loc_txt = {
|
||||
name = "Polygloss",
|
||||
label = "Polygloss",
|
||||
text = {
|
||||
"{C:chips}+#1#{}, {X:chips,C:white}x#2#{} & {X:chips,C:dark_edition}^#3#{} Chips",
|
||||
"{C:mult}+#4#{}, {X:mult,C:white}x#5#{} & {X:mult,C:dark_edition}^#6#{} Mult",
|
||||
"Generates {C:money}+$#7#",
|
||||
"{C:dark_edition,s:0.7,E:2}Shader by : Oiiman"
|
||||
}
|
||||
},
|
||||
config = {chips = 1, mult = 1, x_chips = 1.1, x_mult = 1.1, e_chips = 1.01, e_mult = 1.01, p_dollars = 1},
|
||||
sound = {
|
||||
sound = "jane_e_polygloss",
|
||||
per = 1.2,
|
||||
vol = 0.4
|
||||
},
|
||||
weight = 8,
|
||||
extra_cost = 2,
|
||||
in_shop = true,
|
||||
shader = "polygloss",
|
||||
apply_to_float = false,
|
||||
loc_vars = function(self)
|
||||
return {vars = {
|
||||
self.config.chips,
|
||||
self.config.x_chips,
|
||||
self.config.e_chips,
|
||||
self.config.mult,
|
||||
self.config.x_mult,
|
||||
self.config.e_mult,
|
||||
self.config.p_dollars
|
||||
}}
|
||||
end
|
||||
})
|
||||
|
||||
local jumbo_modifier = Cryptid and 100 or 2
|
||||
|
||||
SMODS.Edition({
|
||||
key = "jumbo",
|
||||
loc_txt = {
|
||||
name = "Jumbo",
|
||||
label = "Jumbo",
|
||||
text = {
|
||||
"All card values are",
|
||||
"{C:attention}multiplied{} by {C:attention}up to " .. jumbo_modifier,
|
||||
"{C:inactive}(If possible)",
|
||||
"{C:inactive,E:1,s:0.7}Whoa, it's huge!!{}"
|
||||
}
|
||||
},
|
||||
on_apply = function(card)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
blocking = false,
|
||||
blockable = false,
|
||||
func = function()
|
||||
resize(card, Jane.config.wee_sizemod)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
|
||||
local obj = card:gc()
|
||||
|
||||
if obj.set == "Booster" or obj.jumbo_mod then
|
||||
jumbo_modifier = obj.jumbo_mod or 10
|
||||
end
|
||||
|
||||
if card.added_to_deck then
|
||||
card:remove_from_deck()
|
||||
end
|
||||
|
||||
Jane.misprintize(card, {min = jumbo_modifier, max = jumbo_modifier}, nil, true)
|
||||
|
||||
if card.added_to_deck then
|
||||
card:add_to_deck()
|
||||
end
|
||||
end,
|
||||
on_remove = function(card)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
blocking = false,
|
||||
blockable = false,
|
||||
func = function()
|
||||
resize(card, 1 / Jane.config.wee_sizemod)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
|
||||
local was_added = card.added_to_deck
|
||||
|
||||
if was_added then
|
||||
card:remove_from_deck()
|
||||
end
|
||||
|
||||
Jane.misprintize(card, {min = 1 / jumbo_modifier, max = 1 / jumbo_modifier}, nil, true)
|
||||
|
||||
if was_added then
|
||||
card:add_to_deck()
|
||||
end
|
||||
end,
|
||||
config = {twos_scored = 0},
|
||||
sound = {
|
||||
sound = "jane_e_jumbo",
|
||||
per = 1,
|
||||
vol = 0.5
|
||||
},
|
||||
weight = 0.8,
|
||||
in_shop = true,
|
||||
shader = false,
|
||||
extra_cost = 12,
|
||||
apply_to_float = false,
|
||||
get_weight = function(self)
|
||||
return G.GAME.edition_rate * self.weight
|
||||
end,
|
||||
})
|
||||
311
src/joker.lua
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
for _, v in pairs({"7granddad", "betmma", "oxy", "peppino"}) do
|
||||
SMODS.Atlas {
|
||||
px = 71,
|
||||
py = 95,
|
||||
key = "jane" .. v,
|
||||
path = Jane.config.texture_pack .. "/j_jane_" .. v .. ".png",
|
||||
}
|
||||
end
|
||||
|
||||
for i = 1, 6 do
|
||||
SMODS.Sound({key = 'grand' .. i, path = 'grand_dad' .. i .. '.ogg'})
|
||||
end
|
||||
|
||||
local exotic = Cryptid and "cry_exotic" or 4
|
||||
|
||||
local food = {
|
||||
"j_gros_michel",
|
||||
"j_egg",
|
||||
"j_ice_cream",
|
||||
"j_cavendish",
|
||||
"j_turtle_bean",
|
||||
"j_diet_cola",
|
||||
"j_popcorn",
|
||||
"j_ramen",
|
||||
"j_selzer",
|
||||
"j_cry_pickle",
|
||||
"j_cry_chili_pepper",
|
||||
"j_cry_oldcandy",
|
||||
"j_cry_caramel",
|
||||
"j_cry_foodm",
|
||||
"j_cry_cotton_candy",
|
||||
"j_cry_wrapped",
|
||||
"j_cry_candy_cane",
|
||||
"j_cry_candy_buttons",
|
||||
"j_cry_jawbreaker",
|
||||
"j_cry_mellowcreme",
|
||||
"j_cry_brittle",
|
||||
"j_jane_peppino",
|
||||
}
|
||||
|
||||
local granddad_palette = {
|
||||
HEX("155fd9"),
|
||||
HEX("ff8170"),
|
||||
HEX("ffffff"),
|
||||
HEX("6c0700")
|
||||
}
|
||||
|
||||
local function food_jokers_count()
|
||||
if not G.jokers then
|
||||
return 0
|
||||
end
|
||||
|
||||
local amount = 0
|
||||
|
||||
for _, v in pairs(food) do
|
||||
amount = amount + #SMODS.find_card(v)
|
||||
end
|
||||
|
||||
return amount
|
||||
end
|
||||
|
||||
local function grand_dad(card)
|
||||
Jane.q(function()
|
||||
card:juice_up(0.5, 0.5)
|
||||
return true
|
||||
end)
|
||||
|
||||
local rnd = math.random(6)
|
||||
local obj = card.edition or {}
|
||||
|
||||
Jane.play_sound(
|
||||
"jane_grand" .. rnd,
|
||||
obj.jane_jumbo and (1 / Jane.config.wee_sizemod) or 1,
|
||||
0.5
|
||||
)
|
||||
|
||||
Jane.card_status_text(
|
||||
card,
|
||||
rnd == 2 and "Flintstones?!" or rnd == 6 and "Gruhh- Dad!" or "Grand Dad!",
|
||||
nil,
|
||||
0.05 * card.T.h,
|
||||
granddad_palette[math.random(#granddad_palette)],
|
||||
0.6,
|
||||
0.6,
|
||||
nil,
|
||||
nil,
|
||||
"bm"
|
||||
)
|
||||
end
|
||||
|
||||
local function voucher_count()
|
||||
if not G.GAME.used_vouchers then
|
||||
return 0
|
||||
end
|
||||
|
||||
local count = 0
|
||||
|
||||
for _, v in pairs(G.GAME.used_vouchers) do
|
||||
if v then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
return count
|
||||
end
|
||||
|
||||
SMODS.Joker {
|
||||
key = "oxy",
|
||||
atlas = "janeoxy",
|
||||
loc_txt = {
|
||||
name = "Oxy",
|
||||
text = {
|
||||
"{C:attention}Scored steel{} cards give",
|
||||
"{X:mult,C:white}x#1#{} {C:mult}Mult {}& {X:chips,C:white}x#1#{} {C:chips}Chips",
|
||||
" ",
|
||||
"{C:inactive,s:0.75,E:1}#2#{C:red,s:1.5,E:1}#3#",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
config = {steel = 1.5},
|
||||
sinis = {x = 2, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 10,
|
||||
rarity = 3,
|
||||
blueprint_compat = true,
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {
|
||||
center.ability.steel,
|
||||
Jane.sinister and "" or "We all cut close...",
|
||||
Jane.sinister and "WHAT ARE YOU DOING DOWN THERE?!?" or "",
|
||||
}}
|
||||
end,
|
||||
calculate = function(self, card, context)
|
||||
if context.individual and
|
||||
context.cardarea == G.play and
|
||||
context.other_card.ability.name == "Steel Card" then
|
||||
return {
|
||||
x_chips = card.ability.steel,
|
||||
x_mult = card.ability.steel,
|
||||
colour = G.C.PURPLE,
|
||||
card = card
|
||||
}, true
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "7granddad",
|
||||
loc_txt = {
|
||||
name = "7 GRAND DAD",
|
||||
text = {
|
||||
"This Joker has a {C:jane_RGB,E:1}strange",
|
||||
"{C:jane_RGB,E:1}reaction {}to scored {C:attention}7{}s",
|
||||
}
|
||||
},
|
||||
config = {},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 12,
|
||||
rarity = exotic,
|
||||
atlas = "jane7granddad",
|
||||
blueprint_compat = true,
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {center.ability.shopslots}}
|
||||
end,
|
||||
add_to_deck = function(_, card, _)
|
||||
grand_dad(card)
|
||||
end,
|
||||
remove_from_deck = function(_, card, _)
|
||||
grand_dad(card)
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
if context.cardarea == G.play then
|
||||
local function scj(c)
|
||||
return c.cardarea and c.cardarea == G.play and not c.before and not c.after and not c.repetition
|
||||
end
|
||||
|
||||
if context.other_card and context.other_card:get_id() == 7 and scj(context) then
|
||||
grand_dad(card)
|
||||
local palette = granddad_palette[math.random(#granddad_palette)]
|
||||
local rnd = pseudorandom(pseudoseed("granddad"), 1, Cryptid and 7 or 5)
|
||||
|
||||
if rnd == 1 then
|
||||
return {
|
||||
message = "+777",
|
||||
chips = 777,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
elseif rnd == 2 then
|
||||
return {
|
||||
message = "+777 Mult",
|
||||
mult = 777,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
elseif rnd == 3 then
|
||||
return {
|
||||
message = "+$7",
|
||||
dollars = 7,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
elseif rnd == 4 then
|
||||
return {
|
||||
message = "x7",
|
||||
x_chips = 7,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
elseif rnd == 5 then
|
||||
return {
|
||||
message = "x7 Mult",
|
||||
x_mult = 7,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
elseif rnd == 6 then
|
||||
return {
|
||||
message = "^1.77",
|
||||
e_chips = 1.77,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
else
|
||||
return {
|
||||
message = "^1.77 Mult",
|
||||
e_mult = 1.77,
|
||||
colour = palette,
|
||||
card = card
|
||||
}, true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local operator = Cryptid and "^" or "*"
|
||||
|
||||
SMODS.Joker {
|
||||
key = "betmma",
|
||||
atlas = "janebetmma",
|
||||
loc_txt = {
|
||||
name = "Betmma",
|
||||
text = {
|
||||
"{X:dark_edition,C:chips}+" .. operator .. "#1#{C:chips} Chips{} for every",
|
||||
"{C:attention}unique Voucher redeemed",
|
||||
"{C:inactive}(Currently {X:dark_edition,C:chips}" .. operator .. "#2#{C:inactive})",
|
||||
}
|
||||
},
|
||||
config = {big_num_scaler = true, extra = {tet = 0.1}},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 50,
|
||||
rarity = exotic,
|
||||
blueprint_compat = true,
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {center.ability.extra.tet, 1 + (voucher_count() * center.ability.extra.tet)}}
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
if context.cardarea ~= G.jokers or context.before or context.after or not context.scoring_name then
|
||||
return
|
||||
end
|
||||
|
||||
local v = voucher_count()
|
||||
|
||||
if v > 0 then
|
||||
local num = 1 + (v * card.ability.extra.tet)
|
||||
|
||||
return {
|
||||
card = card,
|
||||
colour = G.C.jane_RGB,
|
||||
message = operator .. number_format(num),
|
||||
[Cryptid and "Echips_mod" or "xchips_mod"] = num,
|
||||
}, true
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "peppino",
|
||||
atlas = "janepeppino",
|
||||
loc_txt = {
|
||||
name = "Peppino Spaghetti",
|
||||
text = {
|
||||
"{X:dark_edition,C:red}" .. operator .. "2^x{C:red} Mult{} for every",
|
||||
"{C:attention}food or Peppino Joker",
|
||||
"in your possession",
|
||||
"{C:inactive}(Currently {X:dark_edition,C:red}" .. operator .. "#1#{C:red} Mult{C:inactive})",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 50,
|
||||
rarity = exotic,
|
||||
blueprint_compat = true,
|
||||
loc_vars = function(_, _, _)
|
||||
return {vars = {2 ^ food_jokers_count()}}
|
||||
end,
|
||||
calculate = function(_, _, context)
|
||||
local count = food_jokers_count()
|
||||
|
||||
if context.joker_main and count > 0 then
|
||||
return {
|
||||
colour = G.C.DARK_EDITION,
|
||||
message = "^" .. 2 ^ count .. " Mult",
|
||||
[Cryptid and "Emult_mod" or "xmult_mod"] = 2 ^ count,
|
||||
}, true
|
||||
end
|
||||
end
|
||||
}
|
||||
373
src/main.lua
Normal file
|
|
@ -0,0 +1,373 @@
|
|||
Jane = {
|
||||
config = {
|
||||
wee_sizemod = 1.25,
|
||||
texture_pack = "default",
|
||||
bans = {"j_cry_crustulum", "c_cry_hammerspace"}
|
||||
},
|
||||
}
|
||||
|
||||
Jane.misprintize = (Cryptid or {}).misprintize
|
||||
Jane.misprintize_tbl = (Cryptid or {}).misprintize_tbl
|
||||
Jane.misprinitze_val = (Cryptid or {}).misprintize_val
|
||||
|
||||
if not Jane.misprintize then
|
||||
assert(SMODS.load_file("src/misprintize.lua"))()
|
||||
end
|
||||
|
||||
function Jane.canuse()
|
||||
return not (((G.play and #G.play.cards > 0) or
|
||||
(G.CONTROLLER.locked) or
|
||||
(G.GAME.STOP_USE and G.GAME.STOP_USE > 0)) and
|
||||
G.STATE ~= G.STATES.HAND_PLAYED and
|
||||
G.STATE ~= G.STATES.DRAW_TO_HAND and
|
||||
G.STATE ~= G.STATES.PLAY_TAROT)
|
||||
end
|
||||
|
||||
function Jane.card_status_text(
|
||||
card,
|
||||
text,
|
||||
xoffset,
|
||||
yoffset,
|
||||
colour,
|
||||
size,
|
||||
delay,
|
||||
juice,
|
||||
jiggle,
|
||||
align,
|
||||
sound,
|
||||
volume,
|
||||
pitch,
|
||||
trig,
|
||||
f
|
||||
)
|
||||
if (delay or 0) <= 0 then
|
||||
if type(f) == "function" then
|
||||
f(card)
|
||||
end
|
||||
|
||||
attention_text({
|
||||
text = text,
|
||||
scale = size or 1,
|
||||
hold = 0.7,
|
||||
backdrop_colour = colour or (G.C.FILTER),
|
||||
align = align or "bm",
|
||||
major = card,
|
||||
offset = {x = xoffset or 0, y = yoffset or (-0.05*G.CARD_H)}
|
||||
})
|
||||
|
||||
if sound then
|
||||
play_sound(sound, pitch or (0.9 + (0.2 * math.random())), volume or 1)
|
||||
end
|
||||
|
||||
if juice then
|
||||
if type(juice) == "table" then
|
||||
card:juice_up(juice[1], juice[2])
|
||||
elseif type(juice) == "number" and juice ~= 0 then
|
||||
card:juice_up(juice, juice / 6)
|
||||
end
|
||||
end
|
||||
|
||||
if jiggle then
|
||||
G.ROOM.jiggle = G.ROOM.jiggle + jiggle
|
||||
end
|
||||
else
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = trig,
|
||||
delay = delay,
|
||||
func = function()
|
||||
if f and type(f) == "function" then
|
||||
f(card)
|
||||
end
|
||||
|
||||
attention_text({
|
||||
text = text,
|
||||
scale = size or 1,
|
||||
hold = 0.7 + (delay or 0),
|
||||
backdrop_colour = colour or (G.C.FILTER),
|
||||
align = align or "bm",
|
||||
major = card,
|
||||
offset = {x = xoffset or 0, y = yoffset or (-0.05*G.CARD_H)}
|
||||
})
|
||||
|
||||
if sound then
|
||||
play_sound(sound, pitch or (0.9 + (0.2*math.random())), volume or 1)
|
||||
end
|
||||
|
||||
if juice then
|
||||
if type(juice) == "table" then
|
||||
card:juice_up(juice[1], juice[2])
|
||||
elseif type(juice) == "number" and juice ~= 0 then
|
||||
card:juice_up(juice, juice / 6)
|
||||
end
|
||||
end
|
||||
|
||||
if jiggle then
|
||||
G.ROOM.jiggle = G.ROOM.jiggle + jiggle
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
function Jane.empowered()
|
||||
if Cryptid then
|
||||
add_tag(Tag("tag_cry_empowered"))
|
||||
return true
|
||||
end
|
||||
|
||||
local card = create_card("Spectral", G.consumeables, nil, nil, nil, nil, "c_soul", "acceleration_soul")
|
||||
card:set_edition({negative = true})
|
||||
card:add_to_deck()
|
||||
G.consumeables:emplace(card)
|
||||
end
|
||||
|
||||
function Jane.get_chipmult_sum(chips, mult)
|
||||
chips = chips or 0
|
||||
mult = mult or 0
|
||||
|
||||
local op, big = Jane.get_operator(), Talisman.config_file.break_infinity == "omeganum" and
|
||||
to_big or function (x) return x end
|
||||
|
||||
if op >= 3 then
|
||||
return big(chips) ^ big(mult)
|
||||
elseif op == 2 then
|
||||
return big(chips) * big(mult)
|
||||
end
|
||||
|
||||
return big(chips) + big(mult)
|
||||
end
|
||||
|
||||
function Jane.get_operator()
|
||||
if not G.GAME then
|
||||
return 0
|
||||
end
|
||||
|
||||
G.GAME.operator = G.GAME.operator or 2
|
||||
return math.max(math.min(G.GAME.operator, 3), 1)
|
||||
end
|
||||
|
||||
function Jane.hidden(card)
|
||||
return G.GAME and not
|
||||
G.GAME.obsidian and
|
||||
type(card) == 'table' and
|
||||
(card.name == "Black Hole" or card.name == "The Soul" or card.hidden)
|
||||
end
|
||||
|
||||
function Jane.play_sound(sound, per, vol)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
func = function()
|
||||
play_sound(sound,per,vol)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
|
||||
function Jane.q(fc, de, t, tr, bl, ba)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
timer = t,
|
||||
trigger = tr,
|
||||
delay = de,
|
||||
blockable = bl,
|
||||
blocking = ba,
|
||||
func = fc
|
||||
}))
|
||||
end
|
||||
|
||||
function Card:gc()
|
||||
return (self.config or {}).center or {}
|
||||
end
|
||||
|
||||
function Card:norank()
|
||||
return self.ability.name == "Stone Card" or self.config.center.no_rank
|
||||
end
|
||||
|
||||
function Card:nosuit()
|
||||
return self.ability.name == "Stone Card" or self.config.center.no_suit
|
||||
end
|
||||
|
||||
local orig_debuff = Card.set_debuff
|
||||
|
||||
function Card:set_debuff(should_debuff)
|
||||
if should_debuff and ((self.config or {}).center or {}).debuff_immune then
|
||||
Jane.card_status_text(self, "Immune", nil, 0.05 * self.T.h, G.C.RED, nil, 0.6, nil, nil, "bm", "cancel", 1, 0.9)
|
||||
return false
|
||||
else
|
||||
orig_debuff(self, should_debuff)
|
||||
end
|
||||
end
|
||||
|
||||
local orig_menu = Game.main_menu
|
||||
|
||||
function Game:main_menu(change_context)
|
||||
Jane.sinister = nil
|
||||
orig_menu(self, change_context)
|
||||
end
|
||||
|
||||
local orig_update = Game.update
|
||||
|
||||
function Game:update(dt)
|
||||
local function delete_hardbans()
|
||||
if not Jane.config.disable_bans then
|
||||
for _, v in pairs(Jane.config.bans) do
|
||||
local e = SMODS.Center:get_obj(v)
|
||||
|
||||
if e then
|
||||
e:delete()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function hand(name, chip, mul, lv, notif, snd, vol, pit, de)
|
||||
local config = {
|
||||
delay = de or 0.3,
|
||||
pitch = pit or 0.8,
|
||||
volume = vol or 0.7,
|
||||
sound = type(snd) == "string" and snd or type(snd) == "nil" and "button",
|
||||
}
|
||||
|
||||
local vals = {
|
||||
level = lv or "?",
|
||||
mult = mul or "?",
|
||||
StatusText = notif,
|
||||
chips = chip or "?",
|
||||
handname = name or "????",
|
||||
}
|
||||
|
||||
update_hand_text(config, vals)
|
||||
end
|
||||
|
||||
local function rebalance_orrery()
|
||||
local function small(x)
|
||||
return type(x) == "table" and x:to_number() or x
|
||||
end
|
||||
|
||||
local orrery = (G.GAME or {}).orrery
|
||||
|
||||
if not orrery then
|
||||
return
|
||||
end
|
||||
|
||||
local count = 0
|
||||
local hands = {}
|
||||
local pools = {chips = 0, level = 0, mult = 0}
|
||||
|
||||
for k, v in pairs(G.GAME.hands) do
|
||||
if k ~= "cry_WholeDeck" then
|
||||
count = count + 1
|
||||
hands[#hands + 1] = v
|
||||
pools.mult = v.mult + pools.mult
|
||||
pools.chips = v.chips + pools.chips
|
||||
pools.level = v.level + pools.level
|
||||
end
|
||||
end
|
||||
|
||||
if pools.mult == orrery.mult and pools.chips == orrery.chips and pools.level == orrery.level then
|
||||
return
|
||||
end
|
||||
|
||||
table.sort(hands, function (x, y) return x.order > y.order end)
|
||||
|
||||
for i, v in ipairs(hands) do
|
||||
v.mult = math.floor(pools.mult / count) + (small(pools.mult % count) >= i and 1 or 0)
|
||||
v.chips = math.floor(pools.chips / count) + (small(pools.chips % count) >= i and 1 or 0)
|
||||
v.level = math.floor(pools.level / count) + (small(pools.level % count) >= i and 1 or 0)
|
||||
end
|
||||
|
||||
orrery.mult = pools.mult
|
||||
orrery.chips = pools.chips
|
||||
orrery.level = pools.level
|
||||
hand(localize("k_all_hands"), math.floor(pools.chips / count), math.floor(pools.mult / count), math.floor(pools.level / count))
|
||||
delay(1)
|
||||
update_hand_text({sound = "button", volume = 0.7, pitch = 1.1, delay = 0}, {mult = 0, chips = 0, handname = "", level = ""})
|
||||
end
|
||||
|
||||
local function hsv(h, s, v)
|
||||
if s <= 0 then return v, v, v end
|
||||
h = h * 6
|
||||
local c = v * s
|
||||
local x = (1 - math.abs((h % 2) - 1)) * c
|
||||
local m, r, g, b = (v - c), 0, 0, 0
|
||||
|
||||
if h < 1 then
|
||||
r, g, b = c, x, 0
|
||||
elseif h < 2 then
|
||||
r, g, b = x, c, 0
|
||||
elseif h < 3 then
|
||||
r, g, b = 0, c, x
|
||||
elseif h < 4 then
|
||||
r, g, b = 0, x, c
|
||||
elseif h < 5 then
|
||||
r, g, b = x, 0, c
|
||||
else
|
||||
r, g, b = c, 0, x
|
||||
end
|
||||
|
||||
return r + m, g + m, b + m
|
||||
end
|
||||
|
||||
orig_update(self, dt)
|
||||
|
||||
if not Jane.bans_done then
|
||||
delete_hardbans()
|
||||
Jane.bans_done = true
|
||||
end
|
||||
|
||||
if (G.GAME or {}).banned_keys then
|
||||
for _, v in pairs(Jane.config.bans) do
|
||||
G.GAME.banned_keys[v] = true
|
||||
end
|
||||
end
|
||||
|
||||
if G.ARGS.LOC_COLOURS then
|
||||
local r, g, b = hsv(self.C.jane_RGB_HUE / 360, .5, 1)
|
||||
self.C.jane_RGB[1] = r
|
||||
self.C.jane_RGB[3] = g
|
||||
self.C.jane_RGB[2] = b
|
||||
self.C.jane_RGB_HUE = (self.C.jane_RGB_HUE + 0.5) % 360
|
||||
G.ARGS.LOC_COLOURS.jane_RGB = self.C.jane_RGB
|
||||
end
|
||||
|
||||
rebalance_orrery()
|
||||
end
|
||||
|
||||
local orig_card = SMODS.find_card
|
||||
|
||||
---@param key string
|
||||
---@param count_debuffed true?
|
||||
---@return Card[]|table[]
|
||||
--- Returns all cards matching provided `key`.
|
||||
function SMODS.find_card(key, count_debuffed)
|
||||
return orig_card(key == "j_jen_saint" and "j_jane_saint" or key, count_debuffed)
|
||||
end
|
||||
|
||||
SMODS.Atlas {
|
||||
px = 34,
|
||||
py = 34,
|
||||
key = "modicon",
|
||||
path = "almanac_avatar.png",
|
||||
}
|
||||
|
||||
SMODS.Atlas {
|
||||
px = 71,
|
||||
py = 95,
|
||||
key = "janeacc",
|
||||
path = Jane.config.texture_pack .. "/c_jane_acc.png",
|
||||
}
|
||||
|
||||
for _, v in ipairs({
|
||||
"back",
|
||||
"blind",
|
||||
"booster",
|
||||
"edition",
|
||||
"joker",
|
||||
"slugcat",
|
||||
"spectral",
|
||||
"tarot",
|
||||
"token",
|
||||
"voucher",
|
||||
}) do
|
||||
assert(SMODS.load_file("src/" .. v .. ".lua"))()
|
||||
end
|
||||
311
src/misprintize.lua
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
-- The following code is slightly adapted from
|
||||
-- https://github.com/MathIsFun0/Cryptid/blob/main/lib/misprintize.lua
|
||||
|
||||
local base_values = {}
|
||||
|
||||
local big_num_whitelist = {
|
||||
j_egg = true,
|
||||
j_wee = true,
|
||||
j_flash = true,
|
||||
j_ramen = true,
|
||||
j_glass = true,
|
||||
j_caino = true,
|
||||
j_cry_m = true,
|
||||
j_runner = true,
|
||||
j_square = true,
|
||||
j_castle = true,
|
||||
j_yorick = true,
|
||||
j_madness = true,
|
||||
j_vampire = true,
|
||||
j_obelisk = true,
|
||||
j_popcorn = true,
|
||||
j_red_card = true,
|
||||
j_hologram = true,
|
||||
j_trousers = true,
|
||||
j_campfire = true,
|
||||
j_cry_whip = true,
|
||||
j_ice_cream = true,
|
||||
j_lucky_cat = true,
|
||||
j_throwback = true,
|
||||
j_cry_hugem = true,
|
||||
j_cry_pickle = true,
|
||||
j_cry_cursor = true,
|
||||
j_cry_primus = true,
|
||||
j_cry_mprime = true,
|
||||
j_green_joker = true,
|
||||
j_turtle_bean = true,
|
||||
j_cry_wee_fib = true,
|
||||
j_cry_jimball = true,
|
||||
j_ride_the_bus = true,
|
||||
j_hit_the_road = true,
|
||||
j_cry_dropshot = true,
|
||||
j_cry_fspinner = true,
|
||||
j_cry_mondrian = true,
|
||||
j_constellation = true,
|
||||
j_cry_crustulum = true,
|
||||
j_cry_spaceglobe = true,
|
||||
j_cry_exponentia = true,
|
||||
j_cry_chili_pepper = true,
|
||||
j_cry_eternalflame = true,
|
||||
j_cry_stella_mortis = true,
|
||||
j_cry_krustytheclown = true,
|
||||
j_cry_antennastoheaven = true,
|
||||
}
|
||||
|
||||
local function check(v, is_big)
|
||||
if is_big then
|
||||
if not v or type(v) == "number" and (v ~= v or v > 1e300 or v < -1e300) then
|
||||
v = 1e300
|
||||
end
|
||||
|
||||
if type(v) == "table" then
|
||||
return v
|
||||
end
|
||||
|
||||
if v > 1e100 or v < -1e100 then
|
||||
return to_big(v)
|
||||
end
|
||||
end
|
||||
|
||||
return not v or type(v) == "number" and (v ~= v or v > 1e300 or v < -1e300) and 1e300 or v
|
||||
end
|
||||
|
||||
local function deep_copy(obj, seen)
|
||||
if type(obj) ~= "table" then
|
||||
return obj
|
||||
end
|
||||
|
||||
if seen and seen[obj] then
|
||||
return seen[obj]
|
||||
end
|
||||
|
||||
local s = seen or {}
|
||||
local res = setmetatable({}, getmetatable(obj))
|
||||
s[obj] = res
|
||||
|
||||
for k, v in pairs(obj) do
|
||||
res[deep_copy(k, s)] = deep_copy(v, s)
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
local function is_card_big(joker)
|
||||
local center = joker.config and joker.config.center
|
||||
|
||||
if not center then
|
||||
return false
|
||||
end
|
||||
|
||||
return big_num_whitelist[center.key or "Nope!"]
|
||||
end
|
||||
|
||||
local function log_random(seed, min, max)
|
||||
math.randomseed(seed)
|
||||
local lmin = math.log(min, 2.718281828459045)
|
||||
local lmax = math.log(max, 2.718281828459045)
|
||||
local poll = math.random() * (lmax - lmin) + lmin
|
||||
return math.exp(poll)
|
||||
end
|
||||
|
||||
function Jane.misprintize_val(val, override, big)
|
||||
local function format(number, str)
|
||||
return math.abs(to_big(number)) >= to_big(1e300) and number
|
||||
or tonumber(str:format((Big and to_number(to_big(number)) or number)))
|
||||
end
|
||||
|
||||
return is_number(val) and check(
|
||||
format(
|
||||
val * log_random(
|
||||
pseudoseed("cry_misprint" .. G.GAME.round_resets.ante),
|
||||
override and override.min or G.GAME.modifiers.cry_misprint_min,
|
||||
override and override.max or G.GAME.modifiers.cry_misprint_max
|
||||
),
|
||||
"%.2g"
|
||||
),
|
||||
big
|
||||
) or val
|
||||
end
|
||||
|
||||
function Jane.misprintize_tbl(name, ref_tbl, ref_value, clear, override, stack, big)
|
||||
if name and ref_tbl and ref_value then
|
||||
local tbl = deep_copy(ref_tbl[ref_value])
|
||||
|
||||
for k, v in pairs(tbl) do
|
||||
if (type(tbl[k]) ~= "table") or is_number(tbl[k]) then
|
||||
if is_number(tbl[k]) and not
|
||||
(k == "id") and not
|
||||
(k == "colour") and not
|
||||
(k == "suit_nominal") and not
|
||||
(k == "base_nominal") and not
|
||||
(k == "face_nominal") and not
|
||||
(k == "qty") and not
|
||||
(k == "x_mult" and v == 1 and not tbl.override_x_mult_check) and not
|
||||
(k == "selected_d6_face") then
|
||||
if not base_values[name] then
|
||||
base_values[name] = {}
|
||||
end
|
||||
|
||||
if not base_values[name][k] then
|
||||
base_values[name][k] = tbl[k]
|
||||
end
|
||||
|
||||
tbl[k] = check(
|
||||
clear and base_values[name][k]
|
||||
or cry_format(
|
||||
(stack and tbl[k] or base_values[name][k])
|
||||
* log_random(
|
||||
pseudoseed("cry_misprint" .. G.GAME.round_resets.ante),
|
||||
override and override.min or G.GAME.modifiers.cry_misprint_min,
|
||||
override and override.max or G.GAME.modifiers.cry_misprint_max
|
||||
),
|
||||
"%.2g"
|
||||
),
|
||||
big
|
||||
)
|
||||
end
|
||||
else
|
||||
for _k, _ in pairs(tbl[k]) do
|
||||
if is_number(tbl[k][_k]) and not
|
||||
(_k == "id") and not
|
||||
(k == "perish_tally") and not
|
||||
(k == "colour") and not
|
||||
(_k == "suit_nominal") and not
|
||||
(_k == "base_nominal") and not
|
||||
(_k == "face_nominal") and not
|
||||
(_k == "qty") and not
|
||||
(k == "x_mult" and v == 1 and not tbl[k].override_x_mult_check) and not
|
||||
(_k == "selected_d6_face") then
|
||||
if not base_values[name] then
|
||||
base_values[name] = {}
|
||||
end
|
||||
|
||||
if not base_values[name][k] then
|
||||
base_values[name][k] = {}
|
||||
end
|
||||
|
||||
if not base_values[name][k][_k] then
|
||||
base_values[name][k][_k] = tbl[k][_k]
|
||||
end
|
||||
|
||||
tbl[k][_k] = check(
|
||||
clear and base_values[name][k][_k]
|
||||
or cry_format(
|
||||
(stack and tbl[k][_k] or base_values[name][k][_k]) *
|
||||
log_random(
|
||||
pseudoseed("cry_misprint" .. G.GAME.round_resets.ante),
|
||||
override and override.min or G.GAME.modifiers.cry_misprint_min,
|
||||
override and override.max or G.GAME.modifiers.cry_misprint_max
|
||||
),
|
||||
"%.2g"
|
||||
),
|
||||
big
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ref_tbl[ref_value] = tbl
|
||||
end
|
||||
end
|
||||
|
||||
function Jane.misprintize(card, override, force_reset, stack)
|
||||
local function no(self, m, no_no)
|
||||
if no_no then
|
||||
if self.infinifusion then
|
||||
for i = 1, #self.infinifusion do
|
||||
if G.P_CENTERS[self.infinifusion[i].key][m] or
|
||||
(G.GAME and G.GAME[m] and G.GAME[m][self.infinifusion[i].key]) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if not self.config then
|
||||
return G.P_CENTERS[self.key][m] or (G.GAME and G.GAME[m] and G.GAME[m][self.key])
|
||||
end
|
||||
|
||||
return self.config.center[m] or (G.GAME and G.GAME[m] and G.GAME[m][self.config.center_key]) or false
|
||||
end
|
||||
|
||||
return no(self, "no_" .. m, true)
|
||||
end
|
||||
|
||||
if no(card, "immutable", true) then
|
||||
force_reset = true
|
||||
end
|
||||
|
||||
if card.infinifusion then
|
||||
if card.config.center == card.infinifusion_center or card.config.center.key == "j_infus_fused" then
|
||||
---@diagnostic disable-next-line: undefined-global
|
||||
calculate_infinifusion(card, nil, function(i)
|
||||
Jane.misprintize(card, override, force_reset, stack)
|
||||
end)
|
||||
end
|
||||
end
|
||||
if (not force_reset or G.GAME.modifiers.cry_jkr_misprint_mod) and
|
||||
(G.GAME.modifiers.cry_misprint_min or override or card.ability.set == "Joker") and not
|
||||
stack or not
|
||||
no(card, "immutable", true) then
|
||||
if card.ability.name == "Ace Aequilibrium" then
|
||||
return
|
||||
end
|
||||
|
||||
if G.GAME.modifiers.cry_jkr_misprint_mod and card.ability.set == "Joker" then
|
||||
if not override then
|
||||
override = {}
|
||||
end
|
||||
|
||||
override.min = override.min or G.GAME.modifiers.cry_misprint_min or 1
|
||||
override.max = override.max or G.GAME.modifiers.cry_misprint_max or 1
|
||||
override.min = override.min * G.GAME.modifiers.cry_jkr_misprint_mod
|
||||
override.max = override.max * G.GAME.modifiers.cry_jkr_misprint_mod
|
||||
end
|
||||
|
||||
if G.GAME.modifiers.cry_misprint_min or override and override.min then
|
||||
Jane.misprintize_tbl(
|
||||
card.config.center_key,
|
||||
card,
|
||||
"ability",
|
||||
nil,
|
||||
override,
|
||||
stack,
|
||||
is_card_big(card)
|
||||
)
|
||||
|
||||
if card.base then
|
||||
Jane.misprintize_tbl(
|
||||
card.config.card_key,
|
||||
card,
|
||||
"base",
|
||||
nil,
|
||||
override,
|
||||
stack,
|
||||
is_card_big(card)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if G.GAME.modifiers.cry_misprint_min then
|
||||
card.misprint_cost_fac = 1 /
|
||||
log_random(
|
||||
pseudoseed("cry_misprint" .. G.GAME.round_resets.ante),
|
||||
override and override.min or G.GAME.modifiers.cry_misprint_min,
|
||||
override and override.max or G.GAME.modifiers.cry_misprint_max
|
||||
)
|
||||
|
||||
card:set_cost()
|
||||
end
|
||||
else
|
||||
Jane.misprintize_tbl(card.config.center_key, card, "ability", true, nil, nil, is_card_big(card))
|
||||
end
|
||||
|
||||
if card.ability.consumeable then
|
||||
for k, _ in pairs(card.ability.consumeable) do
|
||||
card.ability.consumeable[k] = deep_copy(card.ability[k])
|
||||
end
|
||||
end
|
||||
end
|
||||
606
src/slugcat.lua
Normal file
|
|
@ -0,0 +1,606 @@
|
|||
SMODS.Sound({key = "enlightened", path = "enlightened.ogg"})
|
||||
SMODS.Sound({key = "warning_heartbeat", path = "warning_heartbeat.ogg"})
|
||||
|
||||
for i = 1, 8 do
|
||||
SMODS.Sound({key = "gore" .. i, path = "gore" .. i .. ".ogg"})
|
||||
end
|
||||
|
||||
for _, v in pairs({
|
||||
"artificer",
|
||||
"hunter",
|
||||
"gourmand",
|
||||
"monk",
|
||||
"rivulet",
|
||||
"rot",
|
||||
"saint",
|
||||
"spearmaster",
|
||||
"survivor",
|
||||
}) do
|
||||
SMODS.Atlas {
|
||||
key = "jane" .. v,
|
||||
px = 71,
|
||||
py = 95,
|
||||
path = Jane.config.texture_pack .. "/j_jane_" .. v .. ".png"
|
||||
}
|
||||
end
|
||||
|
||||
local epic = Cryptid and "cry_epic" or 3
|
||||
local exotic = Cryptid and "cry_exotic" or 4
|
||||
|
||||
SMODS.Rarity {
|
||||
key = "junk",
|
||||
loc_txt = {name = "Junk"},
|
||||
badge_colour = G.C.JOKER_GREY,
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "spearmaster",
|
||||
atlas = "janespearmaster",
|
||||
loc_txt = {
|
||||
name = "The Spearmaster",
|
||||
text = {
|
||||
"You can choose {C:attention}any number of cards",
|
||||
"after opening {C:attention}any Booster Pack",
|
||||
"{C:attention}Booster Packs{} have {C:green}+#1#{} additional cards",
|
||||
}
|
||||
},
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {center.ability.extra.extrachoices}}
|
||||
end,
|
||||
config = {extra = {extrachoices = 1}},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 12,
|
||||
rarity = epic,
|
||||
}
|
||||
|
||||
local orig_open = Card.open
|
||||
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function Card:open()
|
||||
local orig = self.ability.extra or 1
|
||||
local spearmasters = SMODS.find_card("j_jane_spearmaster")
|
||||
|
||||
if next(spearmasters) then
|
||||
for _, v in pairs(spearmasters) do
|
||||
orig = orig + v.ability.extra.extrachoices
|
||||
end
|
||||
|
||||
self.config.choose = math.floor(orig)
|
||||
self.ability.extra = math.floor(orig)
|
||||
end
|
||||
|
||||
orig_open(self)
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.5,
|
||||
timer = "REAL",
|
||||
func = function()
|
||||
if next(spearmasters) then
|
||||
G.GAME.pack_choices = math.floor(self.ability.extra)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
|
||||
SMODS.Joker {
|
||||
key = "survivor",
|
||||
atlas = "janesurvivor",
|
||||
loc_txt = {
|
||||
name = "The Survivor",
|
||||
text = {
|
||||
"All cards held in hand",
|
||||
"{C:attention}contribute to scoring",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 20,
|
||||
rarity = 4,
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "monk",
|
||||
atlas = "janemonk",
|
||||
loc_txt = {
|
||||
name = "The Monk",
|
||||
text = {
|
||||
"{C:attention}Retrigger{} scored cards",
|
||||
"{C:attention}<card's rank> {}times",
|
||||
"{C:inactive}(ex. 9 = 9 times, Ace = 11 times)",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 12,
|
||||
rarity = 4,
|
||||
blueprint_compat = true,
|
||||
calculate = function(_, card, context)
|
||||
if context.repetition and
|
||||
context.cardarea == G.play and
|
||||
context.other_card and
|
||||
context.other_card.ability.name ~= "Stone Card" then
|
||||
local id = context.other_card:get_id()
|
||||
|
||||
return {
|
||||
message = localize("k_again_ex"),
|
||||
repetitions = id == 14 and 11 or math.min(id, 10),
|
||||
colour = G.C.ORANGE,
|
||||
card = card
|
||||
}, true
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
local hunter = { 7, 5, 3, 2, 1 }
|
||||
|
||||
SMODS.Joker {
|
||||
key = "hunter",
|
||||
atlas = "janehunter",
|
||||
loc_txt = {
|
||||
name = "The Hunter",
|
||||
text = {
|
||||
"{C:blue}Provides infinite hands",
|
||||
"{C:red,s,E:1}Succumbs to the Rot {}and creates",
|
||||
(Cryptid and "an {C:spectral}Empowered Tag" or "a {C:dark_edition}Negative {C:spectral}Soul") .. " {}after #1#",
|
||||
"When {C:attention}sold#2#{}, turns#3#",
|
||||
"#4#{C:red}The Rot{} without rewards",
|
||||
}
|
||||
},
|
||||
config = {rounds_left = hunter[1]},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 20,
|
||||
rarity = 4,
|
||||
loc_vars = function(_, _, center)
|
||||
local function rounds(amount)
|
||||
return " round" .. ((math.abs(amount) > 1 or math.abs(amount) == 0) and "s" or "")
|
||||
end
|
||||
|
||||
local rounds_left = center.ability.rounds_left
|
||||
local sold = rounds_left - hunter[2]
|
||||
|
||||
return {vars = {
|
||||
rounds_left .. rounds(rounds_left) .. (rounds_left <= 0 and "...?" or ""),
|
||||
sold <= 0 and "" or " after " .. sold .. rounds(sold),
|
||||
sold <= 0 and " into" or "",
|
||||
sold <= 0 and "" or "into ",
|
||||
}}
|
||||
end,
|
||||
update = function(_, card, _)
|
||||
if card.added_to_deck and card.children.center and card.children.floating_sprite then
|
||||
for k, v in ipairs(hunter) do
|
||||
if card.ability.rounds_left <= v then
|
||||
card.children.center:set_sprite_pos({x = 0, y = k - 1})
|
||||
card.children.floating_sprite:set_sprite_pos({x = 1, y = k - 1})
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
local function spawn_rot()
|
||||
card:flip()
|
||||
card:juice_up(2, 0.8)
|
||||
Jane.card_status_text(card, "Dead!", nil, 0.05 * card.T.h, G.C.BLACK, 2, 0, 0, nil, "bm", "jane_gore6")
|
||||
|
||||
Jane.q(function()
|
||||
local card2 = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_jane_rot", "hunter_rot_death")
|
||||
card2:add_to_deck()
|
||||
G.jokers:emplace(card2)
|
||||
card:set_eternal(nil)
|
||||
card2:set_eternal(true)
|
||||
play_sound("jane_gore5")
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
local function die()
|
||||
spawn_rot()
|
||||
|
||||
Jane.q(function()
|
||||
Jane.empowered()
|
||||
return true
|
||||
end, 0.1)
|
||||
|
||||
Jane.q(function()
|
||||
card:start_dissolve()
|
||||
return true
|
||||
end, 1)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if context.blueprint then
|
||||
return
|
||||
end
|
||||
|
||||
if context.selling_self and card.ability.rounds_left <= hunter[2] then
|
||||
spawn_rot()
|
||||
elseif not context.individual and not context.repetition and not context.retrigger_joker then
|
||||
if G.GAME.round_resets.hands <= 0 then
|
||||
G.GAME.round_resets.hands = 1
|
||||
end
|
||||
|
||||
if not card.hunter_prep then
|
||||
card.hunter_prep = true
|
||||
Jane.q(function()
|
||||
Jane.q(function()
|
||||
card.hunter_prep = nil
|
||||
if G.GAME.current_round.hands_left < G.GAME.round_resets.hands then
|
||||
card.ability.hands_replenished =
|
||||
(card.ability.hands_replenished or 0) +
|
||||
(G.GAME.round_resets.hands - G.GAME.current_round.hands_left)
|
||||
|
||||
ease_hands_played(G.GAME.round_resets.hands - G.GAME.current_round.hands_left)
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
if not context.end_of_round then
|
||||
return
|
||||
end
|
||||
|
||||
card.hunter_prep = nil
|
||||
card.ability.rounds_left = card.ability.rounds_left - 1
|
||||
local rl = card.ability.rounds_left
|
||||
Jane.card_status_text(card, tostring(card.ability.rounds_left), nil, nil, G.C.RED, nil, nil, nil, nil, nil, "generic1")
|
||||
|
||||
if rl > hunter[2] then
|
||||
card:juice_up(0.6, 0.1)
|
||||
elseif rl > hunter[3] then
|
||||
if rl == hunter[2] then
|
||||
Jane.play_sound("jane_gore1")
|
||||
end
|
||||
|
||||
card:juice_up(0.6, 0.1)
|
||||
elseif rl > hunter[4] then
|
||||
if rl == hunter[3] then
|
||||
Jane.play_sound("jane_gore3")
|
||||
end
|
||||
|
||||
card:juice_up(0.6, 0.1)
|
||||
elseif rl > hunter[5] then
|
||||
if rl == hunter[4] then
|
||||
Jane.play_sound("jane_gore8")
|
||||
end
|
||||
|
||||
card:juice_up(0.6, 0.1)
|
||||
Jane.play_sound("jane_warning_heartbeat")
|
||||
elseif rl > 0 then
|
||||
if rl == hunter[5] then
|
||||
Jane.play_sound("jane_gore4")
|
||||
end
|
||||
|
||||
card:juice_up(1.8, 0.3)
|
||||
Jane.play_sound("jane_warning_heartbeat")
|
||||
else
|
||||
card:juice_up(2, 0.8)
|
||||
Jane.play_sound("jane_warning_heartbeat")
|
||||
G.E_MANAGER:add_event(Event({trigger = "after", func = die}))
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "gourmand",
|
||||
atlas = "janegourmand",
|
||||
loc_txt = {
|
||||
name = "The Gourmand",
|
||||
text = {
|
||||
"Values on {C:attention}consumables",
|
||||
"are {C:attention}multiplied{} by {C:attention}#1#",
|
||||
"when they are created",
|
||||
"{C:inactive}(If possible)",
|
||||
}
|
||||
},
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {center.ability.modifier}}
|
||||
end,
|
||||
config = {modifier = 2},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 50,
|
||||
rarity = 4,
|
||||
}
|
||||
|
||||
local orig_set_ability = Card.set_ability
|
||||
|
||||
---@diagnostic disable-next-line: duplicate-set-field
|
||||
function Card:set_ability(center, initial, delay_sprites)
|
||||
orig_set_ability(self, center, initial, delay_sprites)
|
||||
|
||||
if next(SMODS.find_card("j_jane_gourmand")) and
|
||||
self.gc and
|
||||
self:gc().key ~= "c_base" and
|
||||
string.sub(self:gc().key, 1, 2) == "c_" then
|
||||
local mod = 1
|
||||
|
||||
for _, v in pairs(SMODS.find_card("j_jane_gourmand")) do
|
||||
mod = mod * v.ability.modifier
|
||||
end
|
||||
|
||||
Jane.misprintize(self, {min = mod, max = mod}, nil, true)
|
||||
end
|
||||
end
|
||||
|
||||
SMODS.Joker {
|
||||
key = "rivulet",
|
||||
atlas = "janerivulet",
|
||||
loc_txt = {
|
||||
name = "The Rivulet",
|
||||
text = {
|
||||
"Non-{C:dark_edition}editioned{} cards are",
|
||||
"{C:attention}given a random {C:dark_edition}Edition",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 20,
|
||||
rarity = 4,
|
||||
}
|
||||
|
||||
local orig_draw = Card.draw
|
||||
|
||||
function Card:draw(layer)
|
||||
local cen = self.gc and self:gc()
|
||||
|
||||
if self.children.floating_sprite and cen.sinis then
|
||||
if Jane.sinister and not self.shows_sinister then
|
||||
self.shows_sinister = true
|
||||
self.children.floating_sprite:set_sprite_pos(cen.sinis)
|
||||
elseif not Jane.sinister and self.shows_sinister then
|
||||
self.shows_sinister = nil
|
||||
self.children.floating_sprite:set_sprite_pos(cen.soul_pos)
|
||||
end
|
||||
|
||||
if self.shows_sinister then
|
||||
self:juice_up(0, math.random())
|
||||
end
|
||||
end
|
||||
|
||||
if cen and
|
||||
self.facing == "front" and
|
||||
self.config and
|
||||
(self.added_to_deck or
|
||||
(self.area and self.area == G.hand)) and not
|
||||
self.edition and
|
||||
(self.area == G.consumeables or cen.set ~= "Booster") and
|
||||
next(SMODS.find_card("j_jane_rivulet")) then
|
||||
self:set_edition({[G.P_CENTER_POOLS.Edition[pseudorandom("rivulet_edition", 1, #G.P_CENTER_POOLS.Edition)].key:sub(3)] = true}, true)
|
||||
end
|
||||
|
||||
orig_draw(self, layer)
|
||||
end
|
||||
|
||||
local attunement = Cryptid and 1.001 or 1.1
|
||||
|
||||
SMODS.Joker {
|
||||
key = "saint",
|
||||
atlas = "janesaint",
|
||||
loc_txt = {
|
||||
name = "The Saint{C:jane_RGB}#1#",
|
||||
text = {
|
||||
"{C:spectral}Gateway {}will {C:attention}not destroy Jokers",
|
||||
"{C:jane_RGB}#2#{}#3#{X:black,C:jane_RGB,s:1.5}#4#{C:spectral}#5#{C:chips}#6#{}#7#{C:mult}#8#",
|
||||
"{C:inactive,s:1.25}#9#{C:attention,s:1.25}#10#{C:inactive,s:1.25}#11#{C:inactive}#12#"
|
||||
}
|
||||
},
|
||||
config = {extra = {karma = 0, max_karma = Cryptid and 10 or 3}},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 20,
|
||||
rarity = 4,
|
||||
blueprint_compat = true,
|
||||
loc_vars = function(_, _, card)
|
||||
local extra = card.ability.extra
|
||||
local karma = extra.karma
|
||||
local max_karma = extra.max_karma
|
||||
local attuned = karma >= max_karma
|
||||
|
||||
return {vars = {
|
||||
attuned and " (Attuned)" or "",
|
||||
attuned and "" or "Attune ",
|
||||
attuned and "" or "after using ",
|
||||
attuned and (Cryptid and "^^" or "^") .. attunement or max_karma,
|
||||
attuned and "" or (Cryptid and " Gateways" or " Souls"),
|
||||
attuned and " Chips " or "",
|
||||
attuned and "& " or "",
|
||||
attuned and "Mult" or "",
|
||||
attuned and "" or "[",
|
||||
attuned and "" or karma,
|
||||
attuned and "" or " / " .. max_karma .. "]",
|
||||
attuned and "(Cannot be debuffed)" or "",
|
||||
}}
|
||||
end,
|
||||
update = function(_, card, _)
|
||||
if card.added_to_deck and card.children.center and card.children.floating_sprite then
|
||||
local extra = card.ability.extra
|
||||
local karma = extra.karma
|
||||
local max_karma = extra.max_karma
|
||||
local is_attuned = karma >= max_karma
|
||||
card.children.floating_sprite:set_sprite_pos({x = is_attuned and 2 or 1, y = 0})
|
||||
end
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
local extra = card.ability.extra
|
||||
local max_karma = extra.max_karma
|
||||
|
||||
if extra.karma >= max_karma then
|
||||
if card.ability then
|
||||
card.ability.perishable = false
|
||||
card.ability.perish_tally = 1e9
|
||||
end
|
||||
|
||||
card.debuff = false
|
||||
|
||||
if not context.joker_main then
|
||||
return
|
||||
end
|
||||
|
||||
return {
|
||||
card = card,
|
||||
colour = G.C.jane_RGB,
|
||||
sound = "talisman_eeechip",
|
||||
message = "^^" .. attunement .. " Chips & Mult",
|
||||
[Cryptid and "EEchip_mod" or "Echip_mod"] = attunement,
|
||||
[Cryptid and "EEmult_mod" or "Emult_mod"] = attunement,
|
||||
}, true
|
||||
end
|
||||
|
||||
if not (not context.blueprint and
|
||||
(not context.retrigger_joker_check and not context.retrigger_joker) and
|
||||
context.using_consumeable and
|
||||
context.consumeable and
|
||||
context.consumeable:gc().key == Cryptid and "c_cry_gateway" or "c_soul") then
|
||||
return
|
||||
end
|
||||
|
||||
local quota = context.consumeable:getEvalQty()
|
||||
extra.karma = extra.karma + quota
|
||||
|
||||
card_eval_status_text(
|
||||
card,
|
||||
"extra",
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
{message = "+" .. quota .. " Karma", colour = G.C.PALE_GREEN}
|
||||
)
|
||||
|
||||
card_eval_status_text(
|
||||
card,
|
||||
"extra",
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
{message = extra.karma .. " / " .. max_karma, colour = G.C.GREEN}
|
||||
)
|
||||
|
||||
if extra.karma < max_karma then
|
||||
return
|
||||
end
|
||||
|
||||
Jane.card_status_text(
|
||||
card,
|
||||
"!!!",
|
||||
nil,
|
||||
0.05 * card.T.h,
|
||||
G.C.DARK_EDITION,
|
||||
0.6,
|
||||
0.6,
|
||||
2,
|
||||
2,
|
||||
"bm",
|
||||
"jane_enlightened"
|
||||
)
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.1,
|
||||
func = function()
|
||||
card:flip()
|
||||
play_sound("card1")
|
||||
return true
|
||||
end
|
||||
}))
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 1,
|
||||
func = function()
|
||||
card:flip()
|
||||
card:juice_up(1, 1)
|
||||
play_sound("card1")
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "artificer",
|
||||
atlas = "janeartificer",
|
||||
loc_txt = {
|
||||
name = "The Artificer",
|
||||
text = {
|
||||
"Grants the {C:green}ability{} to {C:red}destroy",
|
||||
"selected {C:attention}playing cards",
|
||||
}
|
||||
},
|
||||
misc = {
|
||||
text = {"Impervious", "Cannot be debuffed"},
|
||||
col = G.C.JOKER_GREY,
|
||||
tcol = G.C.FILTER
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 50,
|
||||
rarity = exotic,
|
||||
Bakery_use_button_text = function(_, _) return "DESTROY" end,
|
||||
Bakery_can_use = function(_, _)
|
||||
return Jane.canuse() and next(G.hand.highlighted)
|
||||
end,
|
||||
Bakery_use_joker = function(_, _)
|
||||
for _, v in pairs(G.hand.highlighted) do
|
||||
v:start_dissolve()
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
SMODS.Joker {
|
||||
key = "rot",
|
||||
atlas = "janerot",
|
||||
loc_txt = {
|
||||
name = "The Rot",
|
||||
text = {
|
||||
"Clogs up your Joker slots",
|
||||
"{C:attention}Duplicates itself{} at the",
|
||||
"end of {C:attention}every ante",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
soul_pos = {x = 1, y = 0},
|
||||
cost = 0,
|
||||
rarity = "jane_junk",
|
||||
in_pool = function (_, _)
|
||||
return not not next(SMODS.find_card("j_jane_rot"))
|
||||
end,
|
||||
calculate = function(_, card, context)
|
||||
local function has_room()
|
||||
return G.jokers.config.card_count < G.jokers.config.card_limit
|
||||
end
|
||||
|
||||
local function is_end_of_ante()
|
||||
return not context.individual and not
|
||||
context.repetition and not
|
||||
card.debuff and
|
||||
context.end_of_round and not
|
||||
context.blueprint and
|
||||
G.GAME.blind.boss and not
|
||||
(G.GAME.blind.config and G.GAME.blind.config.bonus)
|
||||
end
|
||||
|
||||
local function spawn()
|
||||
local text = context.selling_self and "..!" or "..."
|
||||
local rot = copy_card(card)
|
||||
rot.cloned = true
|
||||
rot:add_to_deck()
|
||||
G.jokers:emplace(rot)
|
||||
Jane.card_status_text(rot, text, nil, 0.05 * card.T.h, G.C.BLACK, 3, 0, 0, nil, "bm")
|
||||
end
|
||||
|
||||
if has_room() and not card.cloned and is_end_of_ante() then
|
||||
spawn()
|
||||
else
|
||||
card.cloned = false
|
||||
end
|
||||
end
|
||||
}
|
||||
354
src/spectral.lua
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
SMODS.Atlas {
|
||||
key = "janertarots",
|
||||
px = 71,
|
||||
py = 95,
|
||||
path = Jane.config.texture_pack .. "/c_jane_reversetarots.png"
|
||||
}
|
||||
|
||||
SMODS.Sound({key = "draw", path = "draw.ogg"})
|
||||
|
||||
local function conjure(card, number)
|
||||
for _ = 1, math.min(
|
||||
math.ceil(card.ability.extra.spectrals) * number,
|
||||
G.consumeables.config.card_limit - #G.consumeables.cards
|
||||
) do
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = "after",
|
||||
delay = 0.4,
|
||||
func = function()
|
||||
if G.consumeables.config.card_limit <= #G.consumeables.cards then
|
||||
return true
|
||||
end
|
||||
|
||||
play_sound("jane_draw")
|
||||
local spectral = create_card("Spectral", G.consumeables, nil, nil, nil, nil, nil, "pri")
|
||||
spectral:add_to_deck()
|
||||
G.consumeables:emplace(spectral)
|
||||
card:juice_up(0.3, 0.5)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
local function createfulldeck(enhancement, edition, amount, emplacement)
|
||||
local cards = {}
|
||||
|
||||
for _, v in pairs(G.P_CARDS) do
|
||||
for i = 1, (amount or 1) do
|
||||
G.E_MANAGER:add_event(Event({
|
||||
delay = 0.1,
|
||||
func = function()
|
||||
cards[i] = true
|
||||
G.playing_card = (G.playing_card and G.playing_card + 1) or 1
|
||||
|
||||
local card = Card(
|
||||
G.play.T.x + G.play.T.w / 2,
|
||||
G.play.T.y, G.CARD_W, G.CARD_H,
|
||||
v,
|
||||
enhancement or G.P_CENTERS.c_base,
|
||||
{playing_card = G.playing_card}
|
||||
)
|
||||
|
||||
if edition then
|
||||
card:set_edition(type(edition) == "table" and edition or {[edition] = true}, true, true)
|
||||
end
|
||||
|
||||
play_sound("card1")
|
||||
table.insert(G.playing_cards, card)
|
||||
card:add_to_deck()
|
||||
|
||||
if emplacement then
|
||||
emplacement:emplace(card)
|
||||
else
|
||||
G.deck:emplace(card)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
end
|
||||
|
||||
Jane.q(function()
|
||||
if next(cards) then
|
||||
playing_card_joker_effects(cards)
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
Jane.q(function()
|
||||
cards = nil
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
local function randomize(targets, noanim)
|
||||
if #targets <= 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if noanim then
|
||||
for i=1, #targets do
|
||||
local card = targets[i]
|
||||
card:set_base(pseudorandom_element(G.P_CARDS))
|
||||
|
||||
card:set_ability(
|
||||
pseudorandom(pseudoseed("chancetime")) > 1 / (#G.P_CENTER_POOLS["Enhanced"] + 1) and
|
||||
pseudorandom_element(G.P_CENTER_POOLS["Enhanced"], pseudoseed("spectral_chance")) or
|
||||
G.P_CENTERS["c_base"]
|
||||
)
|
||||
|
||||
local edition_rate = 2
|
||||
card:set_edition(poll_edition("standard_edition" .. G.GAME.round_resets.ante, edition_rate, true), true, true)
|
||||
local seal_rate = 10
|
||||
local seal_poll = pseudorandom(pseudoseed("stdseal" .. G.GAME.round_resets.ante))
|
||||
|
||||
if seal_poll > 1 - 0.02 * seal_rate then
|
||||
local seal_type = pseudorandom(pseudoseed("stdsealtype" .. G.GAME.round_resets.ante))
|
||||
local seal_list = {}
|
||||
|
||||
for k, _ in pairs(G.P_SEALS) do
|
||||
table.insert(seal_list, k)
|
||||
end
|
||||
|
||||
seal_type = math.floor(seal_type * #seal_list)
|
||||
card:set_seal(seal_list[seal_type], true, true)
|
||||
else
|
||||
card:set_seal(nil, true, true)
|
||||
end
|
||||
|
||||
card:juice_up(0.3, 0.3)
|
||||
end
|
||||
else
|
||||
for i = 1, #targets do
|
||||
local percent = 1.15 - (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = "after",
|
||||
delay = 0.15,
|
||||
func = function()
|
||||
targets[i]:flip()
|
||||
play_sound("card1", percent)
|
||||
targets[i]:juice_up(0.3, 0.3)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
|
||||
delay(0.2)
|
||||
|
||||
for i = 1, #targets do
|
||||
local percent = 0.85 + (i - 0.999) / (#G.hand.cards - 0.998) * 0.3
|
||||
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = "after",
|
||||
delay = 0.1,
|
||||
func = function()
|
||||
local card = targets[i]
|
||||
card:set_base(pseudorandom_element(G.P_CARDS))
|
||||
card:set_ability(pseudorandom_element(G.P_CENTER_POOLS["Enhanced"]))
|
||||
|
||||
local edition_rate = 2
|
||||
card:set_edition(poll_edition("standard_edition" .. G.GAME.round_resets.ante, edition_rate, true))
|
||||
local seal_rate = 10
|
||||
local seal_poll = pseudorandom(pseudoseed("stdseal" .. G.GAME.round_resets.ante))
|
||||
|
||||
if seal_poll > 1 - 0.02 * seal_rate then
|
||||
local seal_type = pseudorandom(pseudoseed("stdsealtype" .. G.GAME.round_resets.ante))
|
||||
local seal_list = {}
|
||||
|
||||
for k, _ in pairs(G.P_SEALS) do
|
||||
table.insert(seal_list, k)
|
||||
end
|
||||
|
||||
seal_type = math.floor(seal_type * #seal_list)
|
||||
card:set_seal(seal_list[seal_type])
|
||||
else
|
||||
card:set_seal()
|
||||
end
|
||||
|
||||
card:flip()
|
||||
play_sound("card3", percent, 0.6)
|
||||
card:juice_up(0.3, 0.3)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SMODS.Consumable {
|
||||
key = "obfuscation",
|
||||
atlas = "janeacc",
|
||||
set = "Spectral",
|
||||
loc_txt = {
|
||||
name = "Obfuscation",
|
||||
text = {
|
||||
"{C:green,E:1}Randomises{} all cards in hand",
|
||||
"{C:inactive}(Rank, seal, edition,",
|
||||
"{C:inactive}enhancement, and suit)",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 4},
|
||||
cost = 4,
|
||||
can_use = function(_, _)
|
||||
return Jane.canuse() and #((G.hand or {}).cards or {}) > 0
|
||||
end,
|
||||
use = function(_, card, _, _)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = "after",
|
||||
delay = 0.4,
|
||||
func = function()
|
||||
play_sound("tarot1")
|
||||
card:juice_up(0.3, 0.5)
|
||||
return true
|
||||
end
|
||||
}))
|
||||
|
||||
randomize(G.hand.cards)
|
||||
delay(0.5)
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Consumable {
|
||||
key = "conjure",
|
||||
set = "Spectral",
|
||||
atlas = "janeacc",
|
||||
loc_txt = {
|
||||
name = "Conjure",
|
||||
text = {
|
||||
"Creates {C:attention}#1#",
|
||||
"{C:spectral}Spectral{} cards",
|
||||
"{C:inactive}(Must have room)",
|
||||
}
|
||||
},
|
||||
config = {extra = {spectrals = 2}},
|
||||
pos = {x = 2, y = 4},
|
||||
cost = 4,
|
||||
loc_vars = function(self, info_queue, center)
|
||||
return {vars = {math.ceil(center.ability.extra.spectrals)}}
|
||||
end,
|
||||
can_use = Jane.canuse,
|
||||
use = function(_, card, _, _)
|
||||
conjure(card, 1)
|
||||
delay(0.6)
|
||||
end,
|
||||
bulk_use = function(_, card, _, _, number)
|
||||
conjure(card, number)
|
||||
delay(0.6)
|
||||
end
|
||||
}
|
||||
|
||||
SMODS.Consumable {
|
||||
key = "shadows",
|
||||
set = "Spectral",
|
||||
atlas = "janeacc",
|
||||
loc_txt = {
|
||||
name = "Shadows",
|
||||
text = {
|
||||
"Create {C:attention}#1#{} {C:green}random {C:dark_edition}Negative",
|
||||
"{C:attention}Perishable {C:attention}Jokers{}, set",
|
||||
"{C:money}sell value{} of {C:attention}all Jokers{} to {C:money}$0",
|
||||
}
|
||||
},
|
||||
config = {extra = {shadows = 2}},
|
||||
pos = {x = 3, y = 4},
|
||||
cost = 4,
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {((center.ability or {}).extra or {}).shadows or 2}}
|
||||
end,
|
||||
can_use = Jane.canuse,
|
||||
use = function(_, card, _, _)
|
||||
for _ = 1, card.ability.extra.shadows do
|
||||
local joker = create_card("Joker", G.jokers, nil, nil, nil, nil, nil, "phantom")
|
||||
joker:set_edition({negative = true})
|
||||
joker.ability.eternal = false
|
||||
joker.ability.perishable = true
|
||||
joker.ability.perish_tally = 5
|
||||
joker:add_to_deck()
|
||||
G.jokers:emplace(joker)
|
||||
end
|
||||
|
||||
delay(0.6)
|
||||
|
||||
for i = 1, #G.jokers.cards do
|
||||
G.jokers.cards[i].base_cost = 0
|
||||
G.jokers.cards[i].extra_cost = 0
|
||||
G.jokers.cards[i].cost = 0
|
||||
G.jokers.cards[i].sell_cost = 0
|
||||
G.jokers.cards[i].sell_cost_label = G.jokers.cards[i].facing == "back" and "?" or G.jokers.cards[i].sell_cost
|
||||
end
|
||||
end,
|
||||
bulk_use = function(_, card, _, _, number)
|
||||
for _ = 1, card.ability.extra.shadows * number do
|
||||
local joker = create_card("Joker", G.jokers, nil, nil, nil, nil, nil, "phantom")
|
||||
joker.no_forced_edition = true
|
||||
joker:set_edition({negative = true})
|
||||
joker.no_forced_edition = nil
|
||||
joker.ability.eternal = false
|
||||
joker.ability.perishable = true
|
||||
joker.ability.perish_tally = 5
|
||||
joker:add_to_deck()
|
||||
G.jokers:emplace(joker)
|
||||
end
|
||||
|
||||
delay(0.6)
|
||||
|
||||
for i = 1, #G.jokers.cards do
|
||||
G.jokers.cards[i].base_cost = 0
|
||||
G.jokers.cards[i].extra_cost = 0
|
||||
G.jokers.cards[i].cost = 0
|
||||
G.jokers.cards[i].sell_cost = 0
|
||||
G.jokers.cards[i].sell_cost_label = G.jokers.cards[i].facing == "back" and "?" or G.jokers.cards[i].sell_cost
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
SMODS.Consumable {
|
||||
key = "reverse_hanged_man",
|
||||
atlas = "janertarots",
|
||||
set = "Spectral",
|
||||
loc_txt = {
|
||||
name = "Zen",
|
||||
text = {
|
||||
"{C:attention}Reset{} your deck to",
|
||||
"a {C:attention}standard 52-card deck"
|
||||
}
|
||||
},
|
||||
config = {extra = {destruction = 0.5}},
|
||||
pos = {x = 7, y = 1},
|
||||
cost = 15,
|
||||
loc_vars = function(_, _, center)
|
||||
return {vars = {
|
||||
math.min(100, center.ability.extra.destruction * 100),
|
||||
math.ceil(#(G.playing_cards or {}) * center.ability.extra.destruction)
|
||||
}}
|
||||
end,
|
||||
can_use = Jane.canuse,
|
||||
use = function(_, _, _, _)
|
||||
Jane.q(function()
|
||||
for _, v in pairs(G.playing_cards) do
|
||||
v:start_dissolve()
|
||||
end
|
||||
|
||||
return true
|
||||
end)
|
||||
|
||||
local function realdelay(time, queue)
|
||||
G.E_MANAGER:add_event(Event({
|
||||
trigger = "after",
|
||||
timer = "REAL",
|
||||
delay = time or 1,
|
||||
func = function()
|
||||
return true
|
||||
end
|
||||
}), queue)
|
||||
end
|
||||
|
||||
realdelay(1)
|
||||
createfulldeck()
|
||||
end
|
||||
}
|
||||
63
src/tarot.lua
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
local blurbs = {
|
||||
"Hey! Pick me!",
|
||||
"You wouldn't say no to a free negative me, would you?",
|
||||
"Sometimes, an extra four mult goes a long way!",
|
||||
"I won't take up space, I promise!",
|
||||
"Don't ask how I ended up in a tarot!",
|
||||
"Hee-hee, hoo-hoo!",
|
||||
"Who knew even fortunes could be a circus act?",
|
||||
"Looks like the joke is on the crystal globe!",
|
||||
"It's a little cramped in this tarot...!",
|
||||
"Ouch, I think the joke is on me!",
|
||||
"Looks like the joke is on you!",
|
||||
"I'm not just a clown; I'm the whole circus!",
|
||||
"Seems a little suspicious for a jolly old fella like me to be in this card...",
|
||||
"I can't help if I'm still in this silly old card, break me out!",
|
||||
"Let me tell you, you'd love the show going on in this tarot!",
|
||||
"I'd give you more tickets to JimCon, but I'm fresh out.",
|
||||
"I've heard of a round buffoon that lives in a pretty funky town...",
|
||||
"I can't give four mult if I'm still in this card!",
|
||||
"I'm rooting for you! Even if it means I'll never get out of this card...",
|
||||
"Who knew I'd have access to a great show? That show being you!",
|
||||
"The stakes are only gonna rise here!",
|
||||
"Juggling is one of my favourite passtimes!",
|
||||
"I wonder what's the deal with pairs?",
|
||||
"You don't need to understand math to enjoy watching the digits climb!",
|
||||
"You should meet my friend Joseph; he's stuck in a Planet card!",
|
||||
"M!",
|
||||
}
|
||||
|
||||
SMODS.Consumable {
|
||||
key = "jokerinatarot",
|
||||
atlas = "janeacc",
|
||||
set = "Tarot",
|
||||
loc_txt = {
|
||||
name = "Joker-in-a-Tarot",
|
||||
text = {
|
||||
"Create a {C:dark_edition}Negative {C:attention}default Joker",
|
||||
"{C:inactive,E:1}#1#{}"
|
||||
}
|
||||
},
|
||||
loc_vars = function(_, _, _)
|
||||
return {vars = {blurbs[math.random(#blurbs)]}}
|
||||
end,
|
||||
pos = {x = 0, y = 1},
|
||||
cost = 3,
|
||||
can_use = Jane.canuse,
|
||||
use = function(_, _, _, _)
|
||||
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_joker", "jokerfromatarot")
|
||||
card:set_edition({negative = true}, true)
|
||||
card.cost = 1
|
||||
card.base_cost = 1
|
||||
card.sell_cost = 1
|
||||
card.extra_cost = 0
|
||||
card.sell_cost_label = card.facing == "back" and "?" or card.sell_cost
|
||||
card:add_to_deck()
|
||||
G.jokers:emplace(card)
|
||||
end,
|
||||
bulk_use = function(self, card, area, copier, number)
|
||||
for _ = 1, number do
|
||||
self:use(card, area, copier)
|
||||
end
|
||||
end
|
||||
}
|
||||
86
src/token.lua
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
SMODS.Atlas {
|
||||
key = "janetokens",
|
||||
px = 71,
|
||||
py = 95,
|
||||
path = Jane.config.texture_pack .. "/c_jane_tokens.png"
|
||||
}
|
||||
|
||||
SMODS.Sound({key = "e_gilded", path = "e_gilded.ogg"})
|
||||
|
||||
SMODS.ConsumableType {
|
||||
key = "jane_tokens",
|
||||
default = "c_jane_token_tag_standard",
|
||||
loc_txt = {
|
||||
collection = "Tokens",
|
||||
name = "Token"
|
||||
},
|
||||
shop_rate = 0,
|
||||
collection_rows = {6, 6},
|
||||
primary_colour = G.C.CHIPS,
|
||||
secondary_colour = G.C.VOUCHER,
|
||||
}
|
||||
|
||||
for _, v in pairs({
|
||||
{"tag_standard", "Standard", 0, 0, 3},
|
||||
{"tag_charm", "Charm", 1, 0, 5},
|
||||
{"tag_meteor", "Meteor", 2, 0, 5},
|
||||
{"tag_ethereal", "Ethereal", 3, 0, 5},
|
||||
{"tag_buffoon", "Buffoon", 4, 0, 8},
|
||||
{"tag_cry_bundle", "Bundle", 1, 1, 10},
|
||||
{"tag_uncommon", "Uncommon", 2, 1, 3},
|
||||
{"tag_rare", "Rare", 3, 1, 5},
|
||||
{"tag_cry_epic", "Epic", 4, 1, 8},
|
||||
{"tag_foil", "Foil", 1, 3, 3},
|
||||
{"tag_holo", "Holographic", 2, 3, 4},
|
||||
{"tag_polychrome", "Polychrome", 3, 3, 5},
|
||||
{"tag_negative", "Negative", 4, 3, 10},
|
||||
{"tag_investment", "Investment", 0, 3, 8},
|
||||
{"tag_voucher", "Voucher", 4, 5, 5},
|
||||
{"tag_handy", "Handy", 1, 5, 8},
|
||||
{"tag_garbage", "Garbage", 0, 5, 6},
|
||||
{"tag_coupon", "Coupon", 4, 4, 10},
|
||||
{"tag_juggle", "Juggle", 2, 5, 2},
|
||||
{"tag_d_six", "Dice", 0, 4, 2},
|
||||
{"tag_top_up", "Top-up", 2, 4, 2},
|
||||
{"tag_skip", "Speed", 4, 2, 7},
|
||||
{"tag_economy", "Economy", 5, 2, 10},
|
||||
{"tag_double", "Double", 0, 2, 6},
|
||||
{"tag_cry_triple", "Triple", 1, 2, 8},
|
||||
{"tag_cry_quadruple", "Quadruple", 2, 2, 10},
|
||||
{"tag_cry_quintuple", "Quintuple", 3, 2, 13},
|
||||
{"tag_cry_memory", "Memory", 5, 4, 8}
|
||||
}) do
|
||||
if Cryptid or v[1]:sub(1, 7) ~= "tag_cry" then
|
||||
SMODS.Consumable {
|
||||
key = "token_" .. v[1],
|
||||
set = "jane_tokens",
|
||||
atlas = "janetokens",
|
||||
loc_txt = {
|
||||
name = v[2] .. " Token",
|
||||
text = {
|
||||
"Use to create a",
|
||||
"{C:attention}" .. v[2] .. " Tag",
|
||||
},
|
||||
},
|
||||
pos = {x = v[3], y = v[4]},
|
||||
cost = v[5],
|
||||
can_stack = true,
|
||||
can_divide = true,
|
||||
can_use = Jane.canuse,
|
||||
in_pool = function (_, _)
|
||||
return G.GAME.used_vouchers.v_jane_token_voucher
|
||||
end,
|
||||
use = function(_, _, _, _)
|
||||
play_sound("jane_e_gilded", 1.25, 0.4)
|
||||
add_tag(Tag(v[1]))
|
||||
end,
|
||||
bulk_use = function(_, _, _, _, number)
|
||||
play_sound("jane_e_gilded", 1.25, 0.4)
|
||||
|
||||
for _ = 1, number do
|
||||
add_tag(Tag(v[1]))
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
23
src/voucher.lua
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
SMODS.Atlas {
|
||||
key = "janetokenvoucher",
|
||||
px = 71,
|
||||
py = 95,
|
||||
path = Jane.config.texture_pack .. "/v_jane_token_voucher.png"
|
||||
}
|
||||
|
||||
SMODS.Voucher {
|
||||
key = "token_voucher",
|
||||
atlas = "janetokenvoucher",
|
||||
loc_txt = {
|
||||
name = "Token Voucher",
|
||||
text = {
|
||||
"{C:attention}Tokens {}can appear",
|
||||
"in the shop",
|
||||
}
|
||||
},
|
||||
pos = {x = 0, y = 0},
|
||||
cost = 15,
|
||||
redeem = function (_, _)
|
||||
G.GAME['jane_tokens_rate'] = 1.5
|
||||
end
|
||||
}
|
||||