--- Hun01连战
local XLevelBossFight0014 = XDlcScriptManager.RegLevelScript(0014, "XLevelBossFight0014")
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 XLevelBossFight0014.GetCameraResRefTable()
return _cameraResRefTable
end
---@param proxy StatusSyncFight.XScriptLuaProxy
function XLevelBossFight0014:Ctor(proxy)
self._proxy = proxy
self._timer = Timer.New()
--const
self._currentPhaseMemKey = 1101
self._worldId = FuncSet.GetWorldId()
if Config.Boss[self._worldId] == nil then
self._worldId = 2
end
--{{{npc
self._playerFocusAnchorDic = {}
self._blackDragonRespawnId = Config.Boss[self._worldId].BlackDragon
self._blackDragonBossRefId = 1 --黑龙boss生成记录的引用id
self._wightDragonRespawnId = Config.Boss[self._worldId].WightDragon
self._wightDragonBossRefId = 2 --白龙boss生成记录的引用id
self._wightDragonHackSoundFx = 8002103
self._wightDragonBornSoundFx = 8002104
self._spearFatalitySoundFx = 8002105
self._bossHidePos = { x = 60, y = -200, z = 60 }
self._bossBornPos = { x = 64, y = 1.95, z = 72.1 }
self._bossBornRot = { x = 0, y = 180, z = 0 }
self._blackDragonNpcId = nil ---boss的id
self._wightDragonNpcId = nil ---boss的id
self._playerNpcContainer = XPlayerNpcContainer.New()
self._playerRescueDict = {}
--}}}
--{{{objects
self._towers = {}
--[[ self._switches = {
{
placeId = 3000,
agent = nil,
object = self,
func = self.TestSwitchStartJumpFun,
param = nil,
times = -1,
defaultEnable = true
},
}]]
self._deathZonePlaceId = 9999
self._outwardsDeathZonePlaceId = 9998 ---暂时用来应对玩家挤出空气墙的处理
self._bossLockTrigger = 17 ---boss等待区域,用于开关玩家自动锁定boss的判断
self._bossReadyTrigger = 18 ---boss停留在场地中央等待跳跳乐开始的区域
self._centerTowerEffectPlayer = 1001
--}}}
--{{{跳跳乐参数
self._playerCompleteJumpFun = {} ---每名玩家是否通过跳跳乐
self._bossEndureMagicId = 8001035
self._removeBossEndureMagicId = 8001036
self._jumpFunStartSignMagicId = 5990130
self._jumpFunEndSignMagicId = 5990131
self._jumpFunDefeatTimeLimit = 60 ---跳跳乐时限
--}}}
self._bgmTrack = 1
self._bgmCurrentTrack = 1
self._debug = false
end
---脚本初始化,自动执行
function XLevelBossFight0014:Init()
self:InitPhase()
self:InitBlackDragon()
self:InitPlayer()
self:InitTower()
--self:InitSwitch()
self:InitListen()
end
---@param dt number @ delta time
function XLevelBossFight0014:Update(dt)
self._timer:Update(dt)
self:OnUpdatePhase(dt)
self:PlayerInteract()
self:OnInteractButton()
self:BgmTrackControl(dt)
end
function XLevelBossFight0014:OnInteractButton()
if self._debug then
if FuncSet.IsKeyDown(ENpcOperationKey.Ball11) then
FuncSet.ApplyMagic(self._playerNpcContainer._localPlayerNpcId, self._playerNpcContainer._localPlayerNpcId, self._wightDragonHackSoundFx, 1)
elseif FuncSet.IsKeyDown(ENpcOperationKey.Ball12) then
FuncSet.ApplyMagic(self._playerNpcContainer._localPlayerNpcId, self._playerNpcContainer._localPlayerNpcId, self._wightDragonBornSoundFx, 1)
elseif FuncSet.IsKeyDown(ENpcOperationKey.Ball10) then
if FuncSet.CheckNpc(self._blackDragonNpcId) then
FuncSet.NpcDie(self._blackDragonNpcId)
end
elseif FuncSet.IsKeyDown(ENpcOperationKey.Ball9) then
self:SpearFatality()
end
end
end
---@param eventType number
---@param eventArgs userdata
function XLevelBossFight0014:HandleEvent(eventType, eventArgs)
XLevelBossFight0014.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._blackDragonNpcId) or FuncSet.CheckNpc(self._wightDragonNpcId))then
--临时天基
self:SpearFatality()
elseif eventArgs.MsgType == 100 then
--设置空气墙碰撞
self:EnableAirWallToNpc(eventArgs.Int[1], eventArgs.Int[2] == 0)
elseif eventArgs.MsgType == 800101 then
--躲黑龙大招的跳跳乐
for _, sequence in pairs(Config.Sequence) do
self:SpecialTowerControl(sequence.tower, sequence.raise, sequence.delayTime)
end
end
end
end
---主控端转移时的关卡状态恢复
function XLevelBossFight0014:GainControl()
self:Init()
local currentPhase = FuncSet.GetLevelMemoryInt(self._currentPhaseMemKey)
if currentPhase > 0 then
self:SetPhase(currentPhase)
end
end
--{{{Init
function XLevelBossFight0014:InitPhase()
--初始化关卡各个阶段的相关变量
self._currentPhase = 0
self._lastPhase = 0
self._phaseStartedDelayTranslate = false ---阶段延迟跳转需要设置为true
self._phaseTimeCount = 0
--phase0 关卡开始,啥都没操作,检测是否进入跳跳乐
--phase1 令黑龙准备跳跳乐,检测是否就位
self._bossCanCastSkillTime = 0
self._bossHasCastSkill = false
self._bossIsReady = false
--phase2 跳跳乐
self._jumpFunCompletePlayerCount = 0 ---通过了跳跳乐的玩家数量
--phase3 跳跳乐结束,龙飞天开大
self._phase3TimeLimit = 28
--phase4 跳跳乐结束,龙被玩家暴打
self._phase4TimeLimit = 15
--phase5 正常进行游戏
--phase10 连战转换
self._centerTowerRaise = nil
self._centerTowerMoving = nil
self._confirmCenterTowerDown = false
self._centerTowerWaitToDo = false
self._towersSequences = {}
self._specialTowerSequences = {}
self._confirmTowersDown = false
--phase11 开始白龙入场演出
XLog.Debug("[SceneHunt01]初始化关卡阶段参数完成")
end
function XLevelBossFight0014:InitBlackDragon()
local id = FuncSet.GetGeneratedNpc(self._blackDragonBossRefId)
--生成怪物
if id <= 0 then
--防止断线重连时重复创建怪物
self._blackDragonNpcId = FuncSet.GenerateNpc(self._blackDragonBossRefId, self._blackDragonRespawnId, ENpcCampType.Camp2, self._bossBornPos, self._bossBornRot)
else
self._blackDragonNpcId = id
end
self._proxy:RegisterBehavior2ScriptMsgEvent(self._blackDragonNpcId)
XLog.Debug("[SceneHunt01]召唤npc黑龙完成")
end
function XLevelBossFight0014:InitWightDragon()
--生成怪物
local id = FuncSet.GetGeneratedNpc(self._wightDragonBossRefId)
if id <= 0 then
--防止断线重连时重复创建怪物
self._wightDragonNpcId = FuncSet.GenerateNpc(self._wightDragonBossRefId, self._wightDragonRespawnId, ENpcCampType.Camp2, self._bossHidePos, self._bossBornRot)
else
self._wightDragonNpcId = id
end
self._proxy:RegisterBehavior2ScriptMsgEvent(self._wightDragonNpcId)
XLog.Debug("[SceneHunt01]召唤npc白龙完成")
end
function XLevelBossFight0014: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("[SceneHunt01]初始化关卡用玩家参数完成")
end
function XLevelBossFight0014:InitTower()
self._towers = Tool.InitTower(Config.Towers)
XLog.Debug("[SceneHunt01]初始化场景中塔完成")
end
function XLevelBossFight0014:InitSwitch()
self._switches = Tool.InitSwitch(self._switches)
XLog.Debug("[SceneHunt01]初始化场景中开关完成")
end
function XLevelBossFight0014:InitListen()
self._proxy:RegisterSceneObjectTriggerEvent(self._bossReadyTrigger, 1) --boss跳到中央塔的位置的检测
self._proxy:RegisterSceneObjectTriggerEvent(self._bossLockTrigger, 1) --boss停留在场地中央等待的区域检测
self._proxy:RegisterSceneObjectTriggerEvent(self._deathZonePlaceId, 1) --死区
self._proxy:RegisterSceneObjectTriggerEvent(self._outwardsDeathZonePlaceId, 1) --外部死区,一个临时解决方案
XLog.Debug("[SceneHunt01]初始化其他监听内容完成")
end
--}}}
function XLevelBossFight0014:OnPlayerNpcCreate(npc)
self._playerFocusAnchorDic[npc] = nil ---注册每名玩家当前选中的勾点
self._playerCompleteJumpFun[npc] = false
self._proxy:RegisterNpcEvent(EScriptEvent.NpcCastSkill, npc)
self._proxy:RegisterNpcEvent(EScriptEvent.NpcExitSkill, npc)
self._playerNpcList = self._playerNpcContainer:GetPlayerNpcList()
self._playerCount = #self._playerNpcList
self._proxy:RegisterBehavior2ScriptMsgEvent(npc) --test
FuncSet.SetSceneColliderIgnoreCollision(npc, "MonsterAirWall", -1, true) --用于限制boss在场边活动的空气墙
XLog.Debug("[SceneHunt01]注册角色技能监听:" .. npc)
XLog.Debug(self._playerFocusAnchorDic)
end
function XLevelBossFight0014:OnPlayerNpcDestroy(npc)
self._playerFocusAnchorDic[npc] = nil
self._playerCompleteJumpFun[npc] = nil
self._proxy:UnregisterNpcEvent(EScriptEvent.NpcCastSkill, npc)
self._proxy:UnregisterNpcEvent(EScriptEvent.NpcExitSkill, npc)
self._playerNpcList = self._playerNpcContainer:GetPlayerNpcList()
self._playerCount = #self._playerNpcList
XLog.Debug("[SceneHunt01]注销角色技能监听:" .. npc)
end
---玩家之间的交互
function XLevelBossFight0014: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 XLevelBossFight0014: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 XLevelBossFight0014: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 XLevelBossFight0014:IsNpcDying(npcId)
return FuncSet.CheckNpcAction(npcId, ENpcAction.Dying)
end
---Npc是否死亡
function XLevelBossFight0014:IsNpcDead(npcId)
return FuncSet.CheckNpcAction(npcId, ENpcAction.Dying) or FuncSet.CheckNpcAction(npcId, ENpcAction.Death)
end
---跳转关卡阶段
function XLevelBossFight0014: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
FuncSet.SetLevelMemoryInt(self._currentPhaseMemKey, self._currentPhase)
end
---当前关卡阶段需要一直执行的逻辑在这里实现。一般用作执行判断、执行持续性的功能、跳转阶段
function XLevelBossFight0014:OnUpdatePhase(dt)
if self._phaseTimeCount == nil then
self._phaseTimeCount = 0
end
self._phaseTimeCount = self._phaseTimeCount + dt
if self._currentPhase == 0 then
--[[ -- 检测条件,如果满足则进入阶段1,通知boss就位
if self:JumpFunStartCheck() then
self:SetPhase(1)
end]]
elseif self._currentPhase == 1 then
if not self._bossHasCastSkill then
--持续放技能
self:BossCastReadySwoop()
end
if self._bossIsReady and self._bossHasCastSkill and FuncSet.CheckCanCastSkill(self._blackDragonNpcId) then
self:SetPhase(2)
end
elseif self._currentPhase == 2 then
--此段逻辑无效,改为检测跳跳乐结束事件来执行
--self:JumpFunProgress(dt)
--[[ if self:JumpFunEndCheck() then
if self._jumpFunCompletePlayerCount < 3 then
self:SetPhase(3)
else
self:SetPhase(4)
end
end]]
elseif self._currentPhase == 3 then
if self._phaseTimeCount >= self._phase3TimeLimit then
self:SetPhase(5)
end
elseif self._currentPhase == 4 then
if self._phaseTimeCount >= self._phase4TimeLimit then
self:SetPhase(5)
end
elseif self._currentPhase == 10 then
self:FixLevelStateUpdate()
self:CheckLevelStateFixed()
if --[[self._waitTime <= self._phaseTimeCount
and ]]self._confirmCenterTowerDown
and self._confirmTowersDown then
self:SetPhase(11)
end
elseif self._currentPhase == 11 then
if self._phaseTimeCount > 8 then
self:SetPhase(12)
end
elseif self._currentPhase == 12 then
if not FuncSet.CheckNpc(self._wightDragonNpcId) and self._phaseTimeCount > 10 then
XLog.Debug("[SceneHunt01]检测到boss死亡")
FuncSet.FinishFight(true)
end
end
if self._currentPhase == 0 and self._phaseTimeCount > 10 then
if not FuncSet.CheckNpc(self._blackDragonNpcId) then
XLog.Debug("[SceneHunt01]检测到boss死亡")
if self._worldId >= 13 then
self:SetPhase(12)
else
self:SetPhase(10)
end
end
elseif not (self._currentPhase == 0) and self._currentPhase < 10 then
if not FuncSet.CheckNpc(self._blackDragonNpcId) then
XLog.Debug("[SceneHunt01]检测到boss死亡")
if self._worldId >= 13 then
self:SetPhase(12)
else
self:SetPhase(10)
end
end
end
end
---进入一个关卡阶段时需要做的事情在这里实现。一般用作设置阶段所需的环境
function XLevelBossFight0014:OnEnterPhase(phase)
if phase == 1 then
--通知boss就位
XLog.Debug("[SceneHunt01]进入阶段1,通知boss就位")
self:LetBossReady()
elseif phase == 2 then
--开始跳跳乐
XLog.Debug("[SceneHunt01]跳跳乐开始")
self:StartJumpFun()
elseif phase == 3 then
XLog.Debug("[SceneHunt01]飞龙在天!")
self:BossFly()
elseif phase == 4 then
XLog.Debug("[SceneHunt01]亢龙有悔!")
self:BossNotFly()
elseif phase == 10 then
-- 如果玩家在phase2、3等进入,锁定还没有恢复,需要处理
-- 塔可能没降,或者序列会继续执行,需要处理
XLog.Debug("[SceneHunt01]准备造假!")
self:FixLevelState()
elseif phase == 11 then
XLog.Debug("[SceneHunt01]异度入侵!")
for _, npc in pairs(self._playerNpcList) do
FuncSet.ApplyMagic(npc, npc, 5990140, 1)
XLog.Debug("[SceneHunt01]层层加码!" .. tostring(npc))
end
--self._timer:Schedule(4, self, self.PlayHackSoundFx, self._playerNpcContainer._localPlayerNpcId)
self:PlayHackSoundFx(self._playerNpcContainer._localPlayerNpcId)
--self._timer:Schedule(5,true,FuncSet.SetFakeSettleActive)
elseif phase == 12 then
XLog.Debug("[SceneHunt01]天外来客!")
self:WightDragonIntro()
end
end
---退出一个关卡阶段时需要做的事情在这里实现。一般用作收拾本阶段的环境
function XLevelBossFight0014:OnExitPhase(phase)
if phase == 0 then
elseif phase == 1 then
elseif phase == 2 then
self:OnJumpFunEnd()
elseif phase == 3 then
self:OnBossFlyEnd()
elseif phase == 4 then
self:OnBossFlyEnd()
end
end
---关卡阶段改变时需要执行的逻辑,一般用于通知外部
function XLevelBossFight0014:OnPhaseChanged(lastPhase, nextPhase)
end
---处理阶段相关的事件响应、状态检测、信息获取
function XLevelBossFight0014:HandlePhaseEvent(eventType, eventArgs)
if self._currentPhase == 0 then
if eventType == EScriptEvent.Behavior2ScriptMsg then
if eventArgs.MsgType == 800100 then
self:SetPhase(1)
end
end
elseif self._currentPhase == 1 then
if eventArgs.SceneObjectId == self._bossReadyTrigger and eventArgs.TriggerState == 1
and eventArgs.SourceActorId == self._blackDragonNpcId then
--self:SetPhase(2)
self._bossIsReady = true
XLog.Debug("[SceneHunt01]boss已就位")
end
elseif self._currentPhase == 2 then
if eventType == EScriptEvent.NpcCastSkill then
if eventArgs.SkillId == 100241 or eventArgs.SkillId == 101439 or eventArgs.SkillId == 100736 then
-- 玩家放出对勾点猎锚第一段 读取玩家猎矛勾选的对象
self._playerFocusAnchorDic[eventArgs.LauncherId] = FuncSet.GetNpcNoteInt(eventArgs.LauncherId, 25003)
--XLog.Debug("关卡缓存玩家" .. tostring(eventArgs.LauncherId) .. "勾取对象: " .. tostring(self._playerFocusAnchorDic[eventArgs.LauncherId]))
elseif eventArgs.SkillId == 100242 or eventArgs.SkillId == 101440 or eventArgs.SkillId == 100737 then
-- 玩家放出对勾点猎锚第二段 升起勾选目标下一步的塔
if self._playerFocusAnchorDic[eventArgs.LauncherId] ~= nil and self._towers[self._playerFocusAnchorDic[eventArgs.LauncherId]].next ~= nil then
for _, nextTower in pairs(self._towers[self._playerFocusAnchorDic[eventArgs.LauncherId]].next) do
self:TowerControl(nextTower, true, 0.1)
end
end
elseif (eventArgs.SkillId == 100227 or eventArgs.SkillId == 101435 or eventArgs.SkillId == 100720) and eventArgs.TargetId == self._blackDragonNpcId then
-- 玩家放出对boss猎锚第一段
self:PlayerSetAnchorToBoss(eventArgs.LauncherId)
end
end
if eventType == EScriptEvent.FightQTEStatusMsg then
XLog.Debug("[SceneHunt01]检测到结束事件")
if eventArgs.Status == 0 then
XLog.Debug("[SceneHunt01]空")
elseif eventArgs.Status == 1 then
XLog.Debug("[SceneHunt01]进行中")
elseif eventArgs.Status == 2 then
XLog.Debug("[SceneHunt01]时间结束")
self:SetPhase(3)
elseif eventArgs.Status == 3 then
XLog.Debug("[SceneHunt01]打够伤害")
self:SetPhase(4)
end
end
end
end
---临时用开关控制跳跳乐环节的方法
function XLevelBossFight0014:TestSwitchStartJumpFun()
if FuncSet.CheckNpc(self._blackDragonNpcId) then
local bossState = FuncSet.GetNpcNoteInt(self._blackDragonNpcId, 5001) --boss状态层
local bossAngry = FuncSet.GetNpcNoteInt(self._blackDragonNpcId, 50) --boss愤怒状态
if (bossState == 0 or bossState == 1) and bossAngry ~= 10 then
self:SetPhase(1)
XLog.Debug("[SceneHunt01]临时开始跳跳乐方法执行")
end
end
end
---检查跳跳乐是否开始,每帧执行
function XLevelBossFight0014:JumpFunStartCheck()
---关卡时间>=X
---boss血量<=Y%
---boss没有狂暴
if FuncSet.CheckNpc(self._blackDragonNpcId) then
local bossHpRate = FuncSet.GetNpcAttribRate(self._blackDragonNpcId, 0) --boss血量百分比
local bossState = FuncSet.GetNpcNoteInt(self._blackDragonNpcId, 5001) --boss状态层
local bossAngry = FuncSet.GetNpcNoteInt(self._blackDragonNpcId, 50) --boss愤怒状态
if bossHpRate <= 0.4 and (bossState == 0 or bossState == 1) and bossAngry ~= 10 then
return true
end
end
end
---告诉boss去就位了,就位以后才是正式的跳跳乐。并关闭玩家锁定功能
function XLevelBossFight0014:LetBossReady()
if FuncSet.CheckNpc(self._blackDragonNpcId) then
FuncSet.SetNpcNoteFloat3(self._blackDragonNpcId, 9001, 60, 0, 60)
FuncSet.ApplyMagic(self._blackDragonNpcId, self._blackDragonNpcId, self._bossEndureMagicId, 1)
end
-- 通知玩家跳跳乐开始
for _, npc in pairs(self._playerNpcList) do
FuncSet.ApplyMagic(npc, npc, self._jumpFunStartSignMagicId, 1)
end
--boss无视跳跳乐用的弹出collider
FuncSet.SetSceneColliderIgnoreCollision(self._blackDragonNpcId, "DynamicBlock", -1, true)
--场地中央开始把玩家弹开
FuncSet.PlaySceneAnimation(5)
end
---对坐标点放技能
function XLevelBossFight0014:BossCastReadySwoop()
if FuncSet.CheckNpcAction(self._blackDragonNpcId, ENpcAction.Move) and FuncSet.CheckCanCastSkill(self._blackDragonNpcId) then
FuncSet.CastSkillToPosition(self._blackDragonNpcId, 8001097, 60, 0, 60)
if self._bossCanCastSkillTime == 0 then
self._bossCanCastSkillTime = self._phaseTimeCount
XLog.Debug("[SceneHunt01]boss释放技能指令开始发出")
end
end
if self._phaseTimeCount - self._bossCanCastSkillTime > 3 then
self._bossHasCastSkill = true
XLog.Debug("[SceneHunt01]boss释放技能指令停止")
end
end
---开始跳跳乐
function XLevelBossFight0014:StartJumpFun()
--中央塔升起
self._timer:Schedule(3, self, self.CenterTowerControl, true)--中央塔升起
--周围的塔升起
self:TowerControl(2, true, 6)
self:TowerControl(3, true, 6)
self:TowerControl(4, true, 6)
--怪物大吼
FuncSet.CastSkill(self._blackDragonNpcId, 8001001)
self:BossRoarMissile()
-- 怪物开始蓄力,可以被qte
self:BigSkill(1)
--bgm切轨
self._bgmTrack = 0
--关闭弹出玩家的碰撞体
self._timer:Schedule(8, 6, FuncSet.PlaySceneAnimation)
--开始QTE
FuncSet.UpdateRoleCountQTETime(15, 10, 5)
self._timer:Schedule(3, 30, FuncSet.AddQTETime)
--开启平台可钩
self:EnablePlatforms(true)
end
function XLevelBossFight0014:BossRoarMissile()
if FuncSet.CheckNpc(self._blackDragonNpcId) then
for _, npc in pairs(self._playerNpcList) do
if FuncSet.CheckNpc(npc) then
FuncSet.LaunchMissile(self._blackDragonNpcId, npc, 800100101)
--XLog.Debug("发子弹发子弹发子弹发子弹发子弹发子弹")
end
end
end
end
---boss在跳跳乐期间的动作管理
function XLevelBossFight0014:BigSkill(param)
if FuncSet.CheckNpc(self._blackDragonNpcId) then
XLog.Debug("[SceneHunt01]令boss 90000 = " .. param)
FuncSet.SetNpcNoteInt(self._blackDragonNpcId, 90000, param)
--XLog.Debug("[SceneHunt01]验证boss 90000 = " .. FuncSet.GetNpcNoteInt(self._blackDragonNpcId,90000))
end
end
---跳跳乐过程中响应
function XLevelBossFight0014:JumpFunProgress()
-- 预计是玩家勾中boss之后延长本阶段剩余时间
end
---跳跳乐期间有玩家勾中boss处理
function XLevelBossFight0014:PlayerSetAnchorToBoss(playerId)
XLog.Debug("[SceneHunt01]有玩家勾中boss了,跳跳乐进度推进")
local completeCount = 0
self._playerCompleteJumpFun[playerId] = true --掉线情况已处理
for _, v in pairs(self._playerCompleteJumpFun) do
if v then
completeCount = completeCount + 1
end
end
self._jumpFunCompletePlayerCount = completeCount
--从体验上来讲,这里的这个逻辑缺乏可视化内容,是反直觉的,还是不要添加一个三名玩家钉上去立马整大活儿的玩法。
--[[ if completeCount >= 3 then
self._timer:Schedule(3,4,FuncSet.SetPhase)
end]]
end
---跳跳乐结束判断
function XLevelBossFight0014:JumpFunEndCheck()
--[[ if self._phaseTimeCount >= self._jumpFunDefeatTimeLimit then
--超时结束
return true
end]]
end
function XLevelBossFight0014:OnJumpFunEnd()
self:BigSkill(0)
--中央塔落下
self:CenterTowerControl(false)
-- bgm切轨
self._bgmTrack = 1
FuncSet.UpdateRoleCountQTETime(-1, -1, -1)
end
---boss飞上天开大
function XLevelBossFight0014:BossFly()
--怪物放大绝
self._timer:Schedule(5.0, self, self.BigSkill, 10)
--塔升降序列
for _, sequence in pairs(Config.Sequence) do
self:SpecialTowerControl(sequence.tower, sequence.raise, sequence.delayTime)
end
--关闭外围空气墙对boss的限制
self:EnableAirWallToNpc(false, self._blackDragonNpcId)
end
---boss落地挨打
function XLevelBossFight0014:BossNotFly()
--怪物蓄力失败受击
self._timer:Schedule(3.5, self, self.BigSkill, 20)
--所有塔一起降下
for tower, data in pairs(self._towers) do
if data.type ~= 14 then
self:TowerControl(tower, false, 5)
end
end
self:EnablePlatforms(false)
--天基
self._timer:Schedule(5, self, self.SpearFatality)
self._timer:Schedule(13.5, self, self.SpearFatalityDamage)
end
function XLevelBossFight0014:SpearFatalityDamage()
if FuncSet.CheckNpc(self._blackDragonNpcId) then
FuncSet.ApplyMagic(self._blackDragonNpcId, self._blackDragonNpcId, 5990132, 1) --10%血量上限的真实伤害
XLog.Debug("[SceneHunt01]天基流程,造成10%伤害")
end
end
---天基演出流程
function XLevelBossFight0014: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)
self:EnablePlatforms(true)
self._timer:Schedule(13, self, self.EnablePlatforms, false)
end
function XLevelBossFight0014:RemoveBlackScreen(npc)
FuncSet.ApplyMagic(npc, npc, 5000006, 1)
end
function XLevelBossFight0014:PlaySpearFatality()
if FuncSet.CheckNpc(self._blackDragonNpcId) then
FuncSet.PlayCameraTimeline("SprearFatality01", self._blackDragonNpcId, 0, 0, 0)
self._timer:Schedule(10.5, "SprearFatality01", FuncSet.StopCameraTimeline, self._blackDragonNpcId)
FuncSet.ApplyMagic(self._blackDragonNpcId, self._blackDragonNpcId, self._spearFatalitySoundFx, 1)
elseif 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 XLevelBossFight0014:OnBossFlyEnd()
--玩家回复锁定能力
for _, npc in pairs(self._playerNpcList) do
FuncSet.ApplyMagic(npc, npc, self._jumpFunEndSignMagicId, 1) --to remove jump fun start sign
XLog.Debug("[SceneHunt01]npc" .. npc .. "恢复锁定能力")
end
--释放boss
if FuncSet.CheckNpc(self._blackDragonNpcId) then
FuncSet.SetNpcNoteFloat3(self._blackDragonNpcId, 9001, 0, 0, 0)
FuncSet.ApplyMagic(self._blackDragonNpcId, self._blackDragonNpcId, self._removeBossEndureMagicId, 1)
end
--恢复外围空气墙对boss的限制
self:EnableAirWallToNpc(true, self._blackDragonNpcId)
--关闭平台可勾
self:EnablePlatforms(false)
end
function XLevelBossFight0014:EnableAirWallToNpc(enable, npc)
FuncSet.SetSceneColliderIgnoreCollision(npc, "AirWalls", -1, enable)
FuncSet.SetSceneColliderIgnoreCollision(npc, "OuterAirWall", -1, enable)
FuncSet.SetSceneColliderIgnoreCollision(npc, "MonsterAirWall", -1, enable)
end
--- 使bgm track 插值到目标值
function XLevelBossFight0014:BgmTrackControl(dt)
if not (self._bgmCurrentTrack == self._bgmTrack) then
if self._bgmTrack > self._bgmCurrentTrack then
if self._bgmCurrentTrack + dt * 0.2 <= self._bgmTrack then
self._bgmCurrentTrack = self._bgmCurrentTrack + dt * 0.2
else
self._bgmCurrentTrack = self._bgmTrack
end
else
if self._bgmCurrentTrack - dt * 0.2 >= self._bgmTrack then
self._bgmCurrentTrack = self._bgmCurrentTrack - dt * 0.2
else
self._bgmCurrentTrack = self._bgmTrack
end
end
FuncSet.SetBgmAisacControl("AisacControl03", self._bgmCurrentTrack)
end
end
function XLevelBossFight0014:CenterTowerControl(raise)
if self._centerTowerMoving then
--运动过程中收到指令会令运动结束以后立刻执行相反运动,或者取消这个命令
if raise == self._centerTowerRaise then
--指令目标和当前运动目标相同,则取消命令
XLog.Debug("CenterTower运行中收到指令,和当前目标一致")
self._centerTowerWaitToDo = false
else
--指令目标和当前运动目标相反,则记录一个命令
XLog.Debug("CenterTower运行中收到指令,和当前目标相反")
self._centerTowerWaitToDo = true
end
return
elseif raise == self._centerTowerRaise then
--目标状态和当前状态一致
XLog.Debug("CenterTower收到指令,和当前状态一致")
return
end
if raise then
FuncSet.PlaySceneAnimation(1)
self._timer:Schedule(2.6, self, self.OnCenterTowerMoveEnd)
self._timer:Schedule(2.3, self._centerTowerEffectPlayer, FuncSet.DoSceneObjectAction, 2001) --中央塔升起结束特效
else
FuncSet.PlaySceneAnimation(2)
self._timer:Schedule(3, self, self.OnCenterTowerMoveEnd)
self._timer:Schedule(2.7, self._centerTowerEffectPlayer, FuncSet.DoSceneObjectAction, 2001) --中央塔降下结束特效
end
FuncSet.DoSceneObjectAction(self._centerTowerEffectPlayer, 2002) --开始移动的特效
self._centerTowerRaise = raise
self._centerTowerMoving = true
end
---中央塔升起结束回调
function XLevelBossFight0014:OnCenterTowerMoveEnd()
XLog.Debug("CenterTower运动结束回调")
self._centerTowerMoving = false
if self._centerTowerWaitToDo then
self._centerTowerWaitToDo = false
self:CenterTowerControl(not self._centerTowerRaise)
end
end
---注册的行动会被直接顶掉,执行的行动按tower里自己的逻辑判断
function XLevelBossFight0014:TowerControl(tower, raise, delay)
if self._towersSequences[tower] ~= nil then
self._timer:Cancel(self._towersSequences[tower])
self._towersSequences[tower] = nil
end
if delay ~= nil then
local id = self._timer:Schedule(delay, self._towers[tower].agent, self._towers[tower].agent.TowerMove, raise)
self._towersSequences[tower] = id
--self._specialTowerSequences[id] = true
else
self._towers[tower].agent:TowerMove(raise)
end
end
---注册的行动不会被顶掉,如果要确认场地关闭需要对注册内容进行清空
function XLevelBossFight0014:SpecialTowerControl(tower, raise, delay)
if delay ~= nil then
local id = self._timer:Schedule(delay, self._towers[tower].agent, self._towers[tower].agent.TowerMove, raise)
--self._towersSequences[tower] = id
table.insert(self._specialTowerSequences, id)
else
self._towers[tower].agent:TowerMove(raise)
end
end
---清空注册的塔行动
function XLevelBossFight0014:CancelSpecialTowerSequences()
for _, id in pairs(self._specialTowerSequences) do
self._timer:Cancel(id)
end
end
function XLevelBossFight0014:FixLevelState()
--玩家回复锁定能力
for _, npc in pairs(self._playerNpcList) do
FuncSet.ApplyMagic(npc, npc, self._jumpFunEndSignMagicId, 1) --to remove jump fun start sign
XLog.Debug("[SceneHunt01]npc" .. npc .. "恢复锁定能力")
end
self:CancelSpecialTowerSequences()
--所有塔一起降下
for tower, data in pairs(self._towers) do
if data.type ~= 14 then
self:TowerControl(tower, false)
end
end
end
function XLevelBossFight0014:FixLevelStateUpdate()
if not self._confirmCenterTowerDown then
if not self._centerTowerMoving then
if self._centerTowerRaise then
self:CenterTowerControl(false)
end
end
end
end
function XLevelBossFight0014:CheckLevelStateFixed()
if not self._centerTowerRaise and not self._centerTowerMoving then
self._confirmCenterTowerDown = true
--XLog.Debug("[SceneHunt01]检测到中央塔已降下")
else
self._confirmCenterTowerDown = false
end
for _, tower in pairs(self._towers) do
if tower.agent.raised or tower.agent._raising then
self._confirmTowersDown = false
return
end
end
self._confirmTowersDown = true
--XLog.Debug("[SceneHunt01]检测到所有塔已降下")
end
function XLevelBossFight0014:PlayHackSoundFx(npc)
XLog.Debug("[SceneHunt01]播放Hack音效")
FuncSet.ApplyMagic(npc, npc, self._wightDragonHackSoundFx, 1)
end
function XLevelBossFight0014:WightDragonIntro()
-- 白龙入场镜头+特效timeline
FuncSet.SwitchSceneTimeline(1, true)
self._timer:Schedule(11.1, 1, FuncSet.SwitchSceneTimeline, false)
-- 召唤白龙,并在特效落地的时候放到位置上
self:InitWightDragon()
self._timer:Schedule(8.17, self._wightDragonNpcId, FuncSet.SetNpcPosition, self._bossBornPos)
FuncSet.ApplyMagic(self._wightDragonNpcId, self._wightDragonNpcId, 8002015, 1) -- 卡住白龙ai
self._timer:Schedule(11.1, self, self.ReleaseWightDragon)
-- 塔击毁的timeline
FuncSet.PlaySceneAnimation(4)
-- 气氛变化timeline
self._timer:Schedule(0.5, 2, FuncSet.SwitchSceneTimeline, true)
-- UI开关
self:SetFightUiActive(false)
self._timer:Schedule(11.1, self, self.SetFightUiActive, true)
-- 音效
XLog.Debug("[SceneHunt01]播放白龙入场音效")
FuncSet.ApplyMagic(
self._playerNpcContainer._localPlayerNpcId,
self._playerNpcContainer._localPlayerNpcId,
self._wightDragonBornSoundFx,
1
)
end
function XLevelBossFight0014:ReleaseWightDragon()
-- 释放白龙ai
FuncSet.ApplyMagic(
self._wightDragonNpcId,
self._wightDragonNpcId,
8002016,
1)
end
function XLevelBossFight0014: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 XLevelBossFight0014:EnablePlatforms(enable)
for _, plat in pairs(self._towers) do
if plat.type == 14 then
plat.agent:HookableEnable(enable)
end
end
end
function XLevelBossFight0014:Terminate()
end
return XLevelBossFight0014