210 lines
6.6 KiB
Lua
210 lines
6.6 KiB
Lua
|
---@class SceneObject
|
||
|
---@field InUseTable table<int32, FString>
|
||
|
---@field UnusedTable table<int32, FString>
|
||
|
---@field AllTable table<FString, SceneObjectItem>
|
||
|
---@field RefreshTime float
|
||
|
---@field IsLimit bool
|
||
|
---@field TotalCount int32
|
||
|
---@field InSpawnCount int32
|
||
|
---@field new fun(InTable:SceneObjItem):SceneObject
|
||
|
---@field LoadSceneItem fun(InClass:UClass)
|
||
|
---@field InitSceneItems fun()
|
||
|
---@field OnUseSceneItem fun(InItem:BP_CustomItemBase_C, InPawn:UGCPlayerPawn_C)
|
||
|
---@field SetOneItemToUse fun(IsInit:bool)
|
||
|
---@field SetOneItemToUnused fun()
|
||
|
---@field ChangeItemCount fun(InCount:int32)
|
||
|
---@field GetTotalCount fun():int32
|
||
|
---@field GetAllItemTable fun():table<FString, SceneObjectItem>
|
||
|
---@field GetSetIds fun():table<int32, int32>
|
||
|
---@field GetUnusedCount fun():int32
|
||
|
---@field GetInUseCount fun():int32
|
||
|
---@field GetAllItemCount fun():int32
|
||
|
---@field GetNearItem fun(InPawn:UGCPlayerPawn_C):BP_CustomItemBase_C
|
||
|
|
||
|
|
||
|
local SceneObject = {};
|
||
|
|
||
|
--- 加载地图上的所有 Buff
|
||
|
---@class SceneObjectItem
|
||
|
---@field Item BP_CustomItemBase_C
|
||
|
---@field IsSet bool 是否设置了Buff
|
||
|
---@field LastTime float 最后一次设置 Buff 的时间
|
||
|
---@field DisToCenter float 距离中心点的长度
|
||
|
|
||
|
---@type table<int32, FString> 正在使用的表
|
||
|
SceneObject.InUseTable = {};
|
||
|
---@type table<int32, FString> 未使用的表
|
||
|
SceneObject.UnusedTable = {};
|
||
|
---@type table<FString, SceneObjectItem> 所有物品表
|
||
|
SceneObject.AllTable = {};
|
||
|
|
||
|
SceneObject.RefreshTime = 0;
|
||
|
SceneObject.IsLimit = false;
|
||
|
SceneObject.TotalCount = 0;
|
||
|
SceneObject.EventType = nil;
|
||
|
|
||
|
--- 已经使用但是还未生成的数量
|
||
|
SceneObject.InSpawnCount = 0;
|
||
|
|
||
|
---@param InTable SceneObjItem
|
||
|
function SceneObject:new(InTable)
|
||
|
return setmetatable({
|
||
|
RefreshTime = InTable.RefreshTime,
|
||
|
IsLimit = InTable.IsLimit,
|
||
|
TotalCount = InTable.TotalCount,
|
||
|
EventType = InTable.EventType,
|
||
|
|
||
|
InUseTable = {},
|
||
|
UnusedTable = {},
|
||
|
AllTable = {},
|
||
|
|
||
|
InSpawnCount = 0,
|
||
|
}, {
|
||
|
__metatable = self,
|
||
|
__index = self,
|
||
|
});
|
||
|
end
|
||
|
|
||
|
---@param InClass UClass
|
||
|
---@param InTable table<int32, AActor>
|
||
|
function SceneObject:LoadSceneItem(InClass, InTable)
|
||
|
local CenterLoc = GameState:GetCenterPointLocation();
|
||
|
if table.isEmpty(InTable) then
|
||
|
local AllActors = {};
|
||
|
UE.FindActorsByClass(InClass, AllActors, function(InIndex, InActor)
|
||
|
self:AddOneItemToTableInternal(InActor, CenterLoc);
|
||
|
return true;
|
||
|
end);
|
||
|
else
|
||
|
for i, v in pairs(InTable) do
|
||
|
if UE.IsA(v, InClass) then
|
||
|
self:AddOneItemToTableInternal(v, CenterLoc);
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
UGCLogSystem.LogTree(string.format("[SceneObject:LoadSceneItem] self.AllTable ="), self.AllTable)
|
||
|
if self.IsLimit then self:InitSceneItems(); end
|
||
|
--- 进行绑定
|
||
|
UGCEventSystem.AddListener(self.EventType, self.OnUseSceneItem, self)
|
||
|
end
|
||
|
|
||
|
---@private
|
||
|
---@param v AActor
|
||
|
---@param CenterLoc FVector
|
||
|
function SceneObject:AddOneItemToTableInternal(v, CenterLoc)
|
||
|
local Name = UE.GetName(v)
|
||
|
self.AllTable[Name] = {
|
||
|
Item = v,
|
||
|
IsSet = false,
|
||
|
LastTime = -1,
|
||
|
DisToCenter = VectorHelper.GetDistance2D(CenterLoc, v:K2_GetActorLocation());
|
||
|
};
|
||
|
table.insert(self.UnusedTable, Name);
|
||
|
end
|
||
|
|
||
|
function SceneObject:InitSceneItems()
|
||
|
if IsServer then
|
||
|
local AllItemCount = self:GetAllItemCount();
|
||
|
self.TotalCount = math.ceil(AllItemCount * self.TotalCount / (self.TotalCount <= 1 and 1 or 100))
|
||
|
if self.TotalCount > AllItemCount then self.TotalCount = AllItemCount; end
|
||
|
UGCLogSystem.Log("[SceneObject:InitSceneItems] self.TotalCount = %s", tostring(self.TotalCount))
|
||
|
for i = 1, self.TotalCount do self:SetOneItemToUse(true); end
|
||
|
UGCLogSystem.LogTree(string.format("[SceneObject:InitSceneItems] self.InUseTable ="), self.InUseTable)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function SceneObject:OnUseSceneItem(InItem, InPawn)
|
||
|
if IsServer then
|
||
|
UGCLogSystem.Log("[SceneObject:OnUseSceneItem] InItem = %s", UE.GetName(InItem))
|
||
|
if not self.IsLimit then return end
|
||
|
local Name = UE.GetName(InItem);
|
||
|
table.removeValue(self.InUseTable, Name);
|
||
|
self.AllTable[Name].IsSet = false;
|
||
|
table.insert(self.UnusedTable, Name);
|
||
|
UGCEventSystem.SetTimer(GameState, function() self:SetOneItemToUse(false) end, self.RefreshTime);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function SceneObject:SetOneItemToUse(IsInit)
|
||
|
if IsServer then
|
||
|
if self:GetUnusedCount() == 0 then return; end
|
||
|
table.Shuffle(self.UnusedTable);
|
||
|
local ItemName = self.UnusedTable[1];
|
||
|
table.remove(self.UnusedTable, 1)
|
||
|
local SceneItem = self.AllTable[ItemName];
|
||
|
UGCLogSystem.Log("[SceneObject:SetOneItemToUse] ItemName = %s", ItemName);
|
||
|
SceneItem.Item:PreRandomNewItem();
|
||
|
SceneItem.Item:RandomNewItem();
|
||
|
SceneItem.IsSet = true;
|
||
|
SceneItem.LastTime = UE.GetCurrentTime();
|
||
|
table.insert(self.InUseTable, ItemName)
|
||
|
SceneItem.Item:OnPostRandomNewItem();
|
||
|
if not IsInit then self.InSpawnCount = self.InSpawnCount - 1; end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
---@param InCount int32
|
||
|
function SceneObject:ChangeItemCount(InCount)
|
||
|
if IsServer then
|
||
|
local CurrCount = self:GetInUseCount();
|
||
|
local TotalCount = self.InSpawnCount + CurrCount;
|
||
|
if TotalCount < InCount then
|
||
|
for i = 1, InCount - TotalCount do self:SetOneItemToUse(true) end
|
||
|
elseif TotalCount > InCount then
|
||
|
for i = 1, TotalCount - InCount do self:SetOneItemToUnused(); end
|
||
|
end
|
||
|
self.TotalCount = InCount;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
---@param InNew float
|
||
|
function SceneObject:ChangeItemPercent(InNew)
|
||
|
self:ChangeItemCount(InNew * self:GetAllItemCount());
|
||
|
end
|
||
|
|
||
|
--- 拿出一个来使用
|
||
|
function SceneObject:SetOneItemToUnused()
|
||
|
if IsServer then
|
||
|
table.Shuffle(self.InUseTable)
|
||
|
local Name = self.InUseTable[1];
|
||
|
table.remove(self.InUseTable, 1);
|
||
|
self.AllTable[Name].IsSet = true;
|
||
|
self.AllTable[Name].Item:ResetItem();
|
||
|
table.insert(self.UnusedTable, Name)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
---@param InPawn UGCPlayerPawn_C
|
||
|
function SceneObject:GetNearItem(InPawn)
|
||
|
local TargetDis, Actor = 1000000, nil;
|
||
|
for i, v in pairs(self.InUseTable) do
|
||
|
local Dis = VectorHelper.GetActorDis2D(InPawn, self.AllTable[v].Item)
|
||
|
if TargetDis > Dis then
|
||
|
TargetDis = Dis;
|
||
|
Actor = self.AllTable[v].Item;
|
||
|
end
|
||
|
end
|
||
|
return Actor;
|
||
|
end
|
||
|
|
||
|
---@param InTable table<int32, int32>
|
||
|
---@return table<int32, BP_CustomItemBase_C>
|
||
|
function SceneObject:GetSetIds(InTable)
|
||
|
if InTable == nil then InTable = {}; end
|
||
|
for i, v in pairs(self.InUseTable) do table.insert(InTable, self.AllTable[v].Item:GetItemId()); end
|
||
|
return InTable;
|
||
|
end
|
||
|
|
||
|
---@return int32
|
||
|
function SceneObject:GetTotalCount() return self.TotalCount; end
|
||
|
---@return table<string, SceneObjectItem>
|
||
|
function SceneObject:GetAllItemTable() return self.AllTable; end
|
||
|
---@return int32
|
||
|
function SceneObject:GetUnusedCount() return table.getCount(self.UnusedTable); end
|
||
|
---@return int32
|
||
|
function SceneObject:GetInUseCount() return table.getCount(self.InUseTable); end
|
||
|
---@return int32
|
||
|
function SceneObject:GetAllItemCount() return table.getCount(self.AllTable); end
|
||
|
|
||
|
return SceneObject;
|