2025-01-04 23:00:19 +08:00

273 lines
9.4 KiB
Lua

---@class BP_JigsawManager_C:AActor
---@field StaticMesh8 UStaticMeshComponent
---@field StaticMesh7 UStaticMeshComponent
---@field StaticMesh6 UStaticMeshComponent
---@field StaticMesh5 UStaticMeshComponent
---@field StaticMesh4 UStaticMeshComponent
---@field StaticMesh3 UStaticMeshComponent
---@field StaticMesh2 UStaticMeshComponent
---@field StaticMesh1 UStaticMeshComponent
---@field StaticMesh UStaticMeshComponent
---@field Cube UStaticMeshComponent
---@field Scene USceneComponent
---@field DefaultSceneRoot USceneComponent
---@field Row int32
---@field Col int32
---@field TipPicClass UClass
---@field JigsawClass UClass
---@field PlayerPickUpRange float
---@field SideLength float
---@field TexIndex int32
---@field RandomTex TArray<UTexture2D*>
--Edit Below--
local BP_JigsawManager = {
-- playerkey: JigsawID
PlayerHasJigsaw = {};
-- JigsawID = MinPos2D
JigsawRelativeRange = {};
AllJigsaws = {};
PlacedNum = 0;
-- 玩家禁止拾取到的时间
PlayerProhibitPickupEndTime = {};
};
function BP_JigsawManager:ReceiveBeginPlay()
self.SuperClass.ReceiveBeginPlay(self);
self:InitParam()
if UGCGameSystem.IsServer() then
UGCEventSystem.AddListener(EventEnum.PlayerPickUpOrPutDownJigsaw, self.PlayerPickUpOrPutDown, self)
UGCEventSystem.AddListener(EventEnum.PlayerExit, self.ResetPlayerJigsaw, self)
self.CheckPlayerAliveHandle = UGCEventSystem.SetTimerLoop(self, self.CheckPlayerAlive, 2)
else
UGCLogSystem.Log("[BP_JigsawManager_ReceiveBeginPlay]")
self:OnRep_TexIndex()
end
end
function BP_JigsawManager:InitParam()
-- 设置每个区间左上角的点位
for i = 1, self.Row do
for j = 1, self.Col do
local Y = self.SideLength * (- self.Row / 2 + i - 1)
local X = self.SideLength * (- self.Col / 2 + j - 1)
self.JigsawRelativeRange[(i - 1) * self.Col + j] = {X = X, Y = Y}
end
end
UGCLogSystem.LogTree("[BP_JigsawManager_InitParam] JigsawRelativeRange:", self.JigsawRelativeRange)
if UGCGameSystem.IsServer() then
-- 获取随机的拼图
self.TexIndex = math.random(1, self.RandomTex:Num())
UGCLogSystem.LogTree("[BP_JigsawManager_InitParam] TexIndex", self.TexIndex)
-- 初始化拼图
local TempAllJigsaws = GameplayStatics.GetAllActorsOfClass(self, self.JigsawClass);
for i, v in pairs(TempAllJigsaws) do
self.AllJigsaws[#self.AllJigsaws + 1] = v
end
table.Shuffle(self.AllJigsaws)
for i, v in pairs(self.AllJigsaws) do
v:SetFrameValue(i)
end
end
end
--[[
function BP_JigsawManager:ReceiveTick(DeltaTime)
self.SuperClass.ReceiveTick(self, DeltaTime);
end
--]]
function BP_JigsawManager:GetTargetTex()
return self.RandomTex[self.TexIndex]
end
function BP_JigsawManager:ClientUpdateTexIndex()
local TargetTex = self:GetTargetTex()
if self.TargetTipActor == nil then
self.TargetTipActor = UGCSystemLibrary.GetUniqueInstanceFromClass(self.TipPicClass)
end
self.TargetTipActor:UpdateTex(TargetTex)
for i, v in pairs(self.AllJigsaws) do
v:UpdateTex(TargetTex)
end
end
function BP_JigsawManager:OnRep_TexIndex()
if UE.IsValid(self) then
self:ClientUpdateTexIndex()
end
end
function BP_JigsawManager:PlayerThrowOut(PlayerKey)
local Jigsaw = self.AllJigsaws[self.PlayerHasJigsaw[PlayerKey]]
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
if Jigsaw then
self.PlayerHasJigsaw[PlayerKey] = nil
local Pos
if TargetPawn then
Pos = TargetPawn:K2_GetActorLocation()
else
Pos = Jigsaw:K2_GetActorLocation()
end
Jigsaw:DetachAndSetTargetPos(VectorHelper.ToLuaTable(Pos))
end
end
function BP_JigsawManager:PlayerPickUpOrPutDown(PlayerKey)
local TargetPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)
if UE.IsValid(TargetPawn) then
if self.PlayerHasJigsaw[PlayerKey] then
self:PlayerPutDown(TargetPawn, self.PlayerHasJigsaw[PlayerKey])
self.PlayerHasJigsaw[PlayerKey] = nil
else
if self:CheckPlayerCanPickUp(PlayerKey) then
self:PlayerPickUp(TargetPawn)
end
end
end
end
function BP_JigsawManager:ProhibitPickupTime(PlayerKey, Time)
self.PlayerProhibitPickupEndTime[PlayerKey] = UGCSystemLibrary.GetGameTime() + Time
self:PlayerThrowOut(PlayerKey)
end
function BP_JigsawManager:CheckPlayerCanPickUp(PlayerKey)
local EndTime = self.PlayerProhibitPickupEndTime[PlayerKey]
if EndTime then
return EndTime < UGCSystemLibrary.GetGameTime()
end
return true
end
function BP_JigsawManager:PlayerPickUp(TargetPawn)
local PawnPos = TargetPawn:K2_GetActorLocation()
local TargetJigsaw = nil
local TargetDis = -1
for i, v in pairs(self.AllJigsaws) do
if not v:GetPlaced() and not v:GetPicked() then
local Dis = VectorHelper.GetDistance2D(PawnPos, v:K2_GetActorLocation())
if Dis <= self.PlayerPickUpRange then
if TargetJigsaw == nil or Dis < TargetDis then
TargetJigsaw = v
TargetDis = Dis
end
end
end
end
if TargetJigsaw then
self.PlayerHasJigsaw[TargetPawn.PlayerKey] = TargetJigsaw:GetFrame()
TargetJigsaw:AttachPlayer(TargetPawn)
end
end
function BP_JigsawManager:PlayerPutDown(TargetPawn, JigsawID)
local PlayerPos = TargetPawn:K2_GetActorLocation()
local PlayerKey = TargetPawn.PlayerKey
local RelativePos = KismetMathLibrary.GreaterGreater_VectorRotator(VectorHelper.Sub(PlayerPos, self:K2_GetActorLocation()), self:K2_GetActorRotation())
UGCLogSystem.Log("[BP_JigsawManager_PlayerPutDown]JigsawID:%s", tostring(JigsawID))
local bPlaced = false
for i, v in pairs(self.JigsawRelativeRange) do
if v.X < RelativePos.X and v.X + self.SideLength > RelativePos.X and
v.Y < RelativePos.Y and v.Y + self.SideLength > RelativePos.Y
then
UGCLogSystem.Log("[BP_JigsawManager_PlayerPutDown]DownID:%s",tostring(i))
if i == JigsawID then
-- 放置正确
self:PlacedJigsaw(i)
-- UGCEventSystem.SendEvent(EventEnum.AddMiniGameScore, PlayerKey, 1)
UGCGameSystem.GameState:PlayerAddMiniGameScore(PlayerKey, 1)
UGCSendRPCSystem.ActorRPCNotify(PlayerKey, self, "PlacedEffect", true)
self.PlacedNum = self.PlacedNum + 1
if self.PlacedNum >= self.Row * self.Col then
UGCEventSystem.SendEvent(EventEnum.MiniGameEndNotify)
end
MiniGameConfig.CheckPlayerTask(PlayerKey, MiniGameConfig.MiniGameType.Jigsaw, UGCGameSystem.GameState:GetPlayerMiniGameScore(PlayerKey), false)
else
-- 放置错误
self.AllJigsaws[JigsawID]:ResetJigsaw()
UGCSendRPCSystem.ActorRPCNotify(PlayerKey, self, "PlacedEffect", false)
end
bPlaced = true
break
end
end
if not bPlaced then
self.AllJigsaws[JigsawID]:ResetJigsaw()
end
end
function BP_JigsawManager:PlacedJigsaw(JigsawID)
local Jigsaw = self.AllJigsaws[JigsawID]
if UGCGameSystem.IsServer() then
Jigsaw:SetPlaced(true)
UGCSendRPCSystem.ActorRPCNotify(nil, self, "PlacedJigsaw", JigsawID)
else
local ID = Jigsaw:GetFrame()
Jigsaw:K2_AttachToActor(self, EAttachmentRule.KeepRelative, EAttachmentRule.SnapToTarget, EAttachmentRule.SnapToTarget)
local RelativePos = {X = self.JigsawRelativeRange[ID].X + self.SideLength/ 2, Y = self.JigsawRelativeRange[ID].Y + self.SideLength/ 2, Z = 0}
UGCLogSystem.Log("[BP_JigsawManager_PlacedJigsaw] RelativePos:%s", VectorHelper.ToString(RelativePos))
Jigsaw:K2_SetActorRelativeLocation(RelativePos)
end
end
function BP_JigsawManager:PlacedEffect(IsTrue)
if IsTrue then
SoundSystem.PlaySound(SoundSystem.ESound.Right)
else
SoundSystem.PlaySound(SoundSystem.ESound.Error)
end
end
function BP_JigsawManager:ResetPlayerJigsaw(Pawn, PlayerKey)
local JigsawID = self.PlayerHasJigsaw[PlayerKey]
UGCLogSystem.Log("[BP_JigsawManager_ResetPlayerJigsaw] PlayerKey:%s, JigsawID:%s", tostring(PlayerKey), tostring(JigsawID))
if JigsawID then
if self.AllJigsaws[JigsawID] then
self.AllJigsaws[JigsawID]:ResetJigsaw()
end
end
self.PlayerHasJigsaw[PlayerKey] = nil
end
function BP_JigsawManager:CheckPlayerAlive()
for PlayerKey, v in pairs(self.PlayerHasJigsaw) do
if not UE.IsValid(UGCGameSystem.GetPlayerPawnByPlayerKey(PlayerKey)) then
self:ResetPlayerJigsaw(nil, PlayerKey)
end
end
end
function BP_JigsawManager:ReceiveEndPlay()
if UGCGameSystem.IsServer() then
UGCEventSystem.RemoveListener(EventEnum.PlayerPickUpOrPutDownJigsaw, self.PlayerPickUpOrPutDown, self)
UGCEventSystem.RemoveListener(EventEnum.PlayerExit, self.ResetPlayerJigsaw, self)
if self.CheckPlayerAliveHandle then
UGCEventSystem.StopTimer(self.CheckPlayerAliveHandle)
self.CheckPlayerAliveHandle = nil
end
else
end
self.SuperClass.ReceiveEndPlay(self);
end
function BP_JigsawManager:GetReplicatedProperties()
return
"AllJigsaws"
end
--[[
function BP_JigsawManager:GetAvailableServerRPCs()
return
end
--]]
return BP_JigsawManager;