229 lines
8.9 KiB
Lua
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; |