diff --git a/README.md b/README.md index 735b607..587ab27 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,5 @@ A Balatro sound loader. _Developed by: [Goldenleaf](https://golden-leaf.itch.io), [JoglaCraft](https://github.com/Joglacraft), [BepisFever](https://github.com/bepisfever)._ + +Note: Please check rhe [Github Wiki](https://github.com/Goldofleaves/Tonsmith/wiki) if you find yourself troubled when making a soundpack. diff --git a/assets/1x/default_soundpack.png b/assets/1x/default_soundpack.png new file mode 100644 index 0000000..dcec500 Binary files /dev/null and b/assets/1x/default_soundpack.png differ diff --git a/assets/2x/default_soundpack.png b/assets/2x/default_soundpack.png new file mode 100644 index 0000000..9f0e391 Binary files /dev/null and b/assets/2x/default_soundpack.png differ diff --git a/config.lua b/config.lua index 0c62d7d..3b9cc42 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,6 @@ return { - soundpack_priority = {}, - display_menu_button = true, + loaded_packs = {}, + menu_button = true, rows = 2, - c_rows = 6 + cols = 6 } \ No newline at end of file diff --git a/localization/default.lua b/localization/default.lua deleted file mode 100644 index 8859107..0000000 --- a/localization/default.lua +++ /dev/null @@ -1,39 +0,0 @@ -return{ - descriptions = { - dictionary = { - tnsmi_config_tab_name = { - text = { - "Soundpack manager" - } - }, - tnsmi_config_tab_desc = { - text = { - "Left less priority, right more priority", - }, - }, - } - }, - misc = { - dictionary = { - -- config - tnsmi_cfg_soundpack_manager = "Open soundpack manager", - tnsmi_cfg_rows = "Rows to display", - tnsmi_cfg_c_rows = "Packs per row", - - -- manager - tnsmi_manager_pause = "Soundpacks", - tnsmi_manager_display_in_pause = "Display in pause menu", - tnsmi_manager_selected = "SELECTED", - tnsmi_manager_click_select = "CLICK TO SELECT", - tnsmi_manager_active = "Soundpacks active", - tnsmi_manager_installed = "Soundpacks installed", - - -- misc - tnsmi_filter_label = "FILTER", - tnsmi_close = "Close", - tnsmi_options = "Options", - tnsmi_version_label = "Version", - - }, - }, -} diff --git a/localization/en-us.lua b/localization/en-us.lua new file mode 100644 index 0000000..f234b1f --- /dev/null +++ b/localization/en-us.lua @@ -0,0 +1,108 @@ +return{ + descriptions = { + SoundPack = { + sp_tnsmi_fools_gambit = { + name = "Fool's Gambit", + text = { + "{X:chips,C:white}Author{}", + "{C:attention,E:1}GoldenLeaf{}" + } + }, + sp_tnsmi_dummy1 = { + name = "Dummy 1", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy2 = { + name = "Dummy 2", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy3 = { + name = "Dummy 3", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy4 = { + name = "Dummy 4", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy5 = { + name = "Dummy 5", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy6 = { + name = "Dummy 6", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy7 = { + name = "Dummy 7", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy8 = { + name = "Dummy 8", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy9 = { + name = "Dummy 9", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy10 = { + name = "Dummy 10", + text = { + "[Dummy Text]" + } + }, + sp_tnsmi_dummy11 = { + name = "Dummy 11", + text = { + "[Dummy Text]" + } + }, + } + }, + misc = { + dictionary = { + -- config + k_soundpack = 'Sound Pack', + b_remove = 'Remove', + tnsmi_cfg_soundpack_manager = "Open soundpack manager", + tnsmi_cfg_rows = "Rows to display", + tnsmi_cfg_cols = "Packs per row", + + -- manager + tnsmi_manager_pause = "Soundpacks", + tnsmi_manager_display_in_pause = "Display in pause menu", + tnsmi_manager_selected = "SELECTED", + tnsmi_manager_loaded = "DRAG FOR PRIORITY", + tnsmi_manager_click_select = "CLICK TO SELECT", + tnsmi_manager_active = "Soundpacks active", + tnsmi_manager_installed = "Soundpacks installed", + + -- misc + tnsmi_filter_label = "FILTER", + tnsmi_close = "Close", + tnsmi_options = "Options", + tnsmi_version_label = "Version", + + }, + v_dictionary = { + tnsmi_search_text = "Showing #1#-#2# of #3# results" + } + }, +} diff --git a/lovely/cardarea.toml b/lovely/cardarea.toml deleted file mode 100644 index 34fe486..0000000 --- a/lovely/cardarea.toml +++ /dev/null @@ -1,28 +0,0 @@ -[manifest] -version = "1.0.0" -dump_lua = true -priority = 0 - -[[patches]] -[patches.pattern] -target = "cardarea.lua" -pattern = ''' -local card_count = self ~= G.shop_vouchers and {n=G.UIT.R, config={align = self == G.jokers and 'cl' or self == G.hand and 'cm' or 'cr', padding = 0.03, no_fill = true}, nodes={ - {n=G.UIT.B, config={w = 0.1,h=0.1}}, - {n=G.UIT.T, config={ref_table = self.config, ref_value = 'card_count', scale = 0.3, colour = G.C.WHITE}}, - {n=G.UIT.T, config={text = '/', scale = 0.3, colour = G.C.WHITE}}, - {n=G.UIT.T, config={ref_table = self.config, ref_value = 'card_limit', scale = 0.3, colour = G.C.WHITE}}, - {n=G.UIT.B, config={w = 0.1,h=0.1}} - }} or nil -''' -position = "at" -payload = ''' -local card_count = self ~= G.shop_vouchers and (not self.config or not self.config.hide_card_count) and {n=G.UIT.R, config={align = self == G.jokers and 'cl' or self == G.hand and 'cm' or 'cr', padding = 0.03, no_fill = true}, nodes={ - {n=G.UIT.B, config={w = 0.1,h=0.1}}, - {n=G.UIT.T, config={ref_table = self.config, ref_value = 'card_count', scale = 0.3, colour = G.C.WHITE}}, - {n=G.UIT.T, config={text = '/', scale = 0.3, colour = G.C.WHITE}}, - {n=G.UIT.T, config={ref_table = self.config, ref_value = 'card_limit', scale = 0.3, colour = G.C.WHITE}}, - {n=G.UIT.B, config={w = 0.1,h=0.1}} - }} or nil -''' -match_indent = true diff --git a/lovely/malverk_override.toml b/lovely/malverk_override.toml index 0ffba1a..434172c 100644 --- a/lovely/malverk_override.toml +++ b/lovely/malverk_override.toml @@ -14,7 +14,7 @@ pattern = '''customize = {n=G.UIT.R, config={minw = 5, align='cl'}, nodes = { }}''' position = "after" payload = ''' -if Malverk and TNSMI and TNSMI.mod_config.display_menu_button then +if Malverk and TNSMI and TNSMI.config.menu_button then customize = {n=G.UIT.R, config={minw = 5, align='cl'}, nodes = { UIBox_button{ label = {localize('b_deck_skins')}, col = true, button = "customize_deck", minw = 3.4}, { n = G.UIT.C, config = {minw = 0.2}}, diff --git a/lovely/text_input.toml b/lovely/text_input.toml deleted file mode 100644 index 174650e..0000000 --- a/lovely/text_input.toml +++ /dev/null @@ -1,21 +0,0 @@ -[manifest] -version = "1.0.0" -dump_lua = true -priority = 1 - -[[patches]] -[patches.pattern] -target = 'functions/button_callbacks.lua' -match_indent = true -position = 'at' -pattern = ''' -if args.key == '[' or args.key == ']' then return end -if args.key == '0' then args.key = 'o' end -''' -payload = ''' -local tnsmi_hook_config = G.CONTROLLER.text_input_hook.config -if not tnsmi_hook_config or not tnsmi_hook_config.tnsmi_input then - if args.key == '0' then args.key = 'o' end -end -if args.key == '[' or args.key == ']' then return end -''' diff --git a/lovely/ui.toml b/lovely/ui.toml new file mode 100644 index 0000000..dd0b462 --- /dev/null +++ b/lovely/ui.toml @@ -0,0 +1,15 @@ +[manifest] +version = "1.0.0" +dump_lua = true +priority = 0 + +[[patches]] +[patches.pattern] +target = "functions/UI_definitions.lua" +pattern = '''customize, +credits''' +position = "at" +payload = '''customize, +UIBox_button{ label = {localize("tnsmi_manager_pause")}, button = "TNSMI_packs_button", minw = 5, colour = G.C.RED}, +credits''' +match_indent = true \ No newline at end of file diff --git a/main.lua b/main.lua index e744df2..443e5d2 100644 --- a/main.lua +++ b/main.lua @@ -1,17 +1,12 @@ -TNSMI = { - CARDAREAS = {}, - row = 2, - card_per_row = 6, - page = 1, - max_pages = 1, - pagecounter = 0, - prompt_text_input = "", - menu_mod = "base", - mod_config = SMODS.current_mod.config, - filterpacks = {} -} +TNSMI = SMODS.current_mod +TNSMI.config.loaded_packs.replace_map = {} +TNSMI.cardareas = {} +TNSMI.prompt_text_input = '' +TNSMI.search_text = '' SMODS.Atlas{key = "modicon", path = "modicon.png", px = 32, py = 32} +G.C.SECONDARY_SET.SoundPack = HEX("56A887") + local mod_contents = { "utils", "overrides", @@ -21,20 +16,10 @@ local mod_contents = { for k, v in pairs(mod_contents) do assert(SMODS.load_file('/src/'..v..'.lua'))() end -TNSMI.Pack{ - name = "Fool's Gambit", - description = { - { - lan = 'en-us', - text = { - "This is the SFX Used in", - "Fool's Gambit." - }, - }, - }, - mods = {"Vanilla"}, - authors = {"GoldenLeaf"}, - thumbnail = "thumb", + +TNSMI.SoundPack({ + key = 'fools_gambit', + atlas = 'thumb', sound_table = { { key = "ambientFire1" }, { key = "ambientFire2" }, @@ -111,10 +96,87 @@ TNSMI.Pack{ { key = "whoosh1" }, { key = "whoosh2" }, { key = "win" }, - { key = "music1" , file = "main", pitch = 1}, - { key = "music2" , file = "arcana", pitch = 1}, - { key = "music3" , file = "celestial", pitch = 1}, - { key = "music4" , file = "shop", pitch = 1}, - { key = "music5" , file = "boss", pitch = 1} + { key = "music1", path = 'main.ogg', pitch = 1}, + { key = "music2", path = 'arcana.ogg', pitch = 1}, + { key = "music3", path = 'celestial.ogg', pitch = 1}, + { key = "music4", path = 'shop.ogg', pitch = 1}, + { key = "music5", path = 'boss.ogg', pitch = 1} + }, +}) + +TNSMI.SoundPack({ + key = 'dummy1', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +TNSMI.SoundPack({ + key = 'dummy2', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +TNSMI.SoundPack({ + key = 'dummy3', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +TNSMI.SoundPack({ + key = 'dummy4', + sound_table = { + { key = "ambientFire1" }, + }, +}) + + +TNSMI.SoundPack({ + key = 'dummy5', + sound_table = { + { key = "ambientFire1" }, + }, +}) +TNSMI.SoundPack({ + key = 'dummy6', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +TNSMI.SoundPack({ + key = 'dummy7', + sound_table = { + { key = "ambientFire1" }, }, -} \ No newline at end of file +}) + +TNSMI.SoundPack({ + key = 'dummy8', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +TNSMI.SoundPack({ + key = 'dummy9', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +TNSMI.SoundPack({ + key = 'dummy10', + sound_table = { + { key = "ambientFire1" }, + }, +}) + +local ref_post_splash = G.FUNCS.initPostSplash or function() end +G.FUNCS.initPostSplash = function() + local ret = ref_post_splash() + TNSMI.save_soundpacks() + return ret +end diff --git a/src/UI.lua b/src/UI.lua index 11b781f..35f04ac 100644 --- a/src/UI.lua +++ b/src/UI.lua @@ -1,363 +1,167 @@ -local function tnsmi_desc_from_rows(desc_nodes, empty, align, maxw) - local t = {} - for k, v in ipairs(desc_nodes) do - t[#t+1] = {n=G.UIT.R, config={align = align or "cl", maxw = maxw}, nodes=v} - end - return {n=G.UIT.R, config={align = "cm", colour = empty and G.C.CLEAR or G.C.UI.BACKGROUND_WHITE, r = 0.1, padding = 0.04, minw = 2, minh = 0.25, emboss = not empty and 0.05 or nil, filler = true}, nodes={ - {n=G.UIT.R, config={align = align or "cl", padding = 0.03}, nodes=t} - }} -end - -function Card:resize(mod) - self:hard_set_T(self.T.x, self.T.y, self.T.w * mod, self.T.h * mod) - remove_all(self.children) - self.children = {} - self.children.shadow = Moveable(0, 0, 0, 0) - self:set_sprites(self.config.center, self.base.id and self.config.card) -end - -function TNSMI.create_fake_card(c_key, area) --Taken from Balatro Star Rail :3 - local card = Card(area.T.x + area.T.w / 2, area.T.y, - G.CARD_W, G.CARD_H, G.P_CARDS.empty, - G.P_CENTERS[c_key]) - card.children.back = Sprite(card.T.x, card.T.y, card.T.w, card.T.h, G.ASSET_ATLAS[(G.P_CENTERS[c_key] and G.P_CENTERS[c_key].atlas) or "Joker"], (G.P_CENTERS[c_key] and G.P_CENTERS[c_key].pos) or {x = 0, y = 0}) - card.children.back.states.hover = card.states.hover - card.children.back.states.click = card.states.click - card.children.back.states.drag = card.states.drag - card.children.back.states.collide.can = false - card.children.back:set_role({major = card, role_type = 'Glued', draw_major = card}) - - area:emplace(card) +function create_soundpack_card(area, pack, pos) + local atlas = G.ANIMATION_ATLAS[pack.atlas] or G.ASSET_ATLAS[pack.atlas] + local size_mod = TNSMI.get_size_mod() + local card = Card( + area.T.x, + area.T.y, + G.CARD_W * size_mod, + G.CARD_H * size_mod, + nil, + {key = pack.key, name = "Sound Pack", atlas = pack.atlas, pos={x=0,y=0}, set = "SoundPack", label = 'Sound Pack', config = {}, generate_ui = SMODS.Center.generate_ui}, + {tnsmi_soundpack = pack.key} + ) - return card -end + card.states.drag.can = area == TNSMI.cardareas.priority + if atlas.frames then + --card.T.w = W + --card.T.h = H + card.children.animatedSprite = AnimatedSprite(card.T.x, card.T.y, card.T.w, card.T.h, atlas, atlas.pos) + card.children.animatedSprite.T.w = W + card.children.animatedSprite.T.h = H + card.children.animatedSprite:set_role({major = card, role_type = 'Glued', draw_major = card}) + card.children.animatedSprite:rescale() + card.children.animatedSprite.collide.can = false + card.children.animatedSprite.drag.can = false + card.children.center:remove() + card.children.back:remove() + card.no_shadow = true + area:emplace(card, pos) + return card + end -G.FUNCS.tnsmi_load_text_input = function(e) - if not e.config or not e.config.auto_selected then - if not e.config then e.config = {} end - e.config.auto_selected = true + area:emplace(card, pos) + if TNSMI.dissolve_flag == pack.key then + card.states.visible = false G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.15, + blocking = false, blockable = false, - func = function() - e.UIBox:recalculate(true) - return true - end + func = (function() + card:start_materialize(nil, nil, 0.25) + return true + end) })) - end -end - -function tnsmi_create_text_input(args) - args = args or {} - args.colour = copy_table(args.colour) or copy_table(G.C.BLUE) - args.hooked_colour = copy_table(args.hooked_colour) or darken(copy_table(G.C.BLUE), 0.3) - args.w = args.w or 2.5 - args.h = args.h or 0.7 - args.text_scale = args.text_scale or 0.4 - args.max_length = args.max_length or 100 - args.all_caps = args.all_caps or false - args.prompt_text = args.prompt_text or localize('k_enter_text') - args.current_prompt_text = '' - args.id = args.id or "text_input" - - local text = {ref_table = args.ref_table, ref_value = args.ref_value, letters = {}, current_position = string.len(args.ref_table[args.ref_value])} - local ui_letters = {} - for i = 1, args.max_length do - text.letters[i] = (args.ref_table[args.ref_value] and (string.sub(args.ref_table[args.ref_value], i, i) or '')) or '' - ui_letters[i] = {n=G.UIT.T, config={ref_table = text.letters, ref_value = i, scale = args.text_scale, colour = G.C.UI.TEXT_LIGHT, id = args.id..'_letter_'..i}} - end - args.text = text - - local position_text_colour = lighten(copy_table(G.C.BLUE), 0.4) - - ui_letters[#ui_letters+1] = {n=G.UIT.T, config={ref_table = args, ref_value = 'current_prompt_text', scale = args.text_scale, colour = lighten(copy_table(args.colour), 0.4), id = args.id..'_prompt'}} - ui_letters[#ui_letters+1] = {n=G.UIT.B, config={r = 0.03,w=0.1, h=0.4, colour = position_text_colour, id = args.id..'_position', func = 'flash'}} - local t = - {n=G.UIT.C, config={align = "cm", colour = G.C.CLEAR}, nodes = { - {n=G.UIT.C, config={id = args.id, align = "cm", padding = 0.05, r = 0.1, hover = true, colour = args.colour,minw = args.w, min_h = args.h, func = "tnsmi_load_text_input", button = 'select_text_input', shadow = true}, nodes={ - {n=G.UIT.R, config={ref_table = args, padding = 0.05, align = "cm", r = 0.1, colour = G.C.CLEAR}, nodes={ - {n=G.UIT.R, config={ref_table = args, align = "cm", r = 0.1, colour = G.C.CLEAR, func = 'text_input', tnsmi_input = true}, nodes= - ui_letters - } - }} - }} - }} - return t -end -function TNSMI.refresh_cardareas() - for i,v in pairs(TNSMI.CARDAREAS) do - v:remove() - TNSMI.CARDAREAS[i] = nil + TNSMI.dissolve_flag = nil end end -function TNSMI.load_cards() - - for _,v in pairs(TNSMI.CARDAREAS) do - if v.cards then - for _,vv in ipairs(v.cards) do - vv:start_dissolve(nil,true,0) - end - v.cards = {} - end - end - if not TNSMI.CARDAREAS.selected or not TNSMI.CARDAREAS.selected.cards then return end - local n_packs = 0 - for _,_ in pairs(TNSMI.packs) do n_packs = n_packs + 1 end - if n_packs < 1 then return end - - for i,v in ipairs(TNSMI.CARDAREAS.selected.cards) do - v:start_dissolve(nil,true,0) - end - - -- For already existing packs - for i,v in ipairs(TNSMI.mod_config.soundpack_priority) do - local exists = false - for ii,vv in ipairs(TNSMI.packs) do - if v == vv.mod_prefix.."_"..vv.name then exists = true end - end - if exists then - local card = TNSMI.create_fake_card("j_"..v,TNSMI.CARDAREAS.selected) - card.ability.tnsmi_card = true - card:resize(0.7) - else - table.remove(TNSMI.mod_config.soundpack_priority,i) - end - end - - -- For newly added packs - for i,v in ipairs(TNSMI.packs) do - if v.priority == 0 and v.selected then - local card = TNSMI.create_fake_card("j_"..v.mod_prefix.."_"..v.name,TNSMI.CARDAREAS.selected) - card.ability.tnsmi_card = true - card:resize(0.7) - end - end - - TNSMI.load_soundpack_order() - - local temp_fill = {} +function create_UIBox_soundpacks() + local size_mod = TNSMI.get_size_mod() + if TNSMI.cardareas.priority then TNSMI.cardareas.priority:remove() end + TNSMI.cardareas.priority = CardArea(0, 0, G.CARD_W * TNSMI.config.cols * size_mod * 1.5, G.CARD_H * size_mod, + {card_limit = TNSMI.config.cols, type = 'soundpack', highlight_limit = 99} + ) - for i,v in ipairs(TNSMI.packs) do - if v and not v.selected then - table.insert(temp_fill,v) - end + for _, v in ipairs(TNSMI.config.loaded_packs) do + create_soundpack_card(TNSMI.cardareas.priority, TNSMI.SoundPacks[v], 'front') end - for i=1, (TNSMI.mod_config.rows*TNSMI.mod_config.c_rows*(TNSMI.page-1)) do table.remove(temp_fill,1) end - - local row = 1 - for i,v in ipairs(temp_fill) do - if row > TNSMI.mod_config.rows then break end - local card = TNSMI.create_fake_card("j_"..v.mod_prefix.."_"..v.name, TNSMI.CARDAREAS["available"..row]) - card.ability.tnsmi_card = true - card:resize(0.7) - if #TNSMI.CARDAREAS["available"..row].cards >= TNSMI.mod_config.c_rows then row = row + 1 end + -- these are likely unnecessary because area references get cleaned when UI is removed (I think) + for i = #TNSMI.cardareas, 1, -1 do + TNSMI.cardareas[i]:remove() + TNSMI.cardareas[i] = nil end -end -function G.FUNCS.tnsmi_search() - TNSMI.packs = SMODS.shallow_copy(TNSMI.reference) - local fuckyou = TNSMI.prompt_text or "" - local function j () - for k, v in ipairs(TNSMI.packs) do - if type(string.find(v.name, fuckyou)) == "nil" then - table.remove(TNSMI.packs, k) - j() - end - end - end - j() - TNSMI.load_cards() -end + if #TNSMI.SoundPack.obj_buffer < 1 then return end -function G.FUNCS.tnsmi_next_page(e) - if TNSMI.max_pages > 0 then - TNSMI.page = TNSMI.page + 1 - TNSMI.page = ((TNSMI.page - 1) % math.ceil(#TNSMI.packs / (TNSMI.mod_config.rows * TNSMI.mod_config.c_rows))) + 1 - end - TNSMI.load_cards() -end + local area_nodes = {} + for i=1, TNSMI.config.rows do + TNSMI.cardareas[i] = CardArea(0, 0, G.CARD_W * TNSMI.config.cols * size_mod * 1.5, G.CARD_H * size_mod, + {card_limit = TNSMI.config.cols, highlight_limit = 99, type = 'soundpack'} + ) -function G.FUNCS.tnsmi_prev_page(e) - if TNSMI.max_pages > 0 then - TNSMI.page = TNSMI.page - 1 - if TNSMI.page < 1 then - TNSMI.page = math.ceil(#TNSMI.packs / (TNSMI.mod_config.rows * TNSMI.mod_config.c_rows)) - TNSMI.page - end + area_nodes[#area_nodes+1] = {n = G.UIT.R, config = {align = "cm", colour = G.C.CLEAR}, nodes = { + {n = G.UIT.O, config = {id = 'tnsmi_area_'..i, object = TNSMI.cardareas[i]}} + }} end - TNSMI.load_cards() -end - -function TNSMI.main_tab () - TNSMI.CARDAREAS.selected = CardArea( - G.ROOM.T.x + 0.2 * G.ROOM.T.w / 2, G.ROOM.T.h, - G.CARD_W * 4, - G.CARD_H / 1.5, - {card_limit = #TNSMI.packs or 0, type = 'joker', hide_card_count = true, no_highlight = true} - ) - local name_node = {} - localize {type = 'descriptions', key = "tnsmi_config_tab_name", set = 'dictionary', nodes = name_node, scale = 2, text_colour = G.C.WHITE, shadow = true} - name_node = tnsmi_desc_from_rows(name_node,true,"cm") --Reorganizes the text in the node properly (?). - name_node.config.align = "cm" + TNSMI.cycle_config = { + options = {}, + w = 4.5, + cycle_shoulders = true, + opt_callback = 'soundpacks_page', + focus_args = {snap_to = true, nav = 'wide'}, + current_option = 1, + colour = G.C.RED, + no_pips = true, + } + local opt_cycle = create_option_cycle(TNSMI.cycle_config) + opt_cycle.nodes[2].nodes[1].nodes[1].config.func = 'tnsmi_shoulder_buttons' + opt_cycle.nodes[2].nodes[1].nodes[3].config.func = 'tnsmi_shoulder_buttons' - local desc_node = {} - localize {type = 'descriptions', key = "tnsmi_config_tab_desc", set = 'dictionary', nodes = desc_node, scale = 1, text_colour = G.C.WHITE} - desc_node = tnsmi_desc_from_rows(desc_node,true,"cm") - desc_node.config.align = "cm" + G.FUNCS.reload_soundpack_cards() - local select_nodes = { - {n = G.UIT.C, config = {align = "cm"}, nodes = { - {n = G.UIT.R, config = {align = "cm", padding = 0.1}, nodes = { - {n = G.UIT.C, config = {align = "cl", colour = G.C.CLEAR}, nodes = { - {n = G.UIT.T, config = {text = localize("tnsmi_manager_click_select"), scale = 0.45, colour = lighten(G.C.GREY,0.2), vert = true}}, - }}, - {n = G.UIT.C, config = {align = "cm", colour = adjust_alpha(G.C.BLACK, 0.5), r = 0.2}, nodes = { - }}, + local t = { + {n = G.UIT.R, config = {align = "cm", colour = G.C.BLACK, r = 0.2, minh = 0.8, padding = 0.1}, nodes = { + {n = G.UIT.C, config = {align = "cl"}, nodes = { + {n = G.UIT.T, config = {align = 'cl', text = localize("tnsmi_manager_loaded"), padding = 0.1, scale = 0.25, colour = lighten(G.C.GREY,0.2), vert = true}}, }}, - {n = G.UIT.R, config = {align = "cm"}, nodes = { - {n = G.UIT.C, config = {align = "cm"}, nodes = { - }}, + {n = G.UIT.C, config = {align = "cr", func = 'TNSMI_change_priority'}, nodes = { + {n = G.UIT.O, config = {align = 'cr', minw = 6, object = TNSMI.cardareas.priority}} }}, }}, - } - - for i = 1, TNSMI.mod_config.rows do - TNSMI.CARDAREAS["available"..i] = CardArea( - G.ROOM.T.x + 0.2 * G.ROOM.T.w / 2, G.ROOM.T.h, - G.CARD_W * 4, - G.CARD_H / 1.5, - {card_limit = 5, type = 'shop', hide_card_count = true, horizontal_align = true, no_highlight = true} - ) - select_nodes[1].nodes[1].nodes[2].nodes[#select_nodes[1].nodes[1].nodes[2].nodes+1] = {n = G.UIT.R, config = {align = "cm", colour = G.C.CLEAR}, nodes = { - {n = G.UIT.O, config = {object = TNSMI.CARDAREAS["available"..i]}} - }} - end - - local page_cycle = { - {n = G.UIT.C, config = {align = "cm", minw = 0.5, minh = 0.5, padding = 0.1, r = 0.1, hover = true, colour = G.C.BLUE, shadow = true, button = "tnsmi_prev_page"}, nodes = { - {n = G.UIT.R, config = {align = "cm", padding = 0.05}, nodes = { - {n = G.UIT.T, config = {text = "<", scale = 0.4, colour = G.C.UI.TEXT_LIGHT}} - }} - }}, - {n = G.UIT.C, config = {align = "cm", minw = 2.5, minh = 0.5, padding = 0.1, r = 0.1, hover = true, colour = G.C.BLUE, shadow = true}, nodes = { - {n = G.UIT.R, config = {align = "cm", padding = 0.05}, nodes = { - {n = G.UIT.O, config = {object = DynaText{string = {localize("k_page").." "}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.4}}}, - {n = G.UIT.O, config = {object = DynaText{string = {{ref_table = TNSMI, ref_value = "page"}}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.4}}}, - {n = G.UIT.O, config = {object = DynaText{string = {"/"}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.4}}}, - {n = G.UIT.O, config = {object = DynaText{string = {{ref_table = TNSMI, ref_value = "max_pages"}}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.4}}}, - - }} - }}, - {n = G.UIT.C, config = {align = "cm", minw = 0.5, minh = 0.5, padding = 0.1, r = 0.1, hover = true, colour = G.C.BLUE, shadow = true, button = "tnsmi_next_page"}, nodes = { - {n = G.UIT.R, config = {align = "cm", padding = 0.05}, nodes = { - {n = G.UIT.T, config = {text = ">", scale = 0.4, colour = G.C.UI.TEXT_LIGHT}} - }} - }}, - } - - local footer = { - {n = G.UIT.R, config = {align = "cm", padding = 0.02, hover = true, shadow = true}, nodes = { - {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{label = {localize("tnsmi_close")}, minw = 2, minh = 0.65, colour = G.C.ORANGE, button = "options"}}}, - {n = G.UIT.C, config = {align = "cm", minw = 0.1}}, - {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{label = {localize("tnsmi_options")}, minw = 2, minh = 0.65, colour = G.C.GREEN, button = "TNSMI_open_mod_options"}}}, - {n = G.UIT.C, config = {align = "cm", minw = 0.2}}, - {n = G.UIT.C, config = {align = "cr", minw = 2}, nodes = { - {n = G.UIT.R, config = {align = "cr"}, nodes = { - {n = G.UIT.O, config = {object = DynaText{string = {localize("tnsmi_manager_active")..": "}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.25}}}, - {n = G.UIT.O, config = {object = DynaText{string = {{ref_table = TNSMI, ref_value = "n_loaded_packs"}}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.25}}} - }}, - {n = G.UIT.R, config = {align = "cr"}, nodes = { - {n = G.UIT.O, config = {object = DynaText{string = {localize("tnsmi_manager_installed")..": "}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.25}}}, - {n = G.UIT.O, config = {object = DynaText{string = {tostring(#TNSMI.packs)}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.25}}} - }}, + {n = G.UIT.R, config = {align = "cr", padding = 0}, nodes = { + {n = G.UIT.C, config = {align = "cr", padding = 0.1}, nodes = { + {n = G.UIT.T, config = {ref_table = TNSMI, ref_value = 'search_text', scale = 0.25, colour = lighten(G.C.GREY, 0.2)}}, }}, - {n = G.UIT.C, config = {align = "cm", minw = 0.1}}, - {n = G.UIT.C, config = {align = "cr", minw = 0}, nodes = { - {n = G.UIT.R, config = {align = "cr"}, nodes = { - {n = G.UIT.O, config = {object = DynaText{string = {localize("tnsmi_version_label")..": "}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.35}}}, - {n = G.UIT.O, config = {object = DynaText{string = {tostring(SMODS.find_mod("tonsmith")[1].version)}, colours = {G.C.UI.TEXT_LIGHT}, scale = 0.35}}} + {n = G.UIT.C, config = {align = "cr", colour = {G.C.L_BLACK[1], G.C.L_BLACK[2], G.C.L_BLACK[3], 0.5}, r = 0.2, padding = 0.1, minw = 3.5}, nodes = { + create_text_input({max_length = 12, w = 3.5, ref_table = TNSMI, ref_value = 'prompt_text_input'}), + {n = G.UIT.C, config = {align = "cm", minw = 0.2, minh = 0.2, padding = 0.1, r = 0.1, hover = true, colour = G.C.BLUE, shadow = true, button = "reload_soundpack_cards"}, nodes = { + {n = G.UIT.R, config = {align = "cm", padding = 0.05, minw = 1.5}, nodes = { + {n = G.UIT.T, config = {text = localize("tnsmi_filter_label"), scale = 0.4, colour = G.C.UI.TEXT_LIGHT}} + }} }}, }}, - }} + }}, + {n = G.UIT.R, config = {align = "cm", colour = G.C.BLACK, r = 0.2, minh = 4, padding = 0.1}, nodes = { + {n = G.UIT.C, config = {align = "cm", colour = G.C.CLEAR}, nodes = area_nodes} + }}, + opt_cycle } - TNSMI.load_cards() + return create_UIBox_generic_options({ contents = t, back_func = 'options', snap_back = nil }) +end - local UI = {n = G.UIT.ROOT, config = {r = 0.1, minw = 5, align = "cm", padding = 0, colour = G.C.L_BLACK, outline = 3, outline_colour = G.C.UI.OUTLINE_LIGHT}, nodes = { - {n = G.UIT.C, config = {r = 0.1, align = "cm", padding = 0.1, colour = G.C.BLACK}, nodes = { - {n = G.UIT.R, config = {align = "tm", colour = G.C.CLEAR}, nodes = { - {n = G.UIT.C, config = {align = "tm", colour = G.C.CLEAR}, nodes = { - name_node, - desc_node - }}, - }}, - {n = G.UIT.R, config = {align = "cm", colour = {G.C.L_BLACK[1], G.C.L_BLACK[2], G.C.L_BLACK[3], 0.5}, r = 0.2, padding = 0.1}, nodes = { - {n = G.UIT.T, config = {text = localize("tnsmi_manager_selected"), scale = 0.45, colour = lighten(G.C.GREY,0.2), vert = true}}, - {n = G.UIT.O, config = {object = TNSMI.CARDAREAS.selected, func = "TNSMI_save_soundpack"}} - }}, - {n = G.UIT.R, config = {align = "cm", padding = 0}, nodes = { - {n = G.UIT.C, config = {align = "cm", minw = 0.2, padding = 0}, nodes = page_cycle}, - {n = G.UIT.C, config = {align = "cm", minw = 0.2}}, - {n = G.UIT.C, config = {align = "cm", colour = {G.C.L_BLACK[1], G.C.L_BLACK[2], G.C.L_BLACK[3], 0.5}, r = 0.2, padding = 0.1}, nodes = { - {n = G.UIT.T, config = {text = "SEARCH", scale = 0.3, colour = lighten(G.C.GREY,0.2), vert = true}}, - tnsmi_create_text_input({max_length = 12, w = 2.5, prompt_text = TNSMI.prompt_text or "", id = "tnsmi_search", extended_corpus = true, ref_table = TNSMI, ref_value = 'prompt_text_input', - callback = function() - TNSMI.prompt_text = TNSMI.prompt_text_input - end - }), - {n = G.UIT.C, config = {align = "cm", minw = 0.2, minh = 0.2, padding = 0.1, r = 0.1, hover = true, colour = G.C.BLUE, shadow = true, button = "tnsmi_search"}, nodes = { - {n = G.UIT.R, config = {align = "cm", padding = 0.05, minw = 1.5}, nodes = { - {n = G.UIT.T, config = {text = localize("tnsmi_filter_label"), scale = 0.4, colour = G.C.UI.TEXT_LIGHT}} - }} - }}, - }}, +function G.UIDEF.soundpack_button(card) + local priority = card.area and card.area == TNSMI.cardareas.priority + local text = priority and 'b_remove' or 'b_select' + local color = priority and G.C.RED or G.C.GREEN + return { + n=G.UIT.ROOT, config = {padding = 0, colour = G.C.CLEAR}, nodes={ + {n=G.UIT.R, config={ref_table = card, r = 0.08, padding = 0.1, align = "bm", minw = 0.5*card.T.w - 0.15, maxw = 0.9*card.T.w - 0.15, minh = 0.5*card.T.h, hover = true, shadow = true, colour = color, one_press = true, button = 'toggle_soundpack'}, nodes={ + {n=G.UIT.T, config={text = localize(text), colour = G.C.UI.TEXT_LIGHT, scale = 0.45, shadow = true}} }}, - {n = G.UIT.R, config = {align = "cm", colour = {G.C.L_BLACK[1], G.C.L_BLACK[2], G.C.L_BLACK[3], 0.5}, r = 0.2}, nodes = select_nodes}, - {n = G.UIT.R, config = {align = "cm", colour = {G.C.L_BLACK[1], G.C.L_BLACK[2], G.C.L_BLACK[3], 0.5}, r = 0.2, padding = 0.1}, nodes = footer} - }}, - }} - - if G.OVERLAY_MENU then G.OVERLAY_MENU:remove() end - G.OVERLAY_MENU = UIBox{ - definition = UI, - config = { - align = "cm", - offset = {x=0,y=0}, - major = G.ROOM_ATTACH, - bond = 'Weak', - no_esc = false - }, + } } end - SMODS.current_mod.config_tab = function () return { n = G.UIT.ROOT, config = {minw = 8, minh = 5, colour = G.C.CLEAR, align = "tm", padding = 0.2}, nodes = { - {n = G.UIT.R, config = {align = "tm"}, nodes = {UIBox_button{ label = {localize("tnsmi_cfg_soundpack_manager")}, button = "TNSMI_main_tab", minw = 5}}}, + {n = G.UIT.R, config = {align = "tm"}, nodes = {UIBox_button{ label = {localize("tnsmi_cfg_soundpack_manager")}, button = "TNSMI_packs_button", minw = 5}}}, {n = G.UIT.R, config = {align = "tm"}, nodes = {create_toggle{ label = "Display in pause menu", scale = 1, minw = 2, minh = 0.5, - ref_table = TNSMI.mod_config, - ref_value = "display_menu_button" + ref_table = TNSMI.config, + ref_value = "menu_button" }}}, {n = G.UIT.R, config = {align = "tm", padding = 0.1}, nodes = { {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.T, config = {align = "cr", text = localize("tnsmi_cfg_rows")..": ", colour = G.C.WHITE, scale = 0.4}}}}, - {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.O, config = {align = "cr", object = DynaText{string = {{ref_table = TNSMI.mod_config, ref_value = "rows"}}, colours = {G.C.WHITE}, scale = 0.4}}}}}, + {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.O, config = {align = "cr", object = DynaText{string = {{ref_table = TNSMI.config, ref_value = "rows"}}, colours = {G.C.WHITE}, scale = 0.4}}}}}, {n = G.UIT.C, config = {minw = 1}}, {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{ label = {"-"}, button = "TNSMI_change_pack_display", minw = 0.5, minh = 0.5, ref_table = {"rows",-1}}}}, {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{ label = {"+"}, button = "TNSMI_change_pack_display", minw = 0.5, minh = 0.5, ref_table = {"rows",1}}}}, }}, {n = G.UIT.R, config = {align = "tm", padding = 0.1}, nodes = { - {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.T, config = {align = "cr", text = localize("tnsmi_cfg_c_rows")..": ", colour = G.C.WHITE, scale = 0.4}}}}, - {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.O, config = {align = "cr", object = DynaText{string = {{ref_table = TNSMI.mod_config, ref_value = "c_rows"}}, colours = {G.C.WHITE}, scale = 0.4}}}}}, + {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.T, config = {align = "cr", text = localize("tnsmi_cfg_cols")..": ", colour = G.C.WHITE, scale = 0.4}}}}, + {n = G.UIT.C, config = {align = "cm"}, nodes = {{n = G.UIT.O, config = {align = "cr", object = DynaText{string = {{ref_table = TNSMI.config, ref_value = "cols"}}, colours = {G.C.WHITE}, scale = 0.4}}}}}, {n = G.UIT.C, config = {minw = 1}}, - {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{ label = {"-"}, button = "TNSMI_change_pack_display", minw = 0.5, minh = 0.5, ref_table = {"c_rows",-1}}}}, - {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{ label = {"+"}, button = "TNSMI_change_pack_display", minw = 0.5, minh = 0.5, ref_table = {"c_rows",1}}}}, + {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{ label = {"-"}, button = "TNSMI_change_pack_display", minw = 0.5, minh = 0.5, ref_table = {"cols",-1}}}}, + {n = G.UIT.C, config = {align = "cm"}, nodes = {UIBox_button{ label = {"+"}, button = "TNSMI_change_pack_display", minw = 0.5, minh = 0.5, ref_table = {"cols",1}}}}, }}, }} end \ No newline at end of file diff --git a/src/callbacks.lua b/src/callbacks.lua index 214ae18..f83d317 100644 --- a/src/callbacks.lua +++ b/src/callbacks.lua @@ -1,33 +1,163 @@ -function G.FUNCS.TNSMI_reload_lists() - print("Reload lists") - for i=1, #TNSMI.CARDAREAS.available.cards do - TNSMI.CARDAREAS.available.cards[i]:start_dissolve(nil,true,0) +function G.FUNCS.TNSMI_change_pack_display(e) -- e represents the node + TNSMI.config[e.config.ref_table[1]] = TNSMI.config[e.config.ref_table[1]] + e.config.ref_table[2] + + TNSMI.config.rows = math.max(1, math.min(4, TNSMI.config.rows)) + TNSMI.config.cols = math.max(1, math.min(16, TNSMI.config.cols)) + + SMODS.save_mod_config(TNSMI) +end + +function G.FUNCS.TNSMI_change_priority(e) + -- check if anything has been moved from expected positions and then save + if TNSMI.dissolve_flag then return end + + local priority_changed = false + for i, v in ipairs(TNSMI.cardareas.priority.cards) do + local priority = #TNSMI.cardareas.priority.cards - i + 1 + if v.params.tnsmi_soundpack ~= TNSMI.config.loaded_packs[priority] then + priority_changed = true + break + end end - for k,v in pairs(TNSMI.packs) do - local card = Card(TNSMI.CARDAREAS.available.T.x+(TNSMI.CARDAREAS.available.T.w/2),TNSMI.CARDAREAS.available.T.y,G.CARD_W,G.CARD_H, G.P_CENTERS.j_joker,G.P_CENTERS.c_base) - TNSMI.CARDAREAS.available:emplace(card) + if not priority_changed then return end + + TNSMI.config.loaded_packs = {} + for i, v in ipairs(TNSMI.cardareas.priority.cards) do + local priority = #TNSMI.cardareas.priority.cards - i + 1 + TNSMI.config.loaded_packs[priority] = v.params.tnsmi_soundpack end -end -function G.FUNCS.TNSMI_main_tab () return TNSMI.main_tab() end -function G.FUNCS.TNSMI_change_pack_display(e) -- e represents the node - TNSMI.mod_config[e.config.ref_table[1]] = TNSMI.mod_config[e.config.ref_table[1]] + e.config.ref_table[2] - - if TNSMI.mod_config.rows < 1 then TNSMI.mod_config.rows = 1 end - if TNSMI.mod_config.rows > 4 then TNSMI.mod_config.rows = 4 end - - if TNSMI.mod_config.c_rows < 1 then TNSMI.mod_config.c_rows = 1 end - if TNSMI.mod_config.c_rows > 16 then TNSMI.mod_config.c_rows = 16 end - + TNSMI.save_soundpacks() end -function G.FUNCS.TNSMI_open_mod_options () - G.SETTINGS.paused = true - _, G.ACTIVE_MOD_UI = next(SMODS.find_mod("tonsmith")) - SMODS.LAST_SELECTED_MOD_TAB = "config" +function G.FUNCS.TNSMI_packs_button(e) + G.SETTINGS.paused = true + SMODS.save_mod_config(TNSMI) G.FUNCS.overlay_menu({ - definition = create_UIBox_mods() - }) + definition = create_UIBox_soundpacks() + }) + G.OVERLAY_MENU:recalculate() +end + +function G.FUNCS.soundpacks_page(args) + G.FUNCS.reload_soundpack_cards() +end + +function G.FUNCS.tnsmi_shoulder_buttons(e) + if #TNSMI.cycle_config.options > 1 then + e.config.colour = G.C.RED + e.config.hover = true + e.config.shadow = true + e.config.button = 'option_cycle' + e.children[1].config.colour = G.C.UI.TEXT_LIGHT + else + e.config.colour = G.C.BLACK + e.config.hover = nil + e.config.shadow = nil + e.config.button = nil + e.children[1].config.colour = G.C.UI.TEXT_INACTIVE + end +end + + +G.FUNCS.reload_soundpack_cards = function() + for i = #TNSMI.cardareas, 1, -1 do + if #TNSMI.cardareas[i].cards > 0 then + remove_all(TNSMI.cardareas[i].cards) + end + TNSMI.cardareas[i].highlighted = {} + end + + -- For already loaded packs + local loaded_map = {} + for _, v in ipairs(TNSMI.config.loaded_packs) do + loaded_map[v] = true + end + + local num_per_page = TNSMI.config.cols * TNSMI.config.rows + local start_index = num_per_page * (TNSMI.cycle_config.current_option - 1) + + -- filtering for the current text input and selected packs + local soundpack_cards = {} + for i, v in ipairs(TNSMI.SoundPack.obj_buffer) do + if not loaded_map[v] and (TNSMI.prompt_text_input == '' + or string.find(string.lower(localize{type = 'name_text', key = v, set = 'SoundPack'}), string.lower(TNSMI.prompt_text_input))) then + soundpack_cards[#soundpack_cards+1] = v + end + end + + -- if it would result in too many pages, go to the last page + if #soundpack_cards < start_index then + start_index = num_per_page * (TNSMI.cycle_config.current_option - 1) + end + + TNSMI.search_text = localize{type = 'variable', key = 'tnsmi_search_text', vars = { + start_index + 1, + math.min((start_index + num_per_page), #soundpack_cards), + #soundpack_cards + }} + + if #soundpack_cards < 1 then return end + + local num_options = math.ceil(#soundpack_cards/num_per_page) + local options = {} + for i=1, num_options do + options[i] = localize('k_page')..' '..tostring(i)..'/'..tostring(num_options) + end + + TNSMI.cycle_config.options = options + TNSMI.cycle_config.current_option = math.min(TNSMI.cycle_config.current_option, num_options) + TNSMI.cycle_config.current_option_val = TNSMI.cycle_config.options[TNSMI.cycle_config.current_option] + + for i=1, num_per_page do + local pack = TNSMI.SoundPacks[soundpack_cards[start_index + i]] + local area_idx = math.floor((i - 1)/TNSMI.config.cols) + 1 + create_soundpack_card(TNSMI.cardareas[area_idx], pack) + + if (start_index + i) >= #soundpack_cards then break end + end +end + +G.FUNCS.toggle_soundpack = function(e) + local card = e.config.ref_table + local key = card.params.tnsmi_soundpack + local is_priority = card.area and card.area == TNSMI.cardareas.priority + + if is_priority then -- Disable pack + for i = #TNSMI.config.loaded_packs, 1, -1 do + if TNSMI.config.loaded_packs[i] == key then + card:start_dissolve(nil, nil, 0.25) + table.remove(TNSMI.config.loaded_packs, i) + break + end + end + TNSMI.dissolve_flag = key + else + for _, pack_area in ipairs(TNSMI.cardareas) do + for _, pack_card in ipairs(pack_area.cards) do + if pack_card.params.tnsmi_soundpack == key then + pack_card:start_dissolve(nil, nil, 0.25) + break + end + end + end + + TNSMI.dissolve_flag = key + create_soundpack_card(TNSMI.cardareas.priority, TNSMI.SoundPacks[key]) + table.insert(TNSMI.config.loaded_packs, key) + end + + G.E_MANAGER:add_event(Event({ + trigger = 'after', + delay = 0.25, + blocking = false, + blockable = false, + func = (function() + G.FUNCS.reload_soundpack_cards() + TNSMI.save_soundpacks() + return true + end) + })) end \ No newline at end of file diff --git a/src/overrides.lua b/src/overrides.lua index 847c7d1..c6f63b9 100644 --- a/src/overrides.lua +++ b/src/overrides.lua @@ -1,140 +1,159 @@ -local hookTo = CardArea.align_cards -function CardArea:align_cards(...) - if self.config and self.config.horizontal_align then - for k, card in ipairs(self.cards) do - if not card.states.drag.is then - card.T.r = 0.1*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x) - local max_cards = math.max(#self.cards, self.config.temp_limit) - card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w) - if #self.cards > 2 or (#self.cards > 1 and self == G.consumeables) or (#self.cards > 1 and self.config.spread) then - card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/(#self.cards-1)) + 0.5*(self.card_w - card.T.w) - elseif #self.cards > 1 and self ~= G.consumeables then - card.T.x = self.T.x + (self.T.w-self.card_w)*((k - 0.5)/(#self.cards)) + 0.5*(self.card_w - card.T.w) - else - card.T.x = self.T.x + self.T.w/2 - self.card_w/2 + 0.5*(self.card_w - card.T.w) - end - local highlight_height = G.HIGHLIGHT_H/2 - if not card.highlighted then highlight_height = 0 end - card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height+ (G.SETTINGS.reduced_motion and 0 or 1)*0.03*math.sin(0.666*G.TIMERS.REAL+card.T.x) - card.T.x = card.T.x + card.shadow_parrallax.x/30 - end - end - table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 - 100*((a.pinned and not a.ignore_pinned) and a.sort_id or 0) < b.T.x + b.T.w/2 - 100*((b.pinned and not b.ignore_pinned) and b.sort_id or 0) end) - else - local ret = hookTo(self,...) - return ret +--[[ +local ref_card_hover = Card.hover +function Card:hover() + if not self.params or not self.params.tnsmi_soundpack then + return ref_card_hover(self) end -end -local hookTo = CardArea.can_highlight -function CardArea:can_highlight(...) - if self.config and self.config.no_highlight then - return false - else - return hookTo(self,...) + self:juice_up(0.05, 0.03) + play_sound('paper1', math.random()*0.2 + 0.9, 0.35) + + --if this is the focused card + if self.states.focus.is and not self.children.focused_ui then + self.children.focused_ui = G.UIDEF.card_focus_ui(self) end -end -local hookTo = Card.click -function Card:click(...) - local ret = hookTo(self,...) - if self.ability and self.ability.tnsmi_card then - TNSMI.toggle_pack(self.config.center.original_key) - G.E_MANAGER:add_event(Event{ - func = function () - TNSMI.load_soundpack_order() - return true - end - }) + if self.facing == 'front' and (not self.states.drag.is or G.CONTROLLER.HID.touch) and not self.no_ui then + self.ability_UIBox_table = generate_card_ui( + {set = 'SoundPack', key = self.params.tnsmi_soundpack, generate_ui = SMODS.Center.generate_ui}, + nil, nil, 'SoundPack', {card_type = 'SoundPack'}, nil, nil, nil, self) + self.config.h_popup = G.UIDEF.card_h_popup(self) + self.config.h_popup_config = self:align_h_popup() + + Node.hover(self) end - return ret end +--]] +local ref_ability = Card.set_ability +function Card:set_ability(center, initial, delay_sprites) + sendDebugMessage(tostring(inspect(center))) + return ref_ability(self, center, initial, delay_sprites) +end -local ref = SMODS.create_mod_badges -function SMODS.create_mod_badges(obj, badges) - if obj then - if obj.config then - if type(obj.config.extra) ~= "table" then - ref(obj, badges) - elseif not obj.config.extra.TNSMI then - ref(obj, badges) +local ref_type_colour = get_type_colour +function get_type_colour(_c, card) + sendDebugMessage("set: "..tostring(_c and _c.set)) + return ref_type_colour(_c, card) +end + +local ref_card_highlight = Card.highlight +function Card:highlight(is_higlighted) + if not self.params or not self.params.tnsmi_soundpack then + return ref_card_highlight(self, is_higlighted) + end + + self.highlighted = is_higlighted + if self.highlighted and self.area then + -- unhighlight all other cards even in different cardareas + for _, pack_area in ipairs(TNSMI.cardareas) do + for _, v in ipairs(pack_area.highlighted) do + if v ~= self then + pack_area:remove_from_highlighted(v) + end end - else - ref(obj,badges) end - else - ref(obj, badges) + + self.children.use_button = UIBox{ + definition = G.UIDEF.soundpack_button(self), + config = {align = "bmi", offset = {x=0,y=0.5}, parent = self} + } + elseif self.children.use_button then + self.children.use_button:remove() + self.children.use_button = nil end end -local ref = Game.update -function Game:update(dt) - TNSMI.load_soundpack_order() +local ref_cardarea_canhighlight = CardArea.can_highlight +function CardArea:can_highlight(card) + return self.config.type == 'soundpack' or ref_cardarea_canhighlight(self, card) +end + +local ref_cardarea_align = CardArea.align_cards +function CardArea:align_cards() + if self.config.type ~= 'soundpack' then + return ref_cardarea_align(self) + end - for i,v in ipairs(TNSMI.mod_config.soundpack_priority) do - local exists = false - for ii,vv in ipairs(TNSMI.packs) do - if v == vv.mod_prefix.."_"..vv.name then exists = true end + local smooth_align = false + for k, card in ipairs(self.cards) do + if G.CONTROLLER.dragging.target == card then + smooth_align = true end - if not exists then - table.remove(TNSMI.mod_config.soundpack_priority,i) + + if not card.states.drag.is then + card.T.r = 0.1*(-#self.cards/2 - 0.5 + k)/(#self.cards)+ (G.SETTINGS.reduced_motion and 0 or 1)*0.02*math.sin(2*G.TIMERS.REAL+card.T.x) + local max_cards = math.max(#self.cards, self.config.temp_limit) + card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/math.max(max_cards-1, 1) - 0.5*(#self.cards-max_cards)/math.max(max_cards-1, 1)) + 0.5*(self.card_w - card.T.w) + + if #self.cards > 2 or (#self.cards > 1 and self == G.consumeables) or (#self.cards > 1 and self.config.spread) then + card.T.x = self.T.x + (self.T.w-self.card_w)*((k-1)/(#self.cards-1)) + 0.5*(self.card_w - card.T.w) + elseif #self.cards > 1 and self ~= G.consumeables then + card.T.x = self.T.x + (self.T.w-self.card_w)*((k - 0.5)/(#self.cards)) + 0.5*(self.card_w - card.T.w) + else + card.T.x = self.T.x + self.T.w/2 - self.card_w/2 + 0.5*(self.card_w - card.T.w) + end + + local highlight_height = G.HIGHLIGHT_H/2 + if not card.highlighted then highlight_height = 0 end + card.T.y = self.T.y + self.T.h/2 - card.T.h/2 - highlight_height + (G.SETTINGS.reduced_motion and 0 or 1)*0.03*math.sin(0.666*G.TIMERS.REAL+card.T.x) + card.T.x = card.T.x + card.shadow_parrallax.x/30 end end - - TNSMI.loaded_packs = {} - TNSMI.unloaded_packs = {} - if TNSMI.page > TNSMI.max_pages then TNSMI.page = TNSMI.page - 1; TNSMI.load_cards() end - if TNSMI.page <= 0 and TNSMI.max_pages > 0 then - TNSMI.page = 1 - end - for i,v in ipairs(TNSMI.packs) do if v.selected then table.insert(TNSMI.loaded_packs,v) else table.insert(TNSMI.unloaded_packs,v) end end + if not smooth_align then + for k, card in ipairs(self.cards) do + if not card.states.drag.is then + card.VT.x = card.T.x + end + end + end - TNSMI.n_loaded_packs = #TNSMI.loaded_packs - TNSMI.max_pages = math.ceil(#TNSMI.unloaded_packs/(TNSMI.mod_config.rows*TNSMI.mod_config.c_rows)) - ref(self,dt) + table.sort(self.cards, function (a, b) return a.T.x + a.T.w/2 < b.T.x + b.T.w/2 end) end -local ref = create_UIBox_options - -function create_UIBox_options(args) - local tbl = ref() - local tnmsi_button = UIBox_button{ label = {localize("tnsmi_manager_pause")}, button = "TNSMI_main_tab", minw = 3.4, colour = G.C.PALE_GREEN} - if TNSMI.mod_config.display_menu_button then - local t = create_UIBox_generic_options({ contents = { - tnmsi_button, - }}) +local ref_cardarea_draw = CardArea.draw +function CardArea:draw() + if self.config.type ~= 'soundpack' then + return ref_cardarea_draw(self) + end - local t_node = tbl.nodes[1].nodes[1].nodes[1].nodes + self:draw_boundingrect() + add_to_drawhash(self) - for k,v in pairs(t_node) do - if v.nodes[1].nodes[1].config then - if v.nodes[1].nodes[1].config.minw == 5 then - v.nodes[1].nodes[1].config.minw = 7 - elseif v.nodes[1].nodes[1].config.minw == 2.4 then - v.nodes[1].nodes[1].config.minw = 3.4 + for k, v in ipairs({'shadow', 'card'}) do + local defer = {} + for i = 1, #self.cards do + if self.cards[i] ~= G.CONTROLLER.focused.target and self.cards[i] ~= G.CONTROLLER.dragging.target then + if self.cards[i].highlighted then + defer[#defer+1] = i + else + self.cards[i]:draw(v) end end end - local exists = false - for k,v in pairs(t_node) do - if v.nodes[1].config.button == "your_collection" then - v.nodes[1].nodes[1].config.minw = 3.4 - local btn = v - t_node[k] = {n = G.UIT.R, nodes = {{n = G.UIT.C, nodes = { - {n = G.UIT.C, nodes = {btn}}, - {n = G.UIT.C, config = {minw = 0.2}}, - {n = G.UIT.C, nodes = {tnmsi_button}}, - }}}} - exists = true - end + for i = 1, #defer do + self.cards[defer[i]]:draw(v) end - if not exists then - tnmsi_button = UIBox_button{ label = {localize("tnsmi_manager_pause")}, button = "TNSMI_main_tab", minw = 7, colour = G.C.PALE_GREEN} - table.insert(t_node,7,tnmsi_button) + end +end + +--[[--- come back to this +local ref = SMODS.create_mod_badges +function SMODS.create_mod_badges(obj, badges) + if obj then + if obj.config then + if type(obj.config.extra) ~= "table" then + ref(obj, badges) + elseif not obj.config.extra.TNSMI then + ref(obj, badges) + end + else + ref(obj,badges) end + else + ref(obj, badges) end - return tbl -end \ No newline at end of file +end +--]] \ No newline at end of file diff --git a/src/utils.lua b/src/utils.lua index abad54f..128306f 100644 --- a/src/utils.lua +++ b/src/utils.lua @@ -1,165 +1,113 @@ -TNSMI.packs = {} -TNSMI.reference = {} +SMODS.Atlas({key = 'default_soundpack', path = 'default_soundpack.png', px = 71, py = 75, prefix_config = false}) +SMODS.Atlas({key = 'thumb' , path = 'thumb.png', px = 71, py = 95, prefix_config = false}) ---Defines and creates a vanilla soundpack for tonsmith to load.
---[View documentation](https://github.com/Goldofleaves/tonsmith/wiki#tnsmipack_vanilla) ---@param args {name:string,mods:string[],description:{},authors:string[],sound_table:table[],thumbnail:string,extension?:".ogg"|string} -TNSMI.Pack = function(args) - local name = args.name or "" - local desc = args.description or {{lan = 'en-us', text = {}}} - local authors = args.authors or {} - local sound_table = args.sound_table or {} - local mods = args.mods or {"Vanilla"} - local thumb = args.thumbnail - local ret = {} - ret.sounds = {} - ret.mod_prefix = SMODS.current_mod.prefix - for i,sound in ipairs(sound_table) do - sound.key = sound.key or "" - sound.extension = sound.extention or sound.extension or "ogg" - sound.prefix = sound.prefix or "" - if sound.prefix ~= "" then sound.prefix = sound.prefix.."_" end - sound.file = sound.file or sound.key - sound.music_track = sound.select_music_track or nil - if string.find(sound.key,"music") then - local ref = sound.music_track or true - sound.music_track = function () - if not ref then return end -- Evaluate if the sound should play - for i,v in ipairs(TNSMI.mod_config.soundpack_priority) do - if v == ret.mod_prefix.."_"..name then return i end - end - end - end - if (sound.req_mod and next(SMODS.find_mod(sound.req_mod))) or not sound.req_mod then - ret.sounds[i] = {SMODS.Sound { - key = sound.key, - path = sound.file.."."..sound.extension, - pitch = sound.pitch, - volume = sound.volume, - sync = sound.sync, - select_music_track = sound.music_track - }, - sound.prefix..sound.key } - end - end - - local loc_txt = {} - - for i,v in ipairs(desc) do - - loc_txt[v.lan] = { - name = name, - text = { - {"{X:green,C:white}"..(G.localization.misc.dictionary.k_tnsmi_descriptions or "Descriptions")}, - {"{X:chips,C:white}"..(G.localization.misc.dictionary.k_tnsmi_authors or "Authors")}, - {"{X:legendary,C:white}"..(G.localization.misc.dictionary.k_tnsmi_mods or "Mods")} - } - } - - for _,vv in ipairs(v.text) do - table.insert(loc_txt[v.lan].text[1],vv) - end - end - for _,v in pairs(loc_txt) do - for _,vv in ipairs(authors) do - table.insert(v.text[2],vv) - end - for _,vv in ipairs(mods) do - table.insert(v.text[3],vv) +TNSMI.SoundPacks = {} +TNSMI.SoundPack = SMODS.GameObject:extend ({ + obj_buffer = {}, + set = 'SoundPack', + obj_table = TNSMI.SoundPacks, + class_prefix = "sp", + prefix_config = { + atlas = false + }, + atlas = 'default_soundpack', + required_params = { + 'key', + 'sound_table' + }, + process_loc_text = function(self) -- LOC_TXT structure = name = string, text = table of strings + SMODS.process_loc_text(G.localization.descriptions.SoundPacks, self.key, self.loc_txt) + end, + register = function(self) + if self.registered then + sendWarnMessage(('Detected duplicate register call on object %s'):format(self.key), self.set) + return end - end - - if thumb then SMODS.Atlas { key = thumb , path = thumb..".png", px = 71, py = 95} end - - ret.joker = SMODS.Joker { - no_collection = true, - unlocked = true, - discovered = true, - key = name, - set_card_type_badge = function (self, card, badges)badges[1] = nil end, - in_pool = function(self, args) return false end, - atlas = thumb or nil, - pos = { x = 0, y = 0 }, - config = {extra = {TNSMI = true}}, - loc_txt = loc_txt - } - - - - ret.name = name - ret.selected = false - ret.priority = 0 - - for i,v in ipairs(TNSMI.mod_config.soundpack_priority) do - if v == ret.mod_prefix.."_"..ret.name then ret.priority = i end - end - table.insert(TNSMI.packs,ret) - table.insert(TNSMI.reference,ret) -end + TNSMI.SoundPack.super.register(self) + end, + inject = function(self) + for _, v in ipairs(self.sound_table) do + if v.key and not v.replace_key and not v.select_music_track then + v.replace_key = v.key + end ----@param name string The sound pack to load. -TNSMI.toggle_pack = function(name) - for _, pack in ipairs(TNSMI.packs) do - if pack.name == name then - if pack.selected then -- Disable pack - pack.selected = false - for _, sound in ipairs(pack.sounds) do - sound[1].replace = nil - SMODS.Sound.replace_sounds[sound[2]] = nil - end + if not v.key and v.replace_key then v.key = v.replace_key end - for i,v in ipairs(TNSMI.mod_config.soundpack_priority) do - if v == pack.mod_prefix.."_"..pack.name then - table.remove(TNSMI.mod_config.soundpack_priority,i) + local path = v.path or v.file + if not path then + path = (v.key..'.ogg') + elseif not string.find(path, '.ogg') and not string.find(path, '.wav') then + path = path..'.ogg' + end + v.key = self.key..'_'..v.key + + local select_music_track = v.select_music_track + if string.find(v.key, "music") and not select_music_track then + -- simple priority selection from highest to lowest + select_music_track = function() + for i = #TNSMI.config.loaded_packs, 1, -1 do + if TNSMI.config.loaded_packs[i] == self.key then return i end end end - -- Reset pack priority - pack.priority = 0 - else -- Enable pack - pack.selected = true - -- return "i did it" - end - if next(TNSMI.CARDAREAS) then - TNSMI.load_cards() end - end - end -end -function TNSMI.save_soundpack_order () - for i,v in ipairs(TNSMI.CARDAREAS.selected.cards) do - -- Save the priority to the config file. - TNSMI.mod_config.soundpack_priority[i] = v.config.center.mod.prefix.."_"..v.config.center.original_key - for ii, vv in ipairs(TNSMI.packs) do - -- Compares the card key and the pack key. - if v.config.center.mod.prefix.."_"..v.config.center.original_key == vv.mod_prefix.."_"..vv.name then - -- Set the pack priority. - vv.priority = i - vv.selected = true + if not v.req_mod or next(SMODS.find_mod(v.req_mod)) then + local new_sound = SMODS.Sound ({ + key = v.key, + path = path, + pitch = v.pitch or self.pitch, + volume = v.volume or self.volume, + sync = v.sync, + select_music_track = v.music_track, + prefix_config = { + key = false + } + }) + + new_sound.mod = self.mod + new_sound.original_mod = self.mod + + -- have to do these manually I think? + new_sound:inject() + new_sound:process_loc_text() end end + end, +}) + +function TNSMI.save_soundpacks() + -- resets all existing replace sounds + local replace_map = TNSMI.config.loaded_packs.replace_map or {} + for k, v in pairs (replace_map) do + SMODS.Sounds[v.key].replace = nil + SMODS.Sound.replace_sounds[k] = nil end -end -function G.FUNCS.TNSMI_save_soundpack () - TNSMI.save_soundpack_order() - TNSMI.load_soundpack_order() -end + replace_map = {} + + if #TNSMI.config.loaded_packs > 0 then + for i = #TNSMI.config.loaded_packs, 1, -1 do + -- Save the priority to the config file. + local pack = TNSMI.SoundPacks[TNSMI.config.loaded_packs[i]] -function TNSMI.load_soundpack_order () - -- Load modded sounds, in order of priority - for i,v in ipairs(TNSMI.mod_config.soundpack_priority) do - for ii, vv in ipairs(TNSMI.packs) do - -- Compares the card key and the pack key. - if v == vv.mod_prefix.."_"..vv.name then - vv.selected = true - vv.priority = i - for _, sound in ipairs(vv.sounds) do - sound[1].replace = sound[2] - SMODS.Sound.replace_sounds[sound[2]] = {times = -1, key = sound[1].key} + for _, sound in ipairs(pack.sound_table) do + if sound.replace_key and not replace_map[sound.replace_key] then + replace_map[sound.replace_key] = { key = sound.key, priority = i} + local obj = SMODS.Sounds[sound.key] + obj:create_replace_sound(sound.replace_key) end end end end + TNSMI.config.loaded_packs.replace_map = replace_map + + SMODS.save_mod_config(TNSMI) end + +function TNSMI.get_size_mod() + return (1 - (TNSMI.config.rows - 1) * 0.2) +end \ No newline at end of file