local TargetComponent = class("TargetComponent") local EventSystem = require('Event/EventSystem') local FP = FP local ipairs = ipairs local table_remove = table.remove function TargetComponent:initialize(entity) self.entity = entity --当前目标 self.Target = nil --最高优先级目标(目前只用于玩家攻击时选取目标) self.SkillHighestPriorityTarget = nil --最近的友方 self.NearestFriendEntity = nil --跟随目标 self.FollowTarget = nil --到跟随目标的距离的平方 self.ToFollowTargetDisSqr = FP.newV1(0) --到目标的距离的平方 self.ToTargetDisSqr = FP.newV1(0) --到目标的朝向 self.ToTargetDir = FP.newV2(0, 1) self.FightMode = LuaConst.EFightMode.TEAM_GUILD self.isDontIgnoreEnemyLevel = LevelManager.CurLevelFunc.dontIgnoreEnemy --忽略敌人列表(在这个列表里,且不在DontIgnoreEnemyDic里的的单位不会被本entity攻击) self.IgnoreEnemyList = {} --不忽略敌人单位列表(在这个列表里的,且在IgnoreEnemyList里的,依然会被本entity攻击) self.DontIgnoreEnemyDic = {} --不忽略的玩家ID列表( self.DontIgnoreEnemyPlayerIDDic = {} --忽略敌人怪物类型(MonsterType在self.IgnoreEnemyMonsterTypes里的Monster不会被本entity攻击) self.IgnoreEnemyMonsterTypes = nil --忽略敌人CharacterTypes (Character在self.IgnoreEnemyCharacterTypes的Monster里的单位不会被本entity攻击) self.IgnoreEnemyCharacterTypes = nil self.IgnoreCanNotBeTargetBuffInDecisionPatrolOrChangeTarget = false --控制:target处于Decision_Patrol和时,调用SystemManager.OnSearchTarget时是否可以选取身上挂有buffID为100047(AI寻敌不能被设置为target)的单位作为目标 end --跟随目标,跟Target不是一个概念 function TargetComponent:SetFollowTarget(target) if self.FollowTarget ~= target then self.FollowTarget = target end end function TargetComponent:RefreshFollowTarget(pos) if self.FollowTarget then self.ToFollowTargetDisSqr = FP.V2.DistanceSqr(pos, self.FollowTarget.components.move.LogicPos) else self.ToFollowTargetDisSqr:Reset() end end function TargetComponent:ResetFollowTarget() self.FollowTarget = nil self:RefreshFollowTarget() end function TargetComponent:SetJoystickTarget(target) if target ~= self.joystickTarget then self.joystickTarget = target end end function TargetComponent:SetTarget(target) if target ~= self.Target then local oldTarget = self.Target self.Target = target EventSystem.Dispatch(EventID.UI_TargetComponent_SetTarget, self) SystemManager.OnSetTarget(self.entity, self.Target, oldTarget) end end function TargetComponent:ResetTarget() if self.Target ~= nil then local oldTarget = self.Target self.Target = nil SystemManager.OnSetTarget(self.entity, self.Target, oldTarget) end self:RefreshTowardsTarget() end --设置强制目标队伍 (对应世界boss模式的强制模式) function TargetComponent:SetForceTeam(teamID) self.oldForceTeamID = self.forceTeamID self.forceTeamID = teamID if self.forceTeamID then self:RefreshForceTargetOfForceTeam() return true else self:SetForceTarget(nil) return false end end function TargetComponent:SetForceTargetToTeam(teamId) local target = nil if teamId then target = TargetManager.GetNearestEnemyOfTeam(self.entity, teamId) end self:SetForceTarget(target) end function TargetComponent:RefreshForceTargetOfForceTeam() self:SetForceTargetToTeam(self.forceTeamID) end function TargetComponent:SwtichForceTeam(teamId) if self.forceTeamID == teamId then return self:SetForceTeam(nil) else return self:SetForceTeam(teamId) end end function TargetComponent:SetForcePlayer(playerID) self.oldForcePlayerID = self.forcePlayerID self.forcePlayerID = playerID if self.forcePlayerID then self:RefreshForceTargetOfForcePlayer() return true else self:SetForceTarget(nil) return false end end function TargetComponent:SetForceTargetToPlayer(playerID) local entities = LevelPlayerManager.GetPlayerEntitysByPlayerIDInRoom(playerID) if entities and entities[1] and entities[1]:IsAlive() then self:SetForceTarget(entities[1]) end end function TargetComponent:RefreshForceTargetOfForcePlayer() self:SetForceTargetToPlayer(self.forcePlayerID) end function TargetComponent:SwtichForcePlayer(playerID) if self.forcePlayerID == playerID then return self:SetForcePlayer(nil) else return self:SetForcePlayer(playerID) end end --设置强制目标(对应世界boss模式的强制模式) function TargetComponent:SetForceTarget(target) --只能设置1个强制目标 if self.ForceTarget ~= target then self.ForceTarget = target end if self.ForceTarget == nil then --如果强制目标被设为了nil,则也重设目标 self:ResetTarget() end end --设置最高优先目标 function TargetComponent:SetSkillHighestPriorityTarget(target) self.SkillHighestPriorityTarget = target end function TargetComponent:SetFightMode(mode, forceFresh) if self.FightMode ~= mode or forceFresh then self.FightMode = mode self:OnFightModeChanged() return true end return false end function TargetComponent:GetFightMode() return self.FightMode end --和平模式跟强制模式(队伍+军团模式)互相切换 function TargetComponent:SwitchFightMode() if self.FightMode == LuaConst.EFightMode.PEACE then self.FightMode = LuaConst.EFightMode.TEAM_GUILD else self.FightMode = LuaConst.EFightMode.PEACE end self:OnFightModeChanged() return self.FightMode end function TargetComponent:OnFightModeChanged() if self.FightMode == LuaConst.EFightMode.TEAM_GUILD then TargetManager.IgnoreAllHeroEnemey(self.entity)--TEAM_GUILD模式在这里忽略所有hero,然后会在RefreshIgnoreEnemyList里排除掉不应该忽略的 self:RefreshIgnoreEnemyList() elseif self.FightMode == LuaConst.EFightMode.PEACE then TargetManager.IgnoreAllHeroEnemey(self.entity) self:SetForcePlayer(nil) self:SetForceTeam(nil) end end function TargetComponent:RefreshTowardsTarget(pos) local target = self.Target if target then local targetPos = target.components.move.LogicPos FP.V2.DistanceSqr(pos, targetPos, self.ToTargetDisSqr) self.ToTargetDir:Reset(targetPos):Sub(pos) self.ToTargetDir:Normalize() else self.ToTargetDisSqr:Reset() self.ToTargetDir:Reset() end end function TargetComponent:SetNearestFriendEntity(nearestFriendEntity) self.NearestFriendEntity = nearestFriendEntity end function TargetComponent:ClearIgnoreEnemy() for i=1,#self.IgnoreEnemyList do self.IgnoreEnemyList[i] = nil end end function TargetComponent:AddIgnoreEnemyEntity(entity) if self.isDontIgnoreEnemyLevel then logging.error(LTAG.ERROR, "HYW : 警告!试图在不启用忽略敌人机制的关卡操作相关数据,请联系战斗程序")--如果要使用忽略敌人机制,需要设置levelfunction的dontIgnoreEnemy为false end table.insert(self.IgnoreEnemyList,entity) end --添加不忽略索敌的单位 function TargetComponent:AddDontIgnoreEnemyEntity(entity) if self.isDontIgnoreEnemyLevel then logging.error(LTAG.ERROR, "HYW : 警告!试图在不启用忽略敌人机制的关卡操作相关数据,请联系战斗程序")--如果要使用忽略敌人机制,需要设置levelfunction的dontIgnoreEnemy为false end self.DontIgnoreEnemyDic[entity.EntityID] = entity end --添加不忽略索敌的playerId function TargetComponent:AddDontIgnoreEnemyPlayerID(playerID) if self.isDontIgnoreEnemyLevel then logging.error(LTAG.ERROR, "HYW : 警告!试图在不启用忽略敌人机制的关卡操作相关数据,请联系战斗程序")--如果要使用忽略敌人机制,需要设置levelfunction的dontIgnoreEnemy为false end self.DontIgnoreEnemyPlayerIDDic[playerID] = true end function TargetComponent:RefreshIgnoreEnemyList() if self.isDontIgnoreEnemyLevel then logging.error(LTAG.ERROR, "HYW : 警告!试图在不启用忽略敌人机制的关卡操作相关数据,请联系战斗程序")--如果要使用忽略敌人机制,需要设置levelfunction的dontIgnoreEnemy为false end local ignoreList = self.IgnoreEnemyList if self.FightMode == LuaConst.EFightMode.ALL then for i=1,#ignoreList do ignoreList[i] = nil end elseif self.FightMode == LuaConst.EFightMode.TEAM_GUILD then local ignoreEnemy = nil for i=#ignoreList, 1, -1 do ignoreEnemy = ignoreList[i] if not self:IsDontIgnoreEnemey(ignoreEnemy) then if not (ignoreEnemy.teamID == self.entity.teamID) and not LevelPlayerManager.IsSameGuild(ignoreEnemy, self.entity) then table_remove(ignoreList, i) end end end end end --添加忽略的怪物类型 function TargetComponent:AddIgnoreEnemyMonsterTypes(types) if self.isDontIgnoreEnemyLevel then logging.error(LTAG.ERROR, "HYW : 警告!试图在不启用忽略敌人机制的关卡操作相关数据,请联系战斗程序")--如果要使用忽略敌人机制,需要设置levelfunction的dontIgnoreEnemy为false end if self.IgnoreEnemyMonsterTypes then local exist = false for i,newType in ipairs(types) do exist = false for j,existType in ipairs(self.IgnoreEnemyMonsterTypes) do if existType == newType then exist = true break end if not exist then table.insert(self.IgnoreEnemyMonsterTypes,newType) end end end else self.IgnoreEnemyMonsterTypes = types end end function TargetComponent:AddIgnoreEnemyCharacterTypes(types) if self.isDontIgnoreEnemyLevel then logging.error(LTAG.ERROR, "HYW : 警告!试图在不启用忽略敌人机制的关卡操作相关数据,请联系战斗程序")--如果要使用忽略敌人机制,需要设置levelfunction的dontIgnoreEnemy为false end if self.IgnoreEnemyCharacterTypes then local exist = false for i,newType in ipairs(types) do exist = false for j,existType in ipairs(self.IgnoreEnemyCharacterTypes) do if existType == newType then exist = true break end if not exist then table.insert(self.IgnoreEnemyCharacterTypes,newType) end end end else self.IgnoreEnemyCharacterTypes = types end end function TargetComponent:IsDontIgnoreEnemey(target) return self.DontIgnoreEnemyDic[target.EntityID] ~= nil or self.DontIgnoreEnemyPlayerIDDic[target._logicInitData.PlayerIDInRoom] ~= nil end --是否把target从敌人中排除出去了 function TargetComponent:IsIgnoreEnemey(target) if self.isDontIgnoreEnemyLevel then return false end local selfMasterEntity = self.entity:GetMasterEntity() if selfMasterEntity then return selfMasterEntity.components.target:IsIgnoreEnemey(target) end local targetMasterEntity = target:GetMasterEntity() if targetMasterEntity then target = targetMasterEntity end if self.IgnoreEnemyCharacterTypes then local characterType = target:GetCharacterType() for i,v in ipairs(self.IgnoreEnemyCharacterTypes) do if characterType == v then return true end end end if self.IgnoreEnemyMonsterTypes then if target:IsMonster() then local targetMonsterType = target._logicInitData._characterData.MonsterType for i,v in ipairs(self.IgnoreEnemyMonsterTypes) do if targetMonsterType == v then return true end end end end for i,_entity in ipairs(self.IgnoreEnemyList) do if _entity == target and not self:IsDontIgnoreEnemey(target) then return true end end return false end function TargetComponent:IsEnemy(otherEntity) return otherEntity:GetCampID() ~= self.entity:GetCampID() and not self:IsIgnoreEnemey(otherEntity) end return TargetComponent