1961 lines
58 KiB
Lua
1961 lines
58 KiB
Lua
local unstbex = SMODS.current_mod
|
|
local filesystem = NFS or love.filesystem
|
|
local path = unstbex.path
|
|
local unstbex_config = unstbex.config
|
|
|
|
--Global Table
|
|
unstbex_global = {}
|
|
unstbex_global.config = unstbex.config
|
|
|
|
unstbex_lib = {}
|
|
|
|
--Library
|
|
SMODS.load_file("/lib/suit_compat.lua")()
|
|
|
|
--Localization Messages
|
|
--local loc = filesystem.load(path..'localization.lua')()
|
|
|
|
-- Debug message
|
|
|
|
local function print(message)
|
|
sendDebugMessage('[UnstableEX] - '..(tostring(message) or '???'))
|
|
end
|
|
|
|
print("Starting UnstableEX")
|
|
|
|
--Compat List
|
|
|
|
unstbex_global.compat = {
|
|
Bunco = (SMODS.Mods["Bunco"] or {}).can_load,
|
|
Familiar = (SMODS.Mods["familiar"] or {}).can_load,
|
|
Ortalab = (SMODS.Mods["ortalab"] or {}).can_load,
|
|
Six_Suit = (SMODS.Mods["SixSuits"] or {}).can_load,
|
|
Inks_Color = (SMODS.Mods["InkAndColor"] or {}).can_load,
|
|
Cryptid = (SMODS.Mods["Cryptid"] or {}).can_load,
|
|
CustomCards = (SMODS.Mods["CustomCards"] or {}).can_load,
|
|
Pokermon = (SMODS.Mods["Pokermon"] or {}).can_load,
|
|
KCVanilla = (SMODS.Mods["kcvanilla"] or {}).can_load,
|
|
DnDJ = (SMODS.Mods["dndj"] or {}).can_load,
|
|
MtJ = (SMODS.Mods["magic_the_jokering"] or {}).can_load,
|
|
Minty = (SMODS.Mods["MintysSillyMod"] or {}).can_load,
|
|
Cardsauce = (SMODS.Mods["Cardsauce"] or {}).can_load,
|
|
Showdown = (SMODS.Mods["showdown"] or {}).can_load,
|
|
}
|
|
|
|
local function check_mod_active(mod_id)
|
|
return unstbex_global.compat[mod_id]
|
|
end
|
|
|
|
--Config Stuff
|
|
|
|
function unstbex.save_config(self)
|
|
SMODS.save_mod_config(self)
|
|
end
|
|
|
|
local unstbex_config_tab = function()
|
|
--Dynamically Building Config Based on loaded mods
|
|
--I'll figure out how to make paginations later
|
|
|
|
local mod_config_ui_tables = {}
|
|
local function create_mod_config(mod_name, conf_list)
|
|
if not check_mod_active(mod_name.key) then return end
|
|
|
|
local ui_nodes = {}
|
|
ui_nodes[1] = {n=G.UIT.R, config={align = "cm"}, nodes={{n = G.UIT.T, config = {text = mod_name.name or mod_name.key, colour = G.C.ORANGE, scale = 0.5}}}}
|
|
|
|
for k,v in pairs(conf_list) do
|
|
ui_nodes[#ui_nodes+1] = create_toggle({label = v.label, ref_table = unstbex.config[v.ref_table], ref_value = k, callback = function() unstbex:save_config() end})
|
|
end
|
|
|
|
mod_config_ui_tables[#mod_config_ui_tables+1] = {n=G.UIT.R, config={align = "cl"}, nodes = ui_nodes }
|
|
end
|
|
|
|
|
|
local function mod_config_ui_init()
|
|
|
|
--List of ALL possible mod config
|
|
|
|
create_mod_config({key= "DnDJ", name = "DnDJ"}, {
|
|
keep_sprite = {label = "Keep Rank Sprites", ref_table = "dndj"},
|
|
})
|
|
|
|
create_mod_config({key= "Showdown", name = "Showdown"}, {
|
|
use_decimal = {label = "Use Decimal Mechanics", ref_table = "showdown"},
|
|
replace_zero = {label = "Replace Rank 0", ref_table = "showdown"},
|
|
})
|
|
end
|
|
|
|
mod_config_ui_init();
|
|
|
|
--Rendering
|
|
local render_table = {}
|
|
local restart_header = nil
|
|
|
|
if #mod_config_ui_tables > 0 then
|
|
for i=1, #mod_config_ui_tables do
|
|
render_table[#render_table+1] = mod_config_ui_tables[i]
|
|
end
|
|
|
|
restart_header = {n=G.UIT.R, config={align = "cm"}, nodes={{n = G.UIT.T, config = {text = localize("unstb_config_requires_restart"), colour = G.C.RED, scale = 0.4}}}}
|
|
else
|
|
render_table = {{n=G.UIT.R, config={align = "cl"}, nodes={
|
|
|
|
{n=G.UIT.R, config={align = "cm"}, nodes={{n = G.UIT.T, config = {text = "No configurable options found for the current modlist", scale = 0.5}}}},
|
|
}}}
|
|
end
|
|
|
|
|
|
return{
|
|
{
|
|
label = "Config",
|
|
chosen = true,
|
|
tab_definition_function = function()
|
|
return {
|
|
n = G.UIT.ROOT,
|
|
config = {
|
|
emboss = 0.05,
|
|
minh = 6,
|
|
r = 0.1,
|
|
minw = 10,
|
|
align = "cm",
|
|
padding = 0.2,
|
|
colour = G.C.BLACK,
|
|
},
|
|
nodes = {
|
|
|
|
{n=G.UIT.R, config={align = "cm"}, nodes= {restart_header} },
|
|
|
|
{n=G.UIT.R, config={align = "cm"}, nodes={ --Base Box containing everything
|
|
|
|
-- Left Side Column
|
|
{n=G.UIT.C, config={align = "cl", padding = 0.2}, nodes = render_table },
|
|
|
|
-- Right Side Column
|
|
--{n=G.UIT.C, config={align = "cl"}, nodes = render_table},
|
|
|
|
}}
|
|
},
|
|
}
|
|
end
|
|
},
|
|
|
|
--[[{ --Reserved Tab, in case the settings are expended in the future
|
|
label = localize("unstb_config_header_joker_settings"),
|
|
tab_definition_function = function()
|
|
return {
|
|
n = G.UIT.ROOT,
|
|
config = {
|
|
emboss = 0.05,
|
|
minh = 6,
|
|
r = 0.1,
|
|
minw = 10,
|
|
align = "cm",
|
|
padding = 0.2,
|
|
colour = G.C.BLACK,
|
|
},
|
|
nodes = {
|
|
|
|
},
|
|
|
|
|
|
}
|
|
end
|
|
}]]
|
|
}
|
|
end
|
|
|
|
unstbex.extra_tabs = unstbex_config_tab
|
|
|
|
--Just so the gear icon shows up
|
|
unstbex.config_tab = true
|
|
|
|
--Map config value with a single string keyword
|
|
local config_value = {
|
|
--["rank_21"] = unstb_config.rank.rank_21,
|
|
|
|
}
|
|
|
|
--Utility
|
|
|
|
--Auto event scheduler, based on Bunco
|
|
local function event(config)
|
|
local e = Event(config)
|
|
G.E_MANAGER:add_event(e)
|
|
return e
|
|
end
|
|
|
|
local function big_juice(card)
|
|
card:juice_up(0.7)
|
|
end
|
|
|
|
local function extra_juice(card)
|
|
card:juice_up(0.6, 0.1)
|
|
end
|
|
|
|
local function play_nope_sound()
|
|
--Copied from Wheel of Fortune lol
|
|
event({trigger = 'after', delay = 0.06*G.SETTINGS.GAMESPEED, blockable = false, blocking = false, func = function()
|
|
play_sound('tarot2', 0.76, 0.4);return true end})
|
|
play_sound('tarot2', 1, 0.4)
|
|
end
|
|
|
|
local function forced_message(message, card, color, delay, juice)
|
|
if delay == true then
|
|
delay = 0.7 * 1.25
|
|
elseif delay == nil then
|
|
delay = 0
|
|
end
|
|
|
|
event({trigger = 'before', delay = delay, func = function()
|
|
|
|
if juice then big_juice(juice) end
|
|
|
|
card_eval_status_text(
|
|
card,
|
|
'extra',
|
|
nil, nil, nil,
|
|
{message = message, colour = color, instant = true}
|
|
)
|
|
return true
|
|
end})
|
|
end
|
|
|
|
-- Index-based coordinates generation
|
|
|
|
local function get_coordinates(position, width)
|
|
if width == nil then width = 10 end -- 10 is default for Jokers
|
|
return {x = (position) % width, y = math.floor((position) / width)}
|
|
end
|
|
|
|
--Mod Icon
|
|
SMODS.Atlas {
|
|
-- Key for code to find it with
|
|
key = "modicon",
|
|
-- The name of the file, for the code to pull the atlas from
|
|
path = "modicon.png",
|
|
-- Width of each sprite in 1x size
|
|
px = 32,
|
|
-- Height of each sprite in 1x size
|
|
py = 32
|
|
}
|
|
|
|
--Creates an atlas for cards to use
|
|
--[[SMODS.Atlas {
|
|
-- Key for code to find it with
|
|
key = "unstbEX_jokers",
|
|
-- The name of the file, for the code to pull the atlas from
|
|
path = "unstbEX_jokers.png",
|
|
-- Width of each sprite in 1x size
|
|
px = 71,
|
|
-- Height of each sprite in 1x size
|
|
py = 95
|
|
}]]
|
|
|
|
--Updated Enhancement atli to include modded suits
|
|
SMODS.Atlas {
|
|
key = "enh_slop",
|
|
path = "enh_slop.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "enh_slop_hc",
|
|
path = "enh_slop_hc.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "enh_res",
|
|
path = "enh_res.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
--Fallback atlas for extra ranks
|
|
|
|
SMODS.Atlas {
|
|
key = "rank_ex_default",
|
|
path = "rank_ex/default/rank_ex.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "rank_ex2_default",
|
|
path = "rank_ex/default/rank_ex2.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
--Bunco's resprites suit colours
|
|
SMODS.Atlas {
|
|
key = "rank_ex_hc_b",
|
|
path = "rank_ex/bunco/rank_ex_hc_b.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "rank_ex2_hc_b",
|
|
path = "rank_ex/bunco/rank_ex2_hc_b.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "enh_slop_hc_b",
|
|
path = "enh_slop_hc_b.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
--Cardsauce Skin
|
|
|
|
local use_cardsauce_skin = false
|
|
|
|
if check_mod_active("Cardsauce") then
|
|
|
|
use_cardsauce_skin = csau_enabled['enableSkins']
|
|
|
|
SMODS.Atlas {
|
|
key = "rank_ex_cs",
|
|
path = "rank_ex/cardsauce/rank_ex_cs.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "rank_ex2_cs",
|
|
path = "rank_ex/cardsauce/rank_ex2_cs.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
end
|
|
|
|
--Familiar's Multi-Suit Cards Fallback
|
|
--(I don't think it is possible to make all combinations by myself, especially to account for modded suits)
|
|
SMODS.Atlas {
|
|
key = "rank_ex_multi",
|
|
path = "rank_ex_multi.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
SMODS.Atlas {
|
|
key = "rank_ex2_multi",
|
|
path = "rank_ex2_multi.png",
|
|
px = 71,
|
|
py = 95
|
|
}
|
|
|
|
--Map new atlas to the rank - new ranks now used more than 1 atlas (split off for maintenance reason)
|
|
local rank_atlas_map = {['unstb_0'] = 1,
|
|
['unstb_0.5'] = 1,
|
|
['unstb_1'] = 1,
|
|
['unstb_r2'] = 1,
|
|
['unstb_e'] = 1,
|
|
['unstb_Pi'] = 1,
|
|
['unstb_21'] = 1,
|
|
['unstb_???'] = 1,
|
|
|
|
['unstb_11'] = 2,
|
|
['unstb_12'] = 2,
|
|
['unstb_13'] = 2,
|
|
['unstb_25'] = 2,
|
|
['unstb_161'] = 2,}
|
|
|
|
local rank_atlas_name = {'unstbex_rank_ex', 'unstbex_rank_ex2'}
|
|
|
|
--Swap the hc atli with bunco resprites version to match suit colours
|
|
local using_bunco_resprites = false
|
|
if check_mod_active("Bunco") then
|
|
if BUNCOMOD and BUNCOMOD.content and BUNCOMOD.content.config then
|
|
using_bunco_resprites = BUNCOMOD.content.config.fixed_sprites
|
|
end
|
|
end
|
|
|
|
local vanilla_suits = {Hearts = true,
|
|
Clubs = true,
|
|
Diamonds = true,
|
|
Spades = true,
|
|
}
|
|
|
|
unstbex_lib.extra_suits = {}
|
|
|
|
--Init extra suits information based on loaded mod
|
|
|
|
if check_mod_active("Bunco") then
|
|
unstbex_lib.init_suit_compat('bunc_Fleurons', 'bunco')
|
|
unstbex_lib.init_suit_compat('bunc_Halberds', 'bunco')
|
|
end
|
|
|
|
if check_mod_active("Six_Suit") then
|
|
unstbex_lib.init_suit_compat('six_Stars', 'sixsuits', true)
|
|
unstbex_lib.init_suit_compat('six_Moons', 'sixsuits', true)
|
|
end
|
|
|
|
if check_mod_active("Inks_Color") then
|
|
unstbex_lib.init_suit_compat('ink_Inks', 'inkscolor', true)
|
|
unstbex_lib.init_suit_compat('ink_Colors', 'inkscolor', true)
|
|
end
|
|
|
|
if check_mod_active("MtJ") then
|
|
unstbex_lib.init_suit_compat('mtg_Clovers', 'mtj')
|
|
end
|
|
|
|
if check_mod_active("Minty") then
|
|
unstbex_lib.init_suit_compat('minty_3s', 'minty', true)
|
|
end
|
|
|
|
--Suit injection code based on Showdown by Mistyk__
|
|
local function inject_p_card_suit_compat(suit, rank)
|
|
local card = {
|
|
name = rank.key .. ' of ' .. suit.key,
|
|
value = rank.key,
|
|
suit = suit.key,
|
|
pos = { x = rank.pos.x, y = rank.suit_map[suit.key] or suit.pos.y },
|
|
lc_atlas = rank.suit_map[suit.key] and rank.lc_atlas or suit.lc_atlas,
|
|
hc_atlas = rank.suit_map[suit.key] and rank.hc_atlas or suit.hc_atlas,
|
|
}
|
|
if not vanilla_suits[card.suit] then
|
|
if not unstbex_lib.extra_suits[card.suit] then
|
|
print("Warning: Unknown suit for "..card.name)
|
|
card.lc_atlas = rank_atlas_name[rank_atlas_map[rank.key]]..'_default'
|
|
card.hc_atlas = rank_atlas_name[rank_atlas_map[rank.key]]..'_default'
|
|
card.pos.y = 0
|
|
else
|
|
card.lc_atlas = unstbex_lib.extra_suits[card.suit].lc_atlas[rank_atlas_map[rank.key]]
|
|
card.hc_atlas = unstbex_lib.extra_suits[card.suit].hc_atlas[rank_atlas_map[rank.key]]
|
|
end
|
|
end
|
|
G.P_CARDS[suit.card_key .. '_' .. rank.card_key] = card
|
|
end
|
|
|
|
local function rank_injection(self)
|
|
print("Performing extra rank injection")
|
|
for _, suit in pairs(SMODS.Suits) do
|
|
inject_p_card_suit_compat(suit, self)
|
|
end
|
|
end
|
|
|
|
local function inject_rank_atlas(prefix)
|
|
for k,v in pairs(SMODS.Ranks) do
|
|
if k:find(prefix) then
|
|
local rank = SMODS.Ranks[k]
|
|
|
|
rank.inject = rank_injection
|
|
|
|
if use_cardsauce_skin then
|
|
rank.lc_atlas = rank_atlas_name[rank_atlas_map[k]]..'_cs'
|
|
rank.hc_atlas = rank_atlas_name[rank_atlas_map[k]]..'_cs'
|
|
end
|
|
|
|
if using_bunco_resprites then
|
|
rank.hc_atlas = rank_atlas_name[rank_atlas_map[k]]..'_hc_b'
|
|
end
|
|
|
|
--[[rank.lc_atlas = rank_atlas_map[k]
|
|
rank.hc_atlas = using_bunco_resprites and rank_atlas_map[k]..'_hc_b' or rank_atlas_map[k]..'_hc'
|
|
rank.suit_map = unstbex_global.rank_suit_map]]
|
|
|
|
print("Injecting the graphic for rank "..rank.key)
|
|
end
|
|
end
|
|
end
|
|
|
|
inject_rank_atlas('unstb_')
|
|
|
|
--Register Suits for UnStable suit system
|
|
|
|
--Modded Suits Code in UnStableEX
|
|
|
|
--Bunco
|
|
--[[register_suit_group("suit_black", "bunc_Halberds")
|
|
register_suit_group("suit_red", "bunc_Fleurons")
|
|
|
|
register_suit_group("suit_black", "six_Moons")
|
|
register_suit_group("suit_red", "six_Stars")
|
|
|
|
register_suit_group("no_smear", "Inks_Inks")
|
|
register_suit_group("no_smear", "Inks_Color")]]
|
|
|
|
--Update extended atlas for Slop and Resource Cards
|
|
|
|
--Separated from rank suit map now
|
|
local enhancement_suit_map = {
|
|
Hearts = 0,
|
|
Clubs = 1,
|
|
Diamonds = 2,
|
|
Spades = 3,
|
|
|
|
bunc_Fleurons = 4,
|
|
bunc_Halberds = 5,
|
|
|
|
six_Stars = 6,
|
|
six_Moons = 7,
|
|
|
|
ink_Inks = 8,
|
|
ink_Colors = 9,
|
|
}
|
|
|
|
local center_unstb_slop = SMODS.Centers['m_unstb_slop'] or {}
|
|
center_unstb_slop.suit_map = enhancement_suit_map
|
|
center_unstb_slop.atlas = 'unstbex_enh_slop'
|
|
center_unstb_slop.lc_atlas = 'unstbex_enh_slop'
|
|
center_unstb_slop.hc_atlas = using_bunco_resprites and 'unstbex_enh_slop_hc_b' or 'unstbex_enh_slop_hc'
|
|
|
|
local center_unstb_resource = SMODS.Centers['m_unstb_resource'] or {}
|
|
center_unstb_resource.suit_map = enhancement_suit_map
|
|
center_unstb_resource.atlas = 'unstbex_enh_res'
|
|
|
|
--Generic Rank Replacement Utility
|
|
|
|
--A map of orignal mod's rank, to new rank, and the mod's tag to check if the config is enabled or not
|
|
local replace_rank_map = {}
|
|
|
|
function register_rank_replacement(originalrank, newrank, keepsprite)
|
|
replace_rank_map[originalrank] = {new_rank = newrank, keep_sprite = keepsprite}
|
|
end
|
|
|
|
local ref_card_set_base = Card.set_base
|
|
function Card:set_base(card, initial)
|
|
card = card or {}
|
|
|
|
ref_card_set_base(self, card, initial)
|
|
|
|
--Only run this piece of codes when inside the run (so, menu animations aren't interrupted)
|
|
if G.GAME and G.GAME.blind then
|
|
if self.base and self.base.value and replace_rank_map[self.base.value] then
|
|
|
|
local replace_rank_data = replace_rank_map[self.base.value]
|
|
|
|
if replace_rank_data.keep_sprite and vanilla_suits[self.base.suit] then
|
|
--Re-assign the rank to UnStable's equivalent
|
|
--Doing it this way should keep the sprites unchanged
|
|
|
|
--Automatically replaced it completely if the suit isn't vanilla for stable reasons
|
|
|
|
self.base.value = replace_rank_data.new_rank
|
|
|
|
local rank = SMODS.Ranks[self.base.value] or {}
|
|
self.base.nominal = rank.nominal or 0
|
|
self.base.face_nominal = rank.face_nominal or 0
|
|
self.base.id = rank.id
|
|
else
|
|
SMODS.change_base(self, nil, replace_rank_map[self.base.value].new_rank)
|
|
end
|
|
|
|
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
--Blacklist "top" ranks for many jokers
|
|
local top_rank_blacklist = {
|
|
['Ace'] = true,
|
|
['unstb_21'] = true,
|
|
['unstb_25'] = true,
|
|
['unstb_161'] = true,
|
|
['unstb_???'] = true,
|
|
}
|
|
|
|
if check_mod_active("Bunco") then
|
|
|
|
print("Inject Bunco Jokers")
|
|
|
|
local bunc_pawn = SMODS.Centers['j_bunc_pawn'] or {}
|
|
|
|
--Blacklist ranks for Pawn
|
|
|
|
bunc_pawn.loc_vars = function(self, info_queue, card)
|
|
if G.playing_cards and #G.playing_cards > 0 then
|
|
local rank = math.huge
|
|
local target_rank = 'unstb_???';
|
|
for _, deck_card in ipairs(G.playing_cards) do
|
|
local newrank = deck_card.base.nominal + (deck_card.base.face_nominal or 0)
|
|
if newrank < rank and (not deck_card.config.center.no_rank or deck_card.config.center ~= G.P_CENTERS.m_stone) then
|
|
rank = newrank
|
|
target_rank = deck_card.base.value
|
|
end
|
|
end
|
|
return {vars = {localize(target_rank, 'ranks')}}
|
|
end
|
|
return {vars = {localize('2', 'ranks')}}
|
|
end
|
|
|
|
bunc_pawn.calculate = function(self, card, context)
|
|
if context.after and context.scoring_hand and not context.blueprint then
|
|
for i = 1, #context.scoring_hand do
|
|
local condition = false
|
|
local other_card = context.scoring_hand[i]
|
|
local rank = math.huge
|
|
local target_rank = 'unstb_???';
|
|
for _, deck_card in ipairs(G.playing_cards) do
|
|
local newrank = deck_card.base.nominal + (deck_card.base.face_nominal or 0)
|
|
if newrank < rank and (not deck_card.config.center.no_rank or deck_card.config.center ~= G.P_CENTERS.m_stone) then
|
|
rank = newrank
|
|
target_rank = deck_card.base.value
|
|
end
|
|
end
|
|
if other_card.base.value == target_rank and not top_rank_blacklist[other_card.base.value] then
|
|
condition = true
|
|
event({trigger = 'after', delay = 0.15, func = function() other_card:flip(); play_sound('card1', 1); other_card:juice_up(0.3, 0.3); return true end })
|
|
event({
|
|
trigger = 'after',
|
|
delay = 0.1,
|
|
func = function()
|
|
local new_rank = get_next_x_rank(other_card.base.value, 1)
|
|
assert(SMODS.change_base(other_card, nil, new_rank))
|
|
return true
|
|
end
|
|
})
|
|
event({trigger = 'after', delay = 0.15, func = function() other_card:flip(); play_sound('tarot2', 1, 0.6); big_juice(card); other_card:juice_up(0.3, 0.3); return true end })
|
|
end
|
|
if condition then delay(0.7 * 1.25) end
|
|
end
|
|
end
|
|
end
|
|
|
|
local bunc_zero_shapiro = SMODS.Centers['j_bunc_zero_shapiro'] or {}
|
|
|
|
local zeroshapiro_zerorank = {
|
|
['unstb_0'] = true,
|
|
['unstb_???'] = true,
|
|
['Jack'] = true,
|
|
['Queen'] = true,
|
|
['King'] = true,
|
|
|
|
['showdown_Butler'] = true,
|
|
['showdown_Princess'] = true,
|
|
['showdown_Lord'] = true,
|
|
['showdown_Zero'] = true,
|
|
}
|
|
|
|
bunc_zero_shapiro.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play then
|
|
if context.other_card.config.center.no_rank or zeroshapiro_zerorank[context.other_card.base.value] then
|
|
if pseudorandom('zero_shapiro'..G.SEED) < G.GAME.probabilities.normal / card.ability.extra.odds then
|
|
return {
|
|
extra = {message = '+'..localize{type = 'name_text', key = 'tag_d_six', set = 'Tag'}, colour = G.C.GREEN},
|
|
card = card,
|
|
func = function()
|
|
event({func = function()
|
|
add_tag(Tag('tag_d_six'))
|
|
return true
|
|
end})
|
|
end
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local bunc_crop_circles = SMODS.Centers['j_bunc_crop_circles'] or {}
|
|
|
|
local crop_circles_rank_mult = {
|
|
['unstb_0'] = 1,
|
|
['unstb_0.5'] = 1,
|
|
['6'] = 1,
|
|
['8'] = 2,
|
|
['9'] = 1,
|
|
['10'] = 1,
|
|
['Queen'] = 1,
|
|
|
|
['showdown_8.5'] = 2,
|
|
['showdown_Butler'] = 2,
|
|
['showdown_Princess'] = 1,
|
|
['showdown_Zero'] = 1,
|
|
}
|
|
|
|
--Implemented differently than in Bunco, but should yield the same result
|
|
bunc_crop_circles.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play then
|
|
local other_card = context.other_card
|
|
local total_mult = 0
|
|
|
|
--Check suit
|
|
if not other_card.config.center.no_suit then
|
|
if other_card.base.suit == 'bunc_Fleurons' then
|
|
total_mult = total_mult + 4
|
|
elseif other_card.base.suit == 'Clubs' then
|
|
total_mult = total_mult + 3
|
|
elseif other_card.base.suit == 'mtg_Clovers' then
|
|
total_mult = total_mult + 4
|
|
end
|
|
end
|
|
|
|
--Check rank
|
|
if not other_card.config.center.no_rank then
|
|
if crop_circles_rank_mult[other_card.base.value] then
|
|
total_mult = total_mult + crop_circles_rank_mult[other_card.base.value]
|
|
end
|
|
end
|
|
|
|
--If the amount is greater than 0, grant the bonus w/ animation
|
|
if total_mult > 0 then
|
|
return {
|
|
mult = total_mult,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
--Hook to Familiar's set_sprite_suits to account for new ranks
|
|
local unstb_ranks_pos = {['unstb_0'] = 6,
|
|
['unstb_0.5'] = 2,
|
|
['unstb_1'] = 5,
|
|
['unstb_r2'] = 7,
|
|
['unstb_e'] = 3,
|
|
['unstb_Pi'] = 4,
|
|
['unstb_21'] = 0,
|
|
['unstb_???'] = 1,
|
|
|
|
['unstb_11'] = 0,
|
|
['unstb_12'] = 1,
|
|
['unstb_13'] = 2,
|
|
['unstb_25'] = 3,
|
|
['unstb_161'] = 4,}
|
|
|
|
if check_mod_active("Familiar") then
|
|
|
|
print('Inject Familiar set_sprite_suits')
|
|
|
|
local ref_set_sprite_suits = set_sprite_suits
|
|
|
|
function set_sprite_suits(card, juice)
|
|
ref_set_sprite_suits(card, juice)
|
|
|
|
--If the rank is one of the UnStable Rank, and has one of the ability
|
|
if unstb_ranks_pos[card.base.value] and (card.ability.is_spade or card.ability.is_heart or card.ability.is_club or card.ability.is_diamond or card.ability.suitless) then
|
|
--print('UnstbEX Set Sprite Suit Hook Active')
|
|
|
|
local suit_check = {card.base.suit == 'Spades' or card.ability.is_spade or false,
|
|
card.base.suit == 'Hearts' or card.ability.is_heart or false,
|
|
card.base.suit == 'Clubs' or card.ability.is_club or false,
|
|
card.base.suit == 'Diamonds' or card.ability.is_diamond or false}
|
|
|
|
local suit_count = 0
|
|
for i=1, #suit_check do
|
|
if suit_check[i] then
|
|
suit_count = suit_count+1
|
|
end
|
|
end
|
|
|
|
--Suitless, or has more than 1 suits
|
|
if card.ability.suitless or suit_count>1 then
|
|
--Technically, if anyone wants to make it works properly, this would be where to check
|
|
--Unfortunately, I don't think I can write them all because there's a lot of combination + lots of graphic to make
|
|
--Hopefully there is a more elegant solution found in the future.
|
|
|
|
card.children.front.atlas = G.ASSET_ATLAS[rank_atlas_map[card.base.value]..'_multi']
|
|
card.children.front:set_sprite_pos({x = unstb_ranks_pos[card.base.value], y = 0})
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
print("Inject Familiar Vigor Fortune Card")
|
|
|
|
local familiar_vigor = SMODS.Centers['c_fam_vigor'] or {}
|
|
|
|
--Reimplemented Familiar Vigor Fortune Card to use get_next_x_rank instead
|
|
familiar_vigor.use = function(self, card)
|
|
for i = 1, #G.hand.highlighted do
|
|
for j = 1, 3 do
|
|
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.1,func = function()
|
|
local card = G.hand.highlighted[i]
|
|
local new_rank = get_next_x_rank(card.base.value, 1)
|
|
assert(SMODS.change_base(card, nil, new_rank))
|
|
card:juice_up(0.3, 0.5)
|
|
return true end }))
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
--Re-implementation of Ortalab's Index Card functions to support UNSTB Ranks
|
|
|
|
--Notice: this rank changes the behavior from vanilla slightly, where rank 0 and 1 is immediately available
|
|
local main_rankList = {'unstb_0', 'unstb_1', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace'}
|
|
|
|
--Special UNSTB Rank is pre-defined
|
|
local rankMap = { ['unstb_0.5'] = {UP = 'unstb_1', MID = 'unstb_0.5' , DOWN = 'unstb_0'},
|
|
['unstb_r2'] = {UP = '2', MID = 'unstb_r2' , DOWN = 'unstb_1'},
|
|
unstb_e = {UP = '3', MID = 'unstb_e' , DOWN = '2'},
|
|
unstb_Pi = {UP = '4', MID = 'unstb_Pi' , DOWN = '3'},
|
|
unstb_21 = {UP = 'unstb_21', MID = 'unstb_21' , DOWN = 'unstb_21'},
|
|
|
|
unstb_11 = {UP = 'unstb_12', MID = 'unstb_11' , DOWN = '10'},
|
|
unstb_12 = {UP = 'unstb_13', MID = 'unstb_12' , DOWN = 'unstb_11'},
|
|
unstb_13 = {UP = 'Ace', MID = 'unstb_13' , DOWN = 'unstb_12'},
|
|
|
|
unstb_25 = {UP = 'unstb_25', MID = 'unstb_25' , DOWN = 'unstb_25'},
|
|
unstb_161 = {UP = 'unstb_161', MID = 'unstb_161' , DOWN = 'unstb_161'},
|
|
|
|
['unstb_???'] = {UP = 'unstb_???', MID = 'unstb_???' , DOWN = 'unstb_???'},
|
|
|
|
['showdown_2.5'] = {UP = '3', MID = 'showdown_2.5' , DOWN = '2'},
|
|
['showdown_5.5'] = {UP = '6', MID = 'showdown_5.5' , DOWN = '5'},
|
|
['showdown_8.5'] = {UP = '9', MID = 'showdown_8.5' , DOWN = '8'},
|
|
|
|
['showdown_Butler'] = {UP = 'Queen', MID = 'showdown_Butler' , DOWN = 'Jack'},
|
|
['showdown_Princess'] = {UP = 'King', MID = 'showdown_Princess' , DOWN = 'Queen'},
|
|
['showdown_Lord'] = {UP = 'Ace', MID = 'showdown_Lord' , DOWN = 'King'},
|
|
|
|
['showdown_Zero'] = {UP = 'unstb_1', MID = 'showdown_Zero' , DOWN = 'Ace'},
|
|
}
|
|
|
|
for i=1, #main_rankList do
|
|
rankMap[main_rankList[i]] = {UP = main_rankList[i+1] or main_rankList[1], MID = main_rankList[i], DOWN = main_rankList[i-1] or main_rankList[#main_rankList]}
|
|
end
|
|
|
|
--print(inspectDepth(rankMap))
|
|
|
|
if check_mod_active("Ortalab") then
|
|
|
|
print('Inject Ortalab Index Card')
|
|
|
|
--Inject new property into Ortalab index card
|
|
local ortalab_index = SMODS.Centers['m_ortalab_index'] or {}
|
|
|
|
ortalab_index.set_ability = function(self, card, initial, delay_sprites)
|
|
print('call set ability')
|
|
|
|
if card.base and card.ability and card.ability.extra and type(card.ability.extra) == 'table' then
|
|
if card.ability.extra.index_state == 'MID' then
|
|
card.ability.extra.mainrank = card.base.value
|
|
elseif card.ability.extra.index_state == 'UP' then
|
|
card.ability.extra.mainrank = rankMap[card.base.value]['DOWN']
|
|
elseif card.ability.extra.index_state == 'DOWN' then
|
|
card.ability.extra.mainrank = rankMap[card.base.value]['UP']
|
|
end
|
|
end
|
|
end
|
|
|
|
ortalab_index.set_sprites = function(self, card, front)
|
|
if card.ability and card.ability.extra and type(card.ability.extra) == 'table' then
|
|
|
|
if card.ability.extra.index_state == 'MID' then
|
|
card.children.center:set_sprite_pos({x = 2, y = 0})
|
|
elseif card.ability.extra.index_state == 'UP' then
|
|
--card.ability.extra.mainrank = rankMap[card.base.value]['DOWN']
|
|
card.children.center:set_sprite_pos({x = 1, y = 2})
|
|
elseif card.ability.extra.index_state == 'DOWN' then
|
|
card.children.center:set_sprite_pos({x = 0, y = 2})
|
|
end
|
|
|
|
--print('main card value is '.. card.ability.extra.mainrank)
|
|
end
|
|
end
|
|
|
|
ortalab_index.update = function(self, card)
|
|
--Jank, handles special case where Tarot like Strength was used
|
|
if (card.VT.w <= 0) then
|
|
local isCollection = (card.area and card.area.config.collection) or false
|
|
|
|
if not isCollection then
|
|
if card.ability.extra.index_state == 'MID' then
|
|
card.ability.extra.mainrank = card.base.value
|
|
elseif card.ability.extra.index_state == 'UP' then
|
|
card.ability.extra.mainrank = rankMap[card.base.value]['DOWN']
|
|
elseif card.ability.extra.index_state == 'DOWN' then
|
|
card.ability.extra.mainrank = rankMap[card.base.value]['UP']
|
|
end
|
|
end
|
|
|
|
--print('main card value changed to '.. card.ability.extra.mainrank)
|
|
end
|
|
end
|
|
|
|
G.FUNCS.increase_index = function(e, mute, nosave)
|
|
--print('using unstbex implementation of func')
|
|
|
|
e.config.button = nil
|
|
local card = e.config.ref_table
|
|
local area = card.area
|
|
local change = 1
|
|
if card.ability.extra.index_state == 'DOWN' then change = 2 end
|
|
card.ability.extra.index_state = 'UP'
|
|
card.children.center:set_sprite_pos({x = 1, y = 2})
|
|
|
|
SMODS.change_base(card, nil, rankMap[card.ability.extra.mainrank] and rankMap[card.ability.extra.mainrank]['UP'] or 'unstb_???')
|
|
end
|
|
|
|
G.FUNCS.mid_index = function(e, mute, nosave)
|
|
--print('using unstbex implementation of func')
|
|
|
|
e.config.button = nil
|
|
local card = e.config.ref_table
|
|
local area = card.area
|
|
local change = 1
|
|
if card.ability.extra.index_state == 'UP' then change = -1 end
|
|
card.ability.extra.index_state = 'MID'
|
|
card.children.center:set_sprite_pos({x = 2, y = 0})
|
|
--card.base.id = card.base.id + change
|
|
SMODS.change_base(card, nil, rankMap[card.ability.extra.mainrank] and rankMap[card.ability.extra.mainrank]['MID'] or 'unstb_???')
|
|
end
|
|
|
|
G.FUNCS.decrease_index = function(e, mute, nosave)
|
|
--print('using unstbex implementation of func')
|
|
|
|
e.config.button = nil
|
|
local card = e.config.ref_table
|
|
local area = card.area
|
|
local change = 1
|
|
if card.ability.extra.index_state == 'UP' then change = 2 end
|
|
card.ability.extra.index_state = 'DOWN'
|
|
card.children.center:set_sprite_pos({x = 0, y = 2})
|
|
--card.base.id = card.base.id - change
|
|
|
|
SMODS.change_base(card, nil, rankMap[card.ability.extra.mainrank] and rankMap[card.ability.extra.mainrank]['DOWN'] or 'unstb_???')
|
|
end
|
|
|
|
--More safety check
|
|
--[[
|
|
G.FUNCS.index_card_increase = function(e)
|
|
|
|
if not e.config.ref_table.ability.extra or type(e.config.ref_table.ability.extra) ~= 'table' then
|
|
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
|
|
e.config.button = nil
|
|
|
|
return
|
|
end
|
|
|
|
if e.config.ref_table.ability.extra.index_state ~= 'UP' then
|
|
e.config.colour = G.C.RED
|
|
e.config.button = 'increase_index'
|
|
else
|
|
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
|
|
e.config.button = nil
|
|
end
|
|
end
|
|
|
|
G.FUNCS.index_card_mid = function(e)
|
|
if not e.config.ref_table.ability.extra or type(e.config.ref_table.ability.extra) ~= 'table' then
|
|
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
|
|
e.config.button = nil
|
|
return
|
|
end
|
|
|
|
if e.config.ref_table.ability.extra.index_state ~= 'MID' then
|
|
e.config.colour = G.C.RED
|
|
e.config.button = 'mid_index'
|
|
else
|
|
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
|
|
e.config.button = nil
|
|
end
|
|
end
|
|
|
|
G.FUNCS.index_card_decrease = function(e)
|
|
if not e.config.ref_table.ability.extra or type(e.config.ref_table.ability.extra) ~= 'table' then
|
|
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
|
|
e.config.button = nil
|
|
|
|
return
|
|
end
|
|
|
|
if e.config.ref_table.ability.extra.index_state ~= 'DOWN' then
|
|
e.config.colour = G.C.RED
|
|
e.config.button = 'decrease_index'
|
|
else
|
|
e.config.colour = G.C.UI.BACKGROUND_INACTIVE
|
|
e.config.button = nil
|
|
end
|
|
end]]
|
|
|
|
print("Inject Ortalab Flag Loteria")
|
|
|
|
local ortalab_lot_flag = SMODS.Centers['c_ortalab_lot_flag'] or {}
|
|
|
|
--Reimplementation to use UnStable version of get_next_x_rank
|
|
ortalab_lot_flag.use = function(self, card, area, copier)
|
|
--print("UnStbEX version")
|
|
|
|
track_usage(card.config.center.set, card.config.center_key)
|
|
local options = {}
|
|
for i=1, card.ability.extra.rank_change do
|
|
table.insert(options, i)
|
|
end
|
|
for i=1, #G.hand.highlighted do
|
|
local percent = 1.15 - (i-0.999)/(#G.hand.highlighted-0.998)*0.3
|
|
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.15,func = function() G.hand.highlighted[i]:flip();play_sound('card1', percent);G.hand.highlighted[i]:juice_up(0.3, 0.3);return true end }))
|
|
end
|
|
for _, card in pairs(G.hand.highlighted) do
|
|
local sign = pseudorandom(pseudoseed('flag_sign')) > 0.5 and 1 or -1
|
|
local change = pseudorandom_element(options, pseudoseed('flag_change'))
|
|
for i=1, change do
|
|
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.4,func = function()
|
|
local new_rank = get_next_x_rank(card.base.value, sign)
|
|
assert(SMODS.change_base(card, nil, new_rank))
|
|
return true end }))
|
|
end
|
|
-- card_eval_status_text(card, 'extra', nil, nil, nil, {message = tostring(sign*change), colour = G.ARGS.LOC_COLOURS.loteria, delay = 0.4})
|
|
end
|
|
for i=1, #G.hand.highlighted do
|
|
local percent = 0.85 + (i-0.999)/(#G.hand.highlighted-0.998)*0.3
|
|
G.E_MANAGER:add_event(Event({trigger = 'after',delay = 0.15,func = function() G.hand.highlighted[i]:flip();play_sound('tarot2', percent, 0.6);G.hand.highlighted[i]:juice_up(0.3, 0.3);return true end }))
|
|
end
|
|
G.E_MANAGER:add_event(Event({trigger = 'after', delay = 0.2,func = function() G.hand:unhighlight_all(); return true end }))
|
|
delay(0.5)
|
|
end
|
|
|
|
--Inject Ortalab Joker code
|
|
|
|
--Mathmagician
|
|
--Now used the same check from UnStable like Odd Todd and Even Steven
|
|
local ortalab_mathmagician = SMODS.Centers['j_ortalab_mathmagician'] or {}
|
|
ortalab_mathmagician.calculate = function(self, card, context) --Mathmagician logic
|
|
if context.discard and context.other_card == context.full_hand[#context.full_hand] then
|
|
local numbered_even = 0
|
|
local numbered_odd = 0
|
|
for _, v in ipairs(context.full_hand) do
|
|
|
|
--Hardcoded check for ??? rank
|
|
--For that, it counts as both. So it increments whatever needed left
|
|
if v.base.value == 'unstb_???' then
|
|
if numbered_odd < 2 then
|
|
numbered_odd = numbered_odd + 1
|
|
else
|
|
numbered_even = numbered_even + 1
|
|
end
|
|
else
|
|
--General case, use modulo check from UnStable
|
|
if unstb_global.modulo_check(v, 2, 1) then
|
|
numbered_odd = numbered_odd + 1
|
|
elseif unstb_global.modulo_check(v, 2, 0) then
|
|
numbered_even = numbered_even + 1
|
|
end
|
|
end
|
|
end
|
|
if numbered_even >= 2 and numbered_odd >= 2 and #G.consumeables.cards + G.GAME.consumeable_buffer < G.consumeables.config.card_limit then
|
|
local choice = pseudorandom('mathmagician') > 0.5 and 'Loteria' or 'Zodiac'
|
|
G.E_MANAGER:add_event(Event({
|
|
func = (function()
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
local card = create_card(choice, G.consumeables)
|
|
card:add_to_deck()
|
|
G.consumeables:emplace(card)
|
|
G.GAME.consumeable_buffer = G.GAME.consumeable_buffer - 1
|
|
return true
|
|
end}))
|
|
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {message = localize('ortalab_'..string.lower(choice)..'_add'), colour = G.C.SET.Loteria})
|
|
return true
|
|
end)}))
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
end
|
|
|
|
--Cryptid Compat
|
|
|
|
if check_mod_active("Cryptid") then
|
|
|
|
--Special interaction w/ Plagiarism and rigged
|
|
--[[
|
|
local j_plagiarism = SMODS.Centers['j_unstb_plagiarism']
|
|
|
|
if j_plagiarism then
|
|
|
|
local ref_j_plagiarism_calculate = j_plagiarism.calculate
|
|
|
|
j_plagiarism.calculate = function(self, card, context)
|
|
--Alternate function entirely if it's rigged
|
|
if card.ability.cry_rigged then
|
|
--Code based on Familiar's Crimsonotype
|
|
|
|
--This bit of code runs before hand played, cannot copyable by other blueprint
|
|
if context.before and not context.blueprint and not context.repetition and not context.repetition_only then
|
|
forced_message('Both', card, G.C.ORANGE, true)
|
|
end
|
|
|
|
local other_joker = nil
|
|
for i = 1, #G.jokers.cards do
|
|
if G.jokers.cards[i] == card then
|
|
other_joker = {G.jokers.cards[i - 1], G.jokers.cards[i + 1]}
|
|
end
|
|
end
|
|
|
|
if other_joker then
|
|
for i = 1, #other_joker do
|
|
if other_joker[i] and other_joker[i] ~= self then
|
|
--local newcontext = context
|
|
context.blueprint = (context.blueprint and (context.blueprint + 1)) or 1
|
|
context.blueprint_card = context.blueprint_card or card
|
|
|
|
if context.blueprint > #G.jokers.cards + 1 then
|
|
return
|
|
end
|
|
|
|
local other_joker_ret, trig = other_joker[i]:calculate_joker(context)
|
|
|
|
--Context needs resetting afterwards, otherwise this value keeps persisting
|
|
context.blueprint = nil
|
|
|
|
local eff_card = context.blueprint_card or card
|
|
context.blueprint_card = nil
|
|
|
|
if other_joker_ret or trig then
|
|
if not other_joker_ret then
|
|
other_joker_ret = {}
|
|
end
|
|
|
|
other_joker_ret.card = eff_card
|
|
other_joker_ret.colour = G.C.GREEN
|
|
other_joker_ret.no_callback = true
|
|
|
|
if other_joker_ret then
|
|
--Jank, might result in message appear at wrong place idk but at least it should be executed properly
|
|
SMODS.calculate_effect(other_joker_ret, context.individual and context.other_card or eff_card)
|
|
--return other_joker_ret
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
else
|
|
return ref_j_plagiarism_calculate(self, card, context)
|
|
end
|
|
|
|
end
|
|
|
|
end]]
|
|
|
|
|
|
--Add appropiate Jokers to the pool
|
|
|
|
--Placeholder, there's no food jokers yet in UNSTB and/or EX
|
|
--[[
|
|
if Cryptid.food then
|
|
local food_jokers = {
|
|
|
|
}
|
|
|
|
for i = 1, #meme_jokers do
|
|
Cryptid.food[#Cryptid.food+1] = food_jokers[i]
|
|
end
|
|
end]]
|
|
|
|
if Cryptid.memepack then
|
|
--Adds pretty much most shitpost-centric Joker onto it
|
|
local meme_jokers = {
|
|
"j_unstb_joker2", --Joker 2
|
|
"j_unstb_joker_stairs", --Joker Stairs
|
|
"j_unstb_plagiarism", --Plagiarism
|
|
"j_unstb_prssj", --prssj
|
|
"j_unstb_the_jolly_joker", --The Jolly too just because
|
|
"j_unstb_what", --69, 420. Unsure if this would break the in_pool tho
|
|
}
|
|
|
|
for i = 1, #meme_jokers do
|
|
Cryptid.memepack[#Cryptid.memepack+1] = meme_jokers[i]
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
-- Hook for is_suit, in case other mods injected into it and it got caught early by the UnStable's hook
|
|
-- Currently only used by CustomCards
|
|
|
|
if check_mod_active("CustomCards") then
|
|
|
|
local ref_card_is_suit = Card.is_suit
|
|
|
|
function Card:is_suit(suit, bypass_debuff, flush_calc, bypass_seal)
|
|
|
|
local result = ref_card_is_suit(self, suit, bypass_debuff, flush_calc, bypass_seal)
|
|
|
|
--Return early if true (suit seal case)
|
|
if result then
|
|
return result
|
|
end
|
|
|
|
--If it is a trading card, check its own value
|
|
if self.ability and self.ability.trading then
|
|
local eval = self:calculate_exotic({bypass_debuff = bypass_debuff, flush_calc = flush_calc, is_suit = suit})
|
|
if eval then
|
|
return eval
|
|
end
|
|
end
|
|
|
|
--Should only return false here at this point?
|
|
return result
|
|
end
|
|
|
|
end
|
|
|
|
--Pokermon Compat
|
|
if check_mod_active("Pokermon") then
|
|
|
|
--Use get_next_x_rank instead
|
|
local ref_poke_vary_rank = poke_vary_rank
|
|
poke_vary_rank = function(card, decrease, seed)
|
|
local new_rank
|
|
if decrease then
|
|
new_rank = get_next_x_rank(card.base.value, -1)
|
|
elseif seed then
|
|
new_rank = pseudorandom_element(SMODS.Ranks, pseudoseed(seed)).key
|
|
else
|
|
new_rank = get_next_x_rank(card.base.value, 1)
|
|
end
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
SMODS.change_base(card, nil, new_rank)
|
|
return true
|
|
end
|
|
}))
|
|
end
|
|
|
|
--Inject Jokers Code
|
|
--Oddish and Bellsprout Lines now used UnStable method of checking odd and even numbers (same as Odd Todd and Even Steven)
|
|
|
|
--Oddish Line
|
|
local poke_oddish = SMODS.Centers['j_poke_oddish'] or {}
|
|
poke_oddish.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 1) then
|
|
local value
|
|
if pseudorandom('oddish') < .50 then
|
|
value = card.ability.extra.mult
|
|
else
|
|
value = card.ability.extra.mult2
|
|
end
|
|
return {
|
|
message = localize{type = 'variable', key = 'a_mult', vars = {value}},
|
|
colour = G.C.MULT,
|
|
mult = value,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
return level_evo(self, card, context, "j_poke_gloom")
|
|
end
|
|
|
|
local poke_gloom = SMODS.Centers['j_poke_gloom'] or {}
|
|
poke_gloom.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 1) then
|
|
local value
|
|
if pseudorandom('gloom') < .50 then
|
|
value = card.ability.extra.mult
|
|
else
|
|
value = card.ability.extra.mult2
|
|
end
|
|
return {
|
|
message = localize{type = 'variable', key = 'a_mult', vars = {value}},
|
|
colour = G.C.MULT,
|
|
mult = value,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
return item_evo(self, card, context)
|
|
end
|
|
|
|
local poke_vileplume = SMODS.Centers['j_poke_vileplume'] or {}
|
|
poke_vileplume.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 1) then
|
|
if pseudorandom('vileplume') < .50 then
|
|
return {
|
|
x_mult = card.ability.extra.Xmult_multi,
|
|
card = card
|
|
}
|
|
else
|
|
return {
|
|
mult = card.ability.extra.mult,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local poke_bellossom = SMODS.Centers['j_poke_bellossom'] or {}
|
|
poke_bellossom.calculate = function(self, card, context)
|
|
if context.before and context.cardarea == G.jokers and not context.blueprint then
|
|
local odds = {}
|
|
for k, v in ipairs(context.scoring_hand) do
|
|
local upgrade = pseudorandom(pseudoseed('bellossom'))
|
|
if (unstb_global.modulo_check(v, 2, 1)) and upgrade > .50 then
|
|
odds[#odds+1] = v
|
|
if v.ability.name == 'Wild Card' and not v.edition then
|
|
local edition = {polychrome = true}
|
|
v:set_edition(edition, true, true)
|
|
end
|
|
v:set_ability(G.P_CENTERS.m_wild, nil, true)
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
v:juice_up()
|
|
return true
|
|
end
|
|
}))
|
|
else
|
|
v.bellossom_score = true
|
|
end
|
|
end
|
|
if #odds > 0 then
|
|
return {
|
|
message = localize("poke_petal_dance_ex"),
|
|
colour = G.C.MULT,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 1) then
|
|
if context.other_card.bellossom_score then
|
|
context.other_card.bellossom_score = nil
|
|
return {
|
|
message = localize{type = 'variable', key = 'a_mult', vars = {card.ability.extra.mult}},
|
|
colour = G.C.MULT,
|
|
mult = card.ability.extra.mult,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local poke_bellsprout = SMODS.Centers['j_poke_bellsprout'] or {}
|
|
poke_bellsprout.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 0) then
|
|
return {
|
|
message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}},
|
|
colour = G.C.CHIPS,
|
|
chips = card.ability.extra.chips,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
return level_evo(self, card, context, "j_poke_weepinbell")
|
|
end
|
|
|
|
local poke_weepinbell = SMODS.Centers['j_poke_weepinbell'] or {}
|
|
poke_weepinbell.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 0) then
|
|
return {
|
|
message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}},
|
|
colour = G.C.CHIPS,
|
|
chips = card.ability.extra.chips,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
return item_evo(self, card, context, "j_poke_victreebel")
|
|
end
|
|
|
|
local poke_victreebel = SMODS.Centers['j_poke_victreebel'] or {}
|
|
poke_victreebel.calculate = function(self, card, context)
|
|
if context.individual and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 0) then
|
|
return {
|
|
message = localize{type = 'variable', key = 'a_chips', vars = {card.ability.extra.chips}},
|
|
colour = G.C.CHIPS,
|
|
chips = card.ability.extra.chips,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
if context.repetition and context.cardarea == G.play and not context.other_card.debuff then
|
|
if unstb_global.modulo_check(context.other_card, 2, 0) then
|
|
return {
|
|
message = localize('k_again_ex'),
|
|
repetitions = card.ability.extra.retriggers,
|
|
card = card
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--KCVanilla Compat
|
|
if check_mod_active("KCVanilla") then
|
|
|
|
print("Inject KCVanilla Joker")
|
|
|
|
--Five Days Forecast, now used get_next_x_rank properly
|
|
|
|
local function unstb_kcv_rank_up_discreetly(card)
|
|
-- local newcard = kcv_get_rank_up_pcard(card)
|
|
card.kcv_ignore_debuff_check = true
|
|
card.kcv_ranked_up_discreetly = true
|
|
-- card:set_base(newcard)
|
|
|
|
local old_rank = SMODS.Ranks[card.base.value]
|
|
local new_rank = get_next_x_rank(card.base.value, 1)
|
|
card.kcv_display_rank = card.kcv_display_rank and card.kcv_display_rank or old_rank
|
|
|
|
SMODS.change_base(card, card.base.suit, new_rank) -- Should respect "kcv_ranked_up_discreetly" as it uses card:set_base
|
|
end
|
|
|
|
local kc_5day = SMODS.Centers['j_kcvanilla_5day'] or {}
|
|
kc_5day.calculate = function(self, card, context)
|
|
if context.kcv_forecast_event and context.scoring_hand then
|
|
if next(context.poker_hands["Straight"]) then
|
|
for i, other_c in ipairs(context.scoring_hand) do
|
|
if not top_rank_blacklist[other_c.base.value] then
|
|
unstb_kcv_rank_up_discreetly(other_c)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if context.before and context.scoring_hand then
|
|
if next(context.poker_hands["Straight"]) then
|
|
local targets = {}
|
|
for i, other_c in ipairs(context.scoring_hand) do
|
|
if other_c.kcv_ranked_up_discreetly then
|
|
table.insert(targets, other_c)
|
|
end
|
|
end
|
|
|
|
card_eval_status_text(context.blueprint_card or card, 'extra', nil, nil, nil, {
|
|
message = localize('k_active_ex'),
|
|
colour = G.C.FILTER,
|
|
card = context.blueprint_card or card
|
|
});
|
|
|
|
for i_2, other_c_2 in ipairs(targets) do
|
|
local percent = 1.15 - (i_2 - 0.999) / (#context.scoring_hand - 0.998) * 0.3
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
if not other_c_2.kcv_ranked_up_discreetly then
|
|
-- was complete, but another 5-day joker is targeting this card
|
|
return true
|
|
end
|
|
play_sound('card1', percent)
|
|
other_c_2:flip()
|
|
return true
|
|
end
|
|
}))
|
|
delay(0.15)
|
|
end
|
|
delay(0.3)
|
|
for i_3, other_c_3 in ipairs(targets) do
|
|
local percent = 0.85 + (i_3 - 0.999) / (#context.scoring_hand - 0.998) * 0.3
|
|
G.E_MANAGER:add_event(Event({
|
|
func = function()
|
|
if not other_c_3.kcv_ranked_up_discreetly then
|
|
-- was complete, but another 5-day joker is targeting this card
|
|
return true
|
|
end
|
|
-- kcv_log(other_c_3.base.id .. ' - ' .. other_c_3.kcv_display_rank)
|
|
other_c_3.kcv_display_rank = SMODS.Ranks[get_next_x_rank(other_c_3.kcv_display_rank.key, 1)]
|
|
|
|
-- Copying method SMODs uses
|
|
local card_suit = SMODS.Suits[other_c_3.base.suit].card_key
|
|
local card_rank = other_c_3.kcv_display_rank.card_key
|
|
local newcard = G.P_CARDS[('%s_%s'):format(card_suit, card_rank)]
|
|
|
|
-- set_base again to update sprites that were postponed by kcv_ranked_up_discreetly
|
|
other_c_3:set_sprites(nil, newcard)
|
|
play_sound('tarot2', percent, 0.6)
|
|
other_c_3:flip()
|
|
if other_c_3.kcv_display_rank.card_key == SMODS.Ranks[other_c_3.base.value].card_key then
|
|
-- cleanup
|
|
other_c_3.kcv_ranked_up_discreetly = nil
|
|
other_c_3.kcv_ignore_debuff_check = nil
|
|
other_c_3.kcv_display_rank = nil
|
|
end
|
|
return true
|
|
end
|
|
}))
|
|
delay(0.15)
|
|
end
|
|
delay(0.5)
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
--DnDJ Compat
|
|
if check_mod_active("DnDJ") then
|
|
|
|
--TO DO: Make it a toggle setting if the card from DnDJ contraband pack would keep its rank graphic or not
|
|
local dndj_keep_sprite = unstbex.config.dndj.keep_sprite
|
|
|
|
local dndj_rank_map = {['dndj_0'] = 'unstb_0',
|
|
['dndj_0.5'] = 'unstb_0.5',
|
|
['dndj_1'] = 'unstb_1',
|
|
['dndj_Pi'] = 'unstb_Pi',
|
|
['dndj_11'] = 'unstb_11',
|
|
['dndj_12'] = 'unstb_12',
|
|
['dndj_13'] = 'unstb_13',
|
|
['dndj_21'] = 'unstb_21'}
|
|
|
|
for k, v in pairs(dndj_rank_map) do
|
|
register_rank_replacement(k, v, dndj_keep_sprite)
|
|
end
|
|
|
|
end
|
|
|
|
--Showdown compat
|
|
if check_mod_active("Showdown") then
|
|
|
|
local enable_unstable_decimal = unstbex.config.showdown.use_decimal
|
|
local replace_zero = unstbex.config.showdown.replace_zero
|
|
|
|
if replace_zero then
|
|
register_rank_replacement('showdown_Zero', 'unstb_0')
|
|
end
|
|
|
|
--Adds "decimal" compat to all counterpart ranks
|
|
local rank_sh_two_half = SMODS.Ranks['showdown_2.5']
|
|
rank_sh_two_half.decimal_compat = true
|
|
|
|
local rank_sh_five_half = SMODS.Ranks['showdown_5.5']
|
|
rank_sh_five_half.decimal_compat = true
|
|
|
|
local rank_sh_eight_half = SMODS.Ranks['showdown_8.5']
|
|
rank_sh_eight_half.decimal_compat = true
|
|
|
|
local rank_sh_butler = SMODS.Ranks['showdown_Butler']
|
|
rank_sh_butler.decimal_compat = true
|
|
|
|
local rank_sh_princess = SMODS.Ranks['showdown_Princess']
|
|
rank_sh_princess.decimal_compat = true
|
|
|
|
local rank_sh_lord = SMODS.Ranks['showdown_Lord']
|
|
rank_sh_lord.decimal_compat = true
|
|
|
|
--Additional information so UnStable's Engineer can work with them
|
|
unstb_global.register_decimal_rank_map('showdown_2.5', '3')
|
|
unstb_global.register_decimal_rank_map('showdown_5.5', '6')
|
|
unstb_global.register_decimal_rank_map('showdown_8.5', '9')
|
|
unstb_global.register_decimal_rank_map('showdown_Butler', 'Queen')
|
|
unstb_global.register_decimal_rank_map('showdown_Princess', 'King')
|
|
unstb_global.register_decimal_rank_map('showdown_Lord', 'Ace')
|
|
|
|
--If the setting is enabled, add proper UnStable decimal rank mechanics onto the ranks
|
|
if enable_unstable_decimal then
|
|
|
|
--Hook into get_counterpart to erase the UI display for them
|
|
local ref_getCounterPart = get_counterpart
|
|
function get_counterpart(rank, onlyCounterpart)
|
|
|
|
--onlyCounterpart is used for UI
|
|
if onlyCounterpart then
|
|
return nil
|
|
end
|
|
|
|
return ref_getCounterPart(rank, onlyCounterpart)
|
|
end
|
|
|
|
local max_rank_id_number = -1
|
|
|
|
for _, v in pairs(SMODS.Ranks) do
|
|
if v.id > 0 and v.id > max_rank_id_number then
|
|
max_rank_id_number = v.id
|
|
end
|
|
end
|
|
|
|
rank_sh_two_half.is_decimal = true
|
|
rank_sh_two_half.rank_act = {'2', '2.5', '3'}
|
|
rank_sh_two_half.next = { 'unstb_e', '3', 'unstb_Pi', '4' }
|
|
rank_sh_two_half.prev = { '2' }
|
|
rank_sh_two_half.strength_effect = {
|
|
fixed = 2,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
rank_sh_two_half.id = max_rank_id_number + 1
|
|
|
|
rank_sh_five_half.is_decimal = true
|
|
rank_sh_five_half.rank_act = {'5', '5.5', '6'}
|
|
rank_sh_five_half.next = { '6', '7'}
|
|
rank_sh_five_half.prev = { '5' }
|
|
rank_sh_five_half.id = max_rank_id_number + 2
|
|
|
|
rank_sh_eight_half.is_decimal = true
|
|
rank_sh_eight_half.rank_act = {'8', '8.5', '9'}
|
|
rank_sh_eight_half.next = { '9', '10'}
|
|
rank_sh_eight_half.prev = { '8' }
|
|
rank_sh_eight_half.id = max_rank_id_number + 3
|
|
|
|
rank_sh_butler.is_decimal = true
|
|
rank_sh_butler.rank_act = {'Jack', 'Butler', 'Queen'}
|
|
rank_sh_butler.next = {'Queen', 'showdown_Princess', 'King'}
|
|
rank_sh_butler.prev = { 'Jack' }
|
|
rank_sh_butler.id = max_rank_id_number + 4
|
|
|
|
rank_sh_princess.is_decimal = true
|
|
rank_sh_princess.rank_act = {'Queen', 'Princess', 'King'}
|
|
rank_sh_princess.next = {'King', 'showdown_Lord', 'Ace'}
|
|
rank_sh_princess.prev = { 'Queen' }
|
|
rank_sh_princess.id = max_rank_id_number + 5
|
|
|
|
rank_sh_lord.is_decimal = true
|
|
rank_sh_lord.rank_act = {'King', 'Lord'}
|
|
rank_sh_lord.next = {'Ace'}
|
|
rank_sh_lord.prev = { 'King' }
|
|
rank_sh_lord.id = max_rank_id_number + 6
|
|
|
|
--Jank, mostly bc Showdown's rank id is forced to be negative for the counterparts, thus ended up mess with the total rank ID orders
|
|
SMODS.Rank.max_id.value = rank_sh_lord.id
|
|
|
|
--Changes to existing ranks to allow Straight in numerical order
|
|
SMODS.Ranks['2'].strength_effect = {
|
|
fixed = 3,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
SMODS.Ranks['2'].next = {'showdown_2.5', 'unstb_e', '3', 'unstb_Pi'}
|
|
|
|
SMODS.Ranks['5'].strength_effect = {
|
|
fixed = 2,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
SMODS.Ranks['5'].next = {'showdown_5.5', '6'}
|
|
|
|
SMODS.Ranks['8'].strength_effect = {
|
|
fixed = 2,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
SMODS.Ranks['8'].next = {'showdown_8.5', '9'}
|
|
|
|
SMODS.Ranks['10'].next = {'Jack', 'showdown_Butler', 'unstb_11'}
|
|
|
|
SMODS.Ranks['Jack'].strength_effect = {
|
|
fixed = 2,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
SMODS.Ranks['Jack'].next = {'showdown_Butler', 'Queen', 'showdown_Princess'}
|
|
|
|
SMODS.Ranks['Queen'].strength_effect = {
|
|
fixed = 2,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
SMODS.Ranks['Queen'].next = {'showdown_Princess', 'King', 'showdown_Lord'}
|
|
|
|
SMODS.Ranks['King'].strength_effect = {
|
|
fixed = 2,
|
|
random = false,
|
|
ignore = false
|
|
}
|
|
SMODS.Ranks['King'].next = {'showdown_Lord', 'Ace'}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
--Hook for the game's splash screen, to initialize any data that is sensitive to the mod's order (mainly rank stuff)
|
|
|
|
local ref_gamesplashscreen = Game.splash_screen
|
|
|
|
function Game:splash_screen()
|
|
ref_gamesplashscreen(self)
|
|
|
|
--Cryptid stuff has to be done on Splash Screen because of its high priority
|
|
if check_mod_active("Cryptid") then
|
|
print("Inject new nominal code override for Cryptid")
|
|
|
|
--Make a dedicated table of rank id and the nominal order
|
|
--This is because Cryptid randomize nominal chips in Misprint Deck and Glitched Edition
|
|
|
|
local rank_nominal_order = {}
|
|
|
|
for key, rank in pairs(SMODS.Ranks) do
|
|
rank_nominal_order[key] = rank.nominal
|
|
end
|
|
|
|
--Basically the same code from the basegame, but swap nominal out with the new rank_nominal_order property
|
|
function Card:get_nominal(mod)
|
|
local mult = 1
|
|
local rank_mult = 1
|
|
if mod == 'suit' then mult = 30000 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
|
|
--Temporary fix so the card with the lowest nominal can still be sorted properly
|
|
local nominal = rank_nominal_order[self.base.value] or 0
|
|
|
|
if self.base.value == 'unstb_???' then
|
|
nominal = 0.3
|
|
elseif nominal < 0.4 then
|
|
nominal = 0.31 + nominal*0.1
|
|
end
|
|
|
|
--Hardcode this so it's sorted properly
|
|
if self.base.value == 'unstb_161' then
|
|
nominal = 30
|
|
end
|
|
|
|
return 10*(nominal)*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
|
|
|
|
--Secret interaction: The "Jolly Joker" (UnStable Joker) counts as Jolly as well
|
|
local ref_card_is_jolly = Card.is_jolly
|
|
function Card:is_jolly()
|
|
if self.config.center.key == 'j_unstb_the_jolly_joker' then
|
|
return true
|
|
end
|
|
|
|
return ref_card_is_jolly(self)
|
|
end
|
|
|
|
--Inject Blinds effect
|
|
|
|
print("Inject Blind effects for Cryptid")
|
|
|
|
local blind_hammer = SMODS.Blinds['bl_cry_hammer'] or {}
|
|
|
|
blind_hammer.recalc_debuff = function(self, card, from_blind)
|
|
if card.area ~= G.jokers and not G.GAME.blind.disabled then
|
|
if
|
|
card.ability.effect ~= "Stone Card"
|
|
and (
|
|
card.base.value == "3"
|
|
or card.base.value == "5"
|
|
or card.base.value == "7"
|
|
or card.base.value == "9"
|
|
or card.base.value == "Ace"
|
|
or card.base.value == "unstb_1"
|
|
or card.base.value == "unstb_21"
|
|
|
|
or card.base.value == "unstb_11"
|
|
or card.base.value == "unstb_13"
|
|
or card.base.value == "unstb_25"
|
|
or card.base.value == "unstb_161"
|
|
|
|
or card.base.value == "unstb_???"
|
|
)
|
|
then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
end
|
|
|
|
local blind_magic = SMODS.Blinds['bl_cry_magic'] or {}
|
|
|
|
blind_magic.recalc_debuff = function(self, card, from_blind)
|
|
if card.area ~= G.jokers and not G.GAME.blind.disabled then
|
|
if
|
|
card.ability.effect ~= "Stone Card"
|
|
and (
|
|
card.base.value == "2"
|
|
or card.base.value == "4"
|
|
or card.base.value == "6"
|
|
or card.base.value == "8"
|
|
or card.base.value == "10"
|
|
or card.base.value == "unstb_0"
|
|
or card.base.value == "unstb_12"
|
|
or card.base.value == "unstb_???"
|
|
|
|
or card.base.value == "showdown_Zero"
|
|
)
|
|
then
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
end
|
|
|
|
--Override ://VARIABLE Code card's code
|
|
--Because the original code has problem with the card with modded rank
|
|
--Also, switch over to SMODS.change_base instead of manually building card key,
|
|
--which was the cause of the problem
|
|
|
|
unstbex_global.cryptid_variable_rank = {'', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace', '', '', '', 'unstb_0', 'unstb_21', 'unstb_0.5', 'unstb_r2', 'unstb_e', 'unstb_Pi', 'unstb_1', 'unstb_11', 'unstb_12', 'unstb_13', 'unstb_25', 'unstb_161', 'unstb_???'}
|
|
|
|
G.FUNCS.variable_apply = function()
|
|
local rank_table = {
|
|
{},
|
|
{ "2", "Two", "II" },
|
|
{ "3", "Three", "III" },
|
|
{ "4", "Four", "IV" },
|
|
{ "5", "Five", "V" },
|
|
{ "6", "Six", "VI" },
|
|
{ "7", "Seven", "VII" },
|
|
{ "8", "Eight", "VIII" },
|
|
{ "9", "Nine", "IX" },
|
|
{ "10", "1O", "Ten", "X", "T" },
|
|
{ "J", "Jack" },
|
|
{ "Q", "Queen" },
|
|
{ "K", "King" },
|
|
{ "A", "Ace"}, --Notably, 1 is now 1 and not Ace :P
|
|
{ "M" },
|
|
{ "nil" },
|
|
{}, --Not sure if I should left it blank but its used for a cheat check below??
|
|
|
|
--UNSTB Rank
|
|
{"0", "O", "Zero"},
|
|
{"21", "Twenty-One", "TwentyOne", "XXI", "BJ"},
|
|
{"0.5", "O.5", "Half"},
|
|
{"1.4", "1.41", "Root2", "Sqrt2", "Root", "Sqrt", "r", "sq"},
|
|
{"2.7", "2.71","e", "Euler"},
|
|
{"3.1", "3.14", "22/7", "Pi", "P"},
|
|
{"1", "One", "I"},
|
|
|
|
{"11", "Eleven", "XI"},
|
|
{"12", "Twelve", "XII"},
|
|
{"13", "Thirteen", "XIII"},
|
|
|
|
{"25", "Twenty-Five", "TwentyFive", "XXV", "quad"},
|
|
|
|
{"161", "OneHundredSixtyOne", "OneSixOne", "CLXI", "abomination"},
|
|
|
|
{"?", "???", "Question", "idk"},
|
|
}
|
|
|
|
local rank_suffix = nil
|
|
|
|
for i, v in pairs(rank_table) do
|
|
for j, k in pairs(v) do
|
|
if string.lower(G.ENTERED_RANK) == string.lower(k) then
|
|
rank_suffix = i
|
|
end
|
|
end
|
|
end
|
|
|
|
if rank_suffix then
|
|
G.PREVIOUS_ENTERED_RANK = G.ENTERED_RANK
|
|
G.GAME.USING_CODE = false
|
|
if rank_suffix == 15 then
|
|
check_for_unlock({ type = "cheat_used" })
|
|
local card = create_card("Joker", G.jokers, nil, nil, nil, nil, "j_jolly")
|
|
card:add_to_deck()
|
|
G.jokers:emplace(card)
|
|
elseif rank_suffix == 16 then
|
|
check_for_unlock({ type = "cheat_used" })
|
|
local card = create_card("Code", G.consumeables, nil, nil, nil, nil, "c_cry_crash")
|
|
card:add_to_deck()
|
|
G.consumeables:emplace(card)
|
|
elseif rank_suffix == 17 then
|
|
check_for_unlock({ type = "cheat_used" })
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.4,
|
|
func = function()
|
|
play_sound("tarot1")
|
|
return true
|
|
end,
|
|
}))
|
|
for i = 1, #G.hand.highlighted do
|
|
local percent = 1.15 - (i - 0.999) / (#G.hand.highlighted - 0.998) * 0.3
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.15,
|
|
func = function()
|
|
G.hand.highlighted[i]:flip()
|
|
play_sound("card1", percent)
|
|
G.hand.highlighted[i]:juice_up(0.3, 0.3)
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
delay(0.2)
|
|
for i = 1, #G.hand.highlighted do
|
|
local CARD = G.hand.highlighted[i]
|
|
local percent = 0.85 + (i - 0.999) / (#G.hand.highlighted - 0.998) * 0.3
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.15,
|
|
func = function()
|
|
CARD:flip()
|
|
CARD:set_ability(
|
|
G.P_CENTERS[pseudorandom_element(G.P_CENTER_POOLS.Consumeables, pseudoseed("cry_variable")).key],
|
|
true,
|
|
nil
|
|
)
|
|
play_sound("tarot2", percent)
|
|
CARD:juice_up(0.3, 0.3)
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
else
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.4,
|
|
func = function()
|
|
play_sound("tarot1")
|
|
return true
|
|
end,
|
|
}))
|
|
for i = 1, #G.hand.highlighted do
|
|
local percent = 1.15 - (i - 0.999) / (#G.hand.highlighted - 0.998) * 0.3
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.15,
|
|
func = function()
|
|
G.hand.highlighted[i]:flip()
|
|
play_sound("card1", percent)
|
|
G.hand.highlighted[i]:juice_up(0.3, 0.3)
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
delay(0.2)
|
|
for i = 1, #G.hand.highlighted do
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.1,
|
|
func = function()
|
|
local card = G.hand.highlighted[i]
|
|
local new_rank = unstbex_global.cryptid_variable_rank[rank_suffix]
|
|
|
|
--Fallback
|
|
if not new_rank or new_rank == '' then
|
|
new_rank = 'unstb_???'
|
|
end
|
|
|
|
SMODS.change_base(card, nil, new_rank)
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
for i = 1, #G.hand.highlighted do
|
|
local percent = 0.85 + (i - 0.999) / (#G.hand.highlighted - 0.998) * 0.3
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.15,
|
|
func = function()
|
|
G.hand.highlighted[i]:flip()
|
|
play_sound("tarot2", percent, 0.6)
|
|
G.hand.highlighted[i]:juice_up(0.3, 0.3)
|
|
return true
|
|
end,
|
|
}))
|
|
end
|
|
G.E_MANAGER:add_event(Event({
|
|
trigger = "after",
|
|
delay = 0.2,
|
|
func = function()
|
|
G.hand:unhighlight_all()
|
|
return true
|
|
end,
|
|
}))
|
|
delay(0.5)
|
|
end
|
|
G.CHOOSE_RANK:remove()
|
|
end
|
|
end
|
|
|
|
end
|
|
end |