local loadout_switcher = {} local string_find = string.find local string_gsub = string.gsub local string_match = string.match local math_random = math.random local math_ceil = math.ceil local player = require("player") local require_loadout_num = nil local doneCallback = nil local timeout_timer = 0 local timeout_active = false local timeout_max = 30 local click_delay_min = 0 local click_delay_max = 0 local click_delay_remaining = 0 local slots = { 14, 15, 16, 23, 24, 25, 32, 33, 34, 41, 42, 43, } local function cleanup() timeout_active = false click_delay_remaining = 0 unregisterClientTick(tickerInventory) unregisterClientTick(timeoutTicker) require_loadout_num = nil end local function stripMinecraftColors(text) return string_gsub(text, "ยง.", "") end local function timeoutCallback() if timeout_active then local title = player.inventory.getChestTitle() if title and string_find(stripMinecraftColors(title), "Loadouts") then player.inventory.closeScreen() end if doneCallback then doneCallback(nil, false) end cleanup() end end local function timeoutTicker() if timeout_active then timeout_timer = timeout_timer + 1 if timeout_timer >= timeout_max then timeoutCallback() end end end local function setClickDelay() if click_delay_min > 0 and click_delay_max > 0 then click_delay_remaining = math_random(click_delay_min, click_delay_max) end end local function tickerInventory() if click_delay_remaining > 0 then click_delay_remaining = click_delay_remaining - 1 return end local title = player.inventory.getChestTitle() if not title then return end local clean_title = stripMinecraftColors(title) if not string_find(clean_title, "Loadouts") then return end if not require_loadout_num then return end local current_page = tonumber(string_match(clean_title, "(%d+)/")) local target_page = math_ceil(require_loadout_num / 12) if current_page and current_page ~= target_page then local search = current_page < target_page and "Next Page" or "Previous Page" local total_slots = player.inventory.getContainerSlots() for slot = 0, total_slots - 1 do local item = player.inventory.getStackFromContainer(slot) if item then local name = stripMinecraftColors(item.display_name) if string_find(name, search) then player.inventory.leftClick(slot) setClickDelay() return end end end return end local target_name = "Loadout " .. tostring(require_loadout_num) for _, slot in ipairs(slots) do local item = player.inventory.getStackFromContainer(slot) if item then local name = stripMinecraftColors(item.display_name) if string_find(name, target_name) then player.inventory.leftClick(slot) player.inventory.closeScreen() if doneCallback then doneCallback(require_loadout_num, true) end cleanup() return end end end end --- Equip a loadout by number. --- @param loadout_num number Loadout number (1, 2, 3...). --- @param callback function Callback function(loadout_num, success). --- @param click_delay_min_ticks number Optional min ticks delay between GUI clicks. --- @param click_delay_max_ticks number Optional max ticks delay between GUI clicks. function loadout_switcher.equipLoadout(loadout_num, callback, click_delay_min_ticks, click_delay_max_ticks) unregisterClientTick(tickerInventory) unregisterClientTick(timeoutTicker) timeout_timer = 0 timeout_active = false click_delay_remaining = 0 if loadout_num then require_loadout_num = loadout_num doneCallback = callback click_delay_min = click_delay_min_ticks or 0 click_delay_max = click_delay_max_ticks or 0 setClickDelay() local max_page_navs = math_ceil(loadout_num / 12) - 1 local max_with_delay = click_delay_max * (max_page_navs + 2) timeout_max = math.max(30, max_with_delay + 20) player.sendCommand("/loadout") timeout_active = true registerClientTick(tickerInventory) registerClientTick(timeoutTicker) end end return loadout_switcher