UGCProjects/GZJ/Script/Blueprint/Monster/BP_BossMagical.lua
2025-01-08 22:46:12 +08:00

257 lines
9.6 KiB
Lua

---@class BP_BossMagical_C:BP_MonsterBoss_C
---@field UAESkillManager UUAESkillManagerComponent
---@field bIsReplica bool
---@field ReplicaParticle UParticleSystem
--Edit Below--
local MonsterBoss = require('Script.Blueprint.Monster.BP_MonsterBoss')
local BP_BossMagical = setmetatable(
{
PawnClass = nil,
ID = 10006,
MonsterName = "Boss",
Replicas = {},
ReplicaNum = 4,
Parent = nil,
-- ReplicaClassPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/Monster/BP_BossMagical_Replica.BP_BossMagical_Replica_C'),
ReplicaClassPath = UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/Monster/BP_BossMagical.BP_BossMagical_C')
},
{
__index = MonsterBoss,
__metatable = MonsterBoss
}
);
function BP_BossMagical:ReceiveBeginPlayEx()
MonsterBoss.ReceiveBeginPlayEx(self)
if self:HasAuthority()then
EventSystem.SetTimer(self,
function ()
UE.Log("[BP_BossMagical_ReceiveBeginPlay] bIsReplica: %s", tostring(self.bIsReplica))
if self.bIsReplica == false then
EventSystem.SetTimer(
self,
function ()
-- body
self:AddSkillMagicalReplica()
end,
3.
)
self:AddSkillAssassinate()
else
if UE.IsValid(self.Parent) == false then
UnrealNetwork.CallUnrealRPC_Multicast(self, "Multicast_RemoveWidget")
self:K2_DestroyActor()
end
end
end,
0.1
)
end
end
function BP_BossMagical:Multicast_InitReplica()
local HealthWidget = self.HealthWidget.Widget
if HealthWidget then
if HealthWidget.HPProgressBar then
HealthWidget.HPProgressBar:SetFillColorAndOpacity({R = 0, G = 0, B = 1, A = 1})
else
UE.Log("[BP_BossMagical_InitReplica] HPProgressBar is nil")
end
else
UE.Log("[BP_BossMagical_InitReplica] HealthWidget is nil")
end
end
function BP_BossMagical:ReceiveEndPlayEx()
MonsterBoss.ReceiveEndPlayEx(self)
if self:HasAuthority()then
else
self:Multicast_RemoveWidget()
end
end
function BP_BossMagical:Multicast_RemoveWidget()
local HealthWidget = self.HealthWidget.Widget
UE.Log("BP_BossMagical_ReceiveEndPlay HealthWidget is %s", tostring(HealthWidget ~= nil))
if HealthWidget then
HealthWidget:SetVisibility(ESlateVisibility.Collapsed)
HealthWidget:RemoveFromParent()
end
end
function BP_BossMagical:GetAvailableServerRPCs()
return
"Multicast_SetActorTransform"
end
function BP_BossMagical:Multicast_SetActorTransform(Position, Rotator)
log_tree("Multicast_SetActorTransform_Position = ", Position)
log_tree("Multicast_SetActorTransform_Rotator = ", Rotator)
self:K2_SetActorLocation(Position)
self:K2_SetActorRotation(Rotator)
end
function BP_BossMagical:GetReplicaClass()
if self.ReplicaClass == nil then self.ReplicaClass = UE.LoadClass(self.ReplicaClassPath) end
return self.ReplicaClass
end
function BP_BossMagical:InitReplica(level, Parent)
if level == nil then level = 1 end
self.Parent = Parent
if self:HasAuthority() and self.bIsReplica then
self:UpdateMonsterLevel(self.MonsterName, level)
UnrealNetwork.CallUnrealRPC_Multicast(self, "Multicast_InitReplica")
end
end
function BP_BossMagical:AddSkillMagicalReplica()
self.SkillMagicalReplicaHandle = EventSystem.SetTimerLoop(
self,
function ()
self:ResetReplicas()
end,
30.
)
end
function BP_BossMagical:ResetReplicas()
local Crystal = UGCGameSystem.GameState:GetCrystal()
if UE.IsValid(Crystal) then
local CenterPosition = Crystal:K2_GetActorLocation()
local Eightpoint = self:GetEightpoint(500)
for i = 1, self.ReplicaNum do
if UE.IsValid(self.Replicas[i]) then
self.Replicas[i]:InitReplica(self.BossLevel, self)
else
local Targetposition = VectorHelper.Add(CenterPosition, Eightpoint[i])
CenterPosition.Z = self:K2_GetActorLocation().Z
Targetposition.Z = self:K2_GetActorLocation().Z
local TargetRotator = KismetMathLibrary.FindLookAtRotation(Targetposition, CenterPosition)
local Replica = UGCGameSystem.SpawnActor(UGCGameSystem.GameState, self:GetReplicaClass(), Targetposition, TargetRotator, VectorHelper.ScaleOne(), nil)
self.Replicas[i] = Replica
Replica.bIsReplica = true
Replica:InitReplica(self.BossLevel, self)
UE.Log("[BP_BossMagical_ResetReplicas] SpawnFinish %d", i)
end
end
end
end
function BP_BossMagical:AddSkillAssassinate()
self.SkillAssassinateHandle = EventSystem.SetTimerLoop(
self,
function ()
local TargetPositions = self:GetMovablePosition()
table.Rand(TargetPositions)
local MoveIndex = 1
for k, v in pairs(self.Replicas) do
if TargetPositions[MoveIndex] == nil then break end
if UE.IsValid(v) then
self:PlayAssassinate(v, TargetPositions[MoveIndex].Location, TargetPositions[MoveIndex].Rotation)
MoveIndex = MoveIndex + 1
end
end
if TargetPositions[MoveIndex] then
self:PlayAssassinate(self, TargetPositions[MoveIndex].Location, TargetPositions[MoveIndex].Rotation)
end
end,
20.
)
end
function BP_BossMagical:PlayAssassinate(TargetBossMagical, Location, Rotation)
-- body
TargetBossMagical:GetController():GetBlackboardComponent():SetValueAsBool("CanPlaySkillAssassinate", true)
TargetBossMagical:K2_SetActorLocation(Location)
TargetBossMagical:K2_SetActorRotation(Rotation)
UnrealNetwork.CallUnrealRPC_Multicast(self, "Multicast_SetActorTransform", Location, Rotation)
EventSystem.SetTimer(TargetBossMagical,
function ()
-- body
if UE.IsValid(TargetBossMagical) and UE.IsValid(TargetBossMagical:GetController()) then
TargetBossMagical:GetController():GetBlackboardComponent():SetValueAsBool("CanPlaySkillAssassinate", false)
end
end,
2
)
end
function BP_BossMagical:GetEightpoint(Length)
local Angle45Len = math.sqrt(2) / 2
return {
Vector.New(Length, 0, 0),
Vector.New(-Length, 0, 0),
Vector.New(0, Length, 0),
Vector.New(0, -Length, 0),
Vector.New( Length * Angle45Len, Length * Angle45Len, 0),
Vector.New(-Length * Angle45Len, Length * Angle45Len, 0),
Vector.New( Length * Angle45Len, -Length * Angle45Len, 0),
Vector.New(-Length * Angle45Len, -Length * Angle45Len, 0)
}
end
function BP_BossMagical:GetMovablePosition()
local ArenaPlayers = UGCGameSystem.GameState:GetPlayersInArena()
local ResTransform = {}
if not table.isEmpty(ArenaPlayers) then
for _, ArenaPlayer in pairs(ArenaPlayers) do
local PawnHelfHeight = ArenaPlayer.CapsuleComponent.CapsuleHalfHeight
local Playerlocation = ArenaPlayer:K2_GetActorLocation()
Playerlocation.Z = Playerlocation.Z + self.Capsule.CapsuleHalfHeight - PawnHelfHeight + 5
local EightLocation = self:GetEightpoint(350)
for k, AddLocation in pairs(EightLocation) do
local Beginlocation = VectorHelper.Add(Playerlocation, AddLocation)
local ObjectTypes = {EObjectTypeQuery.ObjectTypeQuery1}
local bHit, _ = KismetSystemLibrary.CapsuleTraceSingleForObjects(
self, Beginlocation, Beginlocation,
self.Capsule.CapsuleRadius, self.Capsule.CapsuleHalfHeight,
ObjectTypes, false, nil, EDrawDebugTrace.None,
nil, true, nil, nil, 20
)
if not bHit then
-- 判断该位置是否存在地面
local DropLocation = UGCGameSystem.GameState:GetDropLocation(Beginlocation)
if VectorHelper.GetDistance(DropLocation, Beginlocation) > 10 then
Playerlocation.Z = Beginlocation.Z
local TargetRotator = KismetMathLibrary.FindLookAtRotation(Beginlocation, Playerlocation)
table.insert(ResTransform, {Location = VectorHelper.ToLuaTable(Beginlocation), Rotation = VectorHelper.RotToLuaTable(TargetRotator)})
end
end
end
end
end
return ResTransform
end
function BP_BossMagical:ReceiveOnMonsterDeath()
MonsterBoss.ReceiveOnMonsterDeath(self)
if self:HasAuthority() then
-- 本体死亡则销毁分身
if self.bIsReplica == false then
if self.SkillAssassinateHandle then
EventSystem.StopTimer(self.SkillAssassinateHandle)
self.SkillAssassinateHandle = nil
end
if self.SkillMagicalReplicaHandle then
EventSystem.StopTimer(self.SkillMagicalReplicaHandle)
self.SkillMagicalReplicaHandle = nil
end
for k, v in pairs(self.Replicas) do
UnrealNetwork.CallUnrealRPC_Multicast(v, "Multicast_RemoveWidget")
if UE.IsValid(v) then v:K2_DestroyActor() end
end
end
end
end
return BP_BossMagical;