591 lines
23 KiB
Lua
591 lines
23 KiB
Lua
---@class BP_MonsterSpawner_C:AActor
|
|
---@field Box UBoxComponent
|
|
---@field Type TEnumAsByte<EMonsterSpawnerType>
|
|
---@field SpawnerID int32
|
|
--Edit Below--
|
|
local BP_MonsterSpawner = {
|
|
CurPosIndex = 0,
|
|
NumberOfPoints = 500,
|
|
ScalarParam = 3.0,
|
|
|
|
ResourceGrade = 1,
|
|
|
|
DropPositions = {},
|
|
SpawnedMonsters = {},
|
|
SpawnNum = 10,
|
|
|
|
TargetPlayerKey = -100,
|
|
|
|
InheritMonster = {
|
|
['盔'] = false,
|
|
['甲'] = false
|
|
};
|
|
|
|
IsActivate = false,
|
|
|
|
SpawnMonsterIndex = 1,
|
|
|
|
CheckNumInterval = 0.8, --检查剩余怪物数量的间隔时间
|
|
ElapsedTime = 0.0,
|
|
|
|
SpawnWaitingNum = 0, --等待生成的怪物数量
|
|
|
|
SpawnWaitingBossNum = 0,
|
|
};
|
|
|
|
function BP_MonsterSpawner:ReceiveBeginPlay()
|
|
BP_MonsterSpawner.SuperClass.ReceiveBeginPlay(self);
|
|
if self:HasAuthority() then
|
|
self:GenerateDropPosition()
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:ReceiveTick(DeltaTime)
|
|
BP_MonsterSpawner.SuperClass.ReceiveTick(self, DeltaTime);
|
|
|
|
if self.IsActivate == false then
|
|
return
|
|
end
|
|
|
|
if self:HasAuthority() then
|
|
if self.Type == EMonsterSpawnerType.HangUpRoom then
|
|
if self.SpawnWaitingNum > 0 then
|
|
self:SpawnSingleHangupRoomMonster()
|
|
self.SpawnWaitingNum = self.SpawnWaitingNum - 1
|
|
end
|
|
|
|
self.ElapsedTime = self.ElapsedTime + DeltaTime
|
|
if self.ElapsedTime >= self.CheckNumInterval then
|
|
self.ElapsedTime = 0.0
|
|
self.CheckNumInterval = math.random(1, 5) / 10.0
|
|
|
|
local RemainedMonsterNum = table.getCount(self.SpawnedMonsters)
|
|
if RemainedMonsterNum < self.SpawnNum then
|
|
self.SpawnWaitingNum = math.clamp(self.SpawnWaitingNum + (self.SpawnNum - RemainedMonsterNum), 0, 10)
|
|
end
|
|
end
|
|
else
|
|
if self.SpawnWaitingNum > 0 then
|
|
self:SpawnSingleAttackMonster()
|
|
self.SpawnWaitingNum = self.SpawnWaitingNum - 1
|
|
end
|
|
if self.SpawnWaitingBossNum > 0 then
|
|
self:SpawnSingleAttackBoss()
|
|
self.SpawnWaitingBossNum = self.SpawnWaitingBossNum - 1
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
function BP_MonsterSpawner:GetSpawnerType()
|
|
return self.Type
|
|
end
|
|
|
|
function BP_MonsterSpawner:GetSpawnerID()
|
|
return self.SpawnerID
|
|
end
|
|
|
|
function BP_MonsterSpawner:BindPlayerKey(InPlayerKey)
|
|
self.TargetPlayerKey = InPlayerKey
|
|
UE.Log("[BP_MonsterSpawner][BindPlayerKey] %s Bind PlayerKey: %d", KismetSystemLibrary.GetObjectName(self), self.TargetPlayerKey)
|
|
end
|
|
|
|
function BP_MonsterSpawner:StartSpawnHangupMonster(InSpawnNum)
|
|
if self.Type ~= EMonsterSpawnerType.HangUpRoom then
|
|
return
|
|
end
|
|
|
|
self.IsActivate = true
|
|
|
|
UE.Log("[BP_MonsterSpawner][StartSpawnHangupMonster] %s: TargetPlayerKey[%s]", KismetSystemLibrary.GetObjectName(self), tostring(self.TargetPlayerKey))
|
|
|
|
self.SpawnWaitingNum = InSpawnNum
|
|
end
|
|
|
|
function BP_MonsterSpawner:SpawnSingleHangupRoomMonster()
|
|
if table.getCount(self.SpawnedMonsters) >= 10 then
|
|
return
|
|
end
|
|
|
|
local BindedPC = UGCGameSystem.GetPlayerControllerByPlayerKey(self.TargetPlayerKey)
|
|
if BindedPC == nil or UE.IsValid(BindedPC) == false then
|
|
UE.Log("[BP_MonsterSpawner][SpawnSingleHangupRoomMonster] Can't Find BindedPC")
|
|
return
|
|
end
|
|
|
|
local MonsterClass = GameDataManager.GetRandHangupMonsterClass()
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.ScaleOne()
|
|
local Monster = UGCGameSystem.SpawnActor(self, MonsterClass, Location, Rotation, Scale, nil)
|
|
if not Monster then
|
|
return
|
|
end
|
|
Monster:SetOwner(self)
|
|
local MonsterInitSuccess = Monster:InitMonsterByLevel(BindedPC.ResourceGrade)
|
|
-- if MonsterInitSuccess == false then
|
|
-- UE.Log("[BP_MonsterSpawner][SpawnSingleHangupRoomMonster] Monster Init Failed: MonsterName[%s]", KismetSystemLibrary.GetObjectName(Monster))
|
|
-- return
|
|
-- end
|
|
Monster:SetTargetPlayerKey(self.TargetPlayerKey)
|
|
Monster:SetSpawnIndex(self.SpawnMonsterIndex)
|
|
|
|
self.SpawnedMonsters[self.SpawnMonsterIndex] = Monster
|
|
-- UE.Log("[BP_MonsterSpawner][SpawnSingleHangupRoomMonster] Success: MonsterName[%s], SpawnIndex[%d]", KismetSystemLibrary.GetObjectName(Monster), self.SpawnMonsterIndex)
|
|
self.SpawnMonsterIndex = self.SpawnMonsterIndex + 1
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:StartSpawnAttackWave(NormalMonsterNum, BossMonsterNum)
|
|
if self.Type ~= EMonsterSpawnerType.AttackWave then return end
|
|
|
|
self.IsActivate = true
|
|
|
|
UGCGameSystem.GameState:UpdateIsInAttackWave(NormalMonsterNum + BossMonsterNum > 0)
|
|
|
|
self.SpawnWaitingNum = NormalMonsterNum
|
|
self.SpawnWaitingBossNum = BossMonsterNum
|
|
end
|
|
|
|
function BP_MonsterSpawner:SpawnSingleAttackMonster()
|
|
local MonsterClass = GameDataManager.GetAttackWaveCommonMonsterClass()
|
|
MonsterClass = UE.LoadClass(UGCGameSystem.GetUGCResourcesFullPath('Asset/Blueprint/Monster/BP_BossCharm.BP_BossCharm_C'))
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.Scale(1.25)
|
|
local Monster = UGCGameSystem.SpawnActor(self, MonsterClass, Location, Rotation, Scale, nil)
|
|
if Monster then
|
|
table.insert(self.SpawnedMonsters, Monster)
|
|
Monster:SetOwner(self)
|
|
Monster:InitMonsterByLevel(UGCGameSystem.GameState.CurAttackWave)
|
|
Monster.OnDeath:Add(BP_MonsterSpawner.OnSpawnedMonsterDeath, self)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:SpawnSingleAttackBoss()
|
|
local MonsterClass = GameDataManager.GetRandBossMonsterClass()
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.Scale(1.5)
|
|
local Monster = UGCGameSystem.SpawnActor(self, MonsterClass, Location, Rotation, Scale, nil)
|
|
if Monster then
|
|
table.insert(self.SpawnedMonsters, Monster)
|
|
Monster:SetOwner(self)
|
|
Monster:InitMonsterByLevel(GameDataManager.BossIndex)
|
|
Monster.OnDeath:Add(BP_MonsterSpawner.OnSpawnedMonsterDeath, self)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:StartSpawnBreachMonster(RewardWeaponID, InLevel)
|
|
if self.IsActivate == false or self.Type ~= EMonsterSpawnerType.HangUpRoom then
|
|
return
|
|
end
|
|
|
|
if RewardWeaponID == nil or RewardWeaponID <= 0 then
|
|
return
|
|
end
|
|
|
|
self.RewardWeaponID = RewardWeaponID
|
|
|
|
local MonsterClass = GameDataManager.GetRandBreachMonsterClass()
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.ScaleOne()
|
|
local Monster = UGCGameSystem.SpawnActor(self, MonsterClass, Location, Rotation, Scale, nil)
|
|
if not Monster then
|
|
return
|
|
end
|
|
Monster:SetTargetPlayerKey(self.TargetPlayerKey)
|
|
Monster:SetOwner(self)
|
|
Monster.OnDeath:Add(BP_MonsterSpawner.OnSpawnedBreachMonsterDeath, self)
|
|
local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.TargetPlayerKey)
|
|
Monster:InitMonsterByLevel(TargetPlayerState.BreachSuccessTime + 1)
|
|
TargetPlayerState.BreachInfo.NeedBreach = true
|
|
TargetPlayerState.BreachInfo.InBreachProgress = true
|
|
UnrealNetwork.RepLazyProperty(TargetPlayerState, "BreachInfo")
|
|
|
|
if self.BreachLifeSpanHandle ~= nil then
|
|
EventSystem.StopTimer(self.BreachLifeSpanHandle)
|
|
end
|
|
|
|
--设置计时器,检查是否突破成功,若未成功,则继续显示突破按钮
|
|
self.BreachLifeSpanHandle = EventSystem.SetTimer(self, function()
|
|
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.TargetPlayerKey)
|
|
if UE.IsValid(PlayerState) then
|
|
if UE.IsValid(Monster) and Monster:IsAlive() then
|
|
PlayerState.BreachInfo.NeedBreach = true
|
|
PlayerState.BreachInfo.InBreachProgress = false
|
|
UnrealNetwork.RepLazyProperty(PlayerState, "BreachInfo")
|
|
|
|
Monster:K2_DestroyActor()
|
|
|
|
NoticeTipsTools.ServerGeneralNoticeTips(self.TargetPlayerKey, "突破失败,请重新尝试,否则无法继续提升等级", true)
|
|
end
|
|
end
|
|
EventSystem.StopTimer(self.BreachLifeSpanHandle)
|
|
self.BreachLifeSpanHandle = nil
|
|
end, 60)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:StartSpawnChallengeMonster(InChallengeMonsterType, Level)
|
|
if self.IsActivate == false or self.Type ~= EMonsterSpawnerType.HangUpRoom then
|
|
return
|
|
end
|
|
if InChallengeMonsterType < EMonsterType.ChallengeGold or InChallengeMonsterType > EMonsterType.ChallengeWeaponRecasting then
|
|
UE.Log("[BP_MonsterSpawner:StartSpawnChallengeMonster] Error: invalid ChallengeMonsterType")
|
|
return
|
|
end
|
|
|
|
local MonsterClass = GameDataManager.GetRandMonsterClassByType(InChallengeMonsterType)
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.Scale(1.2)
|
|
local Monster = UGCGameSystem.SpawnActor(self, MonsterClass, Location, Rotation, Scale, nil)
|
|
if not Monster then
|
|
return
|
|
end
|
|
Monster:InitMonsterByLevel(Level)
|
|
Monster:SetTargetPlayerKey(self.TargetPlayerKey)
|
|
Monster:SetOwner(self)
|
|
Monster.OnDeath:Add(BP_MonsterSpawner.OnSpawnedChallengeMonsterDeath, self)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:StartSpawnSeal(InPlayerController)
|
|
if self.IsActivate == false or self.Type ~= EMonsterSpawnerType.HangUpRoom then
|
|
return
|
|
end
|
|
local MonsterClass = GameDataManager.GetRandMonsterClassByType(EMonsterType.Unseal)
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.ScaleOne()
|
|
local Monster = UGCGameSystem.SpawnActor(
|
|
self,
|
|
MonsterClass,
|
|
Location,
|
|
Rotation,
|
|
Scale,
|
|
nil)
|
|
if not Monster then
|
|
return
|
|
end
|
|
Monster:SetTargetPlayerKey(self.TargetPlayerKey)
|
|
Monster:SetLifeSpan(60)
|
|
Monster:SetGrowUpLevel(InPlayerController.SealInfo.Times)
|
|
Monster:SetOwner(self)
|
|
Monster.OnDeath:Add(BP_MonsterSpawner.OnSealMonsterDeath, self)
|
|
InPlayerController.SealInfo.IsMonsterAlive = true
|
|
|
|
EventSystem.SetTimer(self, function()
|
|
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.TargetPlayerKey)
|
|
if UE.IsValid(PlayerState) then
|
|
local PlayerController = UGCGameSystem.GetPlayerControllerByPlayerKey(self.TargetPlayerKey)
|
|
if UE.IsValid(Monster) then
|
|
PlayerController.SealInfo.IsMonsterAlive = false
|
|
PlayerController.SealInfo.KillCount = 0
|
|
NoticeTipsTools.ServerGeneralNoticeTips(self.TargetPlayerKey, "封印失败,请重新尝试,否则无法获取封印奖励", true)
|
|
UnrealNetwork.CallUnrealRPC(PlayerController, PlayerController, "ClientRPC_SetSealButtonVisible", true)
|
|
end
|
|
end
|
|
end, 61)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:StartSpawnInherit(InPlayerController, InText, InOldNum)
|
|
if self.IsActivate == false or self.Type ~= EMonsterSpawnerType.HangUpRoom then
|
|
return
|
|
end
|
|
|
|
local MonsterId = 0
|
|
if InText == '盔' then
|
|
MonsterId = 1001
|
|
elseif InText == '甲' then
|
|
MonsterId = 1002
|
|
end
|
|
|
|
local Func = function(InNum)
|
|
return InNum // 10 % 10
|
|
end
|
|
|
|
|
|
local MonsterClass = UE.LoadClass(Tables.MonsterBaseConfig[MonsterId].Path)
|
|
if MonsterClass then
|
|
local Location = self:GetSpawnLocation()
|
|
local Rotation = self:GetSpawnRotation()
|
|
local Scale = VectorHelper.ScaleOne()
|
|
local Monster = UGCGameSystem.SpawnActor(
|
|
self,
|
|
MonsterClass,
|
|
Location,
|
|
Rotation,
|
|
Scale,
|
|
nil)
|
|
if Monster == nil then
|
|
return
|
|
end
|
|
|
|
Monster:SetTargetPlayerKey(self.TargetPlayerKey)
|
|
Monster:SetLifeSpan(60)
|
|
Monster:UpdateMonsterLevel(Monster.MonsterName, Func(InOldNum))
|
|
Monster:SetOwner(self)
|
|
Monster.OnDeath:Add(BP_MonsterSpawner.OnInheritDeath, self)
|
|
self.InheritMonster[InText] = true
|
|
|
|
EventSystem.SetTimer(self, function()
|
|
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(self.TargetPlayerKey)
|
|
if UE.IsValid(PlayerState) and UE.IsValid(Monster) then
|
|
NoticeTipsTools.ServerGeneralNoticeTips(self.TargetPlayerKey, "进阶失败,请重新尝试,否则无法获取奖励", true)
|
|
UnrealNetwork.CallUnrealRPC(self, self, "ClientRPC_UpdateInherit", self.PlayerKey, 2)
|
|
end
|
|
end, 61)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:GenerateDropPosition()
|
|
self.DropPositions = {}
|
|
|
|
local OriginPos = self:K2_GetActorLocation()
|
|
local BoxExtent = self.Box:GetScaledBoxExtent()
|
|
|
|
local NumOfPoints = self.NumberOfPoints
|
|
local ScalarParam = self.ScalarParam
|
|
local ActualWidth = math.max(100.0, BoxExtent.X)
|
|
local GoldenAngle = 1.618 * 2 * 3.141
|
|
local LGRad = ActualWidth * 0.45
|
|
|
|
local SMArea = LGRad * LGRad * 3.141 / NumOfPoints
|
|
for i = 1, NumOfPoints, 1 do
|
|
local Angle = i * GoldenAngle
|
|
local CumArea = i * SMArea
|
|
local SpiralRad = math.sqrt(CumArea / 3.141)
|
|
local X = math.cos(Angle) * SpiralRad * ScalarParam
|
|
local Y = math.sin(Angle) * SpiralRad * ScalarParam
|
|
local RelativePos = Vector.New(X, Y, 0.0)
|
|
local TempPos = VectorHelper.Add(OriginPos, RelativePos)
|
|
table.insert(self.DropPositions, TempPos)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:GetSpawnLocation()
|
|
if #self.DropPositions <= 1 then
|
|
self:GenerateDropPosition()
|
|
end
|
|
return table.remove(self.DropPositions, math.random(1, #self.DropPositions))
|
|
end
|
|
|
|
function BP_MonsterSpawner:GetSpawnRotation()
|
|
return Rotator.New(0.0, math.random(-180.0, 180.0), 0.0)
|
|
end
|
|
|
|
function BP_MonsterSpawner:OnSpawnedMonsterDeath(DeadMonster, KillerController, DamageCauseActor, HitResult, HitImpulseDirection, DamageTypeID, bHeadShotDamage)
|
|
if self:HasAuthority() then
|
|
if self:GetSpawnerType() == EMonsterSpawnerType.AttackWave then
|
|
table.removeValue(self.SpawnedMonsters, DeadMonster)
|
|
if table.getCount(self.SpawnedMonsters) <= 0 then
|
|
UGCGameSystem.GameState:UpdateIsInAttackWave(false)
|
|
end
|
|
end
|
|
|
|
DeadMonster.OnDeath:Remove(BP_MonsterSpawner.OnSpawnedMonsterDeath, self)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:OnSpawnedChallengeMonsterDeath(DeadMonster, KillerController, DamageCauseActor, HitResult, HitImpulseDirection, DamageTypeID, bHeadShotDamage)
|
|
if self:HasAuthority() then
|
|
local Level = DeadMonster.BossLevel
|
|
local MonsterType = GameDataManager.GetMonsterTypeByID(DeadMonster.ID)
|
|
local ChallengeIndex = GameDataManager.GetChallengeInfoIndex(MonsterType)
|
|
Tables.ChallengeInfo[ChallengeIndex].IncomeFun(KillerController.PlayerKey, Level)
|
|
|
|
DeadMonster.OnDeath:Remove(BP_MonsterSpawner.OnSpawnedChallengeMonsterDeath, self)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:OnSpawnedBreachMonsterDeath(DeadMonster, KillerController, DamageCauseActor, HitResult, HitImpulseDirection, DamageTypeID, bHeadShotDamage)
|
|
if self:HasAuthority() then
|
|
if self.RewardWeaponID == nil or self.RewardWeaponID <= 0 then
|
|
return
|
|
end
|
|
|
|
local KillerPlayerKey = KillerController.PlayerKey
|
|
local KillerPlayerPawn = UGCGameSystem.GetPlayerPawnByPlayerKey(KillerPlayerKey)
|
|
local KillerPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(KillerPlayerKey)
|
|
|
|
---检测击杀者是否是自己(防止别人帮你击杀)
|
|
if KillerPlayerKey ~= DeadMonster.TargetPlayerKey then
|
|
local TargetPlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(DeadMonster.TargetPlayerKey)
|
|
TargetPlayerState.BreachInfo.NeedBreach = true
|
|
TargetPlayerState.BreachInfo.InBreachProgress = false
|
|
UnrealNetwork.RepLazyProperty(TargetPlayerState, "BreachInfo")
|
|
|
|
NoticeTipsTools.ServerGeneralNoticeTips(DeadMonster.TargetPlayerKey, "突破失败,请重新尝试,否则无法继续提升等级", true)
|
|
return
|
|
end
|
|
|
|
KillerPlayerState.BreachSuccessTime = KillerPlayerState.BreachSuccessTime + 1
|
|
KillerPlayerState.BreachInfo.NeedBreach = false
|
|
KillerPlayerState.BreachInfo.InBreachProgress = false
|
|
UnrealNetwork.RepLazyProperty(KillerPlayerState, "BreachInfo")
|
|
|
|
KillerPlayerState:OnChangedLevel()
|
|
|
|
if KillerPlayerState.BreachSuccessTime == 1 then
|
|
local DropPos = VectorHelper.Sub(DeadMonster:K2_GetActorLocation(), {X = 0, Y = 0, Z = DeadMonster.Capsule.CapsuleHalfHeight})
|
|
local DropRot = DeadMonster:K2_GetActorRotation()
|
|
if KillerPlayerState:GetNeedTriggerForceGuide() then
|
|
local RayItemData = {
|
|
ItemID = 21240,
|
|
ItemType = EItemType.SkillBook,
|
|
Quality = 4,
|
|
Count = 1,
|
|
}
|
|
EventSystem:SendEvent(EventType.SpawnDropItem, DropPos, DropRot, KillerController.PlayerKey, RayItemData)
|
|
EventSystem:SendEvent(EventType.SpawnDropItem, DropPos, DropRot, KillerController.PlayerKey, GenerateSkillBookData(ESkillType.Active))
|
|
else
|
|
EventSystem:SendEvent(EventType.SpawnDropItem, DropPos, DropRot, KillerController.PlayerKey, GenerateSkillBookData())
|
|
EventSystem:SendEvent(EventType.SpawnDropItem, DropPos, DropRot, KillerController.PlayerKey, GenerateSkillBookData())
|
|
end
|
|
end
|
|
|
|
KillerController:ServerRPC_AddWeapon(self.RewardWeaponID, KillerPlayerKey)
|
|
|
|
UnrealNetwork.CallUnrealRPC(KillerController, KillerController, "ClientRPC_TriggerGuide", 19)
|
|
UnrealNetwork.CallUnrealRPC_Multicast(KillerPlayerPawn, "Client_MulticastRPC_PlayEffect", GameDataManager.GetEffectInstanceId(), 36, KillerPlayerPawn, nil, 0, EEffectSpawnLocationType.Attach)
|
|
NoticeTipsTools.ServerGeneralNoticeTips(KillerPlayerKey, "已消灭突破怪,等级已解锁,已获得突破武器")
|
|
|
|
DeadMonster.OnDeath:Remove(BP_MonsterSpawner.OnSpawnedBreachMonsterDeath, self)
|
|
|
|
if self.BreachLifeSpanHandle ~= nil then
|
|
EventSystem.StopTimer(self.BreachLifeSpanHandle)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:OnSealMonsterDeath(DeadMonster, KillerController, DamageCauseActor, HitResult, HitImpulseDirection, DamageTypeID, bHeadShotDamage)
|
|
if self:HasAuthority() then
|
|
--重置参数
|
|
KillerController.SealInfo.IsMonsterAlive = false
|
|
KillerController.SealInfo.KillCount = 0
|
|
local FinalItems = self:RandomSealRewards(KillerController.SealInfo.Times)
|
|
KillerController.SealInfo.Times = KillerController.SealInfo.Times + 1
|
|
UnrealNetwork.CallUnrealRPC(KillerController, KillerController, "ClientRPC_SetSealRewards", FinalItems)
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:RandomSealRewards(InTimes)
|
|
-- 随机两个
|
|
local Items = {}
|
|
local FinalItems = {}
|
|
local RewardCount = table.getCount(SealTables.Rewards)
|
|
for i = 1, RewardCount do
|
|
table.insert(Items, i)
|
|
end
|
|
|
|
local Func = function(InIndex)
|
|
local TheIndex = 1
|
|
for i, v in pairs(SealTables.Rewards) do
|
|
if TheIndex == InIndex then
|
|
return i
|
|
end
|
|
TheIndex = TheIndex + 1
|
|
end
|
|
end
|
|
|
|
for _ = 1, 2 do
|
|
local FirstIndex = math.random(1, #Items)
|
|
table.remove(Items, FirstIndex)
|
|
local Type = Func(Items[FirstIndex])
|
|
local Value = InTimes * SealTables.Rewards[Type]
|
|
if Type == '配件' or Type == '技能书' then
|
|
Value = InTimes // 5 + 1
|
|
end
|
|
table.insert(FinalItems, { Type = Type, Value = Value })
|
|
end
|
|
|
|
return FinalItems
|
|
end
|
|
|
|
function BP_MonsterSpawner:OnInheritDeath(DeadMonster, KillerController, DamageCauseActor, HitResult, HitImpulseDirection, DamageTypeID, bHeadShotDamage)
|
|
local OldId
|
|
local SelectText
|
|
if DeadMonster.ID == 1001 then
|
|
SelectText = '盔'
|
|
elseif DeadMonster.ID == 1002 then
|
|
SelectText = '甲'
|
|
end
|
|
|
|
OldId = KillerController.PlayerState.InheritItems[SelectText]
|
|
|
|
-- 给予奖励
|
|
local PlayerState = UGCGameSystem.GetPlayerStateByPlayerKey(DeadMonster.TargetPlayerKey)
|
|
local NextId = InheritTable.GetNextId(OldId)
|
|
local Benefit = InheritTable.Items[OldId].Benefit
|
|
for i = 1, #Benefit do
|
|
PlayerState:AddAttribute(Benefit[i].Type, Benefit[i].Value, true)
|
|
end
|
|
PlayerState.InheritItems[SelectText] = NextId
|
|
ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](self, 14)
|
|
local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerState.PlayerKey)
|
|
UnrealNetwork.CallUnrealRPC(PC, PC, "ClientRPC_UpdateInherit", DeadMonster.TargetPlayerKey, 0)
|
|
end
|
|
|
|
function BP_MonsterSpawner:UpdateHangupRoomMonsterLevel(Level)
|
|
local HangupRoomMonsterClass = UE.LoadClass(BPClassPath.HangupRoomMonster)
|
|
for _, Monster in pairs(self.SpawnedMonsters) do
|
|
if UE.IsA(Monster, HangupRoomMonsterClass) then
|
|
Monster:InitMonsterByLevel(Level)
|
|
end
|
|
end
|
|
end
|
|
|
|
function BP_MonsterSpawner:CleanMonsterRefByIndex(SpawnIndex)
|
|
if self.Type ~= EMonsterSpawnerType.HangUpRoom or SpawnIndex == nil or SpawnIndex <= 0 then
|
|
return
|
|
end
|
|
self.SpawnedMonsters[SpawnIndex] = nil
|
|
end
|
|
|
|
function BP_MonsterSpawner:CheckSpecialDropForMonster(MonsterType, DropPos, DropRot, KillerPlayerKey)
|
|
local GameDifficulty = UGCGameSystem.GameState.GameDifficulty
|
|
if GameDifficulty < 3 or GameDifficulty > 10 then
|
|
return
|
|
end
|
|
|
|
if self.RandDropRayDeadCount == nil then
|
|
self.RandDropRayDeadCount = math.random(1, 3)
|
|
end
|
|
|
|
if self.HangupRoomMonsterDeadCount == nil then
|
|
self.HangupRoomMonsterDeadCount = 0
|
|
end
|
|
|
|
if self.HasDroppedRay == nil then
|
|
self.HasDroppedRay = false
|
|
end
|
|
|
|
if self.HasDroppedRay == true then
|
|
return
|
|
end
|
|
|
|
if MonsterType == EMonsterType.HangupRoom then
|
|
self.HangupRoomMonsterDeadCount = self.HangupRoomMonsterDeadCount + 1
|
|
if self.HangupRoomMonsterDeadCount == self.RandDropRayDeadCount then
|
|
UE.Log("[BP_MonsterSpawner][CheckSpecialDropForMonster] HangupRoom Drop")
|
|
local RayItemData = {ItemID = 21240, ItemType = EItemType.SkillBook, Quality = 4, Count = 1,}
|
|
EventSystem:SendEvent(EventType.SpawnDropItem, DropPos, DropRot, KillerPlayerKey, RayItemData)
|
|
self.HasDroppedRay = true
|
|
end
|
|
end
|
|
end
|
|
|
|
return BP_MonsterSpawner; |