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

229 lines
8.9 KiB
Lua

---@class BP_MonsterBoss_C:BP_MonsterAttack_C
---@field HealthWidget UWidgetComponent
---@field NarrationWidget UWidgetComponent
--Edit Below--
local MonsterAttack = require('Script.Blueprint.Monster.BP_MonsterAttack')
local BP_MonsterBoss = setmetatable(
{
HasBegunPlay = false,
KilledPlayerNum = 0,
SpawnMinionsHealthPercents = {0.8, 0.5, 0.3, 0.1},
SpawnedMinions = {},
},
{
__index = MonsterAttack,
__metatable = MonsterAttack
}
)
BP_MonsterBoss.BornTime = nil;
function BP_MonsterBoss:GetReplicatedProperties()
return
"KilledPlayerNum", "bIsStun", "TargetPlayerKey"
end
function BP_MonsterBoss:ReceiveBeginPlayEx()
MonsterAttack.ReceiveBeginPlayEx(self)
if self:HasAuthority() then
local PlayerStates = UGCGameSystem.GetAllPlayerState(false);
local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
for i, v in pairs(PlayerStates) do
if v then
--if v.EasterEggsData[3] == nil then
-- v.EasterEggsData[3] = {}
--end
--v.EasterEggsData[3].BeginTime = ServerTime
end
end
self.BornTime = ServerTime;
else
EventSystem.SetTimer(self, function()
self.NarrationWidget.Widget:UpdateKilledPlayerNum(self.KilledPlayerNum)
end, 1.5)
end
end
function BP_MonsterBoss:BPReceiveDamageEx(DamageAmount, DamageType, EventInstigator, DamageCauser)
if self.bIsReplica then
return
end
local CurHPSpawnThreshold = self.SpawnMinionsHealthPercents[1]
if CurHPSpawnThreshold then
local CurHP = UGCSimpleCharacterSystem.GetHealth(self)
local MaxHP = UGCSimpleCharacterSystem.GetHealthMax(self)
local HPPercent = CurHP / MaxHP
if HPPercent <= CurHPSpawnThreshold then
self:SpawnMinions(#UGCGameSystem.GetAllPlayerPawn() * 5)
table.remove(self.SpawnMinionsHealthPercents, 1)
end
end
UE.Log("[BP_MonsterBoss:BPReceiveDamageEx] %s: CurHealth=%.2f, MaxHealth=%.2f, DamageAmount=%.2f, EventInstigator=%s, Causer=%s",
KismetSystemLibrary.GetObjectName(self),
UGCSimpleCharacterSystem.GetHealth(self),
UGCSimpleCharacterSystem.GetHealthMax(self),
DamageAmount,
KismetSystemLibrary.GetObjectName(EventInstigator),
KismetSystemLibrary.GetObjectName(DamageCauser))
end
function BP_MonsterBoss:SpawnMinions(SpawnNum)
local MonsterClass = GameDataManager.GetAttackWaveCommonMonsterClass()
for i = 1, SpawnNum do
local SpawnLoc = VectorHelper.RandomVector(self:K2_GetActorLocation(), 1)
local SpawnRot = VectorHelper.RandomRotatorYaw(self:K2_GetActorRotation())
local Monster = UGCGameSystem.SpawnActor(self, MonsterClass, SpawnLoc, SpawnRot, VectorHelper.ScaleOne(), nil)
if Monster then
local MaxHP = UGCSimpleCharacterSystem.GetHealthMax(self) / 10.0
UGCSimpleCharacterSystem.SetHealthMax(Monster, MaxHP)
UGCSimpleCharacterSystem.SetHealth(Monster, MaxHP)
UGCSimpleCharacterSystem.SetSpeedScale(Monster, 385 / 600)
Monster.BossLevel = 1
Monster.AttackValue = self.AttackValue / 10.0
Monster.PhysicalDefense = self.PhysicalDefense / 10.0
Monster.DeadCoinPoint = 0.0
Monster.DeadKillPoint = 0.0
Monster.BaseHealthMax = MaxHP
Monster.BaseAttackValue = Monster.AttackValue
Monster.BasePhysicalDefense = Monster.PhysicalDefense
Monster.BaseMaxWalkSpeed = 385
Monster.OnDeath:Add(self.OnMinionDeath, self)
table.insert(self.SpawnedMinions, Monster)
end
end
end
function BP_MonsterBoss:OnMinionDeath(DeadMonster, KillerController, DamageCauser, KillingHitInfo, KillingHitImpulseDir, KillingHitDamageTypeID, DamageTypeClass, IsHeadShotDamage)
for Index, Minion in pairs(self.SpawnedMinions) do
if DeadMonster == Minion then
self.SpawnedMinions[Index] = nil
break
end
end
end
function BP_MonsterBoss:OnRep_KilledPlayerNum()
if UE.IsValid(self.NarrationWidget.Widget) then
self.NarrationWidget.Widget:UpdateKilledPlayerNum(self.KilledPlayerNum)
end
end
function BP_MonsterBoss:ClientOnHealthChangedEx(CurrentHP, MaxHP)
UE.Log("[BP_MonsterBoss:ClientOnHealthChangedEx] %s: CurHealth=%.2f, MaxHealth=%.2f", KismetSystemLibrary.GetObjectName(self), CurrentHP, MaxHP)
if UE.IsValid(self.NarrationWidget.Widget) then
self.NarrationWidget.Widget:UpdateOwnerHealth(CurrentHP, MaxHP)
end
if UE.IsValid(self.HealthWidget.Widget) then
self.HealthWidget.Widget:UpdateOwnerHealth(CurrentHP, MaxHP)
end
end
function BP_MonsterBoss:ReceiveOnMonsterDeath()
MonsterAttack.ReceiveOnMonsterDeath(self)
if self:HasAuthority() then
else
self.NarrationWidget.Widget:UpdateOwnerHealth(0, 100)
self.HealthWidget.Widget:UpdateOwnerHealth(0, 100)
end
end
function BP_MonsterBoss:GetDropRate()
return 100
end
function BP_MonsterBoss:ServerOnDeathEx(DeadMonster, KillerController, DamageCauser, KillingHitInfo, KillingHitImpulseDir, KillingHitDamageTypeID, DamageTypeClass, IsHeadShotDamage)
MonsterAttack.ServerOnDeathEx(self, DeadMonster, KillerController, DamageCauser, KillingHitInfo, KillingHitImpulseDir, KillingHitDamageTypeID, DamageTypeClass, IsHeadShotDamage)
-- 当 BOSS 死亡之后所有玩家的 BOSS 击杀数都加一
if DeadMonster == self then
local PlayerStates = UGCGameSystem.GetAllPlayerState(false);
-- BOSS 死亡掉落
local ChineseName = Tables.MonsterBaseConfig[DeadMonster.ID].ChineseName
-- 检查一下有多少怪物
local Count = 0
local Diff = UGCGameSystem.GameState.GameDifficulty
if Diff >= 4 then
Diff = 4;
end
for i, v in pairs(Tables.GameFightStageConfig[Diff]) do
Count = Count + v.MonsterNum.Boss
end
-- 如果当前 Boss == 最后一位 Boss
local BossList = UGCGameSystem.GameState.BossList
log_tree("[BP_MonsterBoss:OnSelfDeath] BossList = ", BossList)
if DeadMonster.ID == BossList[#BossList] then
EventSystem:SendEvent(EventType.OnSendGameEnd, "LastBossDefeated")
end
local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
local CostTime = ServerTime - self.BornTime
for i, v in pairs(PlayerStates) do
if v then
v.KillCount.Boss = v.KillCount.Boss + 1
v.ArchiveData.TotalBossKilledTimes = v.ArchiveData.TotalBossKilledTimes + 1
ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](v, 3, CostTime);
-- 计算当前彩蛋 3
if v.EasterEggsData[3] == nil then
v.EasterEggsData[3] = {}
v.EasterEggsData[3].BossCount = 1
else
if v.EasterEggsData[3].BossCount == nil then
v.EasterEggsData[3].BossCount = 0
end
v.EasterEggsData[3].BossCount = v.EasterEggsData[3].BossCount + 1
end
if v.EasterEggsData[3].BossCount == Count then
local ServerTime = KismetSystemLibrary.GetGameTimeInSeconds(self)
v.EasterEggsData[3].EndTime = ServerTime
local BeginTime = v.EasterEggsData[3].BeginTime
if BeginTime ~= nil then
ArchiveTable.Funcs[ArchiveTable.ArchiveType.EasterEggs](v, 3, ServerTime - BeginTime)
end
end
-- 计算总的掉落概率
local DropRate = 0
for _, c in pairs(ArchiveTable.BossDropItems[ChineseName]) do
if c.DropRate ~= nil then
DropRate = c.DropRate + DropRate
end
end
local RandNum = math.random()
if RandNum <= DropRate then
local Val = math.random(1, 4)
if v.ArchiveData.BossDropItems[ChineseName] == nil then
v.ArchiveData.BossDropItems[ChineseName] = {}
end
if v.ArchiveData.BossDropItems[ChineseName][Val] == nil then
v.ArchiveData.BossDropItems[ChineseName][Val] = 1
else
v.ArchiveData.BossDropItems[ChineseName][Val] = v.ArchiveData.BossDropItems[ChineseName][Val] + 1
end
end
end
end
for Index, Minion in pairs(self.SpawnedMinions) do
if Minion ~= nil and UE.IsValid(Minion) and Minion:IsAlive() then
Minion:SetLifeSpan(2.0)
end
self.SpawnedMinions[Index] = nil
end
end
end
return BP_MonsterBoss;