573 lines
17 KiB
Lua
573 lines
17 KiB
Lua
-- misprintize.lua - functions for card value randomization
|
|
|
|
--Redefine these here because they're always used
|
|
Cryptid.base_values = {}
|
|
|
|
Cryptid.misprintize_value_blacklist = {
|
|
perish_tally = false,
|
|
id = false,
|
|
suit_nominal = false,
|
|
base_nominal = false,
|
|
face_nominal = false,
|
|
qty = false,
|
|
h_x_chips = false,
|
|
d_size = false,
|
|
h_size = false,
|
|
selected_d6_face = false,
|
|
cry_hook_id = false,
|
|
colour = false,
|
|
suit_nominal_original = false,
|
|
times_played = false,
|
|
-- TARGET: Misprintize Value Blacklist (format: key = false, )
|
|
}
|
|
Cryptid.misprintize_bignum_blacklist = {
|
|
odds = false,
|
|
cry_prob = false,
|
|
--nominal = false,
|
|
}
|
|
|
|
function Cryptid.calculate_misprint(initial, min, max, grow_type, pow_level)
|
|
local big_initial = (type(initial) ~= "table" and to_big(initial)) or initial
|
|
local big_min = (type(min) ~= "table" and to_big(min)) or min
|
|
local big_max = (type(max) ~= "table" and to_big(max)) or max
|
|
|
|
local grow = Cryptid.log_random(pseudoseed("cry_misprint" .. G.GAME.round_resets.ante), big_min, big_max)
|
|
|
|
local calc = big_initial
|
|
if not grow_type then
|
|
calc = calc * grow
|
|
elseif grow_type == "+" then
|
|
calc = calc + grow
|
|
elseif grow_type == "-" then
|
|
calc = calc - grow
|
|
elseif grow_type == "/" then
|
|
calc = calc / grow
|
|
elseif grow_type == "^" then
|
|
pow_level = pow_level or 1
|
|
if pow_level == 1 then
|
|
calc = calc ^ grow
|
|
else
|
|
local function hyper(level, base, height)
|
|
local big_base = (type(base) ~= "table" and to_big(base)) or base
|
|
local big_height = (type(height) ~= "table" and to_big(height)) or height
|
|
|
|
if height == 1 then
|
|
return big_base
|
|
elseif level == 1 then
|
|
return big_base ^ big_height
|
|
else
|
|
local inner = hyper(level, base, height - 1)
|
|
return hyper(level - 1, base, inner)
|
|
end
|
|
end
|
|
|
|
calc = hyper(pow_level, calc, grow)
|
|
end
|
|
end
|
|
|
|
if calc > to_big(-1e100) and calc < to_big(1e100) then
|
|
calc = to_number(calc)
|
|
end
|
|
|
|
return calc
|
|
end
|
|
|
|
function Cryptid.misprintize_tbl(name, ref_tbl, ref_value, clear, override, stack, big, grow_type, pow_level)
|
|
local prob_max = 1e69 -- funny number
|
|
local max_slots = 100
|
|
local max_booster_slots = 25
|
|
|
|
local function num_too_big(initial, min, max, limit)
|
|
return (
|
|
to_big(initial) > to_big(limit)
|
|
or (min and to_big(initial) * min > to_big(limit))
|
|
or (max and to_big(initial) * max > to_big(limit))
|
|
)
|
|
end
|
|
|
|
if name and ref_tbl and ref_value then
|
|
local tbl = Cryptid.deep_copy(ref_tbl[ref_value])
|
|
|
|
local function can_misprintize_value(k, v)
|
|
if
|
|
(k == "x_mult" and v == 1 and not tbl.override_x_mult_check)
|
|
or (k == "x_chips" and v == 1 and not tbl.override_x_chips_check)
|
|
then
|
|
return false
|
|
end
|
|
for key, val in pairs(Cryptid.misprintize_value_blacklist) do
|
|
if tostring(k) == tostring(key) then
|
|
return val
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
for k, v in pairs(tbl) do
|
|
if (type(tbl[k]) ~= "table") or is_number(tbl[k]) then
|
|
if is_number(tbl[k]) and can_misprintize_value(k, tbl[k]) then
|
|
if not Cryptid.base_values[name] then
|
|
Cryptid.base_values[name] = {}
|
|
end
|
|
if not Cryptid.base_values[name][k .. ref_value] then
|
|
Cryptid.base_values[name][k .. ref_value] = tbl[k]
|
|
end
|
|
local initial = (stack and tbl[k] or Cryptid.base_values[name][k .. ref_value])
|
|
local min = override and override.min or G.GAME.modifiers.cry_misprint_min
|
|
local max = override and override.max or G.GAME.modifiers.cry_misprint_max
|
|
|
|
if
|
|
(
|
|
k == "cry_prob"
|
|
-- Hack for vanilla jokers that use the extra field to describe their odds
|
|
or (
|
|
(
|
|
name == "j_8_ball"
|
|
or name == "j_business"
|
|
or name == "j_space"
|
|
or name == "j_hallucination"
|
|
) and k == "extra"
|
|
)
|
|
) and num_too_big(initial, min, max, prob_max)
|
|
then
|
|
initial = Cryptid.base_values[name][k .. ref_value] * prob_max
|
|
min = 1
|
|
max = 1
|
|
end
|
|
|
|
tbl[k] = Cryptid.sanity_check(
|
|
clear and Cryptid.base_values[name][k .. ref_value]
|
|
or cry_format(Cryptid.calculate_misprint(initial, min, max, grow_type, pow_level), "%.2g"),
|
|
big
|
|
)
|
|
end
|
|
elseif not (k == "immutable") and not (k == "colour") then
|
|
for _k, _v in pairs(tbl[k]) do
|
|
if is_number(tbl[k][_k]) and can_misprintize_value(_k, tbl[k][_k]) then
|
|
if not Cryptid.base_values[name] then
|
|
Cryptid.base_values[name] = {}
|
|
end
|
|
if not Cryptid.base_values[name][_k .. k] then
|
|
if
|
|
G.P_CENTERS[name]
|
|
and type(G.P_CENTERS[name].config[k]) == "table"
|
|
and G.P_CENTERS[name].config[k][_k]
|
|
then
|
|
Cryptid.base_values[name][_k .. k] = G.P_CENTERS[name].config[k][_k]
|
|
else
|
|
Cryptid.base_values[name][_k .. k] = tbl[k][_k]
|
|
end
|
|
end
|
|
|
|
local initial = (stack and tbl[k][_k] or Cryptid.base_values[name][_k .. k])
|
|
local min = override and override.min or G.GAME.modifiers.cry_misprint_min
|
|
local max = override and override.max or G.GAME.modifiers.cry_misprint_max
|
|
|
|
if (_k == "odds") and num_too_big(initial, min, max, prob_max) then
|
|
initial = Cryptid.base_values[name][_k .. k] * prob_max
|
|
min = 1
|
|
max = 1
|
|
end
|
|
|
|
if
|
|
(_k == "slots" and (name == "j_cry_tenebris" or name == "j_cry_negative"))
|
|
and num_too_big(initial, min, max, max_slots)
|
|
then
|
|
initial = max_slots
|
|
min = 1
|
|
max = 1
|
|
end
|
|
|
|
if
|
|
(_k == "booster_slots" and (name == "j_cry_booster"))
|
|
and num_too_big(initial, min, max, max_booster_slots)
|
|
then
|
|
initial = max_booster_slots
|
|
min = 1
|
|
max = 1
|
|
end
|
|
|
|
tbl[k][_k] = Cryptid.sanity_check(
|
|
clear and Cryptid.base_values[name][_k .. k]
|
|
or cry_format(
|
|
Cryptid.calculate_misprint(initial, min, max, grow_type, pow_level),
|
|
"%.2g"
|
|
),
|
|
big
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
ref_tbl[ref_value] = tbl
|
|
end
|
|
end
|
|
function Cryptid.misprintize_val(val, override, big, grow_type, pow_level)
|
|
if is_number(val) then
|
|
val = Cryptid.sanity_check(
|
|
cry_format(
|
|
Cryptid.calculate_misprint(
|
|
val,
|
|
override and override.min or G.GAME.modifiers.cry_misprint_min,
|
|
override and override.max or G.GAME.modifiers.cry_misprint_max,
|
|
grow_type,
|
|
pow_level
|
|
),
|
|
"%.2g"
|
|
),
|
|
big
|
|
)
|
|
end
|
|
return val
|
|
end
|
|
function Cryptid.sanity_check(val, is_big)
|
|
if is_big then
|
|
if not val or type(val) == "number" and (val ~= val or val > 1e300 or val < -1e300) then
|
|
val = 1e300
|
|
end
|
|
if type(val) == "table" then
|
|
return val
|
|
end
|
|
if val > 1e100 or val < -1e100 then
|
|
return to_big(val)
|
|
end
|
|
end
|
|
if not val or type(val) == "number" and (val ~= val or val > 1e300 or val < -1e300) then
|
|
return 1e300
|
|
end
|
|
if type(val) == "table" then
|
|
if val > to_big(1e300) then
|
|
return 1e300
|
|
end
|
|
if val < to_big(-1e300) then
|
|
return -1e300
|
|
end
|
|
return to_number(val)
|
|
end
|
|
return val
|
|
end
|
|
function Cryptid.misprintize(card, override, force_reset, stack, grow_type, pow_level)
|
|
local clamps = card.config.center.misprintize_caps or {}
|
|
if Card.no(card, "immutable", true) then
|
|
force_reset = true
|
|
end
|
|
--infinifusion compat
|
|
if card.infinifusion then
|
|
if card.config.center == card.infinifusion_center or card.config.center.key == "j_infus_fused" then
|
|
calculate_infinifusion(card, nil, function(i)
|
|
Cryptid.misprintize(card, override, force_reset, stack, grow_type, pow_level)
|
|
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 Card.no(card, "immutable", true)
|
|
then
|
|
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
|
|
Cryptid.misprintize_tbl(
|
|
card.config.center_key,
|
|
card,
|
|
"ability",
|
|
nil,
|
|
override,
|
|
stack,
|
|
Cryptid.is_card_big(card),
|
|
grow_type,
|
|
pow_level
|
|
)
|
|
if card.base then
|
|
Cryptid.misprintize_tbl(
|
|
card.config.card_key,
|
|
card,
|
|
"base",
|
|
nil,
|
|
override,
|
|
stack,
|
|
Cryptid.is_card_big(card),
|
|
grow_type,
|
|
pow_level
|
|
)
|
|
end
|
|
end
|
|
if G.GAME.modifiers.cry_misprint_min then
|
|
--card.cost = cry_format(card.cost / Cryptid.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),"%.2f")
|
|
card.misprint_cost_fac = 1
|
|
/ Cryptid.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
|
|
Cryptid.misprintize_tbl(
|
|
card.config.center_key,
|
|
card,
|
|
"ability",
|
|
true,
|
|
nil,
|
|
nil,
|
|
Cryptid.is_card_big(card),
|
|
grow_type,
|
|
pow_level
|
|
)
|
|
end
|
|
if clamps then
|
|
for i, v in pairs(clamps) do
|
|
if type(v) == "table" and not v.tetrate then
|
|
for i2, v2 in pairs(v) do
|
|
if to_big(card.ability[i][i2]) > to_big(v2) then
|
|
card.ability[i][i2] = Cryptid.sanity_check(v2, Cryptid.is_card_big(card))
|
|
if
|
|
to_big(card.ability[i][i2]) > to_big(-1e100)
|
|
or to_big(card.ability[i][i2]) < to_big(1e100)
|
|
then
|
|
card.ability[i][i2] = to_number(card.ability[i][i2])
|
|
end
|
|
end
|
|
end
|
|
elseif (type(v) == "table" and v.tetrate) or type(v) == "number" then
|
|
if to_big(card.ability[i]) > to_big(v) then
|
|
card.ability[i] = Cryptid.sanity_check(v, Cryptid.is_card_big(card))
|
|
if to_big(card.ability[i]) > to_big(-1e100) or to_big(card.ability[i]) < to_big(1e100) then
|
|
card.ability[i] = to_number(card.ability[i])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if card.ability.consumeable then
|
|
for k, v in pairs(card.ability.consumeable) do
|
|
card.ability.consumeable[k] = Cryptid.deep_copy(card.ability[k])
|
|
end
|
|
end
|
|
end
|
|
function Cryptid.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 cry_format(number, str)
|
|
if math.abs(to_big(number)) >= to_big(1e300) then
|
|
return number
|
|
end
|
|
return tonumber(str:format((Big and to_number(to_big(number)) or number)))
|
|
end
|
|
--use ID to work with glitched/misprint
|
|
function Card:get_nominal(mod)
|
|
local mult = 1
|
|
local rank_mult = 1
|
|
if mod == "suit" then
|
|
mult = 1000000
|
|
end
|
|
if self.ability.effect == "Stone Card" or (self.config.center.no_suit and self.config.center.no_rank) then
|
|
mult = -10000
|
|
elseif self.config.center.no_suit then
|
|
mult = 0
|
|
elseif self.config.center.no_rank then
|
|
rank_mult = 0
|
|
end
|
|
return 10 * (self.base.id or 0.1) * rank_mult
|
|
+ self.base.suit_nominal * mult
|
|
+ (self.base.suit_nominal_original or 0) * 0.0001 * mult
|
|
+ 10 * self.base.face_nominal * rank_mult
|
|
+ 0.000001 * self.unique_val
|
|
end
|
|
|
|
function Cryptid.manipulate(card, args)
|
|
if not Card.no(card, "immutable", true) or (args and args.bypass_checks) then
|
|
if not args then
|
|
return Cryptid.manipulate(card, {
|
|
min = (G.GAME.modifiers.cry_misprint_min or 1) * (G.GAME.modifiers.cry_jkr_misprint_mod or 1),
|
|
max = (G.GAME.modifiers.cry_misprint_max or 1) * (G.GAME.modifiers.cry_jkr_misprint_mod or 1),
|
|
type = "X",
|
|
dont_stack = true,
|
|
no_deck_effects = true,
|
|
})
|
|
else
|
|
local func = function(card)
|
|
if not args.type then
|
|
args.type = "X"
|
|
end
|
|
--hardcoded whatever
|
|
if card.config.center.set == "Booster" then
|
|
args.big = false
|
|
end
|
|
local caps = card.config.center.misprintize_caps or {}
|
|
if card.infinifusion then
|
|
if card.config.center == card.infinifusion_center or card.config.center.key == "j_infus_fused" then
|
|
calculate_infinifusion(card, nil, function(i)
|
|
Cryptid.manipulate(card, args)
|
|
end)
|
|
end
|
|
end
|
|
Cryptid.manipulate_table(card, card, "ability", args)
|
|
if card.base then
|
|
Cryptid.manipulate_table(card, card, "base", args)
|
|
end
|
|
if G.GAME.modifiers.cry_misprint_min then
|
|
--card.cost = cry_format(card.cost / Cryptid.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),"%.2f")
|
|
card.misprint_cost_fac = 1
|
|
/ Cryptid.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
|
|
if caps then
|
|
for i, v in pairs(caps) do
|
|
if type(v) == "table" and not v.tetrate then
|
|
for i2, v2 in pairs(v) do
|
|
if to_big(card.ability[i][i2]) > to_big(v2) then
|
|
card.ability[i][i2] = Cryptid.sanity_check(v2, Cryptid.is_card_big(card))
|
|
end
|
|
end
|
|
elseif (type(v) == "table" and v.tetrate) or type(v) == "number" then
|
|
if to_big(card.ability[i]) > to_big(v) then
|
|
card.ability[i] = Cryptid.sanity_check(v, Cryptid.is_card_big(card))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local config = copy_table(card.config.center.config)
|
|
if not Cryptid.base_values[card.config.center.key] then
|
|
Cryptid.base_values[card.config.center.key] = {}
|
|
for i, v in pairs(config) do
|
|
if (type(v) == "table" and v.tetrate) or type(v) == "number" and to_big(v) ~= to_big(0) then
|
|
Cryptid.base_values[card.config.center.key][i .. "ability"] = v
|
|
elseif type(v) == "table" then
|
|
for i2, v2 in pairs(v) do
|
|
Cryptid.base_values[card.config.center.key][i2 .. i] = v2
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not args.bypass_checks and not args.no_deck_effects then
|
|
Cryptid.with_deck_effects(card, func)
|
|
else
|
|
func(card)
|
|
end
|
|
if card.ability.consumeable then
|
|
for k, v in pairs(card.ability.consumeable) do
|
|
card.ability.consumeable[k] = Cryptid.deep_copy(card.ability[k])
|
|
end
|
|
end
|
|
--ew ew ew ew
|
|
G.P_CENTERS[card.config.center.key].config = config
|
|
end
|
|
return true
|
|
end
|
|
end
|
|
|
|
function Cryptid.manipulate_table(card, ref_table, ref_value, args, tblkey)
|
|
if ref_value == "consumeable" then
|
|
return
|
|
end
|
|
for i, v in pairs(ref_table[ref_value]) do
|
|
if
|
|
(type(v) == "number" or (type(v) == "table" and v.tetrate))
|
|
and Cryptid.misprintize_value_blacklist[i] ~= false
|
|
then
|
|
local num = v
|
|
if args.dont_stack then
|
|
if
|
|
Cryptid.base_values[card.config.center.key]
|
|
and (
|
|
Cryptid.base_values[card.config.center.key][i .. ref_value]
|
|
or (ref_value == "ability" and Cryptid.base_values[card.config.center.key][i .. "consumeable"])
|
|
)
|
|
then
|
|
num = Cryptid.base_values[card.config.center.key][i .. ref_value]
|
|
or Cryptid.base_values[card.config.center.key][i .. "consumeable"]
|
|
end
|
|
end
|
|
if args.big ~= nil then
|
|
ref_table[ref_value][i] = Cryptid.manipulate_value(num, args, args.big, i)
|
|
else
|
|
ref_table[ref_value][i] = Cryptid.manipulate_value(num, args, Cryptid.is_card_big(card), i)
|
|
end
|
|
elseif i ~= "immutable" and type(v) == "table" and Cryptid.misprintize_value_blacklist[i] ~= false then
|
|
Cryptid.manipulate_table(card, ref_table[ref_value], i, args)
|
|
end
|
|
end
|
|
end
|
|
|
|
function Cryptid.manipulate_value(num, args, is_big, name)
|
|
if args.func then
|
|
num = args.func(num, args, is_big, name)
|
|
else
|
|
if args.min and args.max then
|
|
local new_args = args
|
|
local big_min = to_big(args.min)
|
|
local big_max = to_big(args.max)
|
|
local new_value = Cryptid.log_random(
|
|
pseudoseed(args.seed or ("cry_misprint" .. G.GAME.round_resets.ante)),
|
|
big_min,
|
|
big_max
|
|
)
|
|
if args.type == "+" then
|
|
if to_big(num) ~= to_big(0) and to_big(num) ~= to_big(1) then
|
|
num = num + new_value
|
|
end
|
|
elseif args.type == "X" then
|
|
if
|
|
to_big(num) ~= to_big(0) and (to_big(num) ~= to_big(1) or (name ~= "x_chips" and name ~= "x_mult"))
|
|
then
|
|
num = num * new_value
|
|
end
|
|
elseif args.type == "^" then
|
|
num = to_big(num) ^ new_value
|
|
elseif args.type == "hyper" then
|
|
if to_big(num) ~= to_big(0) and to_big(num) ~= to_big(1) then
|
|
num = to_big(num):arrow(args.value.arrows, to_big(new_value))
|
|
end
|
|
end
|
|
elseif args.value then
|
|
if args.type == "+" then
|
|
if to_big(num) ~= to_big(0) and to_big(num) ~= to_big(1) then
|
|
num = num + to_big(args.value)
|
|
end
|
|
elseif args.type == "X" then
|
|
if
|
|
to_big(num) ~= to_big(0) and (to_big(num) ~= to_big(1) or (name ~= "x_chips" and name ~= "x_mult"))
|
|
then
|
|
num = num * args.value
|
|
end
|
|
elseif args.type == "^" then
|
|
num = to_big(num) ^ args.value
|
|
elseif args.type == "hyper" then
|
|
num = to_big(num):arrow(args.value.arrows, to_big(args.value.height))
|
|
end
|
|
end
|
|
end
|
|
if Cryptid.misprintize_bignum_blacklist[name] == false then
|
|
num = to_number(num)
|
|
return to_number(Cryptid.sanity_check(num, false))
|
|
end
|
|
local val = Cryptid.sanity_check(num, is_big)
|
|
if to_big(val) > to_big(-1e100) and to_big(val) < to_big(1e100) then
|
|
return to_number(val)
|
|
end
|
|
return val
|
|
end
|
|
|
|
local get_nominalref = Card.get_nominal
|
|
function Card:get_nominal(...)
|
|
return to_number(get_nominalref(self, ...))
|
|
end
|