|
|
|
|
| local Utility = {}
|
|
|
| function Utility.formatCash(amount)
|
| if amount >= 1000000 then
|
| return string.format("$%.1fM", amount / 1000000)
|
| elseif amount >= 1000 then
|
| return string.format("$%.1fK", amount / 1000)
|
| else
|
| return "$" .. tostring(math.floor(amount))
|
| end
|
| end
|
|
|
| function Utility.formatTime(seconds)
|
| local min = math.floor(seconds / 60)
|
| local sec = math.floor(seconds % 60)
|
| return string.format("%d:%02d", min, sec)
|
| end
|
|
|
| function Utility.lerp(a, b, t)
|
| return a + (b - a) * t
|
| end
|
|
|
| function Utility.getPartVolume(part)
|
| if not part or not part:IsA("BasePart") then return 0 end
|
| return part.Size.X * part.Size.Y * part.Size.Z
|
| end
|
|
|
| function Utility.randomInRange(min, max)
|
| return min + math.random() * (max - min)
|
| end
|
|
|
| function Utility.randomIntInRange(min, max)
|
| return math.random(min, max)
|
| end
|
|
|
| function Utility.clampVector3(vec, minBounds, maxBounds)
|
| return Vector3.new(
|
| math.clamp(vec.X, minBounds.X, maxBounds.X),
|
| math.clamp(vec.Y, minBounds.Y, maxBounds.Y),
|
| math.clamp(vec.Z, minBounds.Z, maxBounds.Z)
|
| )
|
| end
|
|
|
| function Utility.shuffleTable(tbl)
|
| local shuffled = {}
|
| for _, v in ipairs(tbl) do
|
| table.insert(shuffled, v)
|
| end
|
| for i = #shuffled, 2, -1 do
|
| local j = math.random(1, i)
|
| shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
|
| end
|
| return shuffled
|
| end
|
|
|
| function Utility.tableContains(tbl, value)
|
| for _, v in ipairs(tbl) do
|
| if v == value then return true end
|
| end
|
| return false
|
| end
|
|
|
| function Utility.tableKeys(tbl)
|
| local keys = {}
|
| for k, _ in pairs(tbl) do
|
| table.insert(keys, k)
|
| end
|
| return keys
|
| end
|
|
|
| function Utility.deepCopy(original)
|
| local copy = {}
|
| for k, v in pairs(original) do
|
| if type(v) == "table" then
|
| copy[k] = Utility.deepCopy(v)
|
| else
|
| copy[k] = v
|
| end
|
| end
|
| return copy
|
| end
|
|
|
| return Utility
|
|
|