local player = require("player") local TUI = require("TUI") local fontsLoaded = false registerImGuiInitEvent(function() TUI.initFonts() fontsLoaded = true end) -- === Вспомогательные функции === local function strip_colors(s) return s and s:gsub("§.", "") or "" end -- Парсит MM:SS или просто секунды local function parseTime(text, start_text) local time_str = text:match(start_text .. ":%s+([%d:]+)") if not time_str then return 0 end local parts = {} for part in time_str:gmatch("%d+") do table.insert(parts, tonumber(part)) end if #parts == 2 then return parts[1] * 60 + parts[2] -- Минуты:Секунды elseif #parts == 1 then return parts[1] -- Секунды end return 0 end -- === Функции парсинга Lore === local function isOnCooldown(item) if not item or not item.lore then return false end for _, value in ipairs(item.lore) do if value:find("Cooldown remaining") then return parseTime(strip_colors(value), "Cooldown remaining") end end return false end local function isOnActivitityTImer(item) if not item or not item.lore then return false end for _, value in ipairs(item.lore) do if value:find("Time remaining") then return parseTime(strip_colors(value), "Time remaining") end end return false end local function getCooldown(item) if not item or not item.lore then return 0 end for _, value in ipairs(item.lore) do local clean = strip_colors(value) -- Ищем строку "Cooldown: 30 minutes" if clean:find("Cooldown:") and clean:find("minute") then -- Выцепляем число перед minutes local mins = clean:match("Cooldown:%s+(%d+)") return mins and (tonumber(mins) * 60) or 0 end end return 0 end local function getDuration(item) if not item or not item.lore then return 0 end for _, value in ipairs(item.lore) do local clean = strip_colors(value) -- Ищем строку "Cooldown: 30 minutes" if clean:find("Duration:") then -- Выцепляем число перед minutes local mins = clean:match("Duration:%s+(%d+)") return mins and (tonumber(mins) * 60) or 0 end end return 0 end -- === Состояние данных === local managers = { { id = "bank", title = "Manage Bank", label = "Bank", scan_time = -1, state = {} }, { id = "trans", title = "Manage Transportation", label = "Cart", scan_time = -1, state = {} }, { id = "mine", title = "Manage Mine", label = "Mine", scan_time = -1, state = {} } } registerSlotClick(function(slot) local title = player.inventory.getChestTitle() if not title then return end for _, m in ipairs(managers) do if title:find(m.title) then if slot.slot == 22 then local item = player.inventory.getStackFromContainer(22) local duration = getDuration(item) if item then m.state = { cd_rem = isOnCooldown(item), -- Текущий кулдаун (если есть) act_rem = isOnActivitityTImer(item), -- Текущая работа (если есть) base_cd = getCooldown(item) -- Статичный откат из описания } m.scan_time = os.time() end if duration > 0 then m.state.act_rem = duration end end end end end) registerClientTick(function() local title = player.inventory.getChestTitle() if not title then return end for _, m in ipairs(managers) do if title:find(m.title) then local item = player.inventory.getStackFromContainer(22) if item then m.state = { cd_rem = isOnCooldown(item), -- Текущий кулдаун (если есть) act_rem = isOnActivitityTImer(item), -- Текущая работа (если есть) base_cd = getCooldown(item) -- Статичный откат из описания } m.scan_time = os.time() end end end end) -- === Рендеринг === registerImGuiRenderEvent(function() if not player.entity then return end if not fontsLoaded then return end local sections = {} for _, m in ipairs(managers) do local display = { key = "Waiting", val = "0m, 0s", dtype = "alarm" } if m.scan_time > 0 then local delta = os.time() - m.scan_time local s = m.state if s.cd_rem and (s.cd_rem - delta > 0) then -- 1. Если уже идет игровой кулдаун display.key = "Cooldown" display.val = TUI.formatTime(s.cd_rem - delta) display.dtype = "fast" elseif s.act_rem and (s.act_rem - delta > 0) then -- 2. Если идет работа display.key = "Active" display.val = TUI.formatTime(s.act_rem - delta) display.dtype = "active" elseif s.act_rem and s.base_cd > 0 then -- 3. Если работа кончилась, запускаем откат на base_cd local time_since_end = delta - s.act_rem local virtual_cd = s.base_cd - time_since_end if virtual_cd > 0 then display.key = "Cooldown" display.val = TUI.formatTime(virtual_cd) display.dtype = "fast" end end end table.insert(sections, { header = m.label, entries = { { key = display.key, header = "Status", value = display.val, data_type = display.dtype } } }) end -- Отрисовка панели (проверьте, что TUI.createPanel не вызывается с nil) TUI.createPanel("Timers", 10, 10, { title = "Employee", subtitle = "Timers" }, sections, TUI.Colors.ACTIVE) end)