257 lines
9.6 KiB
Lua
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;
|