-- Scripting and Debug -- DO NOT USE, USE A MAP INSTEAD OF AN ARRAY function Contains(tab, val) for index, value in ipairs(tab) do if value == val then return TRUE end end return FALSE end function parseTimeToSeconds(timeStr) local h, m, s = timeStr:match("(%d+):(%d+):(%d+)") return tonumber(h) * 3600 + tonumber(m) * 60 + tonumber(s) end function getCurrentTimeInSeconds() local t = os.date("*t") return t.hour * 3600 + t.min * 60 + t.sec end function isXSecondsAgo(savedTimeStr, seconds) local savedSec = parseTimeToSeconds(savedTimeStr) local currentSec = getCurrentTimeInSeconds() local diff = currentSec - savedSec -- handle case where saved time was just before midnight and current time is just after if diff < 0 then diff = diff + 24 * 3600 end return diff >= seconds end noLog = nil local logDevided = false local logChrId = nil local logEntityId = nil local lastLogTimestamp = "00:00:00" function Log( ... ) if noLog == true or EnableDebugLogger ~= true or debug.getinfo(2, 'n').name == 'print' or (not fileExists("C:\\Convergence\\Tools\\StartMod.bat") and not fileExists("C:\\Jesse\\Convergence\\ConvergenceWIP\\Start_Convergence.bat") and not fileExists("K:\\Games\\ELDEN RING v.1.12 (2022)\\1.16\\ELDEN RING\\Game\\mod (convergencation)\\launch-eldenring-mods.bat") and not fileExists("D:\\ConvergenceProject\\Chunko 1\\3 Chunko\\bun.png")) then -- Personal check so it only runs for me ever noLog = true return end local fullSource = debug.getinfo(2, "S").source local filename = fullSource:match("([^\\/]+)%.hks") local stringB = "" local timestamp = os.date("%X") if #timestamp == 7 then timestamp = "0" .. timestamp end if timestamp == lastLogTimestamp then timestamp = "--:--:--" else lastLogTimestamp = timestamp end local hksSource = debug.getinfo(4, "S").source:match("([^\\/]+)%.hks") if env(IsCOMPlayer) == TRUE and hksSource ~= "c0000" and (logChrId == nil or GetModel() == logChrId) and (logEntityId == nil or GetEntityId() == logEntityId) then stringB = "[".. timestamp .. "] (" .. string.format("%4d", GetModel()) .. "-" .. (string.format("%8d", GetEntityId())) .. " " .. filename .. "." .. debug.getinfo(2, 'n').name .. " #" .. debug.getinfo(2, 'l').currentline .. ")" elseif IsLocalPlayer() then stringB = "[".. timestamp .. "] (" .. filename .. "." .. debug.getinfo(2, 'n').name .. " #" .. debug.getinfo(2, 'l').currentline .. ")" else noLog = true return end local function valToStr(v, visited, depth) visited = visited or {} depth = depth or 0 if v == nil then return "nil" elseif type(v) == "number" and v ~= v then return "NaN" elseif type(v) == "table" then if visited[v] then return "[]" end visited[v] = true local tblStr = "[" if depth == 0 then tblStr = tblStr .. "\n " end local first = true -- Check if table is array-like local isArray = true local count = 0 for k in pairs(v) do count = count + 1 if type(k) ~= "number" or k ~= count then isArray = false break end end for k, val in pairs(v) do if not first then if depth == 0 then tblStr = tblStr .. "\n " else tblStr = tblStr .. ", " end end if isArray then tblStr = tblStr .. " " .. valToStr(val, visited, depth + 1) else tblStr = tblStr .. tostring(k) .. "=" .. valToStr(val, visited, depth + 1) end first = false end tblStr = tblStr .. "]" return tblStr else return tostring(v) end end for i = 1, select('#', ...), 1 do local v = select(i, ...) stringB = stringB .. " " .. valToStr(v) end noLog = false logDevided = false act(ExposeDebugPrint, stringB) end function LogDivider() if not EnableDebugLogger or noLog ~= false or logDevided then return end if not isXSecondsAgo(lastLogTimestamp, 3) then return end logDevided = true act(ExposeDebugPrint, "---------------------------------------------------------------------------------------") end function OnCooldown(cooldownSeconds, timeContainer1) return (g_DeltaTimeCount - timeContainer1) < cooldownSeconds end function listMethods(obj) for k, v in pairs(getmetatable(obj)) do Log(k) Log(v) end end -- File Functions function fileExists(name) local f = io.open(name,"r") if f ~= nil then io.close(f) return true end return false end local HitboxVisualizerOn = false function HitboxVisualizer() if env(GetSpEffectID, 250) == FALSE or HitboxVisualizerOn then return end HitboxVisualizerOn = true SetPointerValue(GAME_BASE.DMG_MAN.HITBOX_VISUALIZER, TRUE) end -- Feature Support -- function ModifyTeam(teamID, hostileTo, ignores) -- local team = env(GetEventFlag, "1099002000") -- if team == TRUE then -- act(SetEventFlag, "1099002000", FALSE) -- else -- act(SetEventFlag, "1099002000", TRUE) -- end -- end -- function OverwriteTeams() -- ModifyTeam(41) -- end function ForceFallDeathCam() if env(GetSpEffectID, 9000005) == TRUE then act(ClearSpEffect, 9000005) SetPointerValue(CHR_INS_BASE.FALL_CAMERA, TRUE) end end function CompareTables(table1, table2) if table1 == table2 then return true end if type(table1) ~= "table" or type(table2) ~= "table" then return false end for key, value in pairs(table1) do if not CompareTables(value, table2[key]) then return false end end for key, value in pairs(table2) do if not CompareTables(value, table1[key]) then return false end end return true end