local XAiBengyue = XDlcScriptManager.RegCharScript(8001, "XAiBengyue") local FuncSet = CS.StatusSyncFight.XFightScriptFuncs ---@param proxy StatusSyncFight.XScriptLuaProxy function XAiBengyue:Ctor(proxy) print("XLuaFightScript.Ctor Bengyue") self._proxy = proxy self._npcList = {} self._targetId = 0 --2002 self._targetPosition = nil --200201 self._isWaiting = false --buff 80010010 self._waitingTimer = 0 self._waitingTime = 3.0 self._skillPlanId = 0 --5001 self._skillList = {8001032, 8001033, 8001034, 8001043, 8001044, 8001049, 8001050} self._skillCDList = {} for i = 1, #self._skillList do self._skillCDList[i] = 0 end self._skillCDTimer = 0 self._skillCDTime = 3.0 self._turnActionId = 0 --7001 self._farDistance = 999 self._midDistance = 18 self._nearDistance = 8 self._farDistTurnStopAngle = 67.5 self._midDistTurnStopAngle = 42.5 self._nearDistTurnStopAngle = 27.5 self._turnSkillList = { [3] = 8001003, [4] = 8001004, [5] = 8001005, [6] = 8001006, [7] = 8001007, [8] = 8001008, [9] = 8001009, } self._farDistTurnAngles = { [1] = 67.5, [2] = 112.5, [3] = 112.5, [4] = 157.5, [5] = -67.5, [6] = -112.5, [7] = -112.5, [8] = -157.5, [9] = 157.5, [10] = 202.5, } self._midDistTurnAngles = { [1] = 42.5, [2] = 84.375, [3] = 84.375, [4] = 116.25, [5] = 116.25, [6] = 148.125, [7] = -42.5, [8] = -84.375, [9] = -84.375, [10] = -116.25, [11] = -116.25, [12] = -148.125, [13] = 148.125, [14] = 211.875, } self._nearDistTurnAngles = { [1] = 27.5, [2] = 58.125, [3] = 58.125, [4] = 103.75, [5] = 103.75, [6] = 144.375, [7] = -27.5, [8] = -58.125, [9] = -58.125, [10] = -103.75, [11] = -103.75, [12] = -144.375, [13] = 144.375, [14] = 215.625, } self._turnPlanDataTable = { [3] = { {self._farDistTurnAngles[1], self._farDistTurnAngles[2], 311}, {self._farDistTurnAngles[3], self._farDistTurnAngles[4], 312}, {self._farDistTurnAngles[6], self._farDistTurnAngles[5], 321}, {self._farDistTurnAngles[8], self._farDistTurnAngles[7], 322}, {self._farDistTurnAngles[9], self._farDistTurnAngles[10], 330}, }, [2] = { {self._midDistTurnAngles[1], self._midDistTurnAngles[2], 310}, {self._midDistTurnAngles[3], self._midDistTurnAngles[4], 311}, {self._midDistTurnAngles[5], self._midDistTurnAngles[6], 312}, {self._midDistTurnAngles[8], self._midDistTurnAngles[7], 320}, {self._midDistTurnAngles[10], self._midDistTurnAngles[9], 321}, {self._midDistTurnAngles[12], self._midDistTurnAngles[11], 322}, {self._midDistTurnAngles[13], self._midDistTurnAngles[14], 330}, }, [1] = { {self._nearDistTurnAngles[1], self._nearDistTurnAngles[2], 310}, {self._nearDistTurnAngles[3], self._nearDistTurnAngles[4], 311}, {self._nearDistTurnAngles[5], self._nearDistTurnAngles[6], 312}, {self._nearDistTurnAngles[8], self._nearDistTurnAngles[7], 320}, {self._nearDistTurnAngles[10], self._nearDistTurnAngles[9], 321}, {self._nearDistTurnAngles[12], self._nearDistTurnAngles[11], 322}, {self._nearDistTurnAngles[13], self._nearDistTurnAngles[14], 330}, }, } self._turnActionMap = { [310] = self._turnSkillList[3], [320] = self._turnSkillList[4], [311] = self._turnSkillList[5], [321] = self._turnSkillList[6], [312] = self._turnSkillList[7], [322] = self._turnSkillList[8], [330] = self._turnSkillList[9], } self._enable = false self._enable = true end function XAiBengyue:Init() self._npcId = self._proxy:GetSelfNpcId() --self._npcCamp = self._proxy.Npc.Camp --local enemyNpcId = self._proxy:GetBehaviorNoteBool(1, 2002) print("XLuaFightScript.Init Bengyue") end ---@param dt number @ delta time function XAiBengyue:Update(dt) --print("XLuaFightScript.Update Bengyue") local selfId = self._proxy:GetBehaviorNoteInt(1, 2001) local testId = self._proxy:GetBehaviorNoteInt(1, 95786) if selfId > 0 then --print("1#2001 " .. tostring(selfId)) self._proxy:SetBehaviorNoteInt(1, 95786, 123456) end if testId > 0 then --print("1#95786 " .. tostring(testId)) end if not self._enable then return end if self._targetId == 0 then self._npcList = FuncSet.GetNpcList() for i = 1, #self._npcList do local npcId = self._npcList[i] if not FuncSet.CompareNpcCamp(npcId, self._npcId) and npcId ~= self._targetId then self._targetId = npcId --print(string.format("new target:%d", npcId)) end end end if not FuncSet.CheckNpc(self._targetId) then self._targetId = 0 --print("target does not exist") return end if self._isWaiting then self._waitingTimer = self._waitingTimer + dt if self._waitingTimer >= self._waitingTime then self._waitingTimer = 0 self._isWaiting = false else return end end self._targetPosition = FuncSet.GetNpcPosition(self._targetId) -- skill plan local noCastingSkill = not FuncSet.CheckNpcAction(self._npcId, ENpcAction.Skill) local canCastSkill = FuncSet.CheckCanCastSkill(self._npcId) if noCastingSkill and canCastSkill and self._skillPlanId == 0 then end --self._skillCDTimer = self._skillCDTimer + dt --if self._skillCDTimer >= self._skillCDTime and FightFuncs.CheckCanCastSkill(self._npcId) then -- local index = math.random(1, #self._skillList) -- local skillId = self._skillList[index] -- FightFuncs.CastSkill(self._npcId, skillId) -- --print("Bengyue Cast skill " .. tostring(skillId)) --end self:Steering() end ---Steering 游荡行为 function XAiBengyue:Steering() --Turn logic 转向逻辑 if not self._isWaiting and not FuncSet.CheckNpcAction(self._npcId, ENpcAction.Skill) then local turnPlan = -1 local targetDist = FuncSet.CalcNpcDistance(self._npcId, self._targetId) if self._turnActionId < 3 and targetDist >= self._midDistance and targetDist < self._farDistance and not self:IsTargetInMyAngle(self._farDistTurnStopAngle) then turnPlan = 3 elseif self._turnActionId < 2 and targetDist >= self._nearDistance and targetDist < self._midDistance and not self:IsTargetInMyAngle(self._midDistTurnStopAngle) then turnPlan = 2 elseif self._turnActionId < 1 and targetDist < self._nearDistance and not self:IsTargetInMyAngle(self._nearDistTurnStopAngle) then turnPlan = 1 elseif self._turnActionId > 0 and self:IsTargetInMyAngle(self._nearDistTurnStopAngle) then turnPlan = 0 end --print("Turn plan: " .. tostring(turnPlan)) for planId, data in pairs(self._turnPlanDataTable) do --print("Check Turn plan: " .. tostring(planId)) if turnPlan == planId then for j = 1, #data do local pair = data[j] if FuncSet.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, pair[1], pair[2]) then self._turnActionId = pair[3] --print("Turn action: " .. tostring(self._turnActionId)) break end end break end end --if turnPlan == 3 then -- if FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._farDistTurnAngles[1], self._farDistTurnAngles[2]) then -- self._turnActionId = 311 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._farDistTurnAngles[3], self._farDistTurnAngles[4]) then -- self._turnActionId = 312 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._farDistTurnAngles[6], self._farDistTurnAngles[5]) then -- self._turnActionId = 321 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._farDistTurnAngles[8], self._farDistTurnAngles[7]) then -- self._turnActionId = 322 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._farDistTurnAngles[9], self._farDistTurnAngles[10]) then -- self._turnActionId = 330 -- end --elseif turnPlan == 2 then -- if FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[1], self._midDistTurnAngles[2]) then -- self._turnActionId = 310 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[3], self._midDistTurnAngles[4]) then -- self._turnActionId = 311 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[5], self._midDistTurnAngles[6]) then -- self._turnActionId = 312 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[8], self._midDistTurnAngles[7]) then -- self._turnActionId = 320 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[10], self._midDistTurnAngles[9]) then -- self._turnActionId = 321 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[12], self._midDistTurnAngles[11]) then -- self._turnActionId = 322 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._midDistTurnAngles[13], self._midDistTurnAngles[14]) then -- self._turnActionId = 330 -- end --elseif turnPlan == 1 then -- if FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[1], self._nearDistTurnAngles[2]) then -- self._turnActionId = 310 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[3], self._nearDistTurnAngles[4]) then -- self._turnActionId = 311 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[5], self._nearDistTurnAngles[6]) then -- self._turnActionId = 312 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[8], self._nearDistTurnAngles[7]) then -- self._turnActionId = 320 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[10], self._nearDistTurnAngles[9]) then -- self._turnActionId = 321 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[12], self._nearDistTurnAngles[11]) then -- self._turnActionId = 322 -- elseif FightFuncs.CheckNpcInAngleRangeHorizontal(self._npcId, self._targetId, self._nearDistTurnAngles[13], self._nearDistTurnAngles[14]) then -- self._turnActionId = 330 -- end --end --execute turn action for actionId, skillId in pairs(self._turnActionMap) do if self._turnActionId == actionId then FuncSet.CastSkill(self._npcId, skillId) break end end --if self._turnActionId == 310 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[3]) --elseif self._turnActionId == 320 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[4]) --elseif self._turnActionId == 311 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[5]) --elseif self._turnActionId == 321 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[6]) --elseif self._turnActionId == 312 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[7]) --elseif self._turnActionId == 322 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[8]) --elseif self._turnActionId == 330 then -- FightFuncs.CastSkill(self._npcId, self._turnSkillList[9]) --end self._turnActionId = 0 end --Approach logic 接近逻辑 if not FuncSet.CheckNpcAction(self._targetId, ENpcAction.BeHit) and not FuncSet.CheckNpcAction(self._npcId, ENpcAction.Skill) then local movePlan = 0 local targetDist = FuncSet.CalcNpcDistance(self._npcId, self._targetId) if movePlan < 2 and targetDist >= self._farDistance and self:IsTargetInMyAngle(self._farDistTurnStopAngle) then movePlan = 2 elseif movePlan < 1 and targetDist >= self._midDistance and targetDist < self._farDistance and self:IsTargetInMyAngle(self._farDistTurnStopAngle) then movePlan = 1 elseif movePlan < 1 and targetDist >= self._midDistance and targetDist < self._midDistance then movePlan = 0 end if movePlan == 2 then FuncSet.NpcStartMove(self._npcId, self._targetPosition) FuncSet.SetNpcMoveDirection(self._npcId, 0) FuncSet.SetNpcMoveType(self._npcId, 1) elseif movePlan == 1 then FuncSet.NpcStartMove(self._npcId, self._targetPosition) FuncSet.SetNpcMoveDirection(self._npcId, 0) FuncSet.SetNpcMoveType(self._npcId, 0) elseif movePlan == 0 then FuncSet.NpcStopMove(self._npcId) end end self:StartWaiting() end ---@param eventType number ---@param eventArgs userdata function XAiBengyue:HandleEvent(eventType, eventArgs) if eventType == EScriptEvent.Damaged then local args = eventArgs ---@type StatusSyncFight.DamageScriptEventArgs print("XLuaFightScript.HandleEvent Bengyue damaged " .. ",damages:" .. args.PhysicsDamage .. " attacker camp:" .. FuncSet.GetNpcCamp(args.AttackerId)) end end function XAiBengyue:Terminate() print("XLuaFightScript.Terminate Bengyue") end function XAiBengyue:StartWaiting() self._waitingTimer = 0 self._isWaiting = true end function XAiBengyue:IsTargetInMyAngle(angle) return FuncSet.CheckNpcInAngle(self._npcId, self._targetId, angle) end return XAiBengyue --Sequence (And Tree => && --action => action --CheckAction => if CheckAction(...) then nextAction end --Selector (Or Tree => || --[[ if CheckXXX(...) and CheckXXX(...) and CheckXXX(...) and CheckXXX(...) then ActionXXX(...) ActionXXX(...) elseif CheckXXX(...) and CheckXXX(...) and CheckXXX(...) and CheckXXX(...) and BoolAction(...) then ActionXXX(...) ActionXXX(...) end ]] --Parallel --write as normal statements --RandomSelector --local m = math.random(1, n) --same as Selector