local base = require("Battle/Logic/AI/Decision/Decision_Base") local Decision_WanderFleeFriend = class("Decision_WanderFleeFriend", base) local Angle_Back = FP.newV1(135) local Angle_Front = FP.newV1(45) --[[ 初始化 --]] function Decision_WanderFleeFriend:initialize(entity) --类型 self.Type = LuaConst.DecisionType.WanderFleeFriend --瞬时 self.IsOnce = false end -- 效率低,不建议使用 --能否进入 --进入条件:存在最近友方 function Decision_WanderFleeFriend:CanEnter(entity, decisionData, command) self:SetNearestFriendEntity(entity, FP.newV1(decisionData.IntParam1 * decisionData.IntParam1)) local nearestFriendEntity = entity.components.target.NearestFriendEntity return nearestFriendEntity ~= nil end --能否退出 --退出条件:不存在最近友方,或 最近离最近友方距离过大 function Decision_WanderFleeFriend:CanExit(entity, decisionData, command) local targetComponent = entity.components.target local nearestFriendEntity = targetComponent.NearestFriendEntity if nearestFriendEntity then if not FP.V2.IsDistanceSqrGreater(entity.components.move.LogicPos, nearestFriendEntity.components.move.LogicPos, decisionData.IntParam1 * decisionData.IntParam1) then targetComponent:SetNearestFriendEntity(nil) return false end end return true end --输出指令 function Decision_WanderFleeFriend:SetCommand(entity, decisionData, command) --始终朝向目标 local target = entity.components.target.Target if target then command.DecisionID = decisionData.ID local dir = target.components.move.LogicPos - entity.components.move.LogicPos command.RotateDir:Reset(dir) FP.releaseV2(dir) end return command end --执行 function Decision_WanderFleeFriend:Handle(entity, decisionData, stateType, animName) local animComponent = entity.components.anim local targetComponent = entity.components.target if not LuaConst.WanderAnimNameTable[animComponent.CurAnimID] or animComponent.IsCurAnimOver then local nearestFriendEntity = targetComponent.NearestFriendEntity if nearestFriendEntity then animName = self:GetWanderAnimNameByAngle(entity, nearestFriendEntity, targetComponent.Target) return LuaConst.StateType.Common, animName end end return LuaConst.StateType.None, nil end ---这个是方法SetNearestFriendEntity的缓存变量 其它方法不要复用 local _tempNearestV1 = FP.newV1(0) local _minTempNearestV1 = FP.newV1(0) function Decision_WanderFleeFriend:SetNearestFriendEntity(entity, disSqrLimit) local leaderEntity = entity.components.group.LeaderEntity local nearestFriendEntity = nil if leaderEntity then _minTempNearestV1:Reset(FP.Const.Max) for key,tempEntity in pairs(leaderEntity.components.group.GroupEntityList) do if entity._logicInitData.EntityID ~= tempEntity._logicInitData.EntityID then FP.V2.DistanceSqr(entity.components.move.LogicPos, tempEntity.components.move.LogicPos, _tempNearestV1) if _tempNearestV1 <= disSqrLimit then if _minTempNearestV1 > _tempNearestV1 then _minTempNearestV1:Reset(_tempNearestV1) nearestFriendEntity = tempEntity end end end end end entity.components.target:SetNearestFriendEntity(nearestFriendEntity) end function Decision_WanderFleeFriend:GetWanderAnimNameByAngle(entity, nearestFriend, target) local animName = nil local selfToTarget = FP.V2.Normalized(target.components.move.LogicPos - entity.components.move.LogicPos) local selfToFriend = FP.V2.Normalized(nearestFriend.components.move.LogicPos - entity.components.move.LogicPos) local angle = FP.V2.Angle(selfToTarget, selfToFriend) if angle > Angle_Back then animName = "walk_back_loop" elseif angle < Angle_Front then animName = "walk_front_loop" elseif FP.V2.IsRotateClockwise(selfToTarget, selfToFriend) then animName = "walk_right_loop" else animName = "walk_left_loop" end return animName end return Decision_WanderFleeFriend