public SkillSelector(WarServerNpcMgr NpcMgr) { npcMgr = NpcMgr; priorityMgr = SkPriorityMgr.instance; }
//此方法仅仅对单体目标有效,多目标的选择不走优先级排序逻辑 //且不能对自己生效和无优先级 //排序完了之后,按照“血量或距离”筛选出合适的NPC public static ServerNPC GetPrioritiedNpc(ServerNPC caster, TargetClass target, WarServerNpcMgr NpcSource, float range, NpcStatus TarStatusInCfg, SkTargetPriority priority, SkPriorityMgr PriorityMgr, LifeNPCType type = LifeNPCType.SkTarAll) { /// /// 获取未排好序的 /// IEnumerable <ServerNPC> unPriority = GetNPCValideStatus(caster, NpcSource, KindOfNPC.Life, target, TarStatusInCfg, type); /// /// 过滤掉超出范围的数据 /// Vector3 anchor = caster.transform.position; Transform trans = caster.transform; float radius = caster.data.configData.radius; unPriority = unPriority.Where(n => IsInRange(anchor, n.data.configData.radius + radius + range, n.transform)); /// /// 排序 /// IPrioritySelect selector = PriorityMgr.getImplement(priority); selector.SortByPriority(unPriority, NpcSource, hasPriority); /// /// 依照排好序的顺序,依次查找出一个适合的目标 /// 查找的方式为:血量和距离 /// ServerNPC theOne = null; bool Highest = target.AnySame(TargetClass.HpHighest); bool Lowest = target.AnySame(TargetClass.HpLowest); bool Farest = target.AnySame(TargetClass.FarAwary); bool Nearest = target.AnySame(TargetClass.Nearest); bool ExceptionCheck = false; int Condition = 0; if (Highest) { Condition++; } if (Lowest) { Condition++; } if (Farest) { Condition++; } if (Nearest) { Condition++; } #if DEBUG Utils.Assert(Condition >= 2, "TargetPriority shall set only one Max Or Min condition."); #endif int count = hasPriority.Count; if (Highest || Lowest) { for (int i = 0; i < count; ++i) { List <ServerNPC> line = hasPriority[i]; if (line != null) { if (Highest) { theOne = line.OrderByDescending(n => n.data.rtData.CurHpNested).FirstOrDefault(); } if (Lowest) { theOne = line.OrderBy(n => n.data.rtData.CurHpNested).FirstOrDefault(); } if (theOne != null) { break; } } } } if (Farest || Nearest) { for (int i = 0; i < count; ++i) { List <ServerNPC> line = hasPriority[i]; if (line != null) { if (Farest) { theOne = line.OrderByDescending(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault(); } if (Nearest) { theOne = line.OrderBy(n => GetVirtualDistance(trans, n.transform)).FirstOrDefault(); } if (theOne != null) { break; } } } } /// /// 这种情况是没有排序的情况,只要能选出来第一个就可以 /// if (Condition == 0) { for (int i = 0; i < count; ++i) { List <ServerNPC> line = hasPriority[i]; if (line != null && line.Count > 0) { theOne = line[0]; if (theOne != null) { break; } } } } return(theOne); }