316 lines
9.2 KiB
Plaintext
316 lines
9.2 KiB
Plaintext
local Utils = {}
|
||
|
||
--> Services
|
||
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
||
local HttpService = game:GetService("HttpService")
|
||
|
||
--> Variables
|
||
local PlayerDataFolder = ReplicatedStorage:WaitForChild("PlayerData")
|
||
|
||
--> Constants
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
function Utils:WaitPlayerDataFolder(Player: Player)
|
||
local pData = PlayerDataFolder:WaitForChild(Player.UserId)
|
||
if pData then return pData end
|
||
warn("玩家数据不存在: " .. Player.Name)
|
||
return nil
|
||
end
|
||
|
||
function Utils:GetPlayerDataFolder(Player: Player)
|
||
local pData = PlayerDataFolder:FindFirstChild(Player.UserId)
|
||
if pData then return pData end
|
||
--打印堆栈
|
||
print(debug.traceback())
|
||
warn("玩家数据不存在: " .. Player.Name)
|
||
return nil
|
||
end
|
||
|
||
function Utils:CreateFolder(Name: string, Parent: Instance)
|
||
local Folder = Instance.new("Folder")
|
||
Folder.Name = Name
|
||
Folder.Parent = Parent
|
||
return Folder
|
||
end
|
||
|
||
function Utils:SetAttributesList(Object: Instance, Attributes: table)
|
||
for Attribute, Value in Attributes do
|
||
if type(Value) ~= "table" then
|
||
Object:SetAttribute(Attribute, Value)
|
||
end
|
||
end
|
||
end
|
||
|
||
function Utils:GenUniqueId(t: table)
|
||
local min_id = 1
|
||
while t[min_id] ~= nil do
|
||
min_id = min_id + 1
|
||
end
|
||
return min_id
|
||
end
|
||
|
||
function Utils:GenUniqueIdPlayerAI(LastTime: number, Counter: number)
|
||
local now = os.time() -- 或 tick(),精度更高
|
||
if now ~= LastTime then
|
||
Counter = 0
|
||
LastTime = now
|
||
end
|
||
Counter = Counter + 1
|
||
return tostring(now) .. "_" .. tostring(Counter)
|
||
end
|
||
|
||
-- function Utils:GetJsonIdData(JsonName: string, id: number)
|
||
-- local JsonData = require(ReplicatedStorage.Json[JsonName])
|
||
-- for _, item in ipairs(JsonData) do
|
||
-- if item.id == id then
|
||
-- return item
|
||
-- end
|
||
-- end
|
||
-- return nil -- 没找到对应id
|
||
-- end
|
||
|
||
function Utils:GetIdDataFromJson(JsonData: table, id: number)
|
||
-- 遍历JsonData,查找id字段等于目标id的项
|
||
for _, item in ipairs(JsonData) do
|
||
if item.id == tonumber(id) then
|
||
return Utils:DeepCopyTable(item)
|
||
end
|
||
end
|
||
return nil -- 没有找到对应id
|
||
end
|
||
|
||
function Utils:GetSpecialKeyDataFromJson(JsonData: table, Key: string, Value: string)
|
||
-- 遍历JsonData,查找id字段等于目标id的项
|
||
for _, item in ipairs(JsonData) do
|
||
if item[Key] == Value then
|
||
return item
|
||
end
|
||
end
|
||
return nil -- 没有找到对应id
|
||
end
|
||
|
||
-- 获取随机id,ExceptIdList为可选参数,如果传入则排除ExceptIdList中的id
|
||
function Utils:GetRandomIdFromJson(JsonData: table, ExceptIdList: table?)
|
||
local rng = Random.new()
|
||
local randomId = rng:NextInteger(1, #JsonData)
|
||
while ExceptIdList and table.find(ExceptIdList, randomId) do
|
||
randomId = rng:NextInteger(1, #JsonData)
|
||
end
|
||
return randomId
|
||
end
|
||
|
||
|
||
-- 获取随机id,ExceptIdList为可选参数,如果传入则排除ExceptIdList中的id
|
||
function Utils:GetRandomIdFromJsonWithType(JsonData: table, Type: number, ExceptIdList: table?)
|
||
local result = {}
|
||
for _, item in ipairs(JsonData) do
|
||
if item.type == Type then
|
||
table.insert(result, item.id)
|
||
end
|
||
end
|
||
local rng = Random.new()
|
||
local randomId = rng:NextInteger(1, #result)
|
||
while ExceptIdList and table.find(ExceptIdList, randomId) do
|
||
randomId = rng:NextInteger(1, #result)
|
||
end
|
||
return randomId
|
||
end
|
||
|
||
-- 获取随机id,ExceptIdList为可选参数,如果传入则排除ExceptIdList中的id
|
||
function Utils:GetRandomIdFromJsonWithSpecialKey(JsonData: table, Key: string, Value: string, ExceptIdList: table?)
|
||
local result = {}
|
||
for _, item in ipairs(JsonData) do
|
||
if item[Key] == Value then
|
||
table.insert(result, item.id)
|
||
end
|
||
end
|
||
local rng = Random.new()
|
||
local randomId = rng:NextInteger(1, #result)
|
||
while ExceptIdList and table.find(ExceptIdList, randomId) do
|
||
randomId = rng:NextInteger(1, #result)
|
||
end
|
||
return randomId
|
||
end
|
||
|
||
-- 随机获取权重Index
|
||
function Utils:GetRandomWeightIndex(WeightTable: table)
|
||
local totalWeight = 0
|
||
for _, weight in ipairs(WeightTable) do
|
||
totalWeight = totalWeight + weight
|
||
end
|
||
if totalWeight == 0 then
|
||
return nil -- 没有有效权重
|
||
end
|
||
local rng = Random.new()
|
||
local rand = rng:NextInteger(1, totalWeight)
|
||
local sum = 0
|
||
for i, weight in ipairs(WeightTable) do
|
||
sum = sum + weight
|
||
if rand <= sum then
|
||
return i
|
||
end
|
||
end
|
||
end
|
||
|
||
function Utils:GetMaxIdFromJson(JsonData: table)
|
||
local maxId = 0
|
||
for _, item in ipairs(JsonData) do
|
||
if item.id > maxId then
|
||
maxId = item.id
|
||
end
|
||
end
|
||
return maxId
|
||
end
|
||
|
||
-- 将字符串数组转化成真正的数组表,"[1,10,2,10]" -> {1,10,2,10}
|
||
function Utils:StringArrayToTable(StringArray: string)
|
||
if type(StringArray) ~= "string" then return {} end
|
||
-- 去除首尾的中括号
|
||
local content = StringArray:match("%[(.*)%]")
|
||
if not content or content == "" then return {} end
|
||
local result = {}
|
||
for value in string.gmatch(content, "[^,]+") do
|
||
local num = tonumber(value)
|
||
if num then
|
||
table.insert(result, num)
|
||
else
|
||
table.insert(result, value)
|
||
end
|
||
end
|
||
return result
|
||
end
|
||
|
||
function Utils:GetFlatDirectionAndEndPos(startPos: Vector3, targetPos: Vector3, length: number)
|
||
local flatStartPos = Vector3.new(startPos.X, 0, startPos.Z)
|
||
local flatTarget = Vector3.new(targetPos.X, 0, targetPos.Z)
|
||
local direction = (flatTarget - flatStartPos).Unit
|
||
local endPos = flatStartPos + direction * length
|
||
return flatStartPos, endPos, direction
|
||
end
|
||
|
||
function Utils:CreateDataInstance(Player: Player, UniqueId: number, EquipmentData: table, Folder: Instance)
|
||
if not Player or not UniqueId or not EquipmentData or not Folder then
|
||
warn('创建实例失败: ' , Player.Name, UniqueId, EquipmentData, Folder)
|
||
return
|
||
end
|
||
local Config = Instance.new("Configuration")
|
||
Config.Name = UniqueId
|
||
Utils:SetAttributesList(Config, EquipmentData)
|
||
Config.Parent = Folder
|
||
|
||
for KeyName, Value in EquipmentData do
|
||
if type(Value) == "table" then
|
||
local newKeyConfig = Instance.new("Configuration")
|
||
newKeyConfig.Name = KeyName
|
||
Utils:SetAttributesList(newKeyConfig, Value)
|
||
newKeyConfig.Parent = Config
|
||
end
|
||
end
|
||
return Config
|
||
end
|
||
|
||
function Utils:CompareTableJson(t1: table, t2: table)
|
||
local json1 = HttpService:JSONEncode(t1)
|
||
local json2 = HttpService:JSONEncode(t2)
|
||
return json1 == json2
|
||
end
|
||
|
||
-- 复制表
|
||
function Utils:CopyTable(t: table)
|
||
local newTable = {}
|
||
for k, v in pairs(t) do
|
||
newTable[k] = v
|
||
end
|
||
return newTable
|
||
end
|
||
|
||
-- 深度复制表
|
||
function Utils:DeepCopyTable(t: table)
|
||
local newTable = {}
|
||
for k, v in pairs(t) do
|
||
if type(v) == "table" then
|
||
newTable[k] = self:DeepCopyTable(v)
|
||
else
|
||
newTable[k] = v
|
||
end
|
||
end
|
||
return newTable
|
||
end
|
||
|
||
-- 合并表(加法合并)
|
||
function Utils:MergeTable(t1: table, t2: table)
|
||
-- 检查是否为空表
|
||
local t1Empty = next(t1) == nil
|
||
local t2Empty = next(t2) == nil
|
||
|
||
-- 如果其中一个为空表,返回不为空的表
|
||
if t1Empty and not t2Empty then
|
||
return t2
|
||
elseif not t1Empty and t2Empty then
|
||
return t1
|
||
elseif t1Empty and t2Empty then
|
||
return t1 -- 全为空表,返回t1
|
||
end
|
||
|
||
-- 正常合并逻辑
|
||
for k, v in pairs(t2) do
|
||
if type(v) == "number" then
|
||
t1[k] = (t1[k] or 0) + v
|
||
end
|
||
end
|
||
return t1
|
||
end
|
||
|
||
-- 给表增加key,value(加法计算)
|
||
function Utils:TableSafeAddValue(AttributesData: table, AttributeName: string, AttributeValue: number)
|
||
AttributesData[AttributeName] = (AttributesData[AttributeName] or 0) + AttributeValue
|
||
end
|
||
|
||
-- 给表增加key,value(加法计算),按第二个参数表的内容增加
|
||
function Utils:TableSafeAddTableValue(AttributesData: table, AddTableValue: table)
|
||
for AttributeName, AttributeValue in AddTableValue do
|
||
AttributesData[AttributeName] = (AttributesData[AttributeName] or 0) + AttributeValue
|
||
end
|
||
end
|
||
|
||
-- 递归查找
|
||
function Utils:FindInDescendants(root, name)
|
||
if root:FindFirstChild(name) then
|
||
return root:FindFirstChild(name)
|
||
end
|
||
for _, child in ipairs(root:GetChildren()) do
|
||
local found = Utils:FindInDescendants(child, name)
|
||
if found then
|
||
return found
|
||
end
|
||
end
|
||
return nil
|
||
end
|
||
|
||
-- 非递归查找
|
||
function Utils:FindInRoot(root, name)
|
||
return root:FindFirstChild(name)
|
||
end
|
||
|
||
|
||
-- UI递归查找
|
||
function Utils:FindInDescendantsUI(root, name)
|
||
if root:FindFirstChild(name) then
|
||
return root:FindFirstChild(name)
|
||
end
|
||
for _, child in ipairs(root:GetChildren()) do
|
||
local firstTwo = string.sub(child.Name, 1, 2)
|
||
if firstTwo ~= "__" then
|
||
local found = Utils:FindInDescendantsUI(child, name)
|
||
if found then
|
||
return found
|
||
end
|
||
end
|
||
end
|
||
return nil
|
||
end
|
||
|
||
--------------------------------------------------------------------------------
|
||
|
||
return Utils |