PGRData/Script/matrix/xdlcfight/level/0015.lua
2024-09-01 22:49:41 +02:00

345 lines
No EOL
12 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- 白龙boss战
local XLevel0015 = XDlcScriptManager.RegLevelScript(0015, "XLevel0015")
local FuncSet = CS.StatusSyncFight.XFightScriptFuncs
local Config = require("XDLCFight/Level/LevelConfig/Hunt01BossFightConfig") -- 读取场景物体的配置数据,作为实例存在本地
local Tool = require("XDLCFight/Level/Common/XLevelTools")
local XPlayerNpcContainer = require("XDLCFight/Level/Common/XPlayerNpcContainer")
local Timer = require("XDLCFight/Level/Common/XTaskScheduler")
local _cameraResRefTable = {
}
function XLevel0015.GetCameraResRefTable()
return _cameraResRefTable
end
---@param proxy StatusSyncFight.XScriptLuaProxy
function XLevel0015:Ctor(proxy)
self._proxy = proxy
self._timer = Timer.New()
self._worldId = FuncSet.GetWorldId()
if Config.Boss[self._worldId] == nil then
self._worldId = 2
end
self._wightDragonRespawnId = Config.Boss[self._worldId].WightDragon
self._wightDragonBossRefId = 2
self._spearFatalitySoundFx = 8002105
self._bossHidePos = { x = 60, y = -200, z = 60 }
self._bossBornPos = { x = 60, y = 1.95, z = 60 }
self._bossBornRot = { x = 0, y = 180, z = 0 }
self._wightDragonNpcId = nil ---boss的id
self._playerNpcContainer = XPlayerNpcContainer.New()
self._playerRescueDict = {}
--[[ self._switches = {
{
placeId = 1,
agent = nil,
object = self,
func = self.PlaySceneAnim,
param = nil,
times = 1,
defaultEnable = true
},
}]]
self._deathZonePlaceId = 9999
self._outwardsDeathZonePlaceId = 9998 ---暂时用来应对玩家挤出空气墙的处理
self._debug = false
end
function XLevel0015:Init()
self:InitPhase()
self:InitWightDragon()
self:InitPlayer()
--self:InitSwitch()
self:InitListen()
end
---@param dt number @ delta time
function XLevel0015:Update(dt)
self._timer:Update(dt)
self:OnUpdatePhase(dt)
self:PlayerInteract()
self:OnInteractButton()
end
function XLevel0015:OnInteractButton()
if self._debug then
if FuncSet.IsKeyDown(ENpcOperationKey.Ball11) then
elseif FuncSet.IsKeyDown(ENpcOperationKey.Ball12) then
self:SpearFatality()
elseif FuncSet.IsKeyDown(ENpcOperationKey.Ball10) then
elseif FuncSet.IsKeyDown(ENpcOperationKey.Ball9) then
end
end
end
---@param eventType number
---@param eventArgs userdata
function XLevel0015:HandleEvent(eventType, eventArgs)
self.Super.HandleEvent(self, eventType, eventArgs)
self:HandlePhaseEvent(eventType, eventArgs)
self._playerNpcContainer:HandleEvent(eventType, eventArgs)
if eventType == EScriptEvent.SceneObjectTrigger then
--[[ XLog.Debug("XLevelBossFight1 SceneObjectTriggerEvent:"
.. " TouchType " .. tostring(eventArgs.TouchType)
.. " SourceActorId " .. tostring(eventArgs.SourceActorId)
.. " SceneObjectId " .. tostring(eventArgs.SceneObjectId)
.. " TriggerId " .. tostring(eventArgs.TriggerId)
.. " TriggerState " .. tostring(eventArgs.TriggerState)
.. " Log自关卡"
)]]
if eventArgs.SceneObjectId == self._deathZonePlaceId and FuncSet.IsPlayerNpc(eventArgs.SourceActorId) then
FuncSet.ResetNpcToSafePoint(eventArgs.SourceActorId)
end
if eventArgs.SceneObjectId == self._outwardsDeathZonePlaceId and FuncSet.IsPlayerNpc(eventArgs.SourceActorId) and eventArgs.TriggerState == ESceneObjectTriggerState.Exit then
FuncSet.ResetNpcToCheckPoint(eventArgs.SourceActorId)
XLog.Warning("注意npc ".. tostring(eventArgs.SourceActorId).."穿到战斗场景外了")
end
elseif eventType == EScriptEvent.NpcInteractComplete then
--交互完成
self:OnNpcInteractComplete(eventArgs)
end
if eventType == EScriptEvent.Behavior2ScriptMsg then
if eventArgs.MsgType == 1001 and FuncSet.CheckNpc(self._wightDragonNpcId) then
--天基
self:SpearFatality()
elseif eventArgs.MsgType == 100 then
--设置空气墙碰撞
self:EnableAirWallToNpc(eventArgs.Int[1], eventArgs.Int[2] == 0)
end
end
end
function XLevel0015:GainControl()
end
function XLevel0015:InitPhase()
--初始化关卡各个阶段的相关变量
self._currentPhase = 0
self._lastPhase = 0
self._phaseStartedDelayTranslate = false ---阶段延迟跳转需要设置为true
self._phaseTimeCount = 0
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>初始化关卡阶段参数完成")
end
function XLevel0015:InitWightDragon()
--生成怪物
local id = FuncSet.GetGeneratedNpc(self._wightDragonBossRefId)
if id <= 0 then
--防止断线重连时重复创建怪物
self._wightDragonNpcId = FuncSet.GenerateNpc(self._wightDragonBossRefId, self._wightDragonRespawnId, ENpcCampType.Camp2, self._bossBornPos, self._bossBornRot)
else
self._wightDragonNpcId = id
end
self._proxy:RegisterBehavior2ScriptMsgEvent(self._wightDragonNpcId)
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>召唤npc白龙完成")
end
function XLevel0015:InitPlayer()
self._playerNpcContainer:Init(
function(npc)
self:OnPlayerNpcCreate(npc)
end,
function(npc)
self:OnPlayerNpcDestroy(npc)
end
)
self._playerNpcList = self._playerNpcContainer:GetPlayerNpcList()
self._playerCount = #self._playerNpcList
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>初始化关卡用玩家参数完成")
end
function XLevel0015:InitSwitch()
self._switches = Tool.InitSwitch(self._switches)
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>初始化场景中开关完成")
end
function XLevel0015:InitListen()
self._proxy:RegisterSceneObjectTriggerEvent(self._deathZonePlaceId, 1) --死区
self._proxy:RegisterSceneObjectTriggerEvent(self._outwardsDeathZonePlaceId, 1) --外部死区,一个临时解决方案
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>初始化其他监听内容完成")
end
function XLevel0015:OnPlayerNpcCreate(npc)
self._proxy:RegisterNpcEvent(EScriptEvent.NpcCastSkill, npc)
self._proxy:RegisterNpcEvent(EScriptEvent.NpcExitSkill, npc)
self._playerNpcList = self._playerNpcContainer:GetPlayerNpcList()
self._playerCount = #self._playerNpcList
FuncSet.SetSceneColliderIgnoreCollision(npc, "MonsterAirWall", -1, true) --用于限制boss在场边活动的空气墙
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>注册角色技能监听:" .. npc)
end
function XLevel0015:OnPlayerNpcDestroy(npc)
self._proxy:UnregisterNpcEvent(EScriptEvent.NpcCastSkill, npc)
self._proxy:UnregisterNpcEvent(EScriptEvent.NpcExitSkill, npc)
self._playerNpcList = self._playerNpcContainer:GetPlayerNpcList()
self._playerCount = #self._playerNpcList
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>注销角色技能监听:" .. npc)
end
---玩家之间的交互
function XLevel0015:PlayerInteract()
--玩家救援复活交互检测
for i = 1, #self._playerNpcList do
local npcA = self._playerNpcList[i]
for j = 1, #self._playerNpcList do
local npcB = self._playerNpcList[j]
self:CheckPlayerRescueInteract(npcA, npcB, 3.5)
end
end
end
---玩家救援交互
---@param launcher number
---@param target number
---@param dist number @distance
function XLevel0015:CheckPlayerRescueInteract(launcher, target, dist)
if target == launcher then
--不能对自己交互
return
end
local curTarget = self._playerRescueDict[launcher]
if curTarget ~= nil then
local isInRange = FuncSet.CheckNpcDistance(launcher, curTarget, dist)
if not isInRange or self:IsNpcDead(launcher) or not self:IsNpcDying(curTarget) then
self._playerRescueDict[launcher] = nil
FuncSet.CloseInteraction(launcher)
XLog.Debug(string.format("Level CloseInteraction Rescue, launcher:%d target:%d ", launcher, curTarget, dist))
end
else
local isInRange = FuncSet.CheckNpcDistance(launcher, target, dist)
if isInRange and not self:IsNpcDead(launcher) and self:IsNpcDying(target) then
self._playerRescueDict[launcher] = target
FuncSet.ShowInteraction(launcher, target, FuncSet.GetRescueTime(), EInteractType.Rescue)
XLog.Debug(string.format("Level ShowInteraction Rescue, launcher:%d target:%d ", launcher, target, dist))
end
end
end
---@param eventArgs StatusSyncFight.NpcEventArgs
function XLevel0015:OnNpcInteractComplete(eventArgs)
local npc = eventArgs.NpcId
local target = self._playerRescueDict[npc]
if target then
FuncSet.RebornNpc(npc, target) --复活救援对象
self._playerRescueDict[npc] = nil --清除救援对象记录
end
FuncSet.CloseInteraction(npc, false) --关闭救援者的交互按钮
end
---Npc是否处在濒死状态
function XLevel0015:IsNpcDying(npcId)
return FuncSet.CheckNpcAction(npcId, ENpcAction.Dying)
end
---Npc是否死亡
function XLevel0015:IsNpcDead(npcId)
return FuncSet.CheckNpcAction(npcId, ENpcAction.Dying) or FuncSet.CheckNpcAction(npcId, ENpcAction.Death)
end
---跳转关卡阶段
function XLevel0015:SetPhase(phase)
if phase == self._currentPhase then
return
end
self:OnExitPhase(self._currentPhase)
self:OnEnterPhase(phase)
self:OnPhaseChanged(self._currentPhase, self.phase)
self._lastPhase = self._currentPhase
self._currentPhase = phase
self._phaseTimeCount = 0
end
---当前关卡阶段需要一直执行的逻辑在这里实现。一般用作执行判断、执行持续性的功能、跳转阶段
function XLevel0015:OnUpdatePhase(dt)
if self._phaseTimeCount == nil then
self._phaseTimeCount = 0
end
self._phaseTimeCount = self._phaseTimeCount + dt
if self._currentPhase == 0 then
if not FuncSet.CheckNpc(self._wightDragonNpcId) then
XLog.Debug("<color=#F0D800>[SceneHunt01]</color>检测到boss死亡")
FuncSet.FinishFight(true)
end
elseif self._currentPhase == 1 then
end
end
---进入一个关卡阶段时需要做的事情在这里实现。一般用作设置阶段所需的环境
function XLevel0015:OnEnterPhase(phase)
if phase == 1 then
elseif phase == 2 then
end
end
---关卡阶段改变时需要执行的逻辑,一般用于通知外部
function XLevel0015:OnPhaseChanged(lastPhase, nextPhase)
end
---处理阶段相关的事件响应、状态检测、信息获取
function XLevel0015:HandlePhaseEvent(eventType, eventArgs)
if self._currentPhase == 1 then
elseif self._currentPhase == 2 then
end
end
---天基演出流程
function XLevel0015:SpearFatality()
for _, npc in pairs(self._playerNpcList) do
FuncSet.ApplyMagic(npc, npc, 5000003, 1)
self._timer:Schedule(0.5, self, self.RemoveBlackScreen, npc)
end
self:SetFightUiActive(false)
self._timer:Schedule(11, self, self.SetFightUiActive, true)
self._timer:Schedule(0.5, self, self.PlaySpearFatality)
end
function XLevel0015:RemoveBlackScreen(npc)
FuncSet.ApplyMagic(npc, npc, 5000006, 1)
end
function XLevel0015:PlaySpearFatality()
if FuncSet.CheckNpc(self._wightDragonNpcId) then
FuncSet.PlayCameraTimeline("SprearFatality01", self._wightDragonNpcId, 0, 0, 0)
self._timer:Schedule(10.5, "SprearFatality01", FuncSet.StopCameraTimeline, self._wightDragonNpcId)
FuncSet.ApplyMagic(self._wightDragonNpcId, self._wightDragonNpcId, self._spearFatalitySoundFx, 1)
end
end
function XLevel0015:EnableAirWallToNpc(enable, npc)
FuncSet.SetSceneColliderIgnoreCollision(npc, "AirWalls", -1, enable)
FuncSet.SetSceneColliderIgnoreCollision(npc, "OuterAirWall", -1, enable)
FuncSet.SetSceneColliderIgnoreCollision(npc, "MonsterAirWall", -1, enable)
end
function XLevel0015:SetFightUiActive(active)
for _, npc in pairs(self._playerNpcList) do
if active then
FuncSet.ApplyMagic(npc, npc, 5000008)
else
FuncSet.ApplyMagic(npc, npc, 5000007)
end
end
end
function XLevel0015:Terminate()
end
return XLevel0015